vclref: re-work mbInDtor handling, add IsDisposed method and more.

Change-Id: I4b522e0df372d61d8bb7bbcd4b0629c4412cae06
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 09589f5..7d104a4 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -421,7 +421,6 @@ private:
    ::OutputDevice* mpOutputDevice;

    mutable int mnRefCnt;         // reference count
    bool        mbInDtor = false; // true: We're still in Window-Dtor

#ifdef DBG_UTIL
    friend const char* ::ImplDbgCheckWindow( const void* pObj );
@@ -772,6 +771,7 @@ public:
    bool                                IsMenuFloatingWindow() const;
    bool                                IsToolbarFloatingWindow() const;
    bool                                IsTopWindow() const;
    bool                                IsDisposed() const;
    SystemWindow*                       GetSystemWindow() const;

    void                                EnableAllResize( bool bEnable = true );
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index 4eb3c6b..ab9c90a 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -355,7 +355,6 @@ public:
                        mbCompoundControlHasFocus:1,
                        mbPaintDisabled:1,
                        mbAllResize:1,
                        mbInDtor:1,
                        mbInDispose:1,
                        mbExtTextInput:1,
                        mbInFocusHdl:1,
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 1c4eba9..4c3ba1c 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -1633,7 +1633,12 @@ void Application::setDeInitHook(Link const & hook) {
void ImplDelData::AttachToWindow( const vcl::Window* pWindow )
{
    if( pWindow )
        const_cast<vcl::Window*>(pWindow)->ImplAddDel( this );
    {
        if( pWindow->IsDisposed() )
            mbDel = true;
        else
            const_cast<vcl::Window*>(pWindow)->ImplAddDel( this );
    }
}

// define dtor for ImplDelData
diff --git a/vcl/source/window/event.cxx b/vcl/source/window/event.cxx
index da38fde..d4e4601 100644
--- a/vcl/source/window/event.cxx
+++ b/vcl/source/window/event.cxx
@@ -221,6 +221,9 @@ void Window::CallEventListeners( sal_uLong nEvent, void* pData )
    {
        pWindow->ImplAddDel( &aDelData );

        if ( aDelData.IsDead() )
            return;

        pWindow->mpWindowImpl->maChildEventListeners.Call( &aEvent );

        if ( aDelData.IsDead() )
diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx
index bc16a6e..3691a0a 100644
--- a/vcl/source/window/mouse.cxx
+++ b/vcl/source/window/mouse.cxx
@@ -198,7 +198,7 @@ static bool IsWindowFocused(const WindowImpl& rWinImpl)
void Window::ImplGrabFocus( sal_uInt16 nFlags )
{
    // #143570# no focus for destructing windows
    if( mpWindowImpl->mbInDtor )
    if( !mpWindowImpl || mpWindowImpl->mbInDispose )
        return;

    // some event listeners do really bad stuff
@@ -283,7 +283,9 @@ void Window::ImplGrabFocus( sal_uInt16 nFlags )
        pParent = pParent->mpWindowImpl->mpParent;
    }

    if ( ( pSVData->maWinData.mpFocusWin != this && ! mpWindowImpl->mbInDtor ) || ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
    if ( ( pSVData->maWinData.mpFocusWin != this &&
           mpWindowImpl && !mpWindowImpl->mbInDispose ) ||
         ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
    {
        // EndExtTextInput if it is not the same window
        if ( pSVData->maWinData.mpExtTextInputWin &&
diff --git a/vcl/source/window/stacking.cxx b/vcl/source/window/stacking.cxx
index 9d81501..5b58e2a 100644
--- a/vcl/source/window/stacking.cxx
+++ b/vcl/source/window/stacking.cxx
@@ -632,7 +632,7 @@ void Window::EnableAlwaysOnTop( bool bEnable )

bool Window::IsTopWindow() const
{
    if ( mpWindowImpl->mbInDtor )
    if ( !mpWindowImpl || mpWindowImpl->mbInDispose )
        return false;

    // topwindows must be frames or they must have a borderwindow which is a frame
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 9aa378f..ac250c6 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -131,9 +131,14 @@ namespace
}
#endif

bool Window::IsDisposed() const
{
    return !mpWindowImpl;
}

void Window::dispose()
{
    if (!mpWindowImpl)
    if (IsDisposed())
        return;

    assert( !mpWindowImpl->mbInDispose && "vcl::Window - already in dispose()" );
@@ -571,8 +576,6 @@ void Window::dispose()

Window::~Window()
{
    DBG_ASSERT( !mbInDtor, "~Window - already in DTOR!" );
    mbInDtor = true;
    vcl::LazyDeletor<vcl::Window>::Undelete( this );
    dispose();
}
@@ -1197,8 +1200,6 @@ void Window::ImplInitWindowData( WindowType nType )
    mpOutputDevice = (OutputDevice*)this;

    mnRefCnt = 0;
    mbInDtor = false;                     // true: We're still in Window-Dtor

    mpWindowImpl = new WindowImpl( nType );

    meOutDevType        = OUTDEV_WINDOW;
@@ -1363,6 +1364,12 @@ void Window::ImplSetReallyVisible()

void Window::ImplAddDel( ImplDelData* pDel ) // TODO: make "const" when incompatibility ok
{
    if ( IsDisposed() )
    {
        pDel->mbDel = true;
        return;
    }

    DBG_ASSERT( !pDel->mpWindow, "Window::ImplAddDel(): cannot add ImplDelData twice !" );
    if( !pDel->mpWindow )
    {
@@ -1375,6 +1382,10 @@ void Window::ImplAddDel( ImplDelData* pDel ) // TODO: make "const" when incompat
void Window::ImplRemoveDel( ImplDelData* pDel ) // TODO: make "const" when incompatibility ok
{
    pDel->mpWindow = NULL;      // #112873# pDel is not associated with a Window anymore

    if ( IsDisposed() )
        return;

    if ( mpWindowImpl->mpFirstDel == pDel )
        mpWindowImpl->mpFirstDel = pDel->mpNext;
    else
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx
index b8abd0a..d60d15d 100644
--- a/vcl/source/window/window2.cxx
+++ b/vcl/source/window/window2.cxx
@@ -1215,22 +1215,22 @@ bool Window::IsControlBackground() const

bool Window::IsInPaint() const
{
    return mpWindowImpl->mbInPaint;
    return mpWindowImpl ? mpWindowImpl->mbInPaint : false;
}

vcl::Window* Window::GetParent() const
{
    return mpWindowImpl->mpRealParent;
    return mpWindowImpl ? mpWindowImpl->mpRealParent : NULL;
}

bool Window::IsVisible() const
{
    return mpWindowImpl->mbVisible;
    return mpWindowImpl ? mpWindowImpl->mbVisible : false;
}

bool Window::IsReallyVisible() const
{
    return mpWindowImpl->mbReallyVisible;
    return mpWindowImpl ? mpWindowImpl->mbReallyVisible : false;
}

bool Window::IsReallyShown() const
@@ -1370,8 +1370,8 @@ bool Window::IsCreatedWithToolkit() const
void Window::SetCreatedWithToolkit( bool b )
{
    mpWindowImpl->mbCreatedWithToolkit = b;

}

const Pointer& Window::GetPointer() const
{
    return mpWindowImpl->maPointer;
@@ -1442,6 +1442,9 @@ void Window::InvalidateSizeCache()

void Window::queue_resize(StateChangedType eReason)
{
    if (IsDisposed())
        return;

    bool bSomeoneCares = queue_ungrouped_resize(this);

    if (eReason != StateChangedType::VISIBLE)