2 * PROJECT: ReactOS Screen Saver Library
3 * LICENSE: GPL v2 or any later version
4 * FILE: lib/sdk/scrnsave/scrnsave.c
5 * PURPOSE: Library for writing screen savers, compatible with MS' scrnsave.lib
6 * PROGRAMMERS: Anders Norlander <anorland@hem2.passagen.se>
7 * Colin Finck <mail@colinfinck.de>
14 // Screen Saver window class
15 #define CLASS_SCRNSAVE TEXT("WindowsScreenSaverClass")
18 HWND hMainWindow
= NULL
;
19 BOOL fChildPreview
= FALSE
;
20 HINSTANCE hMainInstance
;
21 TCHAR szName
[TITLEBARNAMELEN
];
22 TCHAR szAppName
[APPNAMEBUFFERLEN
];
23 TCHAR szIniFile
[MAXFILELEN
];
24 TCHAR szScreenSaver
[22];
25 TCHAR szHelpFile
[MAXFILELEN
];
26 TCHAR szNoHelpMemory
[BUFFLEN
];
29 // Local house keeping
32 static int ISSPACE(TCHAR c
)
34 return (c
== ' ' || c
== '\t');
37 #define ISNUM(c) ((c) >= '0' && c <= '9')
39 static ULONG_PTR
_toulptr(const TCHAR
*s
)
52 for (n
= 1; p
>= s
; p
--, n
*= 10)
53 res
+= (*p
- '0') * n
;
58 // This function takes care of *must* do tasks, like terminating screen saver
59 static LRESULT WINAPI
SysScreenSaverProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
64 // Mouse is not supposed to move from this position
65 GetCursorPos(&pt_orig
);
85 return ScreenSaverProc(hWnd
, uMsg
, wParam
, lParam
);
88 LRESULT WINAPI
DefScreenSaverProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
90 // Don't do any special processing when in preview mode
92 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
101 // wParam is FALSE, so the screensaver is losing the focus.
102 PostMessage(hWnd
, WM_CLOSE
, 0, 0);
110 if (pt
.x
== pt_orig
.x
&& pt
.y
== pt_orig
.y
)
121 // Send a WM_CLOSE to close the screen saver (allows the screensaver author to do clean-up tasks)
122 PostMessage(hWnd
, WM_CLOSE
, 0, 0);
130 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
133 // Registers the screen saver window class
134 static BOOL
RegisterScreenSaverClass(void)
138 cls
.hIcon
= LoadIcon(hMainInstance
, MAKEINTATOM(ID_APP
));
139 cls
.lpszClassName
= CLASS_SCRNSAVE
;
140 cls
.hbrBackground
= (HBRUSH
)GetStockObject(BLACK_BRUSH
);
141 cls
.hInstance
= hMainInstance
;
142 cls
.style
= CS_VREDRAW
| CS_HREDRAW
| CS_SAVEBITS
| CS_PARENTDC
;
143 cls
.lpfnWndProc
= (WNDPROC
)SysScreenSaverProc
;
145 return RegisterClass(&cls
) != 0;
148 static void LaunchConfig(void)
150 // Only show the dialog if the RegisterDialogClasses function succeeded.
151 // This is the same behaviour as MS' scrnsave.lib.
152 if( RegisterDialogClasses(hMainInstance
) )
153 DialogBox(hMainInstance
, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE
), GetForegroundWindow(), (DLGPROC
) ScreenSaverConfigureDialog
);
156 static int LaunchScreenSaver(HWND hParent
)
162 if (!RegisterScreenSaverClass())
164 MessageBox(NULL
, TEXT("RegisterClass() failed"), NULL
, MB_ICONHAND
);
168 // A slightly different approach needs to be used when displaying in a preview window
172 GetClientRect(hParent
, &rc
);
177 rc
.right
= GetSystemMetrics(SM_CXSCREEN
);
178 rc
.bottom
= GetSystemMetrics(SM_CYSCREEN
);
182 // Create the main screen saver window
183 hMainWindow
= CreateWindowEx(hParent
? 0 : WS_EX_TOPMOST
, CLASS_SCRNSAVE
,
184 TEXT("SCREENSAVER"), style
,
185 0, 0, rc
.right
, rc
.bottom
, hParent
, NULL
,
186 hMainInstance
, NULL
);
188 // Display window and start pumping messages
191 ShowWindow(hMainWindow
, SW_SHOW
);
194 while (GetMessage(&msg
, NULL
, 0, 0))
195 DispatchMessage(&msg
);
201 // Screen Saver entry point
202 int APIENTRY
_tWinMain(HINSTANCE hInst
, HINSTANCE hPrevInst
, LPTSTR CmdLine
, int nCmdShow
)
206 hMainInstance
= hInst
;
208 // Parse the arguments
209 for (p
= CmdLine
; *p
; p
++)
215 // Start the screen saver
216 return LaunchScreenSaver(NULL
);
221 // Start the screen saver in preview mode
223 fChildPreview
= TRUE
;
225 while (ISSPACE(*++p
));
226 hParent
= (HWND
) _toulptr(p
);
228 if (hParent
&& IsWindow(hParent
))
229 return LaunchScreenSaver(hParent
);
235 // Display the configuration dialog