diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index f7a8d4f0c2..e5f9269b65 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -749,6 +749,9 @@ private: // common part of all ctors void Init(); + // common part of UnsubclassWin() and DissociateHandle() + WXHWND DoDetachHWND(); + // the (non-virtual) handlers for the events bool HandleMove(int x, int y); bool HandleMoving(wxRect& rect); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 4520968686..f9d251ffff 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1364,14 +1364,10 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd) void wxWindowMSW::UnsubclassWin() { - wxRemoveHandleAssociation(this); + HWND hwnd = DoDetachHWND(); - // Restore old Window proc - HWND hwnd = GetHwnd(); if ( hwnd ) { - SetHWND(0); - wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in UnsubclassWin") ); if ( m_oldWndProc ) @@ -1386,6 +1382,20 @@ void wxWindowMSW::UnsubclassWin() } } +WXHWND wxWindowMSW::DoDetachHWND() +{ + wxRemoveHandleAssociation(this); + + // Restore old Window proc + HWND hwnd = GetHwnd(); + if ( hwnd ) + { + SetHWND(0); + } + + return hwnd; +} + void wxWindowMSW::AssociateHandle(WXWidget handle) { if ( m_hWnd ) @@ -1404,8 +1414,21 @@ void wxWindowMSW::AssociateHandle(WXWidget handle) void wxWindowMSW::DissociateHandle() { - // this also calls SetHWND(0) for us - UnsubclassWin(); + // Unlike in UnsubclassWin() we don't assume that the old HWND was valid, + // it could have been already destroyed, but if it is valid, we can just + // forward to it. + if ( ::IsWindow(GetHwnd()) ) + { + UnsubclassWin(); + } + else // Otherwise just forget about the old HWND. + { + DoDetachHWND(); + + // We shouldn't try to restore it later as it corresponded to a HWND + // which doesn't exist any longer. + m_oldWndProc = nullptr; + } }