[KSPROXY]
[reactos.git] / reactos / dll / cpl / desk / screensaver.c
index c75e96a..c24cf78 100644 (file)
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS Display Control Panel
- * FILE:            lib/cpl/desk/screensaver.c
+ * FILE:            dll/cpl/desk/screensaver.c
  * PURPOSE:         Screen saver property page
- * 
+ *
  * PROGRAMMERS:     Trevor McCort (lycan359@gmail.com)
+ *                  Ged Murphy (gedmurphy@reactos.org)
  */
 
 #include "desk.h"
 
 #define MAX_SCREENSAVERS 100
 
-void AddListViewItems2();
-void CheckRegScreenSaverIsSecure();
-
-typedef struct {
+typedef struct
+{
     BOOL  bIsScreenSaver; /* Is this background a wallpaper */
     TCHAR szFilename[MAX_PATH];
     TCHAR szDisplayName[256];
 } ScreenSaverItem;
 
-int ImageListSelection       = 0;
-ScreenSaverItem g_ScreenSaverItems[MAX_SCREENSAVERS];
 
-HWND g_hScreenBackgroundPage = NULL;
-HWND g_hScreengroundList = NULL;
-HWND ControlScreenSaverIsSecure = NULL;
+typedef struct _GLOBAL_DATA
+{
+    ScreenSaverItem ScreenSaverItems[MAX_SCREENSAVERS];
+    PROCESS_INFORMATION PrevWindowPi;
+    int Selection;
+} GLOBAL_DATA, *PGLOBAL_DATA;
+
 
-void ListViewItemAreChanged(int itemIndex)
+static LPTSTR
+GetCurrentScreenSaverValue(LPTSTR lpValue)
 {
-    ScreenSaverItem *ScreenSaverItem = NULL;
-    
-    ImageListSelection = itemIndex;
-    ScreenSaverItem = &g_ScreenSaverItems[ImageListSelection];
-    
-    PropSheet_Changed(GetParent(g_hScreenBackgroundPage), g_hScreenBackgroundPage);
+    HKEY hKey;
+    LPTSTR lpBuf = NULL;
+    DWORD BufSize, Type = REG_SZ;
+    LONG Ret;
+
+    Ret = RegOpenKeyEx(HKEY_CURRENT_USER,
+                       _T("Control Panel\\Desktop"),
+                       0,
+                       KEY_READ,
+                       &hKey);
+    if (Ret != ERROR_SUCCESS)
+        return NULL;
+
+    Ret = RegQueryValueEx(hKey,
+                          lpValue,
+                          0,
+                          &Type,
+                          NULL,
+                          &BufSize);
+    if (Ret == ERROR_SUCCESS)
+    {
+        lpBuf = HeapAlloc(GetProcessHeap(),
+                          0,
+                          BufSize);
+        if (lpBuf)
+        {
+            Ret = RegQueryValueEx(hKey,
+                                  lpValue,
+                                  0,
+                                  &Type,
+                                  (LPBYTE)lpBuf,
+                                  &BufSize);
+            if (Ret != ERROR_SUCCESS)
+                lpBuf = NULL;
+        }
+    }
+
+    RegCloseKey(hKey);
+
+    return lpBuf;
 }
 
-INT_PTR
-CALLBACK
-ScreenSaverPageProc(HWND hwndDlg,
-                    UINT uMsg,
-                    WPARAM wParam,
-                    LPARAM lParam)
+
+static VOID
+SelectionChanged(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
 {
-    g_hScreenBackgroundPage = hwndDlg;
-    
-    switch(uMsg) {
-        case WM_INITDIALOG:
+    HWND hwndCombo;
+    BOOL bEnable;
+    INT i;
+
+    hwndCombo = GetDlgItem(hwndDlg, IDC_SCREENS_LIST);
+
+    i = (INT)SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
+    i = (INT)SendMessage(hwndCombo, CB_GETITEMDATA, i, 0);
+
+    pGlobalData->Selection = i;
+
+    bEnable = (i != 0);
+
+    EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_SETTINGS), bEnable);
+    EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_TESTSC), bEnable);
+    EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_USEPASSCHK), bEnable);
+    EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_TIMEDELAY), bEnable);
+    EnableWindow(GetDlgItem(hwndDlg, IDC_SCREENS_TIME), bEnable);
+    EnableWindow(GetDlgItem(hwndDlg, IDC_WAITTEXT), bEnable);
+    EnableWindow(GetDlgItem(hwndDlg, IDC_MINTEXT), bEnable);
+}
+
+
+static VOID
+SetScreenSaverPreviewBox(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
+{
+    HWND hPreview = GetDlgItem(hwndDlg, IDC_SCREENS_PREVIEW);
+    STARTUPINFO si;
+    TCHAR szCmdline[2048];
+
+    /* kill off the previous preview process*/
+    if (pGlobalData->PrevWindowPi.hProcess)
+    {
+        TerminateProcess(pGlobalData->PrevWindowPi.hProcess, 0);
+        CloseHandle(pGlobalData->PrevWindowPi.hProcess);
+        CloseHandle(pGlobalData->PrevWindowPi.hThread);
+        pGlobalData->PrevWindowPi.hThread = pGlobalData->PrevWindowPi.hProcess = NULL;
+    }
+
+    if (pGlobalData->Selection > 0)
+    {
+        _stprintf(szCmdline,
+                  _T("%s /p %u"),
+                  pGlobalData->ScreenSaverItems[pGlobalData->Selection].szFilename,
+                  hPreview);
+
+        ZeroMemory(&si, sizeof(si));
+        si.cb = sizeof(si);
+        ZeroMemory(&pGlobalData->PrevWindowPi, sizeof(pGlobalData->PrevWindowPi));
+
+        if (!CreateProcess(NULL,
+                           szCmdline,
+                           NULL,
+                           NULL,
+                           FALSE,
+                           0,
+                           NULL,
+                           NULL,
+                           &si,
+                           &pGlobalData->PrevWindowPi))
         {
-            g_hScreengroundList = GetDlgItem(g_hScreenBackgroundPage, IDC_SCREENS_CHOICES);
-            SendMessage(GetDlgItem(g_hScreenBackgroundPage, IDC_SCREENS_TIME), UDM_SETRANGE, 0, MAKELONG ((short) 240, (short) 0));
-            AddListViewItems2();
-            CheckRegScreenSaverIsSecure();
-        } break;
-        case WM_COMMAND:
+            pGlobalData->PrevWindowPi.hThread = pGlobalData->PrevWindowPi.hProcess = NULL;
+        }
+    }
+}
+
+static BOOL
+WaitForSettingsDialog(HWND hwndDlg,
+                      HANDLE hProcess)
+{
+    while (TRUE)
+    {
+        DWORD Ret;
+        MSG msg;
+
+        while (PeekMessage(&msg,
+                           NULL,
+                           0,
+                           0,
+                           PM_REMOVE))
         {
-            DWORD controlId = LOWORD(wParam);
-            DWORD command   = HIWORD(wParam);
-            switch(controlId) {
-                case IDC_SCREENS_POWER_BUTTON: // Start Powercfg.Cpl
-                {
-                    if(command == BN_CLICKED)
-                        WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl,,",SW_SHOWNORMAL);
-                } break;
-                case IDC_SCREENS_TESTSC: // Screensaver Preview
-                {
-                    if(command == BN_CLICKED)
-                    {
-                        /*
-                           /p:<hwnd>  Run in preview 
-                           /s         Run normal
-                           /c:<hwnd>  Run configuration, hwnd is handle of calling window
-                           /a         Run change password
-                        */
-
-                        WCHAR szCmdline[2048];                                                
-                        STARTUPINFO si;
-                        PROCESS_INFORMATION pi;                        
-                        swprintf(szCmdline, L"%s /p",g_ScreenSaverItems[ImageListSelection].szFilename);
-
-                        ZeroMemory( &si, sizeof(si) );
-                        si.cb = sizeof(si);
-                        ZeroMemory( &pi, sizeof(pi) );                         
-                       if(CreateProcess( NULL,  szCmdline, NULL, NULL, FALSE,  0,  NULL,NULL,&si, &pi )) 
-                       {                          
-                          CloseHandle( pi.hProcess );
-                          CloseHandle( pi.hThread );                       
-                       }                       
-                    }
-                        
-                } break;
-    /*            case IDC_SCREENS_DELETE: // Delete Screensaver
-                {
-                    if(command == BN_CLICKED) {
-                        if (ImageListSelection == 0) // Can NOT delete None sry:-)
-                           return FALSE;
-                        DeleteFileW(g_ScreenSaverItems[ImageListSelection].szFilename);
-                    }
-                } break; */
-                case IDC_SCREENS_SETTINGS: // Screensaver Settings
-                {
-                    if(command == BN_CLICKED)
-                    {   
-                        /*
-                           /p:<hwnd>  Run in preview 
-                           /s         Run normal
-                           /c:<hwnd>  Run configuration, hwnd is handle of calling window
-                           /a         Run change password
-
-                        */
-
-                        WCHAR szCmdline[2048];                                                
-                        STARTUPINFO si;
-                        PROCESS_INFORMATION pi;                        
-                        swprintf(szCmdline, L"%s /c",g_ScreenSaverItems[ImageListSelection].szFilename);
-
-                        ZeroMemory( &si, sizeof(si) );
-                        si.cb = sizeof(si);
-                        ZeroMemory( &pi, sizeof(pi) );                         
-                       if(CreateProcess( NULL,  szCmdline, NULL, NULL, FALSE,  0,  NULL,NULL,&si, &pi )) 
-                       {                          
-                          CloseHandle( pi.hProcess );
-                          CloseHandle( pi.hThread );                       
-                       }                       
-                    }                       
-                } break;
-                case IDC_SCREENS_USEPASSCHK: // Screensaver Is Secure
-                {
-                    if(command == BN_CLICKED)
-                        MessageBox(NULL, TEXT("That button doesn't do anything yet"), TEXT("Whoops"), MB_OK);
-                } break;
-                case IDC_SCREENS_TIME: // Delay before show screensaver
-                {
-                } break;
-                default:
-                    break;
-            } break;
+            if (msg.message == WM_QUIT)
+                return FALSE;
+
+            if (IsDialogMessage(hwndDlg, &msg))
+            {
+                TranslateMessage(&msg);
+                DispatchMessage(&msg);
+            }
         }
-        case WM_NOTIFY:
+
+        Ret = MsgWaitForMultipleObjects(1,
+                                        &hProcess,
+                                        FALSE,
+                                        INFINITE,
+                                        QS_ALLINPUT);
+        if (Ret == (WAIT_OBJECT_0))
         {
-           LPNMHDR lpnm = (LPNMHDR)lParam;
-                
-           switch(lpnm->code) {   
-             case PSN_APPLY:
-             {
-                return TRUE;
-             } break;
-             case LVN_ITEMCHANGED:
-             {
-                LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam;
-                if((nm->uNewState & LVIS_SELECTED) == 0)
-                  return FALSE;
-                ListViewItemAreChanged(nm->iItem);
-                break;
-             } break;
-            default:
-                break;
-           }
-        } break;
+            return TRUE;
+        }
+    }
+}
+
+
+static VOID
+ScreensaverConfig(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
+{
+    /*
+       /c:<hwnd>  Run configuration, hwnd is handle of calling window
+    */
+
+    TCHAR szCmdline[2048];
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+
+    if (pGlobalData->Selection < 1)
+        return;
+
+    _stprintf(szCmdline,
+              _T("%s /c:%u"),
+              pGlobalData->ScreenSaverItems[pGlobalData->Selection].szFilename,
+              hwndDlg);
+
+    ZeroMemory(&si, sizeof(si));
+    si.cb = sizeof(si);
+    ZeroMemory(&pi, sizeof(pi));
+    if(CreateProcess(NULL,
+                     szCmdline,
+                     NULL,
+                     NULL,
+                     FALSE,
+                     0,
+                     NULL,
+                     NULL,
+                     &si,
+                     &pi))
+    {
+        /* kill off the previous preview process */
+        if (pGlobalData->PrevWindowPi.hProcess)
+        {
+            TerminateProcess(pGlobalData->PrevWindowPi.hProcess, 0);
+            CloseHandle(pGlobalData->PrevWindowPi.hProcess);
+            CloseHandle(pGlobalData->PrevWindowPi.hThread);
+            pGlobalData->PrevWindowPi.hThread = pGlobalData->PrevWindowPi.hProcess = NULL;
+        }
+
+        if (WaitForSettingsDialog(hwndDlg, pi.hProcess))
+            SetScreenSaverPreviewBox(hwndDlg, pGlobalData);
     }
-    
-    return FALSE;
 }
 
-void CheckRegScreenSaverIsSecure()
+
+static VOID
+ScreensaverPreview(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
+{
+    /*
+       /s         Run normal
+    */
+
+    WCHAR szCmdline[2048];
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+
+    if (pGlobalData->Selection < 1)
+        return;
+
+    /* kill off the previous preview process*/
+    if (pGlobalData->PrevWindowPi.hProcess)
+    {
+        TerminateProcess(pGlobalData->PrevWindowPi.hProcess, 0);
+        CloseHandle(pGlobalData->PrevWindowPi.hProcess);
+        CloseHandle(pGlobalData->PrevWindowPi.hThread);
+        pGlobalData->PrevWindowPi.hThread = pGlobalData->PrevWindowPi.hProcess = NULL;
+    }
+
+    _stprintf(szCmdline,
+              _T("%s /s"),
+              pGlobalData->ScreenSaverItems[pGlobalData->Selection].szFilename);
+
+    ZeroMemory(&si, sizeof(si));
+    si.cb = sizeof(si);
+    ZeroMemory(&pi, sizeof(pi));
+    if(CreateProcess(NULL,
+                     szCmdline,
+                     NULL,
+                     NULL,
+                     FALSE,
+                     0,
+                     NULL,
+                     NULL,
+                     &si,
+                     &pi))
+    {
+        WaitForSingleObject(pi.hProcess, INFINITE);
+        CloseHandle(pi.hProcess);
+        CloseHandle(pi.hThread);
+    }
+}
+
+
+static VOID
+CheckRegScreenSaverIsSecure(HWND hwndDlg)
 {
     HKEY hKey;
     TCHAR szBuffer[2];
     DWORD bufferSize = sizeof(szBuffer);
     DWORD varType = REG_SZ;
     LONG result;
-    
-    ControlScreenSaverIsSecure = GetDlgItem(g_hScreenBackgroundPage, IDC_SCREENS_USEPASSCHK);
-
-    RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, &hKey);
-    result = RegQueryValueEx(hKey, TEXT("ScreenSaverIsSecure"), 0, &varType, (LPBYTE)szBuffer, &bufferSize);
-    if(result == ERROR_SUCCESS)
-        if(_ttoi(szBuffer) == 1) {
-          SendMessage(ControlScreenSaverIsSecure, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
-          goto End;
+
+    if (RegOpenKeyEx(HKEY_CURRENT_USER,
+                     _T("Control Panel\\Desktop"),
+                     0,
+                     KEY_ALL_ACCESS,
+                     &hKey) == ERROR_SUCCESS)
+    {
+        result = RegQueryValueEx(hKey,
+                                _T("ScreenSaverIsSecure"),
+                                0,
+                                &varType,
+                                (LPBYTE)szBuffer,
+                                &bufferSize);
+        RegCloseKey(hKey);
+
+        if (result == ERROR_SUCCESS)
+        {
+            if (_ttoi(szBuffer) == 1)
+            {
+                SendDlgItemMessage(hwndDlg,
+                                   IDC_SCREENS_USEPASSCHK,
+                                   BM_SETCHECK,
+                                   (WPARAM)BST_CHECKED,
+                                   0);
+                return;
+            }
         }
-    SendMessage(ControlScreenSaverIsSecure, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
-End:
-    RegCloseKey(hKey);
+
+        SendDlgItemMessage(hwndDlg,
+                           IDC_SCREENS_USEPASSCHK,
+                           BM_SETCHECK,
+                           (WPARAM)BST_UNCHECKED,
+                           0);
+    }
 }
 
-/* Add the bitmaps in the C:\ReactOS directory and the current wallpaper if any */
-void AddListViewItems2()
+
+static VOID
+AddScreenSavers(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
 {
+    HWND hwndScreenSavers = GetDlgItem(hwndDlg, IDC_SCREENS_LIST);
     WIN32_FIND_DATA fd;
     HANDLE hFind;
     TCHAR szSearchPath[MAX_PATH];
-    LV_ITEM listItem;
-    LV_COLUMN dummy;
-    RECT clientRect;
-    HKEY regKey;
-    SHFILEINFO sfi;
-    HIMAGELIST himl;
-    HIMAGELIST g_hScreenShellImageList    = NULL;
-    TCHAR wallpaperFilename[MAX_PATH];
-    DWORD bufferSize = sizeof(wallpaperFilename);
-    DWORD varType = REG_SZ;
-    LONG result;
-    UINT i = 0;
-    int g_ScreenlistViewItemCount         = 0;
+    INT i;
+    int ScreenSaverCount = 0;
     ScreenSaverItem *ScreenSaverItem = NULL;
-    
-    GetClientRect(g_hScreengroundList, &clientRect);
-    
-    ZeroMemory(&dummy, sizeof(LV_COLUMN));
-    dummy.mask      = LVCF_SUBITEM | LVCF_WIDTH;
-    dummy.iSubItem  = 0;
-    dummy.cx        = (clientRect.right - clientRect.left) - GetSystemMetrics(SM_CXVSCROLL);
-    
-    (void)ListView_InsertColumn(g_hScreengroundList, 0, &dummy);
+    HANDLE hModule = NULL;
 
     /* Add the "None" item */
-    ScreenSaverItem = &g_ScreenSaverItems[g_ScreenlistViewItemCount];
-    
+    ScreenSaverItem = &pGlobalData->ScreenSaverItems[ScreenSaverCount];
+
     ScreenSaverItem->bIsScreenSaver = FALSE;
 
     LoadString(hApplet,
                IDS_NONE,
                ScreenSaverItem->szDisplayName,
                sizeof(ScreenSaverItem->szDisplayName) / sizeof(TCHAR));
-    
-    ZeroMemory(&listItem, sizeof(LV_ITEM));
-    listItem.mask       = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
-    listItem.state      = LVIS_SELECTED;
-    listItem.pszText    = ScreenSaverItem->szDisplayName;
-    listItem.iImage     = -1;
-    listItem.iItem      = g_ScreenlistViewItemCount;
-    listItem.lParam     = g_ScreenlistViewItemCount;
-    
-    (void)ListView_InsertItem(g_hScreengroundList, &listItem);
-    ListView_SetItemState(g_hScreengroundList, g_ScreenlistViewItemCount, LVIS_SELECTED, LVIS_SELECTED);
-
-    g_ScreenlistViewItemCount++;
-
-    /* Add current screensaver if any */
-    RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_ALL_ACCESS, &regKey);
-    
-    result = RegQueryValueEx(regKey, TEXT("SCRNSAVE.EXE"), 0, &varType, (LPBYTE)wallpaperFilename, &bufferSize);
-    
-    if((result == ERROR_SUCCESS) && (_tcslen(wallpaperFilename) > 0))
-    {
-        himl = (HIMAGELIST)SHGetFileInfo(wallpaperFilename,
-                                         0,
-                                         &sfi,
-                                         sizeof(sfi),
-                                         SHGFI_SYSICONINDEX | SHGFI_SMALLICON |
-                                         SHGFI_DISPLAYNAME);
-
-        if(himl != NULL)
-        {
-            if(i++ == 0)
-            {
-                g_hScreenShellImageList = himl;
-                (void)ListView_SetImageList(g_hScreengroundList, himl, LVSIL_SMALL);
-            }
-
-            ScreenSaverItem = &g_ScreenSaverItems[g_ScreenlistViewItemCount];
-            
-            ScreenSaverItem->bIsScreenSaver = TRUE;
 
-            _tcscpy(ScreenSaverItem->szDisplayName, sfi.szDisplayName);
-            _tcscpy(ScreenSaverItem->szFilename, wallpaperFilename);
+    i = SendMessage(hwndScreenSavers,
+                    CB_ADDSTRING,
+                    0,
+                    (LPARAM)ScreenSaverItem->szDisplayName);
 
-            ZeroMemory(&listItem, sizeof(LV_ITEM));
-            listItem.mask       = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
-            listItem.state      = LVIS_SELECTED;
-            listItem.pszText    = ScreenSaverItem->szDisplayName;
-            listItem.iImage     = sfi.iIcon;
-            listItem.iItem      = g_ScreenlistViewItemCount;
-            listItem.lParam     = g_ScreenlistViewItemCount;
+    SendMessage(hwndScreenSavers,
+                CB_SETITEMDATA,
+                i,
+                (LPARAM)ScreenSaverCount);
 
-            (void)ListView_InsertItem(g_hScreengroundList, &listItem);
-            ListView_SetItemState(g_hScreengroundList, g_ScreenlistViewItemCount, LVIS_SELECTED, LVIS_SELECTED);
-
-            g_ScreenlistViewItemCount++;
-        }
-    }
-    
-    RegCloseKey(regKey);
+    ScreenSaverCount++;
 
     /* Add all the screensavers in the C:\ReactOS\System32 directory. */
 
     GetSystemDirectory(szSearchPath, MAX_PATH);
     _tcscat(szSearchPath, TEXT("\\*.scr"));
-    
+
     hFind = FindFirstFile(szSearchPath, &fd);
-    while(hFind != INVALID_HANDLE_VALUE)
+    while (ScreenSaverCount < MAX_SCREENSAVERS-1 &&
+           hFind != INVALID_HANDLE_VALUE)
     {
         /* Don't add any hidden screensavers */
-        if((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)
+        if ((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)
         {
             TCHAR filename[MAX_PATH];
-            
+
             GetSystemDirectory(filename, MAX_PATH);
 
             _tcscat(filename, TEXT("\\"));
             _tcscat(filename, fd.cFileName);
-            
-            himl = (HIMAGELIST)SHGetFileInfo(filename,
-                                             0,
-                                             &sfi,
-                                             sizeof(sfi),
-                                             SHGFI_SYSICONINDEX | SHGFI_SMALLICON |
-                                             SHGFI_DISPLAYNAME);
-
-            if(himl == NULL)
+
+            ScreenSaverItem = &pGlobalData->ScreenSaverItems[ScreenSaverCount];
+
+            ScreenSaverItem->bIsScreenSaver = TRUE;
+
+            hModule = LoadLibraryEx(filename,
+                                    NULL,
+                                    DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
+            if (hModule)
             {
-                break;
+               LoadString(hModule,
+                          1,
+                          ScreenSaverItem->szDisplayName,
+                          sizeof(ScreenSaverItem->szDisplayName) / sizeof(TCHAR));
+               FreeLibrary(hModule);
             }
-            
-            if(i++ == 0)
+            else
             {
-                g_hScreenShellImageList = himl;
-                (void)ListView_SetImageList(g_hScreengroundList, himl, LVSIL_SMALL);
+               _tcscpy(ScreenSaverItem->szDisplayName, _T("Unknown"));
             }
 
-            ScreenSaverItem = &g_ScreenSaverItems[g_ScreenlistViewItemCount];
-
-            ScreenSaverItem->bIsScreenSaver = TRUE;
-            
-            _tcscpy(ScreenSaverItem->szDisplayName, sfi.szDisplayName);
             _tcscpy(ScreenSaverItem->szFilename, filename);
 
-            ZeroMemory(&listItem, sizeof(LV_ITEM));
-            listItem.mask       = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
-            listItem.pszText    = ScreenSaverItem->szDisplayName;
-            listItem.state      = 0;
-            listItem.iImage     = sfi.iIcon;
-            listItem.iItem      = g_ScreenlistViewItemCount;
-            listItem.lParam     = g_ScreenlistViewItemCount;
-            
-            (void)ListView_InsertItem(g_hScreengroundList, &listItem);
-            
-            g_ScreenlistViewItemCount++;
+            i = SendMessage(hwndScreenSavers,
+                            CB_ADDSTRING,
+                            0,
+                            (LPARAM)ScreenSaverItem->szDisplayName);
+
+            SendMessage(hwndScreenSavers,
+                        CB_SETITEMDATA,
+                        i,
+                        (LPARAM)ScreenSaverCount);
+
+            ScreenSaverCount++;
         }
-        
-        if(!FindNextFile(hFind, &fd))
+
+        if (!FindNextFile(hFind, &fd))
             hFind = INVALID_HANDLE_VALUE;
     }
 }
 
+
+static VOID
+SetScreenSaver(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
+{
+    HKEY regKey;
+
+    if (RegOpenKeyEx(HKEY_CURRENT_USER,
+                     _T("Control Panel\\Desktop"),
+                     0,
+                     KEY_ALL_ACCESS,
+                     &regKey) == ERROR_SUCCESS)
+    {
+        INT Time;
+        BOOL bRet;
+        TCHAR szTime[256], Sec;
+        UINT Ret;
+
+        /* set the screensaver */
+        if (pGlobalData->ScreenSaverItems[pGlobalData->Selection].bIsScreenSaver)
+        {
+            RegSetValueEx(regKey,
+                          _T("SCRNSAVE.EXE"),
+                          0,
+                          REG_SZ,
+                          (PBYTE)pGlobalData->ScreenSaverItems[pGlobalData->Selection].szFilename,
+                          _tcslen(pGlobalData->ScreenSaverItems[pGlobalData->Selection].szFilename) * sizeof(TCHAR));
+        }
+        else
+        {
+            /* Windows deletes the value if no screensaver is set */
+            RegDeleteValue(regKey, _T("SCRNSAVE.EXE"));
+        }
+
+        /* set the screensaver time delay */
+        Time = GetDlgItemInt(hwndDlg,
+                             IDC_SCREENS_TIMEDELAY,
+                             &bRet,
+                             FALSE);
+        if (Time == 0)
+            Time = 60;
+        else
+            Time *= 60;
+
+        _itot(Time, szTime, 10);
+        RegSetValueEx(regKey,
+                      _T("ScreenSaveTimeOut"),
+                      0,
+                      REG_SZ,
+                      (PBYTE)szTime,
+                      _tcslen(szTime) * sizeof(TCHAR));
+
+        /* set the secure value */
+        Ret = SendDlgItemMessage(hwndDlg,
+                                 IDC_SCREENS_USEPASSCHK,
+                                 BM_GETCHECK,
+                                 0,
+                                 0);
+        Sec = (Ret == BST_CHECKED) ? _T('1') : _T('0');
+        RegSetValueEx(regKey,
+                      _T("ScreenSaverIsSecure"),
+                      0,
+                      REG_SZ,
+                      (PBYTE)&Sec,
+                      sizeof(TCHAR));
+
+        RegCloseKey(regKey);
+    }
+}
+
+
+static BOOL
+OnInitDialog(HWND hwndDlg, PGLOBAL_DATA pGlobalData)
+{
+    LPTSTR lpCurSs;
+    HWND hwndSSCombo = GetDlgItem(hwndDlg, IDC_SCREENS_LIST);
+    INT Num;
+
+    pGlobalData = HeapAlloc(GetProcessHeap(),
+                            HEAP_ZERO_MEMORY,
+                            sizeof(GLOBAL_DATA));
+    if (!pGlobalData)
+    {
+        EndDialog(hwndDlg, -1);
+        return FALSE;
+    }
+
+    SetWindowLongPtr(hwndDlg,
+                     DWLP_USER,
+                     (LONG_PTR)pGlobalData);
+
+    pGlobalData->Selection = -1;
+
+    SendDlgItemMessage(hwndDlg,
+                       IDC_SCREENS_TIME,
+                       UDM_SETRANGE,
+                       0,
+                       MAKELONG
+                       ((short) 240, (short) 1));
+
+    AddScreenSavers(hwndDlg,
+                    pGlobalData);
+
+    CheckRegScreenSaverIsSecure(hwndDlg);
+
+    /* set the current screensaver in the combo box */
+    lpCurSs = GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE"));
+    if (lpCurSs)
+    {
+        BOOL bFound = FALSE;
+        INT i;
+
+        for (i = 0; i < MAX_SCREENSAVERS; i++)
+        {
+            if (!_tcscmp(lpCurSs, pGlobalData->ScreenSaverItems[i].szFilename))
+            {
+                bFound = TRUE;
+                break;
+            }
+        }
+
+        if (bFound)
+        {
+            Num = SendMessage(hwndSSCombo,
+                              CB_FINDSTRINGEXACT,
+                              -1,
+                              (LPARAM)pGlobalData->ScreenSaverItems[i].szDisplayName);
+            if (Num != CB_ERR)
+                SendMessage(hwndSSCombo,
+                            CB_SETCURSEL,
+                            Num,
+                            0);
+        }
+        else
+        {
+            SendMessage(hwndSSCombo,
+                        CB_SETCURSEL,
+                        0,
+                        0);
+        }
+
+        HeapFree(GetProcessHeap(),
+                 0,
+                 lpCurSs);
+    }
+    else
+    {
+        /* set screensaver to (none) */
+        SendMessage(hwndSSCombo,
+                    CB_SETCURSEL,
+                    0,
+                    0);
+    }
+
+    /* set the current timeout */
+    lpCurSs = GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut"));
+    if (lpCurSs)
+    {
+        UINT Time = _ttoi(lpCurSs);
+
+        Time /= 60;
+
+        SendDlgItemMessage(hwndDlg,
+                           IDC_SCREENS_TIME,
+                           UDM_SETPOS32,
+                           0,
+                           Time);
+
+        HeapFree(GetProcessHeap(),
+                 0,
+                 lpCurSs);
+
+    }
+
+    SelectionChanged(hwndDlg,
+                     pGlobalData);
+
+    return TRUE;
+}
+
+
+INT_PTR CALLBACK
+ScreenSaverPageProc(HWND hwndDlg,
+                    UINT uMsg,
+                    WPARAM wParam,
+                    LPARAM lParam)
+{
+    PGLOBAL_DATA pGlobalData;
+
+    pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
+
+    switch (uMsg)
+    {
+        case WM_INITDIALOG:
+        {
+            OnInitDialog(hwndDlg, pGlobalData);
+            break;
+        }
+
+        case WM_DESTROY:
+        {
+            if (pGlobalData->PrevWindowPi.hProcess)
+            {
+                TerminateProcess(pGlobalData->PrevWindowPi.hProcess, 0);
+                CloseHandle(pGlobalData->PrevWindowPi.hProcess);
+                CloseHandle(pGlobalData->PrevWindowPi.hThread);
+            }
+            HeapFree(GetProcessHeap(),
+                     0,
+                     pGlobalData);
+            break;
+        }
+
+        case WM_ENDSESSION:
+        {
+            SetScreenSaverPreviewBox(hwndDlg,
+                                     pGlobalData);
+            break;
+        }
+
+        case WM_COMMAND:
+        {
+            DWORD controlId = LOWORD(wParam);
+            DWORD command   = HIWORD(wParam);
+
+            switch (controlId)
+            {
+                case IDC_SCREENS_LIST:
+                {
+                    if (HIWORD(wParam) == CBN_SELCHANGE)
+                    {
+                        SelectionChanged(hwndDlg, pGlobalData);
+                        SetScreenSaverPreviewBox(hwndDlg, pGlobalData);
+                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    }
+                    break;
+                }
+
+                case IDC_SCREENS_TIMEDELAY:
+                {
+                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    break;
+                }
+
+                case IDC_SCREENS_POWER_BUTTON: // Start Powercfg.Cpl
+                {
+                    if (command == BN_CLICKED)
+                        WinExec("rundll32 shell32.dll,Control_RunDLL powercfg.cpl",SW_SHOWNORMAL);
+                    break;
+                }
+
+                case IDC_SCREENS_TESTSC: // Screensaver Preview
+                {
+                    if(command == BN_CLICKED)
+                    {
+                        ScreensaverPreview(hwndDlg, pGlobalData);
+                        SetScreenSaverPreviewBox(hwndDlg, pGlobalData);
+                    }
+                    break;
+                }
+
+                case IDC_SCREENS_SETTINGS: // Screensaver Settings
+                {
+                    if (command == BN_CLICKED)
+                        ScreensaverConfig(hwndDlg, pGlobalData);
+                    break;
+                }
+
+                case IDC_SCREENS_USEPASSCHK: // Screensaver Is Secure
+                {
+                    if (command == BN_CLICKED)
+                    {
+                        MessageBox(NULL, TEXT("Feature not yet implemented"), TEXT("Sorry"), MB_OK);
+                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    }
+                    break;
+                }
+            }
+            break;
+        }
+
+        case WM_NOTIFY:
+        {
+            LPNMHDR lpnm = (LPNMHDR)lParam;
+
+            switch(lpnm->code)
+            {
+                case PSN_APPLY:
+                {
+                    SetScreenSaver(hwndDlg, pGlobalData);
+                    return TRUE;
+                }
+
+                case PSN_SETACTIVE:
+                {
+                    /* activate screen saver support */
+                    SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDCHANGE);
+                    SetScreenSaverPreviewBox(hwndDlg, pGlobalData);
+                    break;
+                }
+
+                case PSN_KILLACTIVE:
+                {
+                    /* Disable screensaver support */
+                    SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, FALSE, 0, SPIF_SENDCHANGE);
+                    if (pGlobalData->PrevWindowPi.hProcess)
+                    {
+                        TerminateProcess(pGlobalData->PrevWindowPi.hProcess, 0);
+                        CloseHandle(pGlobalData->PrevWindowPi.hProcess);
+                        CloseHandle(pGlobalData->PrevWindowPi.hThread);
+                        pGlobalData->PrevWindowPi.hThread = pGlobalData->PrevWindowPi.hProcess = NULL;
+                    }
+                    break;
+                }
+            }
+        }
+        break;
+    }
+
+    return FALSE;
+}