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
];
414 ScreenSaverItem
*ScreenSaverItem
= NULL
;
417 /* Add the "None" item */
418 ScreenSaverItem
= pData
->ScreenSaverItems
;
420 ScreenSaverItem
->bIsScreenSaver
= FALSE
;
424 ScreenSaverItem
->szDisplayName
,
425 sizeof(ScreenSaverItem
->szDisplayName
) / sizeof(TCHAR
));
427 i
= SendMessage(hwndScreenSavers
,
430 (LPARAM
)ScreenSaverItem
->szDisplayName
);
432 SendMessage(hwndScreenSavers
,
437 // Initialize number of items into the list
438 pData
->ScreenSaverCount
= 1;
440 // Add all the screensavers in the C:\ReactOS\System32 directory.
441 GetSystemDirectory(szSearchPath
, MAX_PATH
);
442 SearchScreenSavers(hwndScreenSavers
, szSearchPath
, pData
);
444 // Add all the screensavers in the C:\ReactOS directory.
445 GetWindowsDirectory(szSearchPath
, MAX_PATH
);
446 SearchScreenSavers(hwndScreenSavers
, szSearchPath
, pData
);
448 // Add all the screensavers where the applet is stored.
449 GetModuleFileName(hApplet
, szSearchPath
, MAX_PATH
);
450 lpBackSlash
= _tcsrchr(szSearchPath
, _T('\\'));
451 if (lpBackSlash
!= NULL
)
454 SearchScreenSavers(hwndScreenSavers
, szSearchPath
, pData
);
460 SetScreenSaver(HWND hwndDlg
, PDATA pData
)
464 if (RegOpenKeyEx(HKEY_CURRENT_USER
,
465 _T("Control Panel\\Desktop"),
468 ®Key
) == ERROR_SUCCESS
)
472 TCHAR szTime
[256], Sec
;
475 /* set the screensaver */
476 if (pData
->ScreenSaverItems
[pData
->Selection
].bIsScreenSaver
)
478 RegSetValueEx(regKey
,
482 (PBYTE
)pData
->ScreenSaverItems
[pData
->Selection
].szFilename
,
483 _tcslen(pData
->ScreenSaverItems
[pData
->Selection
].szFilename
) * sizeof(TCHAR
));
487 /* Windows deletes the value if no screensaver is set */
488 RegDeleteValue(regKey
, _T("SCRNSAVE.EXE"));
491 /* set the screensaver time delay */
492 Time
= GetDlgItemInt(hwndDlg
,
493 IDC_SCREENS_TIMEDELAY
,
501 _itot(Time
, szTime
, 10);
502 RegSetValueEx(regKey
,
503 _T("ScreenSaveTimeOut"),
507 _tcslen(szTime
) * sizeof(TCHAR
));
509 /* set the secure value */
510 Ret
= SendDlgItemMessage(hwndDlg
,
511 IDC_SCREENS_USEPASSCHK
,
515 Sec
= (Ret
== BST_CHECKED
) ? _T('1') : _T('0');
516 RegSetValueEx(regKey
,
517 _T("ScreenSaverIsSecure"),
529 OnInitDialog(HWND hwndDlg
, PDATA pData
)
532 HWND hwndSSCombo
= GetDlgItem(hwndDlg
, IDC_SCREENS_LIST
);
535 pData
= HeapAlloc(GetProcessHeap(),
540 EndDialog(hwndDlg
, -1);
544 SetWindowLongPtr(hwndDlg
,
548 pData
->Selection
= -1;
550 SendDlgItemMessage(hwndDlg
,
555 ((short) 240, (short) 1));
557 AddScreenSavers(hwndDlg
,
560 CheckRegScreenSaverIsSecure(hwndDlg
);
562 /* set the current screensaver in the combo box */
563 lpCurSs
= GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE"));
569 for (i
= 0; i
< MAX_SCREENSAVERS
; i
++)
571 if (!_tcscmp(lpCurSs
, pData
->ScreenSaverItems
[i
].szFilename
))
580 Num
= SendMessage(hwndSSCombo
,
583 (LPARAM
)pData
->ScreenSaverItems
[i
].szDisplayName
);
585 SendMessage(hwndSSCombo
,
592 SendMessage(hwndSSCombo
,
598 HeapFree(GetProcessHeap(),
604 /* set screensaver to (none) */
605 SendMessage(hwndSSCombo
,
611 /* set the current timeout */
612 lpCurSs
= GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut"));
615 UINT Time
= _ttoi(lpCurSs
);
619 SendDlgItemMessage(hwndDlg
,
625 HeapFree(GetProcessHeap(),
631 SelectionChanged(hwndDlg
,
639 ScreenSaverPageProc(HWND hwndDlg
,
646 pData
= (PDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
652 OnInitDialog(hwndDlg
, pData
);
658 if (pData
->PrevWindowPi
.hProcess
)
660 TerminateProcess(pData
->PrevWindowPi
.hProcess
, 0);
661 CloseHandle(pData
->PrevWindowPi
.hProcess
);
662 CloseHandle(pData
->PrevWindowPi
.hThread
);
664 HeapFree(GetProcessHeap(),
672 SetScreenSaverPreviewBox(hwndDlg
,
679 DWORD controlId
= LOWORD(wParam
);
680 DWORD command
= HIWORD(wParam
);
684 case IDC_SCREENS_LIST
:
686 if (HIWORD(wParam
) == CBN_SELCHANGE
)
688 SelectionChanged(hwndDlg
, pData
);
689 SetScreenSaverPreviewBox(hwndDlg
, pData
);
690 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
695 case IDC_SCREENS_TIMEDELAY
:
697 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
701 case IDC_SCREENS_POWER_BUTTON
: // Start Powercfg.Cpl
703 if (command
== BN_CLICKED
)
704 WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl",SW_SHOWNORMAL
);
708 case IDC_SCREENS_TESTSC
: // Screensaver Preview
710 if(command
== BN_CLICKED
)
712 ScreensaverPreview(hwndDlg
, pData
);
713 SetScreenSaverPreviewBox(hwndDlg
, pData
);
718 case IDC_SCREENS_SETTINGS
: // Screensaver Settings
720 if (command
== BN_CLICKED
)
721 ScreensaverConfig(hwndDlg
, pData
);
725 case IDC_SCREENS_USEPASSCHK
: // Screensaver Is Secure
727 if (command
== BN_CLICKED
)
729 MessageBox(NULL
, TEXT("Feature not yet implemented"), TEXT("Sorry"), MB_OK
);
730 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
740 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
746 SetScreenSaver(hwndDlg
, pData
);
752 /* activate screen saver support */
753 SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE
, TRUE
, 0, SPIF_SENDCHANGE
);
754 SetScreenSaverPreviewBox(hwndDlg
, pData
);
760 /* Disable screensaver support */
761 SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE
, FALSE
, 0, SPIF_SENDCHANGE
);
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
;