[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
This commit is contained in:
Stanislav Motylkov 2022-10-03 17:34:10 +03:00
parent 092fc8edd0
commit ab3e0002a6
No known key found for this signature in database
GPG key ID: AFE513258CBA9E92

View file

@ -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;
}