From ab3e0002a6197cd096bee57ffe24489d94cae440 Mon Sep 17 00:00:00 2001 From: Stanislav Motylkov Date: Mon, 3 Oct 2022 17:34:10 +0300 Subject: [PATCH] [DESK] Fix screensaver preview drawing Use window subclassing to override WM_PAINT message handling and use RedrawWindow function along with WS_CLIPCHILDREN style for the parent window in order to preserve screensaver drawing. CORE-15929 --- dll/cpl/desk/screensaver.c | 41 +++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/dll/cpl/desk/screensaver.c b/dll/cpl/desk/screensaver.c index f4b81612ca3..6041c533b60 100644 --- a/dll/cpl/desk/screensaver.c +++ b/dll/cpl/desk/screensaver.c @@ -27,6 +27,7 @@ typedef struct _DATA ScreenSaverItem ScreenSaverItems[MAX_SCREENSAVERS]; PROCESS_INFORMATION PrevWindowPi; int Selection; + WNDPROC OldPreviewProc; UINT ScreenSaverCount; HWND ScreenSaverPreviewParent; } DATA, *PDATA; @@ -107,6 +108,33 @@ SelectionChanged(HWND hwndDlg, PDATA pData) } +LRESULT CALLBACK +RedrawSubclassProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + HWND hwnd; + PDATA pData; + LRESULT Ret = FALSE; + + pData = (PDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (!pData) + return Ret; + + Ret = CallWindowProc(pData->OldPreviewProc, hwndDlg, uMsg, wParam, lParam); + + if (uMsg == WM_PAINT) + { + hwnd = pData->ScreenSaverPreviewParent; + if (hwnd) + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); + } + + return Ret; +} + + static VOID ShowScreenSaverPreview(IN LPDRAWITEMSTRUCT draw, IN PDATA pData) { @@ -650,8 +678,16 @@ OnInitDialog(HWND hwndDlg, PDATA pData) HWND hParent = GetDlgItem(hwndDlg, IDC_SCREENS_PREVIEW); HWND hChild; + if (hParent != NULL) + { + pData->OldPreviewProc = (WNDPROC)GetWindowLongPtr(hParent, GWLP_WNDPROC); + SetWindowLongPtr(hParent, GWLP_WNDPROC, (LONG_PTR)RedrawSubclassProc); + SetWindowLongPtr(hParent, GWLP_USERDATA, (LONG_PTR)pData); + } + hChild = CreateWindowEx(0, szPreviewWndClass, NULL, - WS_CHILD, 0, 0, 0, 0, hParent, + WS_CHILD | WS_CLIPCHILDREN, + 0, 0, 0, 0, hParent, NULL, hApplet, NULL); if (hChild != NULL) { @@ -781,6 +817,9 @@ ScreenSaverPageProc(HWND hwndDlg, { if (pData->ScreenSaverPreviewParent) { + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SCREENS_PREVIEW), + GWLP_WNDPROC, + (LONG_PTR)pData->OldPreviewProc); DestroyWindow(pData->ScreenSaverPreviewParent); pData->ScreenSaverPreviewParent = NULL; }