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