Fix the fix of revision 63943. Noticed by Thomas Faber.
[reactos.git] / reactos / dll / cpl / desk / screensaver.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Display Control Panel
4 * FILE: dll/cpl/desk/screensaver.c
5 * PURPOSE: Screen saver property page
6 *
7 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
8 * Ged Murphy (gedmurphy@reactos.org)
9 */
10
11 #include "desk.h"
12
13 #define MAX_SCREENSAVERS 100
14
15 typedef struct
16 {
17 BOOL bIsScreenSaver; /* Is this background a wallpaper */
18 TCHAR szFilename[MAX_PATH];
19 TCHAR szDisplayName[256];
20 } ScreenSaverItem;
21
22
23 typedef struct _DATA
24 {
25 ScreenSaverItem ScreenSaverItems[MAX_SCREENSAVERS];
26 PROCESS_INFORMATION PrevWindowPi;
27 int Selection;
28 UINT ScreenSaverCount;
29 } DATA, *PDATA;
30
31
32 static LPTSTR
33 GetCurrentScreenSaverValue(LPTSTR lpValue)
34 {
35 HKEY hKey;
36 LPTSTR lpBuf = NULL;
37 DWORD BufSize, Type = REG_SZ;
38 LONG Ret;
39
40 Ret = RegOpenKeyEx(HKEY_CURRENT_USER,
41 _T("Control Panel\\Desktop"),
42 0,
43 KEY_READ,
44 &hKey);
45 if (Ret != ERROR_SUCCESS)
46 return NULL;
47
48 Ret = RegQueryValueEx(hKey,
49 lpValue,
50 0,
51 &Type,
52 NULL,
53 &BufSize);
54 if (Ret == ERROR_SUCCESS)
55 {
56 lpBuf = HeapAlloc(GetProcessHeap(),
57 0,
58 BufSize);
59 if (lpBuf)
60 {
61 Ret = RegQueryValueEx(hKey,
62 lpValue,
63 0,
64 &Type,
65 (LPBYTE)lpBuf,
66 &BufSize);
67 if (Ret != ERROR_SUCCESS)
68 {
69 HeapFree(GetProcessHeap(), 0, lpBuf);
70 lpBuf = NULL;
71 }
72 }
73 }
74
75 RegCloseKey(hKey);
76
77 return lpBuf;
78 }
79
80
81 static VOID
82 SelectionChanged(HWND hwndDlg, PDATA pData)
83 {
84 HWND hwndCombo;
85 BOOL bEnable;
86 INT i;
87
88 hwndCombo = GetDlgItem(hwndDlg, IDC_SCREENS_LIST);
89
90 i = (INT)SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
91 i = (INT)SendMessage(hwndCombo, CB_GETITEMDATA, i, 0);
92
93 pData->Selection = i;
94
95 bEnable = (i != 0);
96
97 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_SETTINGS), bEnable);
98 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_TESTSC), bEnable);
99 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_USEPASSCHK), bEnable);
100 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_TIMEDELAY), bEnable);
101 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_TIME), bEnable);
102 EnableWindow(GetDlgItem(hwndDlg, IDC_WAITTEXT), bEnable);
103 EnableWindow(GetDlgItem(hwndDlg, IDC_MINTEXT), bEnable);
104 }
105
106
107 static VOID
108 SetScreenSaverPreviewBox(HWND hwndDlg, PDATA pData)
109 {
110 HWND hPreview = GetDlgItem(hwndDlg, IDC_SCREENS_PREVIEW);
111 STARTUPINFO si;
112 TCHAR szCmdline[2048];
113
114 /* Kill off the previous preview process */
115 if (pData->PrevWindowPi.hProcess)
116 {
117 TerminateProcess(pData->PrevWindowPi.hProcess, 0);
118 CloseHandle(pData->PrevWindowPi.hProcess);
119 CloseHandle(pData->PrevWindowPi.hThread);
120 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL;
121 }
122
123 if (pData->Selection > 0)
124 {
125 _stprintf(szCmdline,
126 _T("%s /p %Iu"),
127 pData->ScreenSaverItems[pData->Selection].szFilename,
128 (ULONG_PTR)hPreview);
129
130 ZeroMemory(&si, sizeof(si));
131 si.cb = sizeof(si);
132 ZeroMemory(&pData->PrevWindowPi, sizeof(pData->PrevWindowPi));
133
134 if (!CreateProcess(NULL,
135 szCmdline,
136 NULL,
137 NULL,
138 FALSE,
139 0,
140 NULL,
141 NULL,
142 &si,
143 &pData->PrevWindowPi))
144 {
145 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL;
146 }
147 }
148 }
149
150 static BOOL
151 WaitForSettingsDialog(HWND hwndDlg,
152 HANDLE hProcess)
153 {
154 DWORD dwResult;
155 MSG msg;
156
157 while (TRUE)
158 {
159 dwResult = MsgWaitForMultipleObjects(1,
160 &hProcess,
161 FALSE,
162 INFINITE,
163 QS_ALLINPUT);
164 if (dwResult == WAIT_OBJECT_0 + 1)
165 {
166 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
167 {
168 if (msg.message == WM_QUIT)
169 {
170 return FALSE;
171 }
172 if (IsDialogMessage(hwndDlg, &msg))
173 {
174 TranslateMessage(&msg);
175 DispatchMessage(&msg);
176 }
177 }
178 }
179 else
180 {
181 return TRUE;
182 }
183 }
184 }
185
186
187 static VOID
188 ScreensaverConfig(HWND hwndDlg, PDATA pData)
189 {
190 /*
191 * /c:<hwnd> Run configuration, hwnd is handle of calling window
192 */
193
194 TCHAR szCmdline[2048];
195 STARTUPINFO si;
196 PROCESS_INFORMATION pi;
197
198 if (pData->Selection < 1)
199 return;
200
201 _stprintf(szCmdline,
202 _T("%s /c:%Iu"),
203 pData->ScreenSaverItems[pData->Selection].szFilename,
204 (ULONG_PTR)hwndDlg);
205
206 ZeroMemory(&si, sizeof(si));
207 si.cb = sizeof(si);
208 ZeroMemory(&pi, sizeof(pi));
209 if(CreateProcess(NULL,
210 szCmdline,
211 NULL,
212 NULL,
213 FALSE,
214 0,
215 NULL,
216 NULL,
217 &si,
218 &pi))
219 {
220 /* Kill off the previous preview process */
221 if (pData->PrevWindowPi.hProcess)
222 {
223 TerminateProcess(pData->PrevWindowPi.hProcess, 0);
224 CloseHandle(pData->PrevWindowPi.hProcess);
225 CloseHandle(pData->PrevWindowPi.hThread);
226 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL;
227 }
228
229 if (WaitForSettingsDialog(hwndDlg, pi.hProcess))
230 SetScreenSaverPreviewBox(hwndDlg, pData);
231 }
232 }
233
234
235 static VOID
236 ScreensaverPreview(HWND hwndDlg, PDATA pData)
237 {
238 /*
239 /s Run normal
240 */
241
242 TCHAR szCmdline[2048];
243 STARTUPINFO si;
244 PROCESS_INFORMATION pi;
245
246 if (pData->Selection < 1)
247 return;
248
249 /* Kill off the previous preview process */
250 if (pData->PrevWindowPi.hProcess)
251 {
252 TerminateProcess(pData->PrevWindowPi.hProcess, 0);
253 CloseHandle(pData->PrevWindowPi.hProcess);
254 CloseHandle(pData->PrevWindowPi.hThread);
255 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL;
256 }
257
258 _stprintf(szCmdline,
259 _T("%s /s"),
260 pData->ScreenSaverItems[pData->Selection].szFilename);
261
262 ZeroMemory(&si, sizeof(si));
263 si.cb = sizeof(si);
264 ZeroMemory(&pi, sizeof(pi));
265 if(CreateProcess(NULL,
266 szCmdline,
267 NULL,
268 NULL,
269 FALSE,
270 0,
271 NULL,
272 NULL,
273 &si,
274 &pi))
275 {
276 WaitForSingleObject(pi.hProcess, INFINITE);
277 CloseHandle(pi.hProcess);
278 CloseHandle(pi.hThread);
279 }
280 }
281
282
283 static VOID
284 CheckRegScreenSaverIsSecure(HWND hwndDlg)
285 {
286 HKEY hKey;
287 TCHAR szBuffer[2];
288 DWORD bufferSize = sizeof(szBuffer);
289 DWORD varType = REG_SZ;
290 LONG result;
291
292 if (RegOpenKeyEx(HKEY_CURRENT_USER,
293 _T("Control Panel\\Desktop"),
294 0,
295 KEY_ALL_ACCESS,
296 &hKey) == ERROR_SUCCESS)
297 {
298 result = RegQueryValueEx(hKey,
299 _T("ScreenSaverIsSecure"),
300 0,
301 &varType,
302 (LPBYTE)szBuffer,
303 &bufferSize);
304 RegCloseKey(hKey);
305
306 if (result == ERROR_SUCCESS)
307 {
308 if (_ttoi(szBuffer) == 1)
309 {
310 SendDlgItemMessage(hwndDlg,
311 IDC_SCREENS_USEPASSCHK,
312 BM_SETCHECK,
313 (WPARAM)BST_CHECKED,
314 0);
315 return;
316 }
317 }
318
319 SendDlgItemMessage(hwndDlg,
320 IDC_SCREENS_USEPASSCHK,
321 BM_SETCHECK,
322 (WPARAM)BST_UNCHECKED,
323 0);
324 }
325 }
326
327
328 static VOID
329 SearchScreenSavers(HWND hwndScreenSavers,
330 LPCTSTR pszSearchPath,
331 PDATA pData)
332 {
333 WIN32_FIND_DATA fd;
334 TCHAR szSearchPath[MAX_PATH];
335 HANDLE hFind;
336 ScreenSaverItem *ScreenSaverItem;
337 HANDLE hModule;
338 UINT i, ScreenSaverCount;
339 HRESULT hr;
340
341 ScreenSaverCount = pData->ScreenSaverCount;
342
343 hr = StringCbCopy(szSearchPath, sizeof(szSearchPath), pszSearchPath);
344 if (FAILED(hr))
345 return;
346 hr = StringCbCat(szSearchPath, sizeof(szSearchPath), TEXT("\\*.scr"));
347 if (FAILED(hr))
348 return;
349
350 hFind = FindFirstFile(szSearchPath, &fd);
351
352 if (hFind == INVALID_HANDLE_VALUE)
353 return;
354
355 while (ScreenSaverCount < MAX_SCREENSAVERS)
356 {
357 /* Don't add any hidden screensavers */
358 if ((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)
359 {
360 TCHAR filename[MAX_PATH];
361
362 hr = StringCbCopy(filename, sizeof(filename), pszSearchPath);
363 if (FAILED(hr))
364 {
365 FindClose(hFind);
366 return;
367 }
368 hr = StringCbCat(filename, sizeof(filename), _T("\\"));
369 if (FAILED(hr))
370 {
371 FindClose(hFind);
372 return;
373 }
374 hr = StringCbCat(filename, sizeof(filename), fd.cFileName);
375 if (FAILED(hr))
376 {
377 FindClose(hFind);
378 return;
379 }
380
381 ScreenSaverItem = pData->ScreenSaverItems + ScreenSaverCount;
382
383 ScreenSaverItem->bIsScreenSaver = TRUE;
384
385 hModule = LoadLibraryEx(filename,
386 NULL,
387 DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
388 if (hModule)
389 {
390 if (0 == LoadString(hModule,
391 1,
392 ScreenSaverItem->szDisplayName,
393 sizeof(ScreenSaverItem->szDisplayName) / sizeof(TCHAR)))
394 {
395 // If the string does not exists, copy the name of the file
396 hr = StringCbCopy(ScreenSaverItem->szDisplayName, sizeof(ScreenSaverItem->szDisplayName), fd.cFileName);
397 if (FAILED(hr))
398 {
399 FreeLibrary(hModule);
400 FindClose(hFind);
401 return;
402 }
403 ScreenSaverItem->szDisplayName[_tcslen(fd.cFileName)-4] = '\0';
404 }
405 FreeLibrary(hModule);
406 }
407 else
408 {
409 hr = StringCbCopy(ScreenSaverItem->szDisplayName, sizeof(ScreenSaverItem->szDisplayName), _T("Unknown"));
410 if (FAILED(hr))
411 {
412 FindClose(hFind);
413 return;
414 }
415 }
416
417 hr = StringCbCopy(ScreenSaverItem->szFilename, sizeof(ScreenSaverItem->szFilename), filename);
418 if (FAILED(hr))
419 {
420 FindClose(hFind);
421 return;
422 }
423
424 i = SendMessage(hwndScreenSavers,
425 CB_ADDSTRING,
426 0,
427 (LPARAM)ScreenSaverItem->szDisplayName);
428
429 SendMessage(hwndScreenSavers,
430 CB_SETITEMDATA,
431 i,
432 (LPARAM)ScreenSaverCount);
433
434 ScreenSaverCount++;
435 }
436
437 if (!FindNextFile(hFind, &fd))
438 break;
439 }
440
441 FindClose(hFind);
442
443 pData->ScreenSaverCount = ScreenSaverCount;
444 }
445
446
447 static VOID
448 AddScreenSavers(HWND hwndDlg, PDATA pData)
449 {
450 HWND hwndScreenSavers = GetDlgItem(hwndDlg, IDC_SCREENS_LIST);
451 TCHAR szSearchPath[MAX_PATH];
452 TCHAR szLocalPath[MAX_PATH];
453 INT i;
454 ScreenSaverItem *ScreenSaverItem = NULL;
455 LPTSTR lpBackSlash;
456
457 /* Add the "None" item */
458 ScreenSaverItem = pData->ScreenSaverItems;
459
460 ScreenSaverItem->bIsScreenSaver = FALSE;
461
462 LoadString(hApplet,
463 IDS_NONE,
464 ScreenSaverItem->szDisplayName,
465 sizeof(ScreenSaverItem->szDisplayName) / sizeof(TCHAR));
466
467 i = SendMessage(hwndScreenSavers,
468 CB_ADDSTRING,
469 0,
470 (LPARAM)ScreenSaverItem->szDisplayName);
471
472 SendMessage(hwndScreenSavers,
473 CB_SETITEMDATA,
474 i,
475 (LPARAM)0);
476
477 // Initialize number of items into the list
478 pData->ScreenSaverCount = 1;
479
480 // Add all the screensavers where the applet is stored.
481 GetModuleFileName(hApplet, szLocalPath, MAX_PATH);
482 lpBackSlash = _tcsrchr(szLocalPath, _T('\\'));
483 if (lpBackSlash != NULL)
484 {
485 *lpBackSlash = '\0';
486 SearchScreenSavers(hwndScreenSavers, szLocalPath, pData);
487 }
488
489 // Add all the screensavers in the C:\ReactOS\System32 directory.
490 GetSystemDirectory(szSearchPath, MAX_PATH);
491 if (lpBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0)
492 SearchScreenSavers(hwndScreenSavers, szSearchPath, pData);
493
494 // Add all the screensavers in the C:\ReactOS directory.
495 GetWindowsDirectory(szSearchPath, MAX_PATH);
496 if (lpBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0)
497 SearchScreenSavers(hwndScreenSavers, szSearchPath, pData);
498 }
499
500
501 static VOID
502 SetScreenSaver(HWND hwndDlg, PDATA pData)
503 {
504 HKEY regKey;
505 BOOL DeleteMode = FALSE;
506
507 DBG_UNREFERENCED_LOCAL_VARIABLE(DeleteMode);
508
509 if (RegOpenKeyEx(HKEY_CURRENT_USER,
510 _T("Control Panel\\Desktop"),
511 0,
512 KEY_ALL_ACCESS,
513 &regKey) == ERROR_SUCCESS)
514 {
515 INT Time;
516 BOOL bRet;
517 TCHAR Sec;
518 UINT Ret;
519
520 /* Set the screensaver */
521 if (pData->ScreenSaverItems[pData->Selection].bIsScreenSaver)
522 {
523 RegSetValueEx(regKey,
524 _T("SCRNSAVE.EXE"),
525 0,
526 REG_SZ,
527 (PBYTE)pData->ScreenSaverItems[pData->Selection].szFilename,
528 _tcslen(pData->ScreenSaverItems[pData->Selection].szFilename) * sizeof(TCHAR));
529
530 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_UPDATEINIFILE);
531 }
532 else
533 {
534 /* Windows deletes the value if no screensaver is set */
535 RegDeleteValue(regKey, _T("SCRNSAVE.EXE"));
536 DeleteMode = TRUE;
537
538 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, 0, SPIF_UPDATEINIFILE);
539 }
540
541 /* Set the secure value */
542 Ret = SendDlgItemMessage(hwndDlg,
543 IDC_SCREENS_USEPASSCHK,
544 BM_GETCHECK,
545 0,
546 0);
547 Sec = (Ret == BST_CHECKED) ? _T('1') : _T('0');
548 RegSetValueEx(regKey,
549 _T("ScreenSaverIsSecure"),
550 0,
551 REG_SZ,
552 (PBYTE)&Sec,
553 sizeof(TCHAR));
554
555 /* Set the screensaver time delay */
556 Time = GetDlgItemInt(hwndDlg,
557 IDC_SCREENS_TIMEDELAY,
558 &bRet,
559 FALSE);
560 if (Time == 0)
561 Time = 60;
562 else
563 Time *= 60;
564
565 SystemParametersInfoW(SPI_SETSCREENSAVETIMEOUT, Time, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
566
567 RegCloseKey(regKey);
568 }
569 }
570
571
572 static BOOL
573 OnInitDialog(HWND hwndDlg, PDATA pData)
574 {
575 LPTSTR lpCurSs;
576 HWND hwndSSCombo = GetDlgItem(hwndDlg, IDC_SCREENS_LIST);
577 INT Num;
578
579 pData = HeapAlloc(GetProcessHeap(),
580 HEAP_ZERO_MEMORY,
581 sizeof(DATA));
582 if (!pData)
583 {
584 EndDialog(hwndDlg, -1);
585 return FALSE;
586 }
587
588 SetWindowLongPtr(hwndDlg,
589 DWLP_USER,
590 (LONG_PTR)pData);
591
592 pData->Selection = -1;
593
594 SendDlgItemMessage(hwndDlg,
595 IDC_SCREENS_TIME,
596 UDM_SETRANGE,
597 0,
598 MAKELONG
599 ((short) 240, (short) 1));
600
601 AddScreenSavers(hwndDlg,
602 pData);
603
604 CheckRegScreenSaverIsSecure(hwndDlg);
605
606 /* Set the current screensaver in the combo box */
607 lpCurSs = GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE"));
608 if (lpCurSs)
609 {
610 BOOL bFound = FALSE;
611 INT i;
612
613 for (i = 0; i < MAX_SCREENSAVERS; i++)
614 {
615 if (!_tcscmp(lpCurSs, pData->ScreenSaverItems[i].szFilename))
616 {
617 bFound = TRUE;
618 break;
619 }
620 }
621
622 if (bFound)
623 {
624 Num = SendMessage(hwndSSCombo,
625 CB_FINDSTRINGEXACT,
626 -1,
627 (LPARAM)pData->ScreenSaverItems[i].szDisplayName);
628 if (Num != CB_ERR)
629 SendMessage(hwndSSCombo,
630 CB_SETCURSEL,
631 Num,
632 0);
633 }
634 else
635 {
636 SendMessage(hwndSSCombo,
637 CB_SETCURSEL,
638 0,
639 0);
640 }
641
642 HeapFree(GetProcessHeap(),
643 0,
644 lpCurSs);
645 }
646 else
647 {
648 /* Set screensaver to (none) */
649 SendMessage(hwndSSCombo,
650 CB_SETCURSEL,
651 0,
652 0);
653 }
654
655 /* Set the current timeout */
656 lpCurSs = GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut"));
657 if (lpCurSs)
658 {
659 UINT Time = _ttoi(lpCurSs);
660
661 Time /= 60;
662
663 SendDlgItemMessage(hwndDlg,
664 IDC_SCREENS_TIME,
665 UDM_SETPOS32,
666 0,
667 Time);
668
669 HeapFree(GetProcessHeap(),
670 0,
671 lpCurSs);
672
673 }
674
675 SelectionChanged(hwndDlg,
676 pData);
677
678 return TRUE;
679 }
680
681
682 INT_PTR CALLBACK
683 ScreenSaverPageProc(HWND hwndDlg,
684 UINT uMsg,
685 WPARAM wParam,
686 LPARAM lParam)
687 {
688 PDATA pData;
689
690 pData = (PDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
691
692 switch (uMsg)
693 {
694 case WM_INITDIALOG:
695 {
696 OnInitDialog(hwndDlg, pData);
697 break;
698 }
699
700 case WM_DESTROY:
701 {
702 if (pData->PrevWindowPi.hProcess)
703 {
704 TerminateProcess(pData->PrevWindowPi.hProcess, 0);
705 CloseHandle(pData->PrevWindowPi.hProcess);
706 CloseHandle(pData->PrevWindowPi.hThread);
707 }
708 HeapFree(GetProcessHeap(),
709 0,
710 pData);
711 break;
712 }
713
714 case WM_ENDSESSION:
715 {
716 SetScreenSaverPreviewBox(hwndDlg,
717 pData);
718 break;
719 }
720
721 case WM_COMMAND:
722 {
723 DWORD controlId = LOWORD(wParam);
724 DWORD command = HIWORD(wParam);
725
726 switch (controlId)
727 {
728 case IDC_SCREENS_LIST:
729 {
730 if (HIWORD(wParam) == CBN_SELCHANGE)
731 {
732 SelectionChanged(hwndDlg, pData);
733 SetScreenSaverPreviewBox(hwndDlg, pData);
734 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
735 }
736 break;
737 }
738
739 case IDC_SCREENS_TIMEDELAY:
740 {
741 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
742 break;
743 }
744
745 case IDC_SCREENS_POWER_BUTTON: // Start Powercfg.Cpl
746 {
747 if (command == BN_CLICKED)
748 WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl",SW_SHOWNORMAL);
749 break;
750 }
751
752 case IDC_SCREENS_TESTSC: // Screensaver Preview
753 {
754 if(command == BN_CLICKED)
755 {
756 ScreensaverPreview(hwndDlg, pData);
757 SetScreenSaverPreviewBox(hwndDlg, pData);
758 }
759 break;
760 }
761
762 case IDC_SCREENS_SETTINGS: // Screensaver Settings
763 {
764 if (command == BN_CLICKED)
765 ScreensaverConfig(hwndDlg, pData);
766 break;
767 }
768
769 case IDC_SCREENS_USEPASSCHK: // Screensaver Is Secure
770 {
771 if (command == BN_CLICKED)
772 {
773 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
774 }
775 break;
776 }
777 }
778 break;
779 }
780
781 case WM_NOTIFY:
782 {
783 LPNMHDR lpnm = (LPNMHDR)lParam;
784
785 switch(lpnm->code)
786 {
787 case PSN_APPLY:
788 {
789 SetScreenSaver(hwndDlg, pData);
790 return TRUE;
791 }
792
793 case PSN_SETACTIVE:
794 {
795 /* Enable screensaver preview support */
796 SetScreenSaverPreviewBox(hwndDlg, pData);
797 break;
798 }
799
800 case PSN_KILLACTIVE:
801 {
802 /* Kill running preview screensaver */
803 if (pData->PrevWindowPi.hProcess)
804 {
805 TerminateProcess(pData->PrevWindowPi.hProcess, 0);
806 CloseHandle(pData->PrevWindowPi.hProcess);
807 CloseHandle(pData->PrevWindowPi.hThread);
808 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL;
809 }
810 break;
811 }
812 }
813 }
814 break;
815 }
816
817 return FALSE;
818 }