From 5e7e89de16bb5d184d51e2f93924a2b66f9896a1 Mon Sep 17 00:00:00 2001 From: Danail Stoychev Date: Thu, 9 Jul 2020 00:34:44 +0200 Subject: [PATCH] Fix re-parenting TLWs in wxMSW We need to set the new owner for the TLW, instead of using the new parent as the actual parent, in the MSW sense, as this results in a weird situation in which the TLW becomes a child (i.e. non-TLW) window. Closes #18785. --- include/wx/msw/nonownedwnd.h | 1 + src/msw/nonownedwnd.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/wx/msw/nonownedwnd.h b/include/wx/msw/nonownedwnd.h index f19e5d1259..1aeeb6f0d6 100644 --- a/include/wx/msw/nonownedwnd.h +++ b/include/wx/msw/nonownedwnd.h @@ -22,6 +22,7 @@ public: wxNonOwnedWindow(); virtual ~wxNonOwnedWindow(); + virtual bool Reparent(wxWindowBase* newParent); virtual void InheritAttributes() wxOVERRIDE; protected: diff --git a/src/msw/nonownedwnd.cpp b/src/msw/nonownedwnd.cpp index 15f4f89a83..eb0e9309ef 100644 --- a/src/msw/nonownedwnd.cpp +++ b/src/msw/nonownedwnd.cpp @@ -157,6 +157,24 @@ wxNonOwnedWindow::~wxNonOwnedWindow() #endif // wxUSE_GRAPHICS_CONTEXT } +bool wxNonOwnedWindow::Reparent(wxWindowBase* newParent) +{ + // ::SetParent() can't be used for non-owned windows, as they don't have + // any parent, only the owner, so use a different function for them even + // if, confusingly, the owner is stored at the same location as the parent + // and so uses the same GWLP_HWNDPARENT offset. + + // Do not call the base class function here to skip wxWindow reparenting. + if ( !wxWindowBase::Reparent(newParent) ) + return false; + + const HWND hwndOwner = GetParent() ? GetHwndOf(GetParent()) : 0; + + ::SetWindowLongPtr(GetHwnd(), GWLP_HWNDPARENT, (LONG_PTR)hwndOwner); + + return true; +} + namespace {