From 78072514e95dc3178c25878caa6ddedd92a6a307 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 16 Jan 2019 01:46:34 +0100 Subject: [PATCH 1/3] Simplify setting nState in WM_NCPAINT handler No real changes, this is just a trivial simplification removing some unnecessary and unused commented out code. --- src/msw/window.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 652910c9af..bdeb6400f2 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3788,14 +3788,7 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result, } // Draw the border - int nState; - if ( !IsEnabled() ) - nState = ETS_DISABLED; - // should we check this? - //else if ( ::GetWindowLong(GetHwnd(), GWL_STYLE) & ES_READONLY) - // nState = ETS_READONLY; - else - nState = ETS_NORMAL; + const int nState = IsEnabled() ? ETS_NORMAL : ETS_DISABLED; ::DrawThemeBackground(hTheme, GetHdcOf(*impl), EP_EDITTEXT, nState, &rcBorder, NULL); } } From d47dbe9faa54acebd8f0072d32eb55d7ad7482f5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 16 Jan 2019 01:50:44 +0100 Subject: [PATCH 2/3] Take into account enabled state when drawing themed borders Pass ETS_DISABLED instead of ETS_NORMAL when the window is disabled. --- src/msw/window.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index bdeb6400f2..522a544b88 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3738,7 +3738,7 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result, hTheme, GetHdcOf(*impl), EP_EDITTEXT, - ETS_NORMAL, + IsEnabled() ? ETS_NORMAL : ETS_DISABLED, rect, &rcClient) == S_OK ) { @@ -3774,21 +3774,22 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result, wxCopyRectToRECT(GetSize(), rcBorder); RECT rcClient; + + const int nState = IsEnabled() ? ETS_NORMAL : ETS_DISABLED; ::GetThemeBackgroundContentRect( - hTheme, GetHdcOf(*impl), EP_EDITTEXT, ETS_NORMAL, &rcBorder, &rcClient); + hTheme, GetHdcOf(*impl), EP_EDITTEXT, nState, &rcBorder, &rcClient); InflateRect(&rcClient, -1, -1); ::ExcludeClipRect(GetHdcOf(*impl), rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); // Make sure the background is in a proper state - if (::IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL)) + if (::IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, nState)) { ::DrawThemeParentBackground(GetHwnd(), GetHdcOf(*impl), &rcBorder); } // Draw the border - const int nState = IsEnabled() ? ETS_NORMAL : ETS_DISABLED; ::DrawThemeBackground(hTheme, GetHdcOf(*impl), EP_EDITTEXT, nState, &rcBorder, NULL); } } From 712e3652ffbfaa42ac27adc0a6846dc2abff5fca Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 16 Jan 2019 01:52:37 +0100 Subject: [PATCH 3/3] Deal with themes not implementing GetThemeBackgroundContentRect() Some custom themes apparently don't implement this function at all and just return failure error code from it, but our code either assumed that it never failed (when handling WM_NCPAINT) or didn't handle its failure correctly (when handle WM_NCCALCSIZE the client rect wasn't returned at all to the system in this case). Fix this by just falling back to the initial rectangle in case of failure. --- src/msw/window.cpp | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 522a544b88..5da2ec427e 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3740,18 +3740,23 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result, EP_EDITTEXT, IsEnabled() ? ETS_NORMAL : ETS_DISABLED, rect, - &rcClient) == S_OK ) + &rcClient) != S_OK ) { - InflateRect(&rcClient, -1, -1); - if (wParam) - csparam->rgrc[0] = rcClient; - else - *((RECT*)lParam) = rcClient; - - // WVR_REDRAW triggers a bug whereby child windows are moved up and left, - // so don't use. - // rc.result = WVR_REDRAW; + // If GetThemeBackgroundContentRect() failed, as can + // happen with at least some custom themes, just use + // the original client rectangle. + rcClient = *rect; } + + InflateRect(&rcClient, -1, -1); + if (wParam) + csparam->rgrc[0] = rcClient; + else + *((RECT*)lParam) = rcClient; + + // WVR_REDRAW triggers a bug whereby child windows are moved up and left, + // so don't use. + // rc.result = WVR_REDRAW; } } break; @@ -3776,8 +3781,23 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result, RECT rcClient; const int nState = IsEnabled() ? ETS_NORMAL : ETS_DISABLED; - ::GetThemeBackgroundContentRect( - hTheme, GetHdcOf(*impl), EP_EDITTEXT, nState, &rcBorder, &rcClient); + + if ( ::GetThemeBackgroundContentRect + ( + hTheme, + GetHdcOf(*impl), + EP_EDITTEXT, + nState, + &rcBorder, + &rcClient + ) != S_OK ) + { + // As above in WM_NCCALCSIZE, fall back on something + // reasonable for themes which don't implement this + // function. + rcClient = rcBorder; + } + InflateRect(&rcClient, -1, -1); ::ExcludeClipRect(GetHdcOf(*impl), rcClient.left, rcClient.top,