source: vendor/w32api/current/lib/scrnsave.c

Last change on this file was 2720, checked in by bird, 19 years ago

w32api v3.6

File size: 9.9 KB
Line 
1/*
2 Screen saver library by Anders Norlander <anorland@hem2.passagen.se>
3
4 This library is (hopefully) compatible with Microsoft's
5 screen saver library.
6
7 This is public domain software.
8
9 */
10#include <windows.h>
11#include <scrnsave.h>
12#include <regstr.h>
13
14/* screen saver window class */
15#define CLASS_SCRNSAVE TEXT("WindowsScreenSaverClass")
16
17/* globals */
18HWND hMainWindow = NULL;
19BOOL fChildPreview = FALSE;
20HINSTANCE hMainInstance;
21TCHAR szName[TITLEBARNAMELEN];
22TCHAR szAppName[APPNAMEBUFFERLEN];
23TCHAR szIniFile[MAXFILELEN];
24TCHAR szScreenSaver[22];
25TCHAR szHelpFile[MAXFILELEN];
26TCHAR szNoHelpMemory[BUFFLEN];
27UINT MyHelpMessage;
28
29/* local house keeping */
30static HINSTANCE hPwdLib = NULL;
31static POINT pt_orig;
32static BOOL checking_pwd = FALSE;
33static BOOL closing = FALSE;
34static BOOL w95 = FALSE;
35
36typedef BOOL (WINAPI *VERIFYPWDPROC)(HWND);
37typedef DWORD (WINAPI *CHPWDPROC)(LPCTSTR, HWND, DWORD, PVOID);
38static VERIFYPWDPROC VerifyScreenSavePwd = NULL;
39
40/* function names */
41#define szVerifyPassword "VerifyScreenSavePwd"
42
43#ifdef UNICODE
44#define szPwdChangePassword "PwdChangePasswordW"
45#else
46#define szPwdChangePassword "PwdChangePasswordA"
47#endif
48
49static void TerminateScreenSaver(HWND hWnd);
50static BOOL RegisterClasses(void);
51static LRESULT WINAPI SysScreenSaverProc(HWND,UINT,WPARAM,LPARAM);
52static int LaunchScreenSaver(HWND hParent);
53static void LaunchConfig(void);
54
55static int ISSPACE(char c)
56{
57 return (c == ' ' || c == '\t');
58}
59
60#define ISNUM(c) ((c) >= '0' && c <= '9')
61static unsigned long
62_toul(const char *s)
63{
64 unsigned long res;
65 unsigned long n;
66 const char *p;
67 for (p = s; *p; p++)
68 if (!ISNUM(*p)) break;
69 p--;
70 res = 0;
71 for (n = 1; p >= s; p--, n *= 10)
72 res += (*p - '0') * n;
73 return res;
74}
75
76/* screen saver entry point */
77int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
78 LPSTR CmdLine, int nCmdShow)
79{
80 LPSTR p;
81 OSVERSIONINFO vi;
82
83 /* initialize */
84 hMainInstance = hInst;
85
86 vi.dwOSVersionInfoSize = sizeof(vi);
87 GetVersionEx(&vi);
88 /* check if we are going to check for passwords */
89 if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
90 {
91 HKEY hKey;
92 /* we are using windows 95 */
93 w95 = TRUE;
94 if (RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE ,&hKey) ==
95 ERROR_SUCCESS)
96 {
97 DWORD check_pwd;
98 DWORD size = sizeof(DWORD);
99 DWORD type;
100 LONG res;
101 res = RegQueryValueEx(hKey, REGSTR_VALUE_USESCRPASSWORD,
102 NULL, &type, (PBYTE) &check_pwd, &size);
103 if (check_pwd && res == ERROR_SUCCESS)
104 {
105 hPwdLib = LoadLibrary(TEXT("PASSWORD.CPL"));
106 if (hPwdLib)
107 VerifyScreenSavePwd = GetProcAddress(hPwdLib, szVerifyPassword);
108 }
109 RegCloseKey(hKey);
110 }
111 }
112
113 /* parse arguments */
114 for (p = CmdLine; *p; p++)
115 {
116 switch (*p)
117 {
118 case 'S':
119 case 's':
120 /* start screen saver */
121 return LaunchScreenSaver(NULL);
122
123 case 'P':
124 case 'p':
125 {
126 /* start screen saver in preview window */
127 HWND hParent;
128 fChildPreview = TRUE;
129 while (ISSPACE(*++p));
130 hParent = (HWND) _toul(p);
131 if (hParent && IsWindow(hParent))
132 return LaunchScreenSaver(hParent);
133 }
134 return 0;
135
136 case 'C':
137 case 'c':
138 /* display configure dialog */
139 LaunchConfig();
140 return 0;
141
142 case 'A':
143 case 'a':
144 {
145 /* change screen saver password */
146 HWND hParent;
147 while (ISSPACE(*++p));
148 hParent = (HWND) _toul(p);
149 if (!hParent || !IsWindow(hParent))
150 hParent = GetForegroundWindow();
151 ScreenSaverChangePassword(hParent);
152 }
153 return 0;
154
155 case '-':
156 case '/':
157 case ' ':
158 default:
159 break;
160 }
161 }
162 LaunchConfig();
163 return 0;
164}
165
166static void LaunchConfig(void)
167{
168 /* FIXME: should this be called */
169 RegisterDialogClasses(hMainInstance);
170 /* display configure dialog */
171 DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE),
172 GetForegroundWindow(), (DLGPROC) ScreenSaverConfigureDialog);
173}
174
175
176static int LaunchScreenSaver(HWND hParent)
177{
178 BOOL foo;
179 UINT style;
180 RECT rc;
181 MSG msg;
182
183 /* don't allow other tasks to get into the foreground */
184 if (w95 && !fChildPreview)
185 SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, &foo, 0);
186
187 msg.wParam = 0;
188
189 /* register classes, both user defined and classes used by screen saver
190 library */
191 if (!RegisterClasses())
192 {
193 MessageBox(NULL, TEXT("RegisterClasses() failed"), NULL, MB_ICONHAND);
194 goto restore;
195 }
196
197 /* a slightly different approach needs to be used when displaying
198 in a preview window */
199 if (hParent)
200 {
201 style = WS_CHILD;
202 GetClientRect(hParent, &rc);
203 }
204 else
205 {
206 style = WS_POPUP;
207 rc.right = GetSystemMetrics(SM_CXSCREEN);
208 rc.bottom = GetSystemMetrics(SM_CYSCREEN);
209 style |= WS_VISIBLE;
210 }
211
212 /* create main screen saver window */
213 hMainWindow = CreateWindowEx(hParent ? 0 : WS_EX_TOPMOST, CLASS_SCRNSAVE,
214 TEXT("SCREENSAVER"), style,
215 0, 0, rc.right, rc.bottom, hParent, NULL,
216 hMainInstance, NULL);
217
218 /* display window and start pumping messages */
219 if (hMainWindow)
220 {
221 UpdateWindow(hMainWindow);
222 ShowWindow(hMainWindow, SW_SHOW);
223
224 while (GetMessage(&msg, NULL, 0, 0) == TRUE)
225 {
226 TranslateMessage(&msg);
227 DispatchMessage(&msg);
228 }
229 }
230
231restore:
232 /* restore system */
233 if (w95 && !fChildPreview)
234 SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &foo, 0);
235 FreeLibrary(hPwdLib);
236 return msg.wParam;
237}
238
239/* this function takes care of *must* do tasks, like terminating
240 screen saver */
241static LRESULT WINAPI SysScreenSaverProc(HWND hWnd, UINT msg,
242 WPARAM wParam, LPARAM lParam)
243{
244 switch (msg)
245 {
246 case WM_CREATE:
247 if (!fChildPreview)
248 SetCursor(NULL);
249 /* mouse is not supposed to move from this position */
250 GetCursorPos(&pt_orig);
251 break;
252 case WM_DESTROY:
253 PostQuitMessage(0);
254 break;
255 case WM_TIMER:
256 if (closing)
257 return 0;
258 break;
259 case WM_PAINT:
260 if (closing)
261 return DefWindowProc(hWnd, msg, wParam, lParam);
262 break;
263 case WM_SYSCOMMAND:
264 if (!fChildPreview)
265 switch (wParam)
266 {
267 case SC_CLOSE:
268 case SC_SCREENSAVE:
269 case SC_NEXTWINDOW:
270 case SC_PREVWINDOW:
271 return FALSE;
272 }
273 break;
274 case WM_MOUSEMOVE:
275 case WM_LBUTTONDOWN:
276 case WM_RBUTTONDOWN:
277 case WM_MBUTTONDOWN:
278 case WM_KEYDOWN:
279 case WM_SYSKEYDOWN:
280 case WM_NCACTIVATE:
281 case WM_ACTIVATE:
282 case WM_ACTIVATEAPP:
283 if (closing)
284 return DefWindowProc(hWnd, msg, wParam, lParam);
285 break;
286 }
287 return ScreenSaverProc(hWnd, msg, wParam, lParam);
288}
289
290LONG WINAPI DefScreenSaverProc(HWND hWnd, UINT msg,
291 WPARAM wParam, LPARAM lParam)
292{
293 /* don't do any special processing when in preview mode */
294 if (fChildPreview || closing)
295 return DefWindowProc(hWnd, msg, wParam, lParam);
296
297 switch (msg)
298 {
299 case WM_CLOSE:
300 TerminateScreenSaver(hWnd);
301 /* do NOT pass this to DefWindowProc; it will terminate even if
302 an invalid password was given.
303 */
304 return 0;
305 case SCRM_VERIFYPW:
306 /* verify password or return TRUE if password checking is turned off */
307 if (VerifyScreenSavePwd)
308 return VerifyScreenSavePwd(hWnd);
309 else
310 return TRUE;
311 case WM_SETCURSOR:
312 if (checking_pwd)
313 break;
314 SetCursor(NULL);
315 return TRUE;
316 case WM_NCACTIVATE:
317 case WM_ACTIVATE:
318 case WM_ACTIVATEAPP:
319 if (wParam != FALSE)
320 break;
321 case WM_MOUSEMOVE:
322 {
323 POINT pt;
324 GetCursorPos(&pt);
325 if (pt.x == pt_orig.x && pt.y == pt_orig.y)
326 break;
327 }
328 case WM_LBUTTONDOWN:
329 case WM_RBUTTONDOWN:
330 case WM_MBUTTONDOWN:
331 case WM_KEYDOWN:
332 case WM_SYSKEYDOWN:
333 /* try to terminate screen saver */
334 if (!checking_pwd)
335 PostMessage(hWnd, WM_CLOSE, 0, 0);
336 break;
337 }
338 return DefWindowProc(hWnd, msg, wParam, lParam);
339}
340
341static void TerminateScreenSaver(HWND hWnd)
342{
343 /* don't allow recursion */
344 if (checking_pwd || closing)
345 return;
346
347 /* verify password */
348 if (VerifyScreenSavePwd)
349 {
350 checking_pwd = TRUE;
351 closing = SendMessage(hWnd, SCRM_VERIFYPW, 0, 0);
352 checking_pwd = FALSE;
353 }
354 else
355 closing = TRUE;
356
357 /* are we closing? */
358 if (closing)
359 {
360 DestroyWindow(hWnd);
361 }
362 else
363 GetCursorPos(&pt_orig); /* if not: get new mouse position */
364}
365
366/*
367 Register screen saver window class and call user
368 supplied hook.
369 */
370static BOOL RegisterClasses(void)
371{
372 WNDCLASS cls;
373
374 cls.hCursor = NULL;
375 cls.hIcon = LoadIcon(hMainInstance, MAKEINTATOM(ID_APP));
376 cls.lpszMenuName = NULL;
377 cls.lpszClassName = CLASS_SCRNSAVE;
378 cls.hbrBackground = GetStockObject(BLACK_BRUSH);
379 cls.hInstance = hMainInstance;
380 cls.style = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_PARENTDC;
381 cls.lpfnWndProc = (WNDPROC) SysScreenSaverProc;
382 cls.cbWndExtra = 0;
383 cls.cbClsExtra = 0;
384
385 if (!RegisterClass(&cls))
386 return FALSE;
387
388 return RegisterDialogClasses(hMainInstance);
389}
390
391void WINAPI ScreenSaverChangePassword(HWND hParent)
392{
393 /* load Master Password Router (MPR) */
394 HINSTANCE hMpr = LoadLibrary(TEXT("MPR.DLL"));
395
396 if (hMpr)
397 {
398 CHPWDPROC ChangePassword;
399 ChangePassword = (CHPWDPROC) GetProcAddress(hMpr, szPwdChangePassword);
400
401 /* change password for screen saver provider */
402 if (ChangePassword)
403 ChangePassword(TEXT("SCRSAVE"), hParent, 0, NULL);
404
405 FreeLibrary(hMpr);
406 }
407}
Note: See TracBrowser for help on using the repository browser.