[DESK.CPL] Appearance: Fixup control positions after font metrics fix
[reactos.git] / 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 else
179 {
180 return FALSE;
181 }
182 }
183 else if (dwResult == WAIT_OBJECT_0)
184 {
185 return TRUE;
186 }
187 else
188 {
189 return FALSE;
190 }
191 }
192 }
193
194
195 static VOID
196 ScreensaverConfig(HWND hwndDlg, PDATA pData)
197 {
198 /*
199 * /c:<hwnd> Run configuration, hwnd is handle of calling window
200 */
201
202 TCHAR szCmdline[2048];
203 STARTUPINFO si;
204 PROCESS_INFORMATION pi;
205
206 if (pData->Selection < 1)
207 return;
208
209 _stprintf(szCmdline,
210 _T("%s /c:%Iu"),
211 pData->ScreenSaverItems[pData->Selection].szFilename,
212 (ULONG_PTR)hwndDlg);
213
214 ZeroMemory(&si, sizeof(si));
215 si.cb = sizeof(si);
216 ZeroMemory(&pi, sizeof(pi));
217 if (CreateProcess(NULL,
218 szCmdline,
219 NULL,
220 NULL,
221 FALSE,
222 0,
223 NULL,
224 NULL,
225 &si,
226 &pi))
227 {
228 /* Kill off the previous preview process */
229 if (pData->PrevWindowPi.hProcess)
230 {
231 TerminateProcess(pData->PrevWindowPi.hProcess, 0);
232 CloseHandle(pData->PrevWindowPi.hProcess);
233 CloseHandle(pData->PrevWindowPi.hThread);
234 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL;
235 }
236
237 if (WaitForSettingsDialog(hwndDlg, pi.hProcess))
238 SetScreenSaverPreviewBox(hwndDlg, pData);
239 }
240 }
241
242
243 static VOID
244 ScreensaverPreview(HWND hwndDlg, PDATA pData)
245 {
246 /*
247 /s Run normal
248 */
249
250 TCHAR szCmdline[2048];
251 STARTUPINFO si;
252 PROCESS_INFORMATION pi;
253
254 if (pData->Selection < 1)
255 return;
256
257 /* Kill off the previous preview process */
258 if (pData->PrevWindowPi.hProcess)
259 {
260 TerminateProcess(pData->PrevWindowPi.hProcess, 0);
261 CloseHandle(pData->PrevWindowPi.hProcess);
262 CloseHandle(pData->PrevWindowPi.hThread);
263 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL;
264 }
265
266 _stprintf(szCmdline,
267 _T("%s /s"),
268 pData->ScreenSaverItems[pData->Selection].szFilename);
269
270 ZeroMemory(&si, sizeof(si));
271 si.cb = sizeof(si);
272 ZeroMemory(&pi, sizeof(pi));
273 if (CreateProcess(NULL,
274 szCmdline,
275 NULL,
276 NULL,
277 FALSE,
278 0,
279 NULL,
280 NULL,
281 &si,
282 &pi))
283 {
284 WaitForSingleObject(pi.hProcess, INFINITE);
285 CloseHandle(pi.hProcess);
286 CloseHandle(pi.hThread);
287 }
288 }
289
290
291 static VOID
292 CheckRegScreenSaverIsSecure(HWND hwndDlg)
293 {
294 HKEY hKey;
295 TCHAR szBuffer[2];
296 DWORD bufferSize = sizeof(szBuffer);
297 DWORD varType = REG_SZ;
298 LONG result;
299
300 if (RegOpenKeyEx(HKEY_CURRENT_USER,
301 _T("Control Panel\\Desktop"),
302 0,
303 KEY_ALL_ACCESS,
304 &hKey) == ERROR_SUCCESS)
305 {
306 result = RegQueryValueEx(hKey,
307 _T("ScreenSaverIsSecure"),
308 0,
309 &varType,
310 (LPBYTE)szBuffer,
311 &bufferSize);
312 RegCloseKey(hKey);
313
314 if (result == ERROR_SUCCESS)
315 {
316 if (_ttoi(szBuffer) == 1)
317 {
318 SendDlgItemMessage(hwndDlg,
319 IDC_SCREENS_USEPASSCHK,
320 BM_SETCHECK,
321 (WPARAM)BST_CHECKED,
322 0);
323 return;
324 }
325 }
326
327 SendDlgItemMessage(hwndDlg,
328 IDC_SCREENS_USEPASSCHK,
329 BM_SETCHECK,
330 (WPARAM)BST_UNCHECKED,
331 0);
332 }
333 }
334
335
336 static VOID
337 SearchScreenSavers(HWND hwndScreenSavers,
338 LPCTSTR pszSearchPath,
339 PDATA pData)
340 {
341 WIN32_FIND_DATA fd;
342 TCHAR szSearchPath[MAX_PATH];
343 HANDLE hFind;
344 ScreenSaverItem *ScreenSaverItem;
345 HANDLE hModule;
346 UINT i, ScreenSaverCount;
347 HRESULT hr;
348
349 ScreenSaverCount = pData->ScreenSaverCount;
350
351 hr = StringCbCopy(szSearchPath, sizeof(szSearchPath), pszSearchPath);
352 if (FAILED(hr))
353 return;
354 hr = StringCbCat(szSearchPath, sizeof(szSearchPath), TEXT("\\*.scr"));
355 if (FAILED(hr))
356 return;
357
358 hFind = FindFirstFile(szSearchPath, &fd);
359
360 if (hFind == INVALID_HANDLE_VALUE)
361 return;
362
363 while (ScreenSaverCount < MAX_SCREENSAVERS)
364 {
365 /* Don't add any hidden screensavers */
366 if ((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)
367 {
368 TCHAR filename[MAX_PATH];
369
370 hr = StringCbCopy(filename, sizeof(filename), pszSearchPath);
371 if (FAILED(hr))
372 {
373 FindClose(hFind);
374 return;
375 }
376 hr = StringCbCat(filename, sizeof(filename), _T("\\"));
377 if (FAILED(hr))
378 {
379 FindClose(hFind);
380 return;
381 }
382 hr = StringCbCat(filename, sizeof(filename), fd.cFileName);
383 if (FAILED(hr))
384 {
385 FindClose(hFind);
386 return;
387 }
388
389 ScreenSaverItem = pData->ScreenSaverItems + ScreenSaverCount;
390
391 ScreenSaverItem->bIsScreenSaver = TRUE;
392
393 hModule = LoadLibraryEx(filename,
394 NULL,
395 DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
396 if (hModule)
397 {
398 if (0 == LoadString(hModule,
399 1,
400 ScreenSaverItem->szDisplayName,
401 sizeof(ScreenSaverItem->szDisplayName) / sizeof(TCHAR)))
402 {
403 // If the string does not exists, copy the name of the file
404 hr = StringCbCopy(ScreenSaverItem->szDisplayName, sizeof(ScreenSaverItem->szDisplayName), fd.cFileName);
405 if (FAILED(hr))
406 {
407 FreeLibrary(hModule);
408 FindClose(hFind);
409 return;
410 }
411 ScreenSaverItem->szDisplayName[_tcslen(fd.cFileName)-4] = '\0';
412 }
413 FreeLibrary(hModule);
414 }
415 else
416 {
417 hr = StringCbCopy(ScreenSaverItem->szDisplayName, sizeof(ScreenSaverItem->szDisplayName), _T("Unknown"));
418 if (FAILED(hr))
419 {
420 FindClose(hFind);
421 return;
422 }
423 }
424
425 hr = StringCbCopy(ScreenSaverItem->szFilename, sizeof(ScreenSaverItem->szFilename), filename);
426 if (FAILED(hr))
427 {
428 FindClose(hFind);
429 return;
430 }
431
432 i = SendMessage(hwndScreenSavers,
433 CB_ADDSTRING,
434 0,
435 (LPARAM)ScreenSaverItem->szDisplayName);
436
437 SendMessage(hwndScreenSavers,
438 CB_SETITEMDATA,
439 i,
440 (LPARAM)ScreenSaverCount);
441
442 ScreenSaverCount++;
443 }
444
445 if (!FindNextFile(hFind, &fd))
446 break;
447 }
448
449 FindClose(hFind);
450
451 pData->ScreenSaverCount = ScreenSaverCount;
452 }
453
454
455 static VOID
456 AddScreenSavers(HWND hwndDlg, PDATA pData)
457 {
458 HWND hwndScreenSavers = GetDlgItem(hwndDlg, IDC_SCREENS_LIST);
459 TCHAR szSearchPath[MAX_PATH];
460 TCHAR szLocalPath[MAX_PATH];
461 INT i;
462 ScreenSaverItem *ScreenSaverItem = NULL;
463 LPTSTR lpBackSlash;
464
465 /* Add the "None" item */
466 ScreenSaverItem = pData->ScreenSaverItems;
467
468 ScreenSaverItem->bIsScreenSaver = FALSE;
469
470 LoadString(hApplet,
471 IDS_NONE,
472 ScreenSaverItem->szDisplayName,
473 sizeof(ScreenSaverItem->szDisplayName) / sizeof(TCHAR));
474
475 i = SendMessage(hwndScreenSavers,
476 CB_ADDSTRING,
477 0,
478 (LPARAM)ScreenSaverItem->szDisplayName);
479
480 SendMessage(hwndScreenSavers,
481 CB_SETITEMDATA,
482 i,
483 (LPARAM)0);
484
485 // Initialize number of items into the list
486 pData->ScreenSaverCount = 1;
487
488 // Add all the screensavers where the applet is stored.
489 GetModuleFileName(hApplet, szLocalPath, MAX_PATH);
490 lpBackSlash = _tcsrchr(szLocalPath, _T('\\'));
491 if (lpBackSlash != NULL)
492 {
493 *lpBackSlash = '\0';
494 SearchScreenSavers(hwndScreenSavers, szLocalPath, pData);
495 }
496
497 // Add all the screensavers in the C:\ReactOS\System32 directory.
498 GetSystemDirectory(szSearchPath, MAX_PATH);
499 if (lpBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0)
500 SearchScreenSavers(hwndScreenSavers, szSearchPath, pData);
501
502 // Add all the screensavers in the C:\ReactOS directory.
503 GetWindowsDirectory(szSearchPath, MAX_PATH);
504 if (lpBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0)
505 SearchScreenSavers(hwndScreenSavers, szSearchPath, pData);
506 }
507
508
509 static VOID
510 SetScreenSaver(HWND hwndDlg, PDATA pData)
511 {
512 HKEY regKey;
513 BOOL DeleteMode = FALSE;
514
515 DBG_UNREFERENCED_LOCAL_VARIABLE(DeleteMode);
516
517 if (RegOpenKeyEx(HKEY_CURRENT_USER,
518 _T("Control Panel\\Desktop"),
519 0,
520 KEY_ALL_ACCESS,
521 &regKey) == ERROR_SUCCESS)
522 {
523 INT Time;
524 BOOL bRet;
525 TCHAR Sec;
526 UINT Ret;
527
528 /* Set the screensaver */
529 if (pData->ScreenSaverItems[pData->Selection].bIsScreenSaver)
530 {
531 SIZE_T Length = _tcslen(pData->ScreenSaverItems[pData->Selection].szFilename) * sizeof(TCHAR);
532 RegSetValueEx(regKey,
533 _T("SCRNSAVE.EXE"),
534 0,
535 REG_SZ,
536 (PBYTE)pData->ScreenSaverItems[pData->Selection].szFilename,
537 (DWORD)Length);
538
539 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_UPDATEINIFILE);
540 }
541 else
542 {
543 /* Windows deletes the value if no screensaver is set */
544 RegDeleteValue(regKey, _T("SCRNSAVE.EXE"));
545 DeleteMode = TRUE;
546
547 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, 0, SPIF_UPDATEINIFILE);
548 }
549
550 /* Set the secure value */
551 Ret = SendDlgItemMessage(hwndDlg,
552 IDC_SCREENS_USEPASSCHK,
553 BM_GETCHECK,
554 0,
555 0);
556 Sec = (Ret == BST_CHECKED) ? _T('1') : _T('0');
557 RegSetValueEx(regKey,
558 _T("ScreenSaverIsSecure"),
559 0,
560 REG_SZ,
561 (PBYTE)&Sec,
562 sizeof(TCHAR));
563
564 /* Set the screensaver time delay */
565 Time = GetDlgItemInt(hwndDlg,
566 IDC_SCREENS_TIMEDELAY,
567 &bRet,
568 FALSE);
569 if (Time == 0)
570 Time = 60;
571 else
572 Time *= 60;
573
574 SystemParametersInfoW(SPI_SETSCREENSAVETIMEOUT, Time, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
575
576 RegCloseKey(regKey);
577 }
578 }
579
580
581 static BOOL
582 OnInitDialog(HWND hwndDlg, PDATA pData)
583 {
584 LPTSTR lpCurSs;
585 HWND hwndSSCombo = GetDlgItem(hwndDlg, IDC_SCREENS_LIST);
586 INT Num;
587
588 pData = HeapAlloc(GetProcessHeap(),
589 HEAP_ZERO_MEMORY,
590 sizeof(DATA));
591 if (!pData)
592 {
593 EndDialog(hwndDlg, -1);
594 return FALSE;
595 }
596
597 SetWindowLongPtr(hwndDlg,
598 DWLP_USER,
599 (LONG_PTR)pData);
600
601 pData->Selection = -1;
602
603 SendDlgItemMessage(hwndDlg,
604 IDC_SCREENS_TIME,
605 UDM_SETRANGE,
606 0,
607 MAKELONG
608 ((short) 240, (short) 1));
609
610 AddScreenSavers(hwndDlg,
611 pData);
612
613 CheckRegScreenSaverIsSecure(hwndDlg);
614
615 /* Set the current screensaver in the combo box */
616 lpCurSs = GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE"));
617 if (lpCurSs)
618 {
619 BOOL bFound = FALSE;
620 INT i;
621
622 for (i = 0; i < MAX_SCREENSAVERS; i++)
623 {
624 if (!_tcscmp(lpCurSs, pData->ScreenSaverItems[i].szFilename))
625 {
626 bFound = TRUE;
627 break;
628 }
629 }
630
631 if (bFound)
632 {
633 Num = SendMessage(hwndSSCombo,
634 CB_FINDSTRINGEXACT,
635 -1,
636 (LPARAM)pData->ScreenSaverItems[i].szDisplayName);
637 if (Num != CB_ERR)
638 SendMessage(hwndSSCombo,
639 CB_SETCURSEL,
640 Num,
641 0);
642 }
643 else
644 {
645 SendMessage(hwndSSCombo,
646 CB_SETCURSEL,
647 0,
648 0);
649 }
650
651 HeapFree(GetProcessHeap(),
652 0,
653 lpCurSs);
654 }
655 else
656 {
657 /* Set screensaver to (none) */
658 SendMessage(hwndSSCombo,
659 CB_SETCURSEL,
660 0,
661 0);
662 }
663
664 /* Set the current timeout */
665 lpCurSs = GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut"));
666 if (lpCurSs)
667 {
668 UINT Time = _ttoi(lpCurSs);
669
670 Time /= 60;
671
672 SendDlgItemMessage(hwndDlg,
673 IDC_SCREENS_TIME,
674 UDM_SETPOS32,
675 0,
676 Time);
677
678 HeapFree(GetProcessHeap(),
679 0,
680 lpCurSs);
681
682 }
683
684 SelectionChanged(hwndDlg,
685 pData);
686
687 return TRUE;
688 }
689
690
691 INT_PTR CALLBACK
692 ScreenSaverPageProc(HWND hwndDlg,
693 UINT uMsg,
694 WPARAM wParam,
695 LPARAM lParam)
696 {
697 PDATA pData;
698
699 pData = (PDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
700
701 switch (uMsg)
702 {
703 case WM_INITDIALOG:
704 {
705 OnInitDialog(hwndDlg, pData);
706 break;
707 }
708
709 case WM_DESTROY:
710 {
711 if (pData->PrevWindowPi.hProcess)
712 {
713 TerminateProcess(pData->PrevWindowPi.hProcess, 0);
714 CloseHandle(pData->PrevWindowPi.hProcess);
715 CloseHandle(pData->PrevWindowPi.hThread);
716 }
717 HeapFree(GetProcessHeap(),
718 0,
719 pData);
720 break;
721 }
722
723 case WM_ENDSESSION:
724 {
725 SetScreenSaverPreviewBox(hwndDlg,
726 pData);
727 break;
728 }
729
730 case WM_COMMAND:
731 {
732 DWORD controlId = LOWORD(wParam);
733 DWORD command = HIWORD(wParam);
734
735 switch (controlId)
736 {
737 case IDC_SCREENS_LIST:
738 {
739 if (HIWORD(wParam) == CBN_SELCHANGE)
740 {
741 SelectionChanged(hwndDlg, pData);
742 SetScreenSaverPreviewBox(hwndDlg, pData);
743 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
744 }
745 break;
746 }
747
748 case IDC_SCREENS_TIMEDELAY:
749 {
750 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
751 break;
752 }
753
754 case IDC_SCREENS_POWER_BUTTON: // Start Powercfg.Cpl
755 {
756 if (command == BN_CLICKED)
757 WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl",SW_SHOWNORMAL);
758 break;
759 }
760
761 case IDC_SCREENS_TESTSC: // Screensaver Preview
762 {
763 if (command == BN_CLICKED)
764 {
765 ScreensaverPreview(hwndDlg, pData);
766 SetScreenSaverPreviewBox(hwndDlg, pData);
767 }
768 break;
769 }
770
771 case IDC_SCREENS_SETTINGS: // Screensaver Settings
772 {
773 if (command == BN_CLICKED)
774 ScreensaverConfig(hwndDlg, pData);
775 break;
776 }
777
778 case IDC_SCREENS_USEPASSCHK: // Screensaver Is Secure
779 {
780 if (command == BN_CLICKED)
781 {
782 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
783 }
784 break;
785 }
786 }
787 break;
788 }
789
790 case WM_NOTIFY:
791 {
792 LPNMHDR lpnm = (LPNMHDR)lParam;
793
794 switch(lpnm->code)
795 {
796 case PSN_APPLY:
797 {
798 SetScreenSaver(hwndDlg, pData);
799 return TRUE;
800 }
801
802 case PSN_SETACTIVE:
803 {
804 /* Enable screensaver preview support */
805 SetScreenSaverPreviewBox(hwndDlg, pData);
806 break;
807 }
808
809 case PSN_KILLACTIVE:
810 {
811 /* Kill running preview screensaver */
812 if (pData->PrevWindowPi.hProcess)
813 {
814 TerminateProcess(pData->PrevWindowPi.hProcess, 0);
815 CloseHandle(pData->PrevWindowPi.hProcess);
816 CloseHandle(pData->PrevWindowPi.hThread);
817 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL;
818 }
819 break;
820 }
821 }
822 }
823 break;
824 }
825
826 return FALSE;
827 }