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 static const TCHAR szPreviewWndClass[] = TEXT("SSDemoParent"); 16 17 typedef struct 18 { 19 BOOL bIsScreenSaver; /* Is this a valid screensaver */ 20 TCHAR szFilename[MAX_PATH]; 21 TCHAR szDisplayName[256]; 22 } SCREEN_SAVER_ITEM; 23 24 25 typedef struct _DATA 26 { 27 SCREEN_SAVER_ITEM ScreenSaverItems[MAX_SCREENSAVERS]; 28 PROCESS_INFORMATION PrevWindowPi; 29 int Selection; 30 WNDPROC OldPreviewProc; 31 UINT ScreenSaverCount; 32 HWND ScreenSaverPreviewParent; 33 } DATA, *PDATA; 34 35 36 static LPTSTR 37 GetCurrentScreenSaverValue(LPTSTR lpValue) 38 { 39 HKEY hKey; 40 LPTSTR lpBuf = NULL; 41 DWORD BufSize, Type = REG_SZ; 42 LONG Ret; 43 44 Ret = RegOpenKeyEx(HKEY_CURRENT_USER, 45 _T("Control Panel\\Desktop"), 46 0, 47 KEY_READ, 48 &hKey); 49 if (Ret != ERROR_SUCCESS) 50 return NULL; 51 52 Ret = RegQueryValueEx(hKey, 53 lpValue, 54 0, 55 &Type, 56 NULL, 57 &BufSize); 58 if (Ret == ERROR_SUCCESS) 59 { 60 lpBuf = HeapAlloc(GetProcessHeap(), 0, BufSize); 61 if (lpBuf) 62 { 63 Ret = RegQueryValueEx(hKey, 64 lpValue, 65 0, 66 &Type, 67 (LPBYTE)lpBuf, 68 &BufSize); 69 if (Ret != ERROR_SUCCESS) 70 { 71 HeapFree(GetProcessHeap(), 0, lpBuf); 72 lpBuf = NULL; 73 } 74 } 75 } 76 77 RegCloseKey(hKey); 78 79 return lpBuf; 80 } 81 82 83 static VOID 84 SelectionChanged(HWND hwndDlg, PDATA pData) 85 { 86 HWND hwndCombo; 87 BOOL bEnable; 88 INT i; 89 90 hwndCombo = GetDlgItem(hwndDlg, IDC_SCREENS_LIST); 91 92 i = (INT)SendMessage(hwndCombo, CB_GETCURSEL, 0, 0); 93 i = (INT)SendMessage(hwndCombo, CB_GETITEMDATA, i, 0); 94 95 pData->Selection = i; 96 97 bEnable = (i != 0); 98 99 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_SETTINGS), bEnable); 100 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_TESTSC), bEnable); 101 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_USEPASSCHK), bEnable); 102 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_TIMEDELAY), bEnable); 103 EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_TIME), bEnable); 104 EnableWindow(GetDlgItem(hwndDlg, IDC_WAITTEXT), bEnable); 105 EnableWindow(GetDlgItem(hwndDlg, IDC_MINTEXT), bEnable); 106 } 107 108 109 LRESULT CALLBACK 110 RedrawSubclassProc(HWND hwndDlg, 111 UINT uMsg, 112 WPARAM wParam, 113 LPARAM lParam) 114 { 115 HWND hwnd; 116 PDATA pData; 117 LRESULT Ret = FALSE; 118 119 pData = (PDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 120 if (!pData) 121 return Ret; 122 123 Ret = CallWindowProc(pData->OldPreviewProc, hwndDlg, uMsg, wParam, lParam); 124 125 if (uMsg == WM_PAINT) 126 { 127 hwnd = pData->ScreenSaverPreviewParent; 128 if (hwnd) 129 RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); 130 } 131 132 return Ret; 133 } 134 135 136 static VOID 137 ShowScreenSaverPreview(IN LPDRAWITEMSTRUCT draw, IN PDATA pData) 138 { 139 HBRUSH hBrush; 140 HDC hDC; 141 HGDIOBJ hOldObj; 142 RECT rcItem = { 143 MONITOR_LEFT, 144 MONITOR_TOP, 145 MONITOR_RIGHT, 146 MONITOR_BOTTOM 147 }; 148 149 hDC = CreateCompatibleDC(draw->hDC); 150 hOldObj = SelectObject(hDC, g_GlobalData.hMonitorBitmap); 151 152 if (!IsWindowVisible(pData->ScreenSaverPreviewParent)) 153 { 154 /* FIXME: Draw static bitmap inside monitor. */ 155 hBrush = CreateSolidBrush(g_GlobalData.desktop_color); 156 FillRect(hDC, &rcItem, hBrush); 157 DeleteObject(hBrush); 158 } 159 160 GdiTransparentBlt(draw->hDC, 161 draw->rcItem.left, draw->rcItem.top, 162 draw->rcItem.right - draw->rcItem.left + 1, 163 draw->rcItem.bottom - draw->rcItem.top + 1, 164 hDC, 165 0, 0, 166 g_GlobalData.bmMonWidth, g_GlobalData.bmMonHeight, 167 MONITOR_ALPHA); 168 169 SelectObject(hDC, hOldObj); 170 DeleteDC(hDC); 171 } 172 173 174 /* 175 * /p:<hwnd> Run preview, hwnd is handle of calling window 176 */ 177 static VOID 178 SetScreenSaverPreviewBox(HWND hwndDlg, PDATA pData) 179 { 180 HWND hPreview = pData->ScreenSaverPreviewParent; 181 HRESULT hr; 182 STARTUPINFO si; 183 TCHAR szCmdline[2048]; 184 185 /* Kill off the previous preview process */ 186 if (pData->PrevWindowPi.hProcess) 187 { 188 TerminateProcess(pData->PrevWindowPi.hProcess, 0); 189 CloseHandle(pData->PrevWindowPi.hProcess); 190 CloseHandle(pData->PrevWindowPi.hThread); 191 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL; 192 } 193 ShowWindow(pData->ScreenSaverPreviewParent, SW_HIDE); 194 195 if (pData->Selection < 1) 196 return; 197 198 hr = StringCbPrintf(szCmdline, sizeof(szCmdline), 199 TEXT("%s /p %Iu"), 200 pData->ScreenSaverItems[pData->Selection].szFilename, 201 (ULONG_PTR)hPreview); 202 if (FAILED(hr)) 203 return; 204 205 ZeroMemory(&si, sizeof(si)); 206 si.cb = sizeof(si); 207 ZeroMemory(&pData->PrevWindowPi, sizeof(pData->PrevWindowPi)); 208 209 ShowWindow(pData->ScreenSaverPreviewParent, SW_SHOW); 210 211 if (!CreateProcess(NULL, 212 szCmdline, 213 NULL, 214 NULL, 215 FALSE, 216 0, 217 NULL, 218 NULL, 219 &si, 220 &pData->PrevWindowPi)) 221 { 222 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL; 223 } 224 } 225 226 static BOOL 227 WaitForSettingsDialog(HWND hwndDlg, 228 HANDLE hProcess) 229 { 230 DWORD dwResult; 231 MSG msg; 232 233 while (TRUE) 234 { 235 dwResult = MsgWaitForMultipleObjects(1, 236 &hProcess, 237 FALSE, 238 INFINITE, 239 QS_ALLINPUT); 240 if (dwResult == WAIT_OBJECT_0 + 1) 241 { 242 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 243 { 244 if (msg.message == WM_QUIT) 245 { 246 return FALSE; 247 } 248 if (IsDialogMessage(hwndDlg, &msg)) 249 { 250 TranslateMessage(&msg); 251 DispatchMessage(&msg); 252 } 253 } 254 } 255 else if (dwResult == WAIT_OBJECT_0) 256 { 257 return TRUE; 258 } 259 else 260 { 261 return FALSE; 262 } 263 } 264 } 265 266 267 /* 268 * /c:<hwnd> Run configuration, hwnd is handle of calling window 269 */ 270 static VOID 271 ScreenSaverConfig(HWND hwndDlg, PDATA pData) 272 { 273 HRESULT hr; 274 STARTUPINFO si; 275 PROCESS_INFORMATION pi; 276 TCHAR szCmdline[2048]; 277 278 if (pData->Selection < 1) 279 return; 280 281 hr = StringCbPrintf(szCmdline, sizeof(szCmdline), 282 TEXT("%s /c:%Iu"), 283 pData->ScreenSaverItems[pData->Selection].szFilename, 284 (ULONG_PTR)hwndDlg); 285 if (FAILED(hr)) 286 return; 287 288 ZeroMemory(&si, sizeof(si)); 289 si.cb = sizeof(si); 290 ZeroMemory(&pi, sizeof(pi)); 291 if (CreateProcess(NULL, 292 szCmdline, 293 NULL, 294 NULL, 295 FALSE, 296 0, 297 NULL, 298 NULL, 299 &si, 300 &pi)) 301 { 302 /* Kill off the previous preview process */ 303 if (pData->PrevWindowPi.hProcess) 304 { 305 TerminateProcess(pData->PrevWindowPi.hProcess, 0); 306 CloseHandle(pData->PrevWindowPi.hProcess); 307 CloseHandle(pData->PrevWindowPi.hThread); 308 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL; 309 } 310 311 if (WaitForSettingsDialog(hwndDlg, pi.hProcess)) 312 SetScreenSaverPreviewBox(hwndDlg, pData); 313 314 CloseHandle(pi.hProcess); 315 CloseHandle(pi.hThread); 316 } 317 } 318 319 /* 320 * /s Run normal 321 */ 322 static VOID 323 ScreenSaverPreview(HWND hwndDlg, PDATA pData) 324 { 325 HRESULT hr; 326 STARTUPINFO si; 327 PROCESS_INFORMATION pi; 328 TCHAR szCmdline[2048]; 329 330 if (pData->Selection < 1) 331 return; 332 333 /* Kill off the previous preview process */ 334 if (pData->PrevWindowPi.hProcess) 335 { 336 TerminateProcess(pData->PrevWindowPi.hProcess, 0); 337 CloseHandle(pData->PrevWindowPi.hProcess); 338 CloseHandle(pData->PrevWindowPi.hThread); 339 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL; 340 } 341 342 hr = StringCbPrintf(szCmdline, sizeof(szCmdline), 343 TEXT("%s /s"), 344 pData->ScreenSaverItems[pData->Selection].szFilename); 345 if (FAILED(hr)) 346 return; 347 348 ZeroMemory(&si, sizeof(si)); 349 si.cb = sizeof(si); 350 ZeroMemory(&pi, sizeof(pi)); 351 if (CreateProcess(NULL, 352 szCmdline, 353 NULL, 354 NULL, 355 FALSE, 356 0, 357 NULL, 358 NULL, 359 &si, 360 &pi)) 361 { 362 WaitForSingleObject(pi.hProcess, INFINITE); 363 CloseHandle(pi.hProcess); 364 CloseHandle(pi.hThread); 365 } 366 } 367 368 369 static VOID 370 CheckRegScreenSaverIsSecure(HWND hwndDlg) 371 { 372 HKEY hKey; 373 TCHAR szBuffer[2]; 374 DWORD bufferSize = sizeof(szBuffer); 375 DWORD varType = REG_SZ; 376 LONG result; 377 378 if (RegOpenKeyEx(HKEY_CURRENT_USER, 379 _T("Control Panel\\Desktop"), 380 0, 381 KEY_ALL_ACCESS, 382 &hKey) == ERROR_SUCCESS) 383 { 384 result = RegQueryValueEx(hKey, 385 _T("ScreenSaverIsSecure"), 386 0, 387 &varType, 388 (LPBYTE)szBuffer, 389 &bufferSize); 390 RegCloseKey(hKey); 391 392 if (result == ERROR_SUCCESS) 393 { 394 if (_ttoi(szBuffer) == 1) 395 { 396 SendDlgItemMessage(hwndDlg, 397 IDC_SCREENS_USEPASSCHK, 398 BM_SETCHECK, 399 (WPARAM)BST_CHECKED, 400 0); 401 return; 402 } 403 } 404 405 SendDlgItemMessage(hwndDlg, 406 IDC_SCREENS_USEPASSCHK, 407 BM_SETCHECK, 408 (WPARAM)BST_UNCHECKED, 409 0); 410 } 411 } 412 413 414 static BOOL 415 AddScreenSaverItem( 416 _In_ HWND hwndScreenSavers, 417 _In_ PDATA pData, 418 _In_ SCREEN_SAVER_ITEM* ScreenSaverItem) 419 { 420 UINT i; 421 422 if (pData->ScreenSaverCount >= MAX_SCREENSAVERS) 423 return FALSE; 424 425 i = SendMessage(hwndScreenSavers, 426 CB_ADDSTRING, 427 0, 428 (LPARAM)ScreenSaverItem->szDisplayName); 429 if ((i == CB_ERR) || (i == CB_ERRSPACE)) 430 return FALSE; 431 432 SendMessage(hwndScreenSavers, 433 CB_SETITEMDATA, 434 i, 435 (LPARAM)pData->ScreenSaverCount); 436 437 pData->ScreenSaverCount++; 438 return TRUE; 439 } 440 441 static BOOL 442 AddScreenSaver( 443 _In_ HWND hwndScreenSavers, 444 _In_ PDATA pData, 445 _In_ LPCTSTR pszFilePath, 446 _In_ LPCTSTR pszFileName) 447 { 448 SCREEN_SAVER_ITEM* ScreenSaverItem; 449 HANDLE hModule; 450 HRESULT hr; 451 452 if (pData->ScreenSaverCount >= MAX_SCREENSAVERS) 453 return FALSE; 454 455 ScreenSaverItem = pData->ScreenSaverItems + pData->ScreenSaverCount; 456 457 ScreenSaverItem->bIsScreenSaver = TRUE; 458 459 hModule = LoadLibraryEx(pszFilePath, 460 NULL, 461 DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); 462 if (hModule) 463 { 464 if (LoadString(hModule, 465 1, 466 ScreenSaverItem->szDisplayName, 467 _countof(ScreenSaverItem->szDisplayName)) == 0) 468 { 469 /* If the string does not exist, copy the file name */ 470 hr = StringCbCopy(ScreenSaverItem->szDisplayName, 471 sizeof(ScreenSaverItem->szDisplayName), 472 pszFileName); 473 if (FAILED(hr)) 474 { 475 FreeLibrary(hModule); 476 return FALSE; 477 } 478 /* Remove the .scr extension */ 479 ScreenSaverItem->szDisplayName[_tcslen(pszFileName)-4] = _T('\0'); 480 } 481 FreeLibrary(hModule); 482 } 483 else 484 { 485 hr = StringCbCopy(ScreenSaverItem->szDisplayName, 486 sizeof(ScreenSaverItem->szDisplayName), 487 _T("Unknown")); 488 if (FAILED(hr)) 489 return FALSE; 490 } 491 492 hr = StringCbCopy(ScreenSaverItem->szFilename, 493 sizeof(ScreenSaverItem->szFilename), 494 pszFilePath); 495 if (FAILED(hr)) 496 return FALSE; 497 498 return AddScreenSaverItem(hwndScreenSavers, pData, ScreenSaverItem); 499 } 500 501 static VOID 502 SearchScreenSavers( 503 _In_ HWND hwndScreenSavers, 504 _In_ PDATA pData, 505 _In_ LPCTSTR pszSearchPath) 506 { 507 HRESULT hr; 508 WIN32_FIND_DATA fd; 509 HANDLE hFind; 510 TCHAR szFilePath[MAX_PATH]; 511 512 hr = StringCbPrintf(szFilePath, sizeof(szFilePath), 513 TEXT("%s\\*.scr"), pszSearchPath); 514 if (FAILED(hr)) 515 return; 516 517 hFind = FindFirstFile(szFilePath, &fd); 518 if (hFind == INVALID_HANDLE_VALUE) 519 return; 520 521 do 522 { 523 /* Don't add any hidden screensavers */ 524 if (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) 525 continue; 526 527 if (pData->ScreenSaverCount >= MAX_SCREENSAVERS) 528 break; 529 530 hr = StringCbPrintf(szFilePath, sizeof(szFilePath), 531 TEXT("%s\\%s"), pszSearchPath, fd.cFileName); 532 if (FAILED(hr)) 533 break; 534 535 if (!AddScreenSaver(hwndScreenSavers, pData, szFilePath, fd.cFileName)) 536 break; 537 538 } while (FindNextFile(hFind, &fd)); 539 540 FindClose(hFind); 541 } 542 543 static VOID 544 EnumScreenSavers( 545 _In_ HWND hwndScreenSavers, 546 _In_ PDATA pData) 547 { 548 SCREEN_SAVER_ITEM* ScreenSaverItem; 549 PTCHAR pBackSlash; 550 TCHAR szSearchPath[MAX_PATH]; 551 TCHAR szLocalPath[MAX_PATH]; 552 553 /* Initialize the number of list items */ 554 pData->ScreenSaverCount = 0; 555 556 /* Add the "(None)" item */ 557 ScreenSaverItem = pData->ScreenSaverItems; 558 559 ScreenSaverItem->bIsScreenSaver = FALSE; 560 561 LoadString(hApplet, 562 IDS_NONE, 563 ScreenSaverItem->szDisplayName, 564 _countof(ScreenSaverItem->szDisplayName)); 565 566 AddScreenSaverItem(hwndScreenSavers, pData, ScreenSaverItem); 567 568 /* Add all the screensavers where the applet is stored */ 569 GetModuleFileName(hApplet, szLocalPath, _countof(szLocalPath)); 570 pBackSlash = _tcsrchr(szLocalPath, _T('\\')); 571 if (pBackSlash != NULL) 572 { 573 *pBackSlash = _T('\0'); 574 SearchScreenSavers(hwndScreenSavers, pData, szLocalPath); 575 } 576 577 /* Add all the screensavers in the C:\ReactOS\System32 directory */ 578 GetSystemDirectory(szSearchPath, _countof(szSearchPath)); 579 if (pBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0) 580 SearchScreenSavers(hwndScreenSavers, pData, szSearchPath); 581 582 /* Add all the screensavers in the C:\ReactOS directory */ 583 GetWindowsDirectory(szSearchPath, _countof(szSearchPath)); 584 if (pBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0) 585 SearchScreenSavers(hwndScreenSavers, pData, szSearchPath); 586 } 587 588 589 static VOID 590 SetScreenSaver(HWND hwndDlg, PDATA pData) 591 { 592 HKEY regKey; 593 BOOL DeleteMode = FALSE; 594 595 DBG_UNREFERENCED_LOCAL_VARIABLE(DeleteMode); 596 597 if (RegOpenKeyEx(HKEY_CURRENT_USER, 598 _T("Control Panel\\Desktop"), 599 0, 600 KEY_ALL_ACCESS, 601 ®Key) == ERROR_SUCCESS) 602 { 603 INT Time; 604 BOOL bRet; 605 TCHAR Sec; 606 UINT Ret; 607 608 /* Set the screensaver */ 609 if (pData->ScreenSaverItems[pData->Selection].bIsScreenSaver) 610 { 611 SIZE_T Length = (_tcslen(pData->ScreenSaverItems[pData->Selection].szFilename) + 1) * sizeof(TCHAR); 612 RegSetValueEx(regKey, 613 _T("SCRNSAVE.EXE"), 614 0, 615 REG_SZ, 616 (PBYTE)pData->ScreenSaverItems[pData->Selection].szFilename, 617 (DWORD)Length); 618 619 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_UPDATEINIFILE); 620 } 621 else 622 { 623 /* Windows deletes the value if no screensaver is set */ 624 RegDeleteValue(regKey, _T("SCRNSAVE.EXE")); 625 DeleteMode = TRUE; 626 627 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, 0, SPIF_UPDATEINIFILE); 628 } 629 630 /* Set the secure value */ 631 Ret = SendDlgItemMessage(hwndDlg, 632 IDC_SCREENS_USEPASSCHK, 633 BM_GETCHECK, 634 0, 635 0); 636 Sec = (Ret == BST_CHECKED) ? _T('1') : _T('0'); 637 RegSetValueEx(regKey, 638 _T("ScreenSaverIsSecure"), 639 0, 640 REG_SZ, 641 (PBYTE)&Sec, 642 sizeof(TCHAR)); 643 644 /* Set the screensaver time delay */ 645 Time = GetDlgItemInt(hwndDlg, 646 IDC_SCREENS_TIMEDELAY, 647 &bRet, 648 FALSE); 649 if (Time == 0) 650 Time = 1; 651 Time *= 60; // Convert to seconds 652 653 SystemParametersInfoW(SPI_SETSCREENSAVETIMEOUT, Time, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 654 655 RegCloseKey(regKey); 656 } 657 } 658 659 660 static BOOL 661 OnInitDialog(HWND hwndDlg, PDATA pData) 662 { 663 HWND hwndSSCombo = GetDlgItem(hwndDlg, IDC_SCREENS_LIST); 664 LPTSTR pSsValue; 665 INT iCurSs; 666 WNDCLASS wc = {0}; 667 668 pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DATA)); 669 if (!pData) 670 { 671 EndDialog(hwndDlg, -1); 672 return FALSE; 673 } 674 675 wc.lpfnWndProc = DefWindowProc; 676 wc.hInstance = hApplet; 677 wc.hCursor = NULL; 678 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 679 wc.lpszClassName = szPreviewWndClass; 680 681 if (RegisterClass(&wc)) 682 { 683 HWND hParent = GetDlgItem(hwndDlg, IDC_SCREENS_PREVIEW); 684 HWND hChild; 685 686 if (hParent != NULL) 687 { 688 pData->OldPreviewProc = (WNDPROC)GetWindowLongPtr(hParent, GWLP_WNDPROC); 689 SetWindowLongPtr(hParent, GWLP_WNDPROC, (LONG_PTR)RedrawSubclassProc); 690 SetWindowLongPtr(hParent, GWLP_USERDATA, (LONG_PTR)pData); 691 } 692 693 hChild = CreateWindowEx(0, szPreviewWndClass, NULL, 694 WS_CHILD | WS_CLIPCHILDREN, 695 0, 0, 0, 0, hParent, 696 NULL, hApplet, NULL); 697 if (hChild != NULL) 698 { 699 RECT rc; 700 GetClientRect(hParent, &rc); 701 rc.left += MONITOR_LEFT; 702 rc.top += MONITOR_TOP; 703 MoveWindow(hChild, rc.left, rc.top, MONITOR_WIDTH, MONITOR_HEIGHT, FALSE); 704 } 705 706 pData->ScreenSaverPreviewParent = hChild; 707 } 708 709 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pData); 710 711 pData->Selection = -1; 712 713 SendDlgItemMessage(hwndDlg, 714 IDC_SCREENS_TIME, 715 UDM_SETRANGE, 716 0, 717 MAKELONG(240, 1)); 718 719 EnumScreenSavers(hwndSSCombo, pData); 720 721 CheckRegScreenSaverIsSecure(hwndDlg); 722 723 /* Set the current screensaver in the combo box */ 724 iCurSs = 0; // Default to "(None)" 725 pSsValue = GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE")); 726 if (pSsValue) 727 { 728 BOOL bFound = FALSE; 729 INT i; 730 731 /* Find whether the current screensaver is in the list */ 732 for (i = 0; i < pData->ScreenSaverCount; i++) 733 { 734 if (!_tcsicmp(pSsValue, pData->ScreenSaverItems[i].szFilename)) 735 { 736 bFound = TRUE; 737 break; 738 } 739 } 740 741 if (!bFound) 742 { 743 /* The current screensaver is not in the list: add it */ 744 // i = pData->ScreenSaverCount; 745 bFound = AddScreenSaver(hwndSSCombo, pData, pSsValue, _T("SCRNSAVE.EXE")); 746 if (bFound) 747 i = pData->ScreenSaverCount - 1; 748 } 749 750 HeapFree(GetProcessHeap(), 0, pSsValue); 751 752 if (bFound) 753 { 754 /* The current screensaver should be in the list: select it */ 755 iCurSs = SendMessage(hwndSSCombo, 756 CB_FINDSTRINGEXACT, 757 -1, 758 (LPARAM)pData->ScreenSaverItems[i].szDisplayName); 759 if (iCurSs == CB_ERR) 760 iCurSs = 0; // Default to "(None)" 761 } 762 } 763 SendMessage(hwndSSCombo, CB_SETCURSEL, iCurSs, 0); 764 765 /* Set the current timeout */ 766 pSsValue = GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut")); 767 if (pSsValue) 768 { 769 UINT Time = _ttoi(pSsValue) / 60; 770 771 HeapFree(GetProcessHeap(), 0, pSsValue); 772 773 SendDlgItemMessage(hwndDlg, 774 IDC_SCREENS_TIME, 775 UDM_SETPOS32, 776 0, 777 Time); 778 } 779 780 SelectionChanged(hwndDlg, pData); 781 782 return TRUE; 783 } 784 785 786 INT_PTR CALLBACK 787 ScreenSaverPageProc(HWND hwndDlg, 788 UINT uMsg, 789 WPARAM wParam, 790 LPARAM lParam) 791 { 792 PDATA pData; 793 794 pData = (PDATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 795 796 switch (uMsg) 797 { 798 case WM_INITDIALOG: 799 { 800 OnInitDialog(hwndDlg, pData); 801 break; 802 } 803 804 case WM_DESTROY: 805 { 806 if (pData->ScreenSaverPreviewParent) 807 { 808 SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SCREENS_PREVIEW), 809 GWLP_WNDPROC, 810 (LONG_PTR)pData->OldPreviewProc); 811 DestroyWindow(pData->ScreenSaverPreviewParent); 812 pData->ScreenSaverPreviewParent = NULL; 813 } 814 UnregisterClass(szPreviewWndClass, hApplet); 815 if (pData->PrevWindowPi.hProcess) 816 { 817 TerminateProcess(pData->PrevWindowPi.hProcess, 0); 818 CloseHandle(pData->PrevWindowPi.hProcess); 819 CloseHandle(pData->PrevWindowPi.hThread); 820 } 821 HeapFree(GetProcessHeap(), 0, pData); 822 break; 823 } 824 825 case WM_ENDSESSION: 826 { 827 SetScreenSaverPreviewBox(hwndDlg, pData); 828 break; 829 } 830 831 case WM_DRAWITEM: 832 { 833 LPDRAWITEMSTRUCT lpDrawItem; 834 lpDrawItem = (LPDRAWITEMSTRUCT)lParam; 835 836 if (lpDrawItem->CtlID == IDC_SCREENS_PREVIEW) 837 ShowScreenSaverPreview(lpDrawItem, pData); 838 break; 839 } 840 841 case WM_COMMAND: 842 { 843 DWORD controlId = LOWORD(wParam); 844 DWORD command = HIWORD(wParam); 845 846 switch (controlId) 847 { 848 case IDC_SCREENS_LIST: 849 { 850 if (HIWORD(wParam) == CBN_SELCHANGE) 851 { 852 SelectionChanged(hwndDlg, pData); 853 SetScreenSaverPreviewBox(hwndDlg, pData); 854 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 855 } 856 break; 857 } 858 859 case IDC_SCREENS_TIMEDELAY: 860 { 861 if (command == EN_CHANGE) 862 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 863 break; 864 } 865 866 case IDC_SCREENS_POWER_BUTTON: // Start Powercfg.Cpl 867 { 868 if (command == BN_CLICKED) 869 WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl",SW_SHOWNORMAL); 870 break; 871 } 872 873 case IDC_SCREENS_TESTSC: // Screensaver Preview 874 { 875 if (command == BN_CLICKED) 876 { 877 ScreenSaverPreview(hwndDlg, pData); 878 SetScreenSaverPreviewBox(hwndDlg, pData); 879 } 880 break; 881 } 882 883 case IDC_SCREENS_SETTINGS: // Screensaver Settings 884 { 885 if (command == BN_CLICKED) 886 ScreenSaverConfig(hwndDlg, pData); 887 break; 888 } 889 890 case IDC_SCREENS_USEPASSCHK: // Screensaver Is Secure 891 { 892 if (command == BN_CLICKED) 893 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 894 break; 895 } 896 } 897 break; 898 } 899 900 case WM_NOTIFY: 901 { 902 LPNMHDR lpnm = (LPNMHDR)lParam; 903 904 switch(lpnm->code) 905 { 906 case PSN_APPLY: 907 { 908 SetScreenSaver(hwndDlg, pData); 909 return TRUE; 910 } 911 912 case PSN_SETACTIVE: 913 { 914 /* Enable screensaver preview support */ 915 SetScreenSaverPreviewBox(hwndDlg, pData); 916 break; 917 } 918 919 case PSN_KILLACTIVE: 920 { 921 /* Kill running preview screensaver */ 922 if (pData->PrevWindowPi.hProcess) 923 { 924 TerminateProcess(pData->PrevWindowPi.hProcess, 0); 925 CloseHandle(pData->PrevWindowPi.hProcess); 926 CloseHandle(pData->PrevWindowPi.hThread); 927 pData->PrevWindowPi.hThread = pData->PrevWindowPi.hProcess = NULL; 928 } 929 break; 930 } 931 } 932 } 933 break; 934 } 935 936 return FALSE; 937 } 938