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 while (PeekMessage(&msg
,
161 if (msg
.message
== WM_QUIT
)
164 if (IsDialogMessage(hwndDlg
, &msg
))
166 TranslateMessage(&msg
);
167 DispatchMessage(&msg
);
171 Ret
= MsgWaitForMultipleObjects(1,
176 if (Ret
== (WAIT_OBJECT_0
))
185 ScreensaverConfig(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
188 /c:<hwnd> Run configuration, hwnd is handle of calling window
191 TCHAR szCmdline
[2048];
193 PROCESS_INFORMATION pi
;
195 if (pGlobalData
->Selection
< 1)
200 pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].szFilename
,
203 ZeroMemory(&si
, sizeof(si
));
205 ZeroMemory(&pi
, sizeof(pi
));
206 if(CreateProcess(NULL
,
217 /* kill off the previous preview process */
218 if (pGlobalData
->PrevWindowPi
.hProcess
)
220 TerminateProcess(pGlobalData
->PrevWindowPi
.hProcess
, 0);
221 CloseHandle(pGlobalData
->PrevWindowPi
.hProcess
);
222 CloseHandle(pGlobalData
->PrevWindowPi
.hThread
);
223 pGlobalData
->PrevWindowPi
.hThread
= pGlobalData
->PrevWindowPi
.hProcess
= NULL
;
226 if (WaitForSettingsDialog(hwndDlg
, pi
.hProcess
))
227 SetScreenSaverPreviewBox(hwndDlg
, pGlobalData
);
233 ScreensaverPreview(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
239 WCHAR szCmdline
[2048];
241 PROCESS_INFORMATION pi
;
243 if (pGlobalData
->Selection
< 1)
246 /* kill off the previous preview process*/
247 if (pGlobalData
->PrevWindowPi
.hProcess
)
249 TerminateProcess(pGlobalData
->PrevWindowPi
.hProcess
, 0);
250 CloseHandle(pGlobalData
->PrevWindowPi
.hProcess
);
251 CloseHandle(pGlobalData
->PrevWindowPi
.hThread
);
252 pGlobalData
->PrevWindowPi
.hThread
= pGlobalData
->PrevWindowPi
.hProcess
= NULL
;
257 pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].szFilename
);
259 ZeroMemory(&si
, sizeof(si
));
261 ZeroMemory(&pi
, sizeof(pi
));
262 if(CreateProcess(NULL
,
273 WaitForSingleObject(pi
.hProcess
, INFINITE
);
274 CloseHandle(pi
.hProcess
);
275 CloseHandle(pi
.hThread
);
281 CheckRegScreenSaverIsSecure(HWND hwndDlg
)
285 DWORD bufferSize
= sizeof(szBuffer
);
286 DWORD varType
= REG_SZ
;
289 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
290 _T("Control Panel\\Desktop"),
293 &hKey
) == ERROR_SUCCESS
)
295 result
= RegQueryValueEx(hKey
,
296 _T("ScreenSaverIsSecure"),
303 if (result
== ERROR_SUCCESS
)
305 if (_ttoi(szBuffer
) == 1)
307 SendDlgItemMessage(hwndDlg
,
308 IDC_SCREENS_USEPASSCHK
,
316 SendDlgItemMessage(hwndDlg
,
317 IDC_SCREENS_USEPASSCHK
,
319 (WPARAM
)BST_UNCHECKED
,
326 AddScreenSavers(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
328 HWND hwndScreenSavers
= GetDlgItem(hwndDlg
, IDC_SCREENS_LIST
);
331 TCHAR szSearchPath
[MAX_PATH
];
333 int ScreenSaverCount
= 0;
334 ScreenSaverItem
*ScreenSaverItem
= NULL
;
335 HANDLE hModule
= NULL
;
337 /* Add the "None" item */
338 ScreenSaverItem
= &pGlobalData
->ScreenSaverItems
[ScreenSaverCount
];
340 ScreenSaverItem
->bIsScreenSaver
= FALSE
;
344 ScreenSaverItem
->szDisplayName
,
345 sizeof(ScreenSaverItem
->szDisplayName
) / sizeof(TCHAR
));
347 i
= SendMessage(hwndScreenSavers
,
350 (LPARAM
)ScreenSaverItem
->szDisplayName
);
352 SendMessage(hwndScreenSavers
,
355 (LPARAM
)ScreenSaverCount
);
359 /* Add all the screensavers in the C:\ReactOS\System32 directory. */
361 GetSystemDirectory(szSearchPath
, MAX_PATH
);
362 _tcscat(szSearchPath
, TEXT("\\*.scr"));
364 hFind
= FindFirstFile(szSearchPath
, &fd
);
365 while (ScreenSaverCount
< MAX_SCREENSAVERS
-1 &&
366 hFind
!= INVALID_HANDLE_VALUE
)
368 /* Don't add any hidden screensavers */
369 if ((fd
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) == 0)
371 TCHAR filename
[MAX_PATH
];
373 GetSystemDirectory(filename
, MAX_PATH
);
375 _tcscat(filename
, TEXT("\\"));
376 _tcscat(filename
, fd
.cFileName
);
378 ScreenSaverItem
= &pGlobalData
->ScreenSaverItems
[ScreenSaverCount
];
380 ScreenSaverItem
->bIsScreenSaver
= TRUE
;
382 hModule
= LoadLibraryEx(filename
,
384 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
389 ScreenSaverItem
->szDisplayName
,
390 sizeof(ScreenSaverItem
->szDisplayName
) / sizeof(TCHAR
));
391 FreeLibrary(hModule
);
395 _tcscpy(ScreenSaverItem
->szDisplayName
, _T("Unknown"));
398 _tcscpy(ScreenSaverItem
->szFilename
, filename
);
400 i
= SendMessage(hwndScreenSavers
,
403 (LPARAM
)ScreenSaverItem
->szDisplayName
);
405 SendMessage(hwndScreenSavers
,
408 (LPARAM
)ScreenSaverCount
);
413 if (!FindNextFile(hFind
, &fd
))
414 hFind
= INVALID_HANDLE_VALUE
;
420 SetScreenSaver(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
424 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
425 _T("Control Panel\\Desktop"),
428 ®Key
) == ERROR_SUCCESS
)
432 TCHAR szTime
[256], Sec
;
435 /* set the screensaver */
436 if (pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].bIsScreenSaver
)
438 RegSetValueEx(regKey
,
442 (PBYTE
)pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].szFilename
,
443 _tcslen(pGlobalData
->ScreenSaverItems
[pGlobalData
->Selection
].szFilename
) * sizeof(TCHAR
));
447 /* Windows deletes the value if no screensaver is set */
448 RegDeleteValue(regKey
, _T("SCRNSAVE.EXE"));
451 /* set the screensaver time delay */
452 Time
= GetDlgItemInt(hwndDlg
,
453 IDC_SCREENS_TIMEDELAY
,
461 _itot(Time
, szTime
, 10);
462 RegSetValueEx(regKey
,
463 _T("ScreenSaveTimeOut"),
467 _tcslen(szTime
) * sizeof(TCHAR
));
469 /* set the secure value */
470 Ret
= SendDlgItemMessage(hwndDlg
,
471 IDC_SCREENS_USEPASSCHK
,
475 Sec
= (Ret
== BST_CHECKED
) ? _T('1') : _T('0');
476 RegSetValueEx(regKey
,
477 _T("ScreenSaverIsSecure"),
489 OnInitDialog(HWND hwndDlg
, PGLOBAL_DATA pGlobalData
)
492 HWND hwndSSCombo
= GetDlgItem(hwndDlg
, IDC_SCREENS_LIST
);
495 pGlobalData
= HeapAlloc(GetProcessHeap(),
497 sizeof(GLOBAL_DATA
));
500 EndDialog(hwndDlg
, -1);
504 SetWindowLongPtr(hwndDlg
,
506 (LONG_PTR
)pGlobalData
);
508 pGlobalData
->Selection
= -1;
510 SendDlgItemMessage(hwndDlg
,
515 ((short) 240, (short) 1));
517 AddScreenSavers(hwndDlg
,
520 CheckRegScreenSaverIsSecure(hwndDlg
);
522 /* set the current screensaver in the combo box */
523 lpCurSs
= GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE"));
529 for (i
= 0; i
< MAX_SCREENSAVERS
; i
++)
531 if (!_tcscmp(lpCurSs
, pGlobalData
->ScreenSaverItems
[i
].szFilename
))
540 Num
= SendMessage(hwndSSCombo
,
543 (LPARAM
)pGlobalData
->ScreenSaverItems
[i
].szDisplayName
);
545 SendMessage(hwndSSCombo
,
552 SendMessage(hwndSSCombo
,
558 HeapFree(GetProcessHeap(),
564 /* set screensaver to (none) */
565 SendMessage(hwndSSCombo
,
571 /* set the current timeout */
572 lpCurSs
= GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut"));
575 UINT Time
= _ttoi(lpCurSs
);
579 SendDlgItemMessage(hwndDlg
,
585 HeapFree(GetProcessHeap(),
591 SelectionChanged(hwndDlg
,
599 ScreenSaverPageProc(HWND hwndDlg
,
604 PGLOBAL_DATA pGlobalData
;
606 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
612 OnInitDialog(hwndDlg
, pGlobalData
);
618 if (pGlobalData
->PrevWindowPi
.hProcess
)
620 TerminateProcess(pGlobalData
->PrevWindowPi
.hProcess
, 0);
621 CloseHandle(pGlobalData
->PrevWindowPi
.hProcess
);
622 CloseHandle(pGlobalData
->PrevWindowPi
.hThread
);
624 HeapFree(GetProcessHeap(),
632 SetScreenSaverPreviewBox(hwndDlg
,
639 DWORD controlId
= LOWORD(wParam
);
640 DWORD command
= HIWORD(wParam
);
644 case IDC_SCREENS_LIST
:
646 if (HIWORD(wParam
) == CBN_SELCHANGE
)
648 SelectionChanged(hwndDlg
, pGlobalData
);
649 SetScreenSaverPreviewBox(hwndDlg
, pGlobalData
);
650 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
655 case IDC_SCREENS_TIMEDELAY
:
657 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
661 case IDC_SCREENS_POWER_BUTTON
: // Start Powercfg.Cpl
663 if (command
== BN_CLICKED
)
664 WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl",SW_SHOWNORMAL
);
668 case IDC_SCREENS_TESTSC
: // Screensaver Preview
670 if(command
== BN_CLICKED
)
672 ScreensaverPreview(hwndDlg
, pGlobalData
);
673 SetScreenSaverPreviewBox(hwndDlg
, pGlobalData
);
678 case IDC_SCREENS_SETTINGS
: // Screensaver Settings
680 if (command
== BN_CLICKED
)
681 ScreensaverConfig(hwndDlg
, pGlobalData
);
685 case IDC_SCREENS_USEPASSCHK
: // Screensaver Is Secure
687 if (command
== BN_CLICKED
)
689 MessageBox(NULL
, TEXT("Feature not yet implemented"), TEXT("Sorry"), MB_OK
);
690 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
700 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
706 SetScreenSaver(hwndDlg
, pGlobalData
);
712 /* activate screen saver support */
713 SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE
, TRUE
, 0, SPIF_SENDCHANGE
);
714 SetScreenSaverPreviewBox(hwndDlg
, pGlobalData
);
720 /* Disable screensaver support */
721 SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE
, FALSE
, 0, SPIF_SENDCHANGE
);
722 if (pGlobalData
->PrevWindowPi
.hProcess
)
724 TerminateProcess(pGlobalData
->PrevWindowPi
.hProcess
, 0);
725 CloseHandle(pGlobalData
->PrevWindowPi
.hProcess
);
726 CloseHandle(pGlobalData
->PrevWindowPi
.hThread
);
727 pGlobalData
->PrevWindowPi
.hThread
= pGlobalData
->PrevWindowPi
.hProcess
= NULL
;