https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ab3e0002a6197cd096bee57ffe24489d94cae440

commit ab3e0002a6197cd096bee57ffe24489d94cae440
Author:     Stanislav Motylkov <x86co...@gmail.com>
AuthorDate: Mon Oct 3 17:34:10 2022 +0300
Commit:     Stanislav Motylkov <x86co...@gmail.com>
CommitDate: Tue Oct 4 21:16:08 2022 +0300

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

Reply via email to