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];
25 ScreenSaverItem ScreenSaverItems
[MAX_SCREENSAVERS
];
26 PROCESS_INFORMATION PrevWindowPi
;
28 UINT ScreenSaverCount
;
33 GetCurrentScreenSaverValue(LPTSTR lpValue
)
37 DWORD BufSize
, Type
= REG_SZ
;
40 Ret
= RegOpenKeyEx(HKEY_CURRENT_USER
,
41 _T("Control Panel\\Desktop"),
45 if (Ret
!= ERROR_SUCCESS
)
48 Ret
= RegQueryValueEx(hKey
,
54 if (Ret
== ERROR_SUCCESS
)
56 lpBuf
= HeapAlloc(GetProcessHeap(),
61 Ret
= RegQueryValueEx(hKey
,
67 if (Ret
!= ERROR_SUCCESS
)
79 SelectionChanged(HWND hwndDlg
, PDATA pData
)
85 hwndCombo
= GetDlgItem(hwndDlg
, IDC_SCREENS_LIST
);
87 i
= (INT
)SendMessage(hwndCombo
, CB_GETCURSEL
, 0, 0);
88 i
= (INT
)SendMessage(hwndCombo
, CB_GETITEMDATA
, i
, 0);
94 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_SETTINGS
), bEnable
);
95 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_TESTSC
), bEnable
);
96 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_USEPASSCHK
), bEnable
);
97 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_TIMEDELAY
), bEnable
);
98 EnableWindow(GetDlgItem(hwndDlg
, IDC_SCREENS_TIME
), bEnable
);
99 EnableWindow(GetDlgItem(hwndDlg
, IDC_WAITTEXT
), bEnable
);
100 EnableWindow(GetDlgItem(hwndDlg
, IDC_MINTEXT
), bEnable
);
105 SetScreenSaverPreviewBox(HWND hwndDlg
, PDATA pData
)
107 HWND hPreview
= GetDlgItem(hwndDlg
, IDC_SCREENS_PREVIEW
);
109 TCHAR szCmdline
[2048];
111 /* Kill off the previous preview process */
112 if (pData
->PrevWindowPi
.hProcess
)
114 TerminateProcess(pData
->PrevWindowPi
.hProcess
, 0);
115 CloseHandle(pData
->PrevWindowPi
.hProcess
);
116 CloseHandle(pData
->PrevWindowPi
.hThread
);
117 pData
->PrevWindowPi
.hThread
= pData
->PrevWindowPi
.hProcess
= NULL
;
120 if (pData
->Selection
> 0)
124 pData
->ScreenSaverItems
[pData
->Selection
].szFilename
,
127 ZeroMemory(&si
, sizeof(si
));
129 ZeroMemory(&pData
->PrevWindowPi
, sizeof(pData
->PrevWindowPi
));
131 if (!CreateProcess(NULL
,
140 &pData
->PrevWindowPi
))
142 pData
->PrevWindowPi
.hThread
= pData
->PrevWindowPi
.hProcess
= NULL
;
148 WaitForSettingsDialog(HWND hwndDlg
,
156 dwResult
= MsgWaitForMultipleObjects(1,
161 if (dwResult
== WAIT_OBJECT_0
+ 1)
163 if (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
165 if (msg
.message
== WM_QUIT
)
169 if (IsDialogMessage(hwndDlg
, &msg
))
171 TranslateMessage(&msg
);
172 DispatchMessage(&msg
);
185 ScreensaverConfig(HWND hwndDlg
, PDATA pData
)
188 /c:<hwnd> Run configuration, hwnd is handle of calling window
191 TCHAR szCmdline
[2048];
193 PROCESS_INFORMATION pi
;
195 if (pData
->Selection
< 1)
200 pData
->ScreenSaverItems
[pData
->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 (pData
->PrevWindowPi
.hProcess
)
220 TerminateProcess(pData
->PrevWindowPi
.hProcess
, 0);
221 CloseHandle(pData
->PrevWindowPi
.hProcess
);
222 CloseHandle(pData
->PrevWindowPi
.hThread
);
223 pData
->PrevWindowPi
.hThread
= pData
->PrevWindowPi
.hProcess
= NULL
;
226 if (WaitForSettingsDialog(hwndDlg
, pi
.hProcess
))
227 SetScreenSaverPreviewBox(hwndDlg
, pData
);
233 ScreensaverPreview(HWND hwndDlg
, PDATA pData
)
239 TCHAR szCmdline
[2048];
241 PROCESS_INFORMATION pi
;
243 if (pData
->Selection
< 1)
246 /* Kill off the previous preview process */
247 if (pData
->PrevWindowPi
.hProcess
)
249 TerminateProcess(pData
->PrevWindowPi
.hProcess
, 0);
250 CloseHandle(pData
->PrevWindowPi
.hProcess
);
251 CloseHandle(pData
->PrevWindowPi
.hThread
);
252 pData
->PrevWindowPi
.hThread
= pData
->PrevWindowPi
.hProcess
= NULL
;
257 pData
->ScreenSaverItems
[pData
->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 SearchScreenSavers(HWND hwndScreenSavers
,
327 LPCTSTR pszSearchPath
,
331 TCHAR szSearchPath
[MAX_PATH
];
333 ScreenSaverItem
*ScreenSaverItem
;
335 UINT i
, ScreenSaverCount
;
337 ScreenSaverCount
= pData
->ScreenSaverCount
;
339 _tcscpy(szSearchPath
, pszSearchPath
);
340 _tcscat(szSearchPath
, TEXT("\\*.scr"));
342 hFind
= FindFirstFile(szSearchPath
, &fd
);
344 if (hFind
== INVALID_HANDLE_VALUE
)
347 while (ScreenSaverCount
< MAX_SCREENSAVERS
)
349 /* Don't add any hidden screensavers */
350 if ((fd
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) == 0)
352 TCHAR filename
[MAX_PATH
];
354 _tcscpy(filename
, pszSearchPath
);
355 _tcscat(filename
, _T("\\"));
356 _tcscat(filename
, fd
.cFileName
);
358 ScreenSaverItem
= pData
->ScreenSaverItems
+ ScreenSaverCount
;
360 ScreenSaverItem
->bIsScreenSaver
= TRUE
;
362 hModule
= LoadLibraryEx(filename
,
364 DONT_RESOLVE_DLL_REFERENCES
| LOAD_LIBRARY_AS_DATAFILE
);
367 if (0 == LoadString(hModule
,
369 ScreenSaverItem
->szDisplayName
,
370 sizeof(ScreenSaverItem
->szDisplayName
) / sizeof(TCHAR
)))
372 // If the string does not exists, copy the name of the file
373 _tcscpy(ScreenSaverItem
->szDisplayName
, fd
.cFileName
);
374 ScreenSaverItem
->szDisplayName
[_tcslen(fd
.cFileName
)-4] = '\0';
376 FreeLibrary(hModule
);
380 _tcscpy(ScreenSaverItem
->szDisplayName
, _T("Unknown"));
383 _tcscpy(ScreenSaverItem
->szFilename
, filename
);
385 i
= SendMessage(hwndScreenSavers
,
388 (LPARAM
)ScreenSaverItem
->szDisplayName
);
390 SendMessage(hwndScreenSavers
,
393 (LPARAM
)ScreenSaverCount
);
398 if (!FindNextFile(hFind
, &fd
))
404 pData
->ScreenSaverCount
= ScreenSaverCount
;
409 AddScreenSavers(HWND hwndDlg
, PDATA pData
)
411 HWND hwndScreenSavers
= GetDlgItem(hwndDlg
, IDC_SCREENS_LIST
);
412 TCHAR szSearchPath
[MAX_PATH
];
413 TCHAR szLocalPath
[MAX_PATH
];
415 ScreenSaverItem
*ScreenSaverItem
= NULL
;
418 /* Add the "None" item */
419 ScreenSaverItem
= pData
->ScreenSaverItems
;
421 ScreenSaverItem
->bIsScreenSaver
= FALSE
;
425 ScreenSaverItem
->szDisplayName
,
426 sizeof(ScreenSaverItem
->szDisplayName
) / sizeof(TCHAR
));
428 i
= SendMessage(hwndScreenSavers
,
431 (LPARAM
)ScreenSaverItem
->szDisplayName
);
433 SendMessage(hwndScreenSavers
,
438 // Initialize number of items into the list
439 pData
->ScreenSaverCount
= 1;
441 // Add all the screensavers where the applet is stored.
442 GetModuleFileName(hApplet
, szLocalPath
, MAX_PATH
);
443 lpBackSlash
= _tcsrchr(szLocalPath
, _T('\\'));
444 if (lpBackSlash
!= NULL
)
447 SearchScreenSavers(hwndScreenSavers
, szLocalPath
, pData
);
450 // Add all the screensavers in the C:\ReactOS\System32 directory.
451 GetSystemDirectory(szSearchPath
, MAX_PATH
);
452 if (lpBackSlash
!= NULL
&& _tcsicmp(szSearchPath
, szLocalPath
) != 0)
453 SearchScreenSavers(hwndScreenSavers
, szSearchPath
, pData
);
455 // Add all the screensavers in the C:\ReactOS directory.
456 GetWindowsDirectory(szSearchPath
, MAX_PATH
);
457 if (lpBackSlash
!= NULL
&& _tcsicmp(szSearchPath
, szLocalPath
) != 0)
458 SearchScreenSavers(hwndScreenSavers
, szSearchPath
, pData
);
463 SetScreenSaver(HWND hwndDlg
, PDATA pData
)
466 BOOL DeleteMode
= FALSE
;
468 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
469 _T("Control Panel\\Desktop"),
472 ®Key
) == ERROR_SUCCESS
)
479 /* Set the screensaver */
480 if (pData
->ScreenSaverItems
[pData
->Selection
].bIsScreenSaver
)
482 RegSetValueEx(regKey
,
486 (PBYTE
)pData
->ScreenSaverItems
[pData
->Selection
].szFilename
,
487 _tcslen(pData
->ScreenSaverItems
[pData
->Selection
].szFilename
) * sizeof(TCHAR
));
489 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE
, TRUE
, 0, SPIF_UPDATEINIFILE
);
493 /* Windows deletes the value if no screensaver is set */
494 RegDeleteValue(regKey
, _T("SCRNSAVE.EXE"));
497 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE
, FALSE
, 0, SPIF_UPDATEINIFILE
);
500 /* Set the secure value */
501 Ret
= SendDlgItemMessage(hwndDlg
,
502 IDC_SCREENS_USEPASSCHK
,
506 Sec
= (Ret
== BST_CHECKED
) ? _T('1') : _T('0');
507 RegSetValueEx(regKey
,
508 _T("ScreenSaverIsSecure"),
514 /* Set the screensaver time delay */
515 Time
= GetDlgItemInt(hwndDlg
,
516 IDC_SCREENS_TIMEDELAY
,
524 SystemParametersInfoW(SPI_SETSCREENSAVETIMEOUT
, Time
, 0, SPIF_SENDCHANGE
| SPIF_UPDATEINIFILE
);
532 OnInitDialog(HWND hwndDlg
, PDATA pData
)
535 HWND hwndSSCombo
= GetDlgItem(hwndDlg
, IDC_SCREENS_LIST
);
538 pData
= HeapAlloc(GetProcessHeap(),
543 EndDialog(hwndDlg
, -1);
547 SetWindowLongPtr(hwndDlg
,
551 pData
->Selection
= -1;
553 SendDlgItemMessage(hwndDlg
,
558 ((short) 240, (short) 1));
560 AddScreenSavers(hwndDlg
,
563 CheckRegScreenSaverIsSecure(hwndDlg
);
565 /* Set the current screensaver in the combo box */
566 lpCurSs
= GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE"));
572 for (i
= 0; i
< MAX_SCREENSAVERS
; i
++)
574 if (!_tcscmp(lpCurSs
, pData
->ScreenSaverItems
[i
].szFilename
))
583 Num
= SendMessage(hwndSSCombo
,
586 (LPARAM
)pData
->ScreenSaverItems
[i
].szDisplayName
);
588 SendMessage(hwndSSCombo
,
595 SendMessage(hwndSSCombo
,
601 HeapFree(GetProcessHeap(),
607 /* Set screensaver to (none) */
608 SendMessage(hwndSSCombo
,
614 /* Set the current timeout */
615 lpCurSs
= GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut"));
618 UINT Time
= _ttoi(lpCurSs
);
622 SendDlgItemMessage(hwndDlg
,
628 HeapFree(GetProcessHeap(),
634 SelectionChanged(hwndDlg
,
642 ScreenSaverPageProc(HWND hwndDlg
,
649 pData
= (PDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
655 OnInitDialog(hwndDlg
, pData
);
661 if (pData
->PrevWindowPi
.hProcess
)
663 TerminateProcess(pData
->PrevWindowPi
.hProcess
, 0);
664 CloseHandle(pData
->PrevWindowPi
.hProcess
);
665 CloseHandle(pData
->PrevWindowPi
.hThread
);
667 HeapFree(GetProcessHeap(),
675 SetScreenSaverPreviewBox(hwndDlg
,
682 DWORD controlId
= LOWORD(wParam
);
683 DWORD command
= HIWORD(wParam
);
687 case IDC_SCREENS_LIST
:
689 if (HIWORD(wParam
) == CBN_SELCHANGE
)
691 SelectionChanged(hwndDlg
, pData
);
692 SetScreenSaverPreviewBox(hwndDlg
, pData
);
693 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
698 case IDC_SCREENS_TIMEDELAY
:
700 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
704 case IDC_SCREENS_POWER_BUTTON
: // Start Powercfg.Cpl
706 if (command
== BN_CLICKED
)
707 WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl",SW_SHOWNORMAL
);
711 case IDC_SCREENS_TESTSC
: // Screensaver Preview
713 if(command
== BN_CLICKED
)
715 ScreensaverPreview(hwndDlg
, pData
);
716 SetScreenSaverPreviewBox(hwndDlg
, pData
);
721 case IDC_SCREENS_SETTINGS
: // Screensaver Settings
723 if (command
== BN_CLICKED
)
724 ScreensaverConfig(hwndDlg
, pData
);
728 case IDC_SCREENS_USEPASSCHK
: // Screensaver Is Secure
730 if (command
== BN_CLICKED
)
732 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
742 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
748 SetScreenSaver(hwndDlg
, pData
);
754 /* Enable screensaver preview support */
755 SetScreenSaverPreviewBox(hwndDlg
, pData
);
761 /* Kill running preview screensaver */
762 if (pData
->PrevWindowPi
.hProcess
)
764 TerminateProcess(pData
->PrevWindowPi
.hProcess
, 0);
765 CloseHandle(pData
->PrevWindowPi
.hProcess
);
766 CloseHandle(pData
->PrevWindowPi
.hThread
);
767 pData
->PrevWindowPi
.hThread
= pData
->PrevWindowPi
.hProcess
= NULL
;