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
7 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
8 * Ged Murphy (gedmurphy@reactos.org)
13 #define MAX_SCREENSAVERS 100
17 BOOL bIsScreenSaver
; /* Is this background a wallpaper */
18 TCHAR szFilename
[MAX_PATH
];
19 TCHAR szDisplayName
[256];
23 typedef struct _GLOBAL_DATA
25 ScreenSaverItem ScreenSaverItems
[MAX_SCREENSAVERS
];
26 PROCESS_INFORMATION PrevWindowPi
;
28 } GLOBAL_DATA
, *PGLOBAL_DATA
;
32 GetCurrentScreenSaverValue(LPTSTR lpValue
)
36 DWORD BufSize
, Type
= REG_SZ
;
39 Ret
= RegOpenKeyEx(HKEY_CURRENT_USER
,
40 _T("Control Panel\\Desktop"),
44 if (Ret
!= ERROR_SUCCESS
)
47 Ret
= RegQueryValueEx(hKey
,
53 if (Ret
== ERROR_SUCCESS
)
55 lpBuf
= HeapAlloc(GetProcessHeap(),
60 Ret
= RegQueryValueEx(hKey
,
66 if (Ret
!= ERROR_SUCCESS
)
78 SelectionChanged(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
84 hwndCombo
= GetDlgItem(hwndDlg
, IDC_SCREENS_LIST
);
86 i
= (INT
)SendMessage(hwndCombo
, CB_GETCURSEL
, 0, 0);
87 i
= (INT
)SendMessage(hwndCombo
, CB_GETITEMDATA
, i
, 0);
89 pGlobalData
->Selection
= i
;
93 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_SETTINGS
), bEnable
);
94 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_TESTSC
), bEnable
);
95 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_USEPASSCHK
), bEnable
);
96 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_TIMEDELAY
), bEnable
);
97 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_TIME
), bEnable
);
98 EnableWindow(GetDlgItem(hwndDlg
, IDC_WAITTEXT
), bEnable
);
99 EnableWindow(GetDlgItem(hwndDlg
, IDC_MINTEXT
), bEnable
);
104 SetScreenSaverPreviewBox(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
106 HWND hPreview
= GetDlgItem(hwndDlg
, IDC_SCREENS_PREVIEW
);
108 TCHAR szCmdline
[2048];
110 /* kill off the previous preview process*/
111 if (pGlobalData
->PrevWindowPi
.hProcess
)
113 TerminateProcess(pGlobalData
->PrevWindowPi
.hProcess
, 0);
114 CloseHandle(pGlobalData
->PrevWindowPi
.hProcess
);
115 CloseHandle(pGlobalData
->PrevWindowPi
.hThread
);
116 pGlobalData
->PrevWindowPi
.hThread
= pGlobalData
->PrevWindowPi
.hProcess
= NULL
;
119 if (pGlobalData
->Selection
> 0)
123 pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].szFilename
,
126 ZeroMemory(&si
, sizeof(si
));
128 ZeroMemory(&pGlobalData
->PrevWindowPi
, sizeof(pGlobalData
->PrevWindowPi
));
130 if (!CreateProcess(NULL
,
139 &pGlobalData
->PrevWindowPi
))
141 pGlobalData
->PrevWindowPi
.hThread
= pGlobalData
->PrevWindowPi
.hProcess
= NULL
;
147 WaitForSettingsDialog(HWND hwndDlg
,
155 dwResult
= MsgWaitForMultipleObjects(1,
160 if (dwResult
== WAIT_OBJECT_0
+ 1)
162 if (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
164 if (msg
.message
== WM_QUIT
)
168 if (IsDialogMessage(hwndDlg
, &msg
))
170 TranslateMessage(&msg
);
171 DispatchMessage(&msg
);
184 ScreensaverConfig(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
187 /c:<hwnd> Run configuration, hwnd is handle of calling window
190 TCHAR szCmdline
[2048];
192 PROCESS_INFORMATION pi
;
194 if (pGlobalData
->Selection
< 1)
199 pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].szFilename
,
202 ZeroMemory(&si
, sizeof(si
));
204 ZeroMemory(&pi
, sizeof(pi
));
205 if(CreateProcess(NULL
,
216 /* kill off the previous preview process */
217 if (pGlobalData
->PrevWindowPi
.hProcess
)
219 TerminateProcess(pGlobalData
->PrevWindowPi
.hProcess
, 0);
220 CloseHandle(pGlobalData
->PrevWindowPi
.hProcess
);
221 CloseHandle(pGlobalData
->PrevWindowPi
.hThread
);
222 pGlobalData
->PrevWindowPi
.hThread
= pGlobalData
->PrevWindowPi
.hProcess
= NULL
;
225 if (WaitForSettingsDialog(hwndDlg
, pi
.hProcess
))
226 SetScreenSaverPreviewBox(hwndDlg
, pGlobalData
);
232 ScreensaverPreview(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
238 WCHAR szCmdline
[2048];
240 PROCESS_INFORMATION pi
;
242 if (pGlobalData
->Selection
< 1)
245 /* kill off the previous preview process*/
246 if (pGlobalData
->PrevWindowPi
.hProcess
)
248 TerminateProcess(pGlobalData
->PrevWindowPi
.hProcess
, 0);
249 CloseHandle(pGlobalData
->PrevWindowPi
.hProcess
);
250 CloseHandle(pGlobalData
->PrevWindowPi
.hThread
);
251 pGlobalData
->PrevWindowPi
.hThread
= pGlobalData
->PrevWindowPi
.hProcess
= NULL
;
256 pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].szFilename
);
258 ZeroMemory(&si
, sizeof(si
));
260 ZeroMemory(&pi
, sizeof(pi
));
261 if(CreateProcess(NULL
,
272 WaitForSingleObject(pi
.hProcess
, INFINITE
);
273 CloseHandle(pi
.hProcess
);
274 CloseHandle(pi
.hThread
);
280 CheckRegScreenSaverIsSecure(HWND hwndDlg
)
284 DWORD bufferSize
= sizeof(szBuffer
);
285 DWORD varType
= REG_SZ
;
288 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
289 _T("Control Panel\\Desktop"),
292 &hKey
) == ERROR_SUCCESS
)
294 result
= RegQueryValueEx(hKey
,
295 _T("ScreenSaverIsSecure"),
302 if (result
== ERROR_SUCCESS
)
304 if (_ttoi(szBuffer
) == 1)
306 SendDlgItemMessage(hwndDlg
,
307 IDC_SCREENS_USEPASSCHK
,
315 SendDlgItemMessage(hwndDlg
,
316 IDC_SCREENS_USEPASSCHK
,
318 (WPARAM
)BST_UNCHECKED
,
325 AddScreenSavers(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
327 HWND hwndScreenSavers
= GetDlgItem(hwndDlg
, IDC_SCREENS_LIST
);
330 TCHAR szSearchPath
[MAX_PATH
];
332 int ScreenSaverCount
= 0;
333 ScreenSaverItem
*ScreenSaverItem
= NULL
;
334 HANDLE hModule
= NULL
;
336 /* Add the "None" item */
337 ScreenSaverItem
= &pGlobalData
->ScreenSaverItems
[ScreenSaverCount
];
339 ScreenSaverItem
->bIsScreenSaver
= FALSE
;
343 ScreenSaverItem
->szDisplayName
,
344 sizeof(ScreenSaverItem
->szDisplayName
) / sizeof(TCHAR
));
346 i
= SendMessage(hwndScreenSavers
,
349 (LPARAM
)ScreenSaverItem
->szDisplayName
);
351 SendMessage(hwndScreenSavers
,
354 (LPARAM
)ScreenSaverCount
);
358 /* Add all the screensavers in the C:\ReactOS\System32 directory. */
360 GetSystemDirectory(szSearchPath
, MAX_PATH
);
361 _tcscat(szSearchPath
, TEXT("\\*.scr"));
363 hFind
= FindFirstFile(szSearchPath
, &fd
);
364 while (ScreenSaverCount
< MAX_SCREENSAVERS
-1 &&
365 hFind
!= INVALID_HANDLE_VALUE
)
367 /* Don't add any hidden screensavers */
368 if ((fd
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) == 0)
370 TCHAR filename
[MAX_PATH
];
372 GetSystemDirectory(filename
, MAX_PATH
);
374 _tcscat(filename
, TEXT("\\"));
375 _tcscat(filename
, fd
.cFileName
);
377 ScreenSaverItem
= &pGlobalData
->ScreenSaverItems
[ScreenSaverCount
];
379 ScreenSaverItem
->bIsScreenSaver
= TRUE
;
381 hModule
= LoadLibraryEx(filename
,
383 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
388 ScreenSaverItem
->szDisplayName
,
389 sizeof(ScreenSaverItem
->szDisplayName
) / sizeof(TCHAR
));
390 FreeLibrary(hModule
);
394 _tcscpy(ScreenSaverItem
->szDisplayName
, _T("Unknown"));
397 _tcscpy(ScreenSaverItem
->szFilename
, filename
);
399 i
= SendMessage(hwndScreenSavers
,
402 (LPARAM
)ScreenSaverItem
->szDisplayName
);
404 SendMessage(hwndScreenSavers
,
407 (LPARAM
)ScreenSaverCount
);
412 if (!FindNextFile(hFind
, &fd
))
413 hFind
= INVALID_HANDLE_VALUE
;
419 SetScreenSaver(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
423 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
424 _T("Control Panel\\Desktop"),
427 ®Key
) == ERROR_SUCCESS
)
431 TCHAR szTime
[256], Sec
;
434 /* set the screensaver */
435 if (pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].bIsScreenSaver
)
437 RegSetValueEx(regKey
,
441 (PBYTE
)pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].szFilename
,
442 _tcslen(pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].szFilename
) * sizeof(TCHAR
));
446 /* Windows deletes the value if no screensaver is set */
447 RegDeleteValue(regKey
, _T("SCRNSAVE.EXE"));
450 /* set the screensaver time delay */
451 Time
= GetDlgItemInt(hwndDlg
,
452 IDC_SCREENS_TIMEDELAY
,
460 _itot(Time
, szTime
, 10);
461 RegSetValueEx(regKey
,
462 _T("ScreenSaveTimeOut"),
466 _tcslen(szTime
) * sizeof(TCHAR
));
468 /* set the secure value */
469 Ret
= SendDlgItemMessage(hwndDlg
,
470 IDC_SCREENS_USEPASSCHK
,
474 Sec
= (Ret
== BST_CHECKED
) ? _T('1') : _T('0');
475 RegSetValueEx(regKey
,
476 _T("ScreenSaverIsSecure"),
488 OnInitDialog(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
491 HWND hwndSSCombo
= GetDlgItem(hwndDlg
, IDC_SCREENS_LIST
);
494 pGlobalData
= HeapAlloc(GetProcessHeap(),
496 sizeof(GLOBAL_DATA
));
499 EndDialog(hwndDlg
, -1);
503 SetWindowLongPtr(hwndDlg
,
505 (LONG_PTR
)pGlobalData
);
507 pGlobalData
->Selection
= -1;
509 SendDlgItemMessage(hwndDlg
,
514 ((short) 240, (short) 1));
516 AddScreenSavers(hwndDlg
,
519 CheckRegScreenSaverIsSecure(hwndDlg
);
521 /* set the current screensaver in the combo box */
522 lpCurSs
= GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE"));
528 for (i
= 0; i
< MAX_SCREENSAVERS
; i
++)
530 if (!_tcscmp(lpCurSs
, pGlobalData
->ScreenSaverItems
[i
].szFilename
))
539 Num
= SendMessage(hwndSSCombo
,
542 (LPARAM
)pGlobalData
->ScreenSaverItems
[i
].szDisplayName
);
544 SendMessage(hwndSSCombo
,
551 SendMessage(hwndSSCombo
,
557 HeapFree(GetProcessHeap(),
563 /* set screensaver to (none) */
564 SendMessage(hwndSSCombo
,
570 /* set the current timeout */
571 lpCurSs
= GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut"));
574 UINT Time
= _ttoi(lpCurSs
);
578 SendDlgItemMessage(hwndDlg
,
584 HeapFree(GetProcessHeap(),
590 SelectionChanged(hwndDlg
,
598 ScreenSaverPageProc(HWND hwndDlg
,
603 PGLOBAL_DATA pGlobalData
;
605 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
611 OnInitDialog(hwndDlg
, pGlobalData
);
617 if (pGlobalData
->PrevWindowPi
.hProcess
)
619 TerminateProcess(pGlobalData
->PrevWindowPi
.hProcess
, 0);
620 CloseHandle(pGlobalData
->PrevWindowPi
.hProcess
);
621 CloseHandle(pGlobalData
->PrevWindowPi
.hThread
);
623 HeapFree(GetProcessHeap(),
631 SetScreenSaverPreviewBox(hwndDlg
,
638 DWORD controlId
= LOWORD(wParam
);
639 DWORD command
= HIWORD(wParam
);
643 case IDC_SCREENS_LIST
:
645 if (HIWORD(wParam
) == CBN_SELCHANGE
)
647 SelectionChanged(hwndDlg
, pGlobalData
);
648 SetScreenSaverPreviewBox(hwndDlg
, pGlobalData
);
649 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
654 case IDC_SCREENS_TIMEDELAY
:
656 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
660 case IDC_SCREENS_POWER_BUTTON
: // Start Powercfg.Cpl
662 if (command
== BN_CLICKED
)
663 WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl",SW_SHOWNORMAL
);
667 case IDC_SCREENS_TESTSC
: // Screensaver Preview
669 if(command
== BN_CLICKED
)
671 ScreensaverPreview(hwndDlg
, pGlobalData
);
672 SetScreenSaverPreviewBox(hwndDlg
, pGlobalData
);
677 case IDC_SCREENS_SETTINGS
: // Screensaver Settings
679 if (command
== BN_CLICKED
)
680 ScreensaverConfig(hwndDlg
, pGlobalData
);
684 case IDC_SCREENS_USEPASSCHK
: // Screensaver Is Secure
686 if (command
== BN_CLICKED
)
688 MessageBox(NULL
, TEXT("Feature not yet implemented"), TEXT("Sorry"), MB_OK
);
689 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
699 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
705 SetScreenSaver(hwndDlg
, pGlobalData
);
711 /* activate screen saver support */
712 SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE
, TRUE
, 0, SPIF_SENDCHANGE
);
713 SetScreenSaverPreviewBox(hwndDlg
, pGlobalData
);
719 /* Disable screensaver support */
720 SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE
, FALSE
, 0, SPIF_SENDCHANGE
);
721 if (pGlobalData
->PrevWindowPi
.hProcess
)
723 TerminateProcess(pGlobalData
->PrevWindowPi
.hProcess
, 0);
724 CloseHandle(pGlobalData
->PrevWindowPi
.hProcess
);
725 CloseHandle(pGlobalData
->PrevWindowPi
.hThread
);
726 pGlobalData
->PrevWindowPi
.hThread
= pGlobalData
->PrevWindowPi
.hProcess
= NULL
;