From ed7f5a671cd055f63e310daa5e76efb07ac63e7c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 11 Jul 2023 13:22:36 +0100 Subject: [PATCH] Fix wxDateTimePickerCtrl arrows redrawing with WS_EX_COMPOSITED This is similar to 79567c83f4 (Fix wxSpinButton redrawing when using WS_EX_COMPOSITED, 2023-07-08) and does the same thing for the spin part of the date time picker control. See #23656. Closes #18231. Closes #23705. --- src/msw/datetimectrl.cpp | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/msw/datetimectrl.cpp b/src/msw/datetimectrl.cpp index 516d89deb7..787a30b8e9 100644 --- a/src/msw/datetimectrl.cpp +++ b/src/msw/datetimectrl.cpp @@ -50,6 +50,40 @@ // wxDateTimePickerCtrl implementation // ============================================================================ +namespace wxMSWImpl +{ + +LRESULT CALLBACK +DateTimeUDProc(HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam, + UINT_PTR uIdSubclass, DWORD_PTR WXUNUSED(dwRefData)) +{ + switch ( nMsg ) + { + case WM_PAINT: + // This is a bit ridiculous, but we have to explicitly paint the + // control here, even if all we do is to let it draw itself, + // because without this it may not draw the lower arrow at all when + // using WS_EX_COMPOSITED (it probably optimizes redraw by assuming + // that previously drawn part doesn't change, but this is not the + // case when compositing it used). + { + PAINTSTRUCT ps; + ::BeginPaint(hwnd, &ps); + ::DefSubclassProc(hwnd, WM_PAINT, (WPARAM)ps.hdc, 0); + ::EndPaint(hwnd, &ps); + } + return 0; + + case WM_NCDESTROY: + ::RemoveWindowSubclass(hwnd, DateTimeUDProc, uIdSubclass); + break; + } + + return ::DefSubclassProc(hwnd, nMsg, wParam, lParam); +} + +} // namespace wxMSWImpl + bool wxDateTimePickerCtrl::MSWCreateDateTimePicker(wxWindow *parent, wxWindowID id, @@ -76,6 +110,15 @@ wxDateTimePickerCtrl::MSWCreateDateTimePicker(wxWindow *parent, else SetValue(wxDateTime::Now()); + // If have an up-down control, we must explicitly paint it ourselves + // because otherwise it may be not redrawn at all with WS_EX_COMPOSITED. + WinStruct info; + ::SendMessage(GetHwnd(), DTM_GETDATETIMEPICKERINFO, 0, (LPARAM)&info); + if ( info.hwndUD ) + { + ::SetWindowSubclass(info.hwndUD, wxMSWImpl::DateTimeUDProc, 0, 0); + } + return true; }