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