Author: hbelusca
Date: Thu Aug 20 19:44:13 2015
New Revision: 68776
URL: 
http://svn.reactos.org/svn/reactos?rev=68776&view=rev
Log:
[SDK:SCRNSAVE]
- Add support for specifying a parent window handle for the screensaver configuration
dialog, adapted from patch by Timo Kreuzer, see CORE-5718.
- Fix failure return values from the helper functions.
- Add TranslateMessage call in the message pump.
- Get the correct left/top coordinates for the screensaver, being multi-screen aware.
- Use Win-compatible window names & styles for the screensaver preview dialog &
screensaver window, compatible MS' scrnsave.lib.
Modified:
    trunk/reactos/lib/sdk/scrnsave/scrnsave.c
Modified: trunk/reactos/lib/sdk/scrnsave/scrnsave.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/scrnsave/scrnsave.…
==============================================================================
--- trunk/reactos/lib/sdk/scrnsave/scrnsave.c   [iso-8859-1] (original)
+++ trunk/reactos/lib/sdk/scrnsave/scrnsave.c   [iso-8859-1] Thu Aug 20 19:44:13 2015
@@ -2,7 +2,8 @@
  * PROJECT:         ReactOS Screen Saver Library
  * LICENSE:         GPL v2 or any later version
  * FILE:            lib/sdk/scrnsave/scrnsave.c
- * PURPOSE:         Library for writing screen savers, compatible with MS'
scrnsave.lib
+ * PURPOSE:         Library for writing screen savers, compatible with
+ *                  MS' scrnsave.lib without Win9x support.
  * PROGRAMMERS:     Anders Norlander <anorland(a)hem2.passagen.se>
  *                  Colin Finck <mail(a)colinfinck.de>
  */
@@ -38,7 +39,7 @@
     return (c == ' ' || c == '\t');
 }
-#define ISNUM(c) ((c) >= '0' && c <= '9')
+#define ISNUM(c) ((c) >= '0' && (c) <= '9')
 static ULONG_PTR _toulptr(const TCHAR *s)
 {
@@ -78,9 +79,11 @@
             {
                 switch (wParam)
                 {
-                    case SC_CLOSE:
-                    case SC_SCREENSAVE:
-                        return FALSE;
+                    case SC_CLOSE:      // - Closing the screen saver, or...
+                    case SC_NEXTWINDOW: // - Switching to
+                    case SC_PREVWINDOW: //   different windows, or...
+                    case SC_SCREENSAVE: // - Starting another screen saver:
+                        return FALSE;   // Fail it!
                 }
             }
             break;
@@ -102,7 +105,7 @@
         case WM_ACTIVATEAPP:
             if (!wParam)
             {
-                // wParam is FALSE, so the screensaver is losing the focus.
+                // wParam is FALSE, so the screen saver is losing the focus.
                 PostMessage(hWnd, WM_CLOSE, 0, 0);
             }
             break;
@@ -111,6 +114,8 @@
         {
             POINT pt;
             GetCursorPos(&pt);
+            // TODO: Implement mouse move threshold. See:
+            //
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/screensavers/…
             if (pt.x == pt_orig.x && pt.y == pt_orig.y)
                 break;
@@ -118,11 +123,14 @@
         }
         case WM_LBUTTONDOWN:
+        case WM_MBUTTONDOWN:
         case WM_RBUTTONDOWN:
-        case WM_MBUTTONDOWN:
+        case WM_XBUTTONDOWN:
         case WM_KEYDOWN:
         case WM_KEYUP:
-            // Send a WM_CLOSE to close the screen saver (allows the screensaver author
to do clean-up tasks)
+        case WM_SYSKEYDOWN:
+            // Send a WM_CLOSE to close the screen saver (allows
+            // the screen saver to perform clean-up tasks)
             PostMessage(hWnd, WM_CLOSE, 0, 0);
             break;
@@ -137,60 +145,81 @@
 // Registers the screen saver window class
 static BOOL RegisterScreenSaverClass(void)
 {
-    WNDCLASS cls = {0,};
-
-    cls.hIcon = LoadIcon(hMainInstance, MAKEINTATOM(ID_APP));
+    WNDCLASS cls;
+
+    cls.hCursor       = NULL;
+    cls.hIcon         = LoadIcon(hMainInstance, MAKEINTATOM(ID_APP));
+    cls.lpszMenuName  = NULL;
     cls.lpszClassName = CLASS_SCRNSAVE;
     cls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
-    cls.hInstance = hMainInstance;
-    cls.style = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_PARENTDC;
-    cls.lpfnWndProc = SysScreenSaverProc;
-
-    return RegisterClass(&cls) != 0;
-}
-
-static void LaunchConfig(void)
+    cls.hInstance     = hMainInstance;
+    cls.style         = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_SAVEBITS | CS_PARENTDC;
+    cls.lpfnWndProc   = SysScreenSaverProc;
+    cls.cbWndExtra    = 0;
+    cls.cbClsExtra    = 0;
+
+    return (RegisterClass(&cls) != 0);
+}
+
+static int LaunchConfig(HWND hParent)
 {
     // Only show the dialog if the RegisterDialogClasses function succeeded.
     // This is the same behaviour as MS' scrnsave.lib.
-    if( RegisterDialogClasses(hMainInstance) )
-        DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE),
GetForegroundWindow(), (DLGPROC) ScreenSaverConfigureDialog);
+    if (!RegisterDialogClasses(hMainInstance))
+        return -1;
+
+    return DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE),
+                     hParent, (DLGPROC)ScreenSaverConfigureDialog);
 }
 static int LaunchScreenSaver(HWND hParent)
 {
-    UINT style;
+    LPCTSTR lpWindowName;
+    UINT style, exstyle;
     RECT rc;
     MSG msg;
     if (!RegisterScreenSaverClass())
     {
         MessageBox(NULL, TEXT("RegisterClass() failed"), NULL, MB_ICONHAND);
-        return 1;
+        return -1;
     }
     // A slightly different approach needs to be used when displaying in a preview window
     if (hParent)
     {
-        style = WS_CHILD;
+        fChildPreview = TRUE;
+        lpWindowName  = TEXT("Preview");
+
+        style   = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN;
+        exstyle = 0;
+
         GetClientRect(hParent, &rc);
+        rc.left = 0;
+        rc.top  = 0;
     }
     else
     {
-        style = WS_POPUP;
-        rc.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+        fChildPreview = FALSE;
+        lpWindowName  = TEXT("Screen Saver");
+
+        style   = WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+        exstyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
+
+        // Get the left & top side coordinates of the virtual screen
+        rc.left   = GetSystemMetrics(SM_XVIRTUALSCREEN);
+        rc.top    = GetSystemMetrics(SM_YVIRTUALSCREEN);
+        // Get the width and height of the virtual screen
+        rc.right  = GetSystemMetrics(SM_CXVIRTUALSCREEN);
         rc.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
-        style |= WS_VISIBLE;
     }
     // Create the main screen saver window
-    hMainWindow = CreateWindowEx(hParent ? 0 : WS_EX_TOPMOST, CLASS_SCRNSAVE,
-                                 TEXT("SCREENSAVER"), style,
-                                 0, 0, rc.right, rc.bottom, hParent, NULL,
-                                 hMainInstance, NULL);
-
-    if(!hMainWindow)
-        return 1;
+    hMainWindow = CreateWindowEx(exstyle, CLASS_SCRNSAVE, lpWindowName, style,
+                                 rc.left, rc.top, rc.right, rc.bottom,
+                                 hParent, NULL, hMainInstance, NULL);
+    if (!hMainWindow)
+        return -1;
     // Display window and start pumping messages
     ShowWindow(hMainWindow, SW_SHOW);
@@ -198,7 +227,10 @@
         SetCursor(NULL);
     while (GetMessage(&msg, NULL, 0, 0))
+    {
+        TranslateMessage(&msg);
         DispatchMessage(&msg);
+    }
     return msg.wParam;
 }
@@ -208,12 +240,16 @@
 {
     LPTSTR p;
-       UNREFERENCED_PARAMETER(nCmdShow);
-       UNREFERENCED_PARAMETER(hPrevInst);
+    UNREFERENCED_PARAMETER(nCmdShow);
+    UNREFERENCED_PARAMETER(hPrevInst);
     hMainInstance = hInst;
-    // Parse the arguments
+    // Parse the arguments:
+    //   -a <hwnd>  (Change the password; only for Win9x, unused on WinNT)
+    //   -s         (Run the screensaver)
+    //   -p <hwnd>  (Preview)
+    //   -c <hwnd>  (Configure)
     for (p = CmdLine; *p; p++)
     {
         switch (*p)
@@ -226,23 +262,34 @@
             case 'P':
             case 'p':
             {
+                HWND hParent;
+
+                while (ISSPACE(*++p));
+                hParent = (HWND)_toulptr(p);
+
                 // Start the screen saver in preview mode
-                HWND hParent;
-                fChildPreview = TRUE;
-
-                while (ISSPACE(*++p));
-                hParent = (HWND) _toulptr(p);
-
                 if (hParent && IsWindow(hParent))
                     return LaunchScreenSaver(hParent);
+                else
+                    return -1;
             }
-            return 0;
             case 'C':
             case 'c':
+            {
+                HWND hParent;
+
+                if (p[1] == ':')
+                    hParent = (HWND)_toulptr(p + 2);
+                else
+                    hParent = GetForegroundWindow();
+
                 // Display the configuration dialog
-                LaunchConfig();
-                return 0;
+                if (hParent && IsWindow(hParent))
+                    return LaunchConfig(hParent);
+                else
+                    return -1;
+            }
             case '-':
             case '/':
@@ -252,7 +299,5 @@
         }
     }
-    LaunchConfig();
-
-    return 0;
-}
+    return LaunchConfig(NULL);
+}