From f0868129c68ce6df5afeaa0d1ce95c37f1ddec68 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 2 Nov 2019 21:40:57 +0100 Subject: [PATCH] Fix problems with themed borders (dis)appearance in wxMSW Ensure that all native controls get WM_NCCALCSIZE soon after creation, so that we can tell Windows about the themed controls we draw ourselves in WM_NCPAINT. Otherwise we could end up without any visible borders at all and, worse, with bad display artefacts after resizing the control. Just call SetWindowPos(SWP_FRAMECHANGED) to ensure that WM_NCCALCSIZE is generated, even if the control is not resized later, which happens for controls with fixed initial size. Closes #18549. --- src/msw/control.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/msw/control.cpp b/src/msw/control.cpp index 060269776d..1836c3fd71 100644 --- a/src/msw/control.cpp +++ b/src/msw/control.cpp @@ -174,6 +174,29 @@ bool wxControl::MSWCreateControl(const wxChar *classname, // set the size now if no initial size specified SetInitialSize(size); + if ( size.IsFullySpecified() ) + { + // Usually all windows get WM_NCCALCSIZE when their size is set, + // however if the initial size is fixed, it's not going to change and + // this message won't be sent at all, meaning that we won't get a + // chance to tell Windows that we need extra space for our custom + // themed borders, when using them. So force sending this message by + // using SWP_FRAMECHANGED (and use SWP_NOXXX to avoid doing anything + // else) to fix themed borders when they're used (if they're not, this + // is harmless, and it's simpler and more fool proof to always do it + // rather than try to determine whether we need to do it or not). + ::SetWindowPos(GetHwnd(), NULL, 0, 0, 0, 0, + SWP_FRAMECHANGED | + SWP_NOSIZE | + SWP_NOMOVE | + SWP_NOZORDER | + SWP_NOREDRAW | + SWP_NOACTIVATE | + SWP_NOCOPYBITS | + SWP_NOOWNERZORDER | + SWP_NOSENDCHANGING); + } + return true; }