[KSPROXY]
[reactos.git] / reactos / dll / cpl / main / mouse.c
index eb69944..c208fb2 100644 (file)
@@ -12,9 +12,9 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 /* $Id$
  *
@@ -28,8 +28,6 @@
 //TODO:
 //  add missing icons
 
-#define WINVER 0x0501
-
 #include <windows.h>
 #include <winuser.h>
 #include <devguid.h>
@@ -38,6 +36,9 @@
 #include <tchar.h>
 #include <math.h>
 #include <limits.h>
+#include <shlobj.h>
+#include <cplext.h>
+#include <regstr.h>
 
 #include <stdio.h>
 
@@ -54,7 +55,6 @@
 #define MAX_DOUBLE_CLICK_SPEED         900
 #define DEFAULT_WHEEL_SCROLL_LINES     3
 
-
 typedef struct _BUTTON_DATA
 {
     ULONG g_SwapMouseButtons;
@@ -75,8 +75,8 @@ typedef struct _BUTTON_DATA
 
 typedef struct _POINTER_DATA
 {
-    BOOL bDropShadow;
-    BOOL bOrigDropShadow;
+    BOOL bCursorShadow;
+    BOOL bOrigCursorShadow;
 
     INT cxCursor;
     INT cyCursor;
@@ -199,6 +199,7 @@ ClickLockProc(IN HWND hwndDlg,
 {
     HWND hDlgCtrl;
     int pos;
+    static HICON hIcon;
 
     PBUTTON_DATA pButtonData;
 
@@ -214,6 +215,10 @@ ClickLockProc(IN HWND hwndDlg,
             SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 10));
             pos = (pButtonData->g_ClickLockTime - 200) / 200;
             SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos);
+
+            hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOOK_KEY),
+                              IMAGE_ICON, 16, 16, 0);
+            SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
             return TRUE;
 
         case WM_COMMAND:
@@ -222,10 +227,12 @@ ClickLockProc(IN HWND hwndDlg,
                 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK);
                 pButtonData->g_ClickLockTime = (DWORD) (SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) * 200) + 200;
                 EndDialog(hwndDlg, TRUE);
+                if (hIcon) DestroyIcon(hIcon);
             }
             else if (LOWORD(wParam) == IDCANCEL)
             {
                 EndDialog(hwndDlg, FALSE);
+                if (hIcon) DestroyIcon(hIcon);
             }
             break;
     }
@@ -326,7 +333,7 @@ ButtonProc(IN HWND hwndDlg,
                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
                         SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight);
                     }
-                    SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_SwapMouseButtons, NULL, 0);
+                    //SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_SwapMouseButtons, NULL, 0);
                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                     break;
 
@@ -369,14 +376,17 @@ ButtonProc(IN HWND hwndDlg,
             {
                 if (pButtonData->g_OrigSwapMouseButtons != pButtonData->g_SwapMouseButtons)
                 {
-                    SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
                     pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons;
+                    SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
+                    
                 }
+                SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
+                //SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
 
 #if (WINVER >= 0x0500)
-                SystemParametersInfo(SPI_SETMOUSECLICKLOCK, pButtonData->g_ClickLockEnabled, NULL, SPIF_SENDCHANGE);
+                SystemParametersInfo(SPI_SETMOUSECLICKLOCK, 0, UlongToPtr(pButtonData->g_ClickLockEnabled), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
                 if (pButtonData->g_ClickLockEnabled)
-                   SystemParametersInfo(SPI_SETMOUSECLICKLOCKTIME, pButtonData->g_ClickLockTime, NULL, SPIF_SENDCHANGE);
+                   SystemParametersInfo(SPI_SETMOUSECLICKLOCKTIME, pButtonData->g_ClickLockTime, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
 #endif
             }
             else if (lppsn->hdr.code == PSN_RESET)
@@ -385,8 +395,8 @@ ButtonProc(IN HWND hwndDlg,
                 SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, 0);
 
                 /* Reset double click speed setting */
-//                SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_OrigDoubleClickSpeed, NULL, 0);
-                SetDoubleClickTime(pButtonData->g_OrigDoubleClickSpeed);
+                SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_OrigDoubleClickSpeed, NULL, 0);
+                //SetDoubleClickTime(pButtonData->g_OrigDoubleClickSpeed);
             }
             return TRUE;
 
@@ -404,14 +414,14 @@ ButtonProc(IN HWND hwndDlg,
                     case TB_ENDTRACK:
                         lResult = SendDlgItemMessage(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED, TBM_GETPOS, 0, 0);
                         pButtonData->g_DoubleClickSpeed = (14 - (INT)lResult) * 50 + 200;
-//                        SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, 0);
+                       //SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
                         SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                         break;
 
                     case TB_THUMBTRACK:
                         pButtonData->g_DoubleClickSpeed = (14 - (INT)HIWORD(wParam)) * 50 + 200;
-//                        SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, 0);
+                        //SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, 0);
                         SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                         break;
@@ -424,6 +434,42 @@ ButtonProc(IN HWND hwndDlg,
 }
 
 
+static VOID
+CompressPath(LPTSTR lpShortPath, LPTSTR lpPath)
+{
+    TCHAR szUserProfile[MAX_PATH];
+    TCHAR szSystemRoot[MAX_PATH];
+    TCHAR szProgramFiles[MAX_PATH];
+    DWORD dwUserProfile;
+    DWORD dwSystemRoot;
+    DWORD dwProgramFiles;
+
+    dwUserProfile = GetEnvironmentVariable(_T("USERPROFILE"), szUserProfile, MAX_PATH);
+    dwSystemRoot = GetEnvironmentVariable(_T("SystemRoot"), szSystemRoot, MAX_PATH);
+    dwProgramFiles = GetEnvironmentVariable(_T("ProgramFiles"), szProgramFiles, MAX_PATH);
+
+    if (dwUserProfile > 0 && _tcsncmp(lpPath, szUserProfile, dwUserProfile) == 0)
+    {
+        _tcscpy(lpShortPath, _T("%USERPROFILE%"));
+        _tcscat(lpShortPath, &lpPath[dwUserProfile]);
+    }
+    else if (dwSystemRoot > 0 && _tcsncmp(lpPath, szSystemRoot, dwSystemRoot) == 0)
+    {
+        _tcscpy(lpShortPath, _T("%SystemRoot%"));
+        _tcscat(lpShortPath, &lpPath[dwSystemRoot]);
+    }
+    else if (dwProgramFiles > 0 && _tcsncmp(lpPath, szProgramFiles, dwProgramFiles) == 0)
+    {
+        _tcscpy(lpShortPath, _T("%ProgramFiles%"));
+        _tcscat(lpShortPath, &lpPath[dwProgramFiles]);
+    }
+    else
+    {
+        _tcscpy(lpShortPath, lpPath);
+    }
+}
+
+
 static BOOL
 EnumerateCursorSchemes(HWND hwndDlg)
 {
@@ -433,6 +479,7 @@ EnumerateCursorSchemes(HWND hwndDlg)
     DWORD dwValueName;
     TCHAR szSystemScheme[MAX_PATH];
     TCHAR szValueData[2000];
+    TCHAR szTempData[2000];
     DWORD dwValueData;
     LONG lError;
     HWND hDlgCtrl;
@@ -455,19 +502,21 @@ EnumerateCursorSchemes(HWND hwndDlg)
             if (lError == ERROR_NO_MORE_ITEMS)
                 break;
 
-            if (_tcslen(szValueData) > 0)
+            ExpandEnvironmentStrings(szValueData, szTempData, 2000);
+
+            if (_tcslen(szTempData) > 0)
             {
                 LPTSTR lpCopy, lpStart;
 
                 /* Remove quotation marks */
-                if (szValueData[0] == _T('"'))
+                if (szTempData[0] == _T('"'))
                 {
                     lpStart = szValueData + 1;
-                    szValueData[_tcslen(szValueData) - 1] = 0;
+                    szTempData[_tcslen(szTempData) - 1] = 0;
                 }
                 else
                 {
-                    lpStart = szValueData;
+                    lpStart = szTempData;
                 }
 
                 lpCopy = _tcsdup(lpStart);
@@ -661,6 +710,7 @@ SaveCursorScheme(HWND hwndDlg)
     TCHAR szSystemScheme[MAX_PATH];
     TCHAR szSchemeName[MAX_PATH];
     TCHAR szNewSchemeName[MAX_PATH];
+    TCHAR szTempPath[MAX_PATH];
     TCHAR szTitle[128];
     TCHAR szText[256];
     INT nSel;
@@ -739,9 +789,10 @@ SaveCursorScheme(HWND hwndDlg)
 
     for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
     {
+        CompressPath(szTempPath, g_CursorData[i].szCursorPath);
         if (i > 0)
             _tcscat(lpSchemeData, _T(","));
-        _tcscat(lpSchemeData, g_CursorData[i].szCursorPath);
+        _tcscat(lpSchemeData, szTempPath);
     }
 
     if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS)
@@ -753,8 +804,9 @@ SaveCursorScheme(HWND hwndDlg)
         return FALSE;
     }
 
-    lError = RegSetValueEx(hCuCursorKey, szNewSchemeName, 0, REG_EXPAND_SZ,
-                           (LPBYTE)lpSchemeData, nLength * sizeof(TCHAR));
+    lError = RegSetValueEx(hCuCursorKey, szNewSchemeName, 0,
+                           REG_EXPAND_SZ, (LPBYTE)lpSchemeData,
+                           (_tcslen(lpSchemeData) + 1) * sizeof(TCHAR));
 
     RegCloseKey(hCuCursorKey);
     RegCloseKey(hCuKey);
@@ -919,7 +971,7 @@ OnDrawItem(UINT idCtl,
                    GetSysColor(COLOR_WINDOWTEXT));
     }
 
-    if (lpdis->itemID != -1)
+    if (lpdis->itemID != (UINT)-1)
     {
         CopyRect(&rc, &lpdis->rcItem);
         rc.left += 5;
@@ -1080,6 +1132,7 @@ ApplyCursorScheme(HWND hwndDlg)
 {
     TCHAR szSchemeName[MAX_PATH];
     TCHAR szSystemScheme[MAX_PATH];
+    TCHAR szTempPath[MAX_PATH];
     LPTSTR lpSchemeData;
     DWORD dwNameLength;
     DWORD dwSchemeSource;
@@ -1131,9 +1184,10 @@ ApplyCursorScheme(HWND hwndDlg)
 
     for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
     {
+        CompressPath(szTempPath, g_CursorData[i].szCursorPath);
         RegSetValueEx(hCursorKey, g_CursorData[i].lpValueName, 0,
-                      REG_EXPAND_SZ, (LPBYTE)g_CursorData[i].szCursorPath,
-                      (_tcslen(g_CursorData[i].szCursorPath) + 1) * sizeof(TCHAR));
+                      REG_EXPAND_SZ, (LPBYTE)szTempPath,
+                      (_tcslen(szTempPath) + 1) * sizeof(TCHAR));
     }
 
     RegCloseKey(hCursorKey);
@@ -1169,15 +1223,13 @@ PointerProc(IN HWND hwndDlg,
             EnumerateCursorSchemes(hwndDlg);
             LoadInitialCursorScheme(hwndDlg);
 
-            /* Get drop shadow setting */
-            if (!SystemParametersInfo(SPI_GETDROPSHADOW, 0, &pPointerData->bDropShadow, 0))
-                pPointerData->bDropShadow = FALSE;
+            /* Get cursor shadow setting */
+            SystemParametersInfo(SPI_GETCURSORSHADOW, 0, &pPointerData->bCursorShadow, 0);
+            pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow;
 
-            pPointerData->bOrigDropShadow = pPointerData->bDropShadow;
-
-            if (pPointerData->bDropShadow)
+            if (pPointerData->bCursorShadow)
             {
-                SendDlgItemMessage(hwndDlg, IDC_CHECK_DROP_SHADOW, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
+                SendDlgItemMessage(hwndDlg, IDC_CHECK_CURSOR_SHADOW, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
             }
 
             if ((INT)wParam == IDC_LISTBOX_CURSOR)
@@ -1204,10 +1256,10 @@ PointerProc(IN HWND hwndDlg,
             {
                 ApplyCursorScheme(hwndDlg);
 //#if (WINVER >= 0x0500)
-                if (pPointerData->bOrigDropShadow != pPointerData->bDropShadow)
+                if (pPointerData->bOrigCursorShadow != pPointerData->bCursorShadow)
                 {
-                    SystemParametersInfo(SPI_SETDROPSHADOW, 0, (PVOID)pPointerData->bDropShadow, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
-                    pPointerData->bOrigDropShadow = pPointerData->bDropShadow;
+                    SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
+                    pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow;
                 }
 //#endif
                 return TRUE;
@@ -1215,7 +1267,7 @@ PointerProc(IN HWND hwndDlg,
             else if (lppsn->hdr.code == PSN_RESET)
             {
 //#if (WINVER >= 0x0500)
-                SystemParametersInfo(SPI_SETDROPSHADOW, 0, (PVOID)pPointerData->bOrigDropShadow, 0);
+                SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bOrigCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
 //#endif
             }
             break;
@@ -1298,23 +1350,23 @@ PointerProc(IN HWND hwndDlg,
                     DeleteUserCursorScheme(hwndDlg);
                     break;
 
-                case IDC_CHECK_DROP_SHADOW:
-                    if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_DROP_SHADOW))
+                case IDC_CHECK_CURSOR_SHADOW:
+                    if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_CURSOR_SHADOW))
                     {
-                        pPointerData->bDropShadow = FALSE;
+                        pPointerData->bCursorShadow = FALSE;
                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
 //#if (WINVER >= 0x0500)
-//                        SystemParametersInfo(SPI_SETDROPSHADOW, 0, (PVOID)pPointerData->bDropShadow, 0);
+//                        SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bCursorShadow, 0);
 //#endif
 //                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                     }
                     else
                     {
-                        pPointerData->bDropShadow = TRUE;
+                        pPointerData->bCursorShadow = TRUE;
                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
                     }
 //#if (WINVER >= 0x0500)
-                    SystemParametersInfo(SPI_SETDROPSHADOW, 0, (PVOID)pPointerData->bDropShadow, 0);
+                    //SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bCursorShadow, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
 //#endif
                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                     break;
@@ -1361,23 +1413,19 @@ OptionProc(IN HWND hwndDlg,
             pOptionData->OrigMouseAccel.nThreshold2 = pOptionData->MouseAccel.nThreshold2;
 
             /* snap to default button */
-            if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &pOptionData->bSnapToDefaultButton, 0))
-                pOptionData->bSnapToDefaultButton = FALSE;
+            SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &pOptionData->bSnapToDefaultButton, 0);
             pOptionData->bOrigSnapToDefaultButton = pOptionData->bSnapToDefaultButton;
 
             /* mouse trails */
-            if (!SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &pOptionData->uMouseTrails, 0))
-                pOptionData->uMouseTrails = 0;
+            SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &pOptionData->uMouseTrails, 0);
             pOptionData->uOrigMouseTrails = pOptionData->uMouseTrails;
 
             /* hide pointer while typing */
-            if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &pOptionData->bMouseVanish, 0))
-                pOptionData->bMouseVanish = FALSE;
+            SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &pOptionData->bMouseVanish, 0);
             pOptionData->bOrigMouseVanish = pOptionData->bMouseVanish;
 
             /* show pointer with Ctrl-Key */
-            if (!SystemParametersInfo(SPI_GETMOUSESONAR, 0, &pOptionData->bMouseSonar, 0))
-                pOptionData->bMouseSonar = FALSE;
+            SystemParametersInfo(SPI_GETMOUSESONAR, 0, &pOptionData->bMouseSonar, 0);
             pOptionData->bOrigMouseSonar = pOptionData->bMouseSonar;
 
             /* Set mouse speed */
@@ -1498,7 +1546,7 @@ OptionProc(IN HWND hwndDlg,
                         pOptionData->bMouseVanish = TRUE;
                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
                     }
-                    SystemParametersInfo(SPI_SETMOUSEVANISH, 0, (PVOID)pOptionData->bMouseVanish, 0);
+                    SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bMouseVanish), 0);
                     break;
 
                 case IDC_CHECK_SHOW_POINTER:
@@ -1512,7 +1560,7 @@ OptionProc(IN HWND hwndDlg,
                         pOptionData->bMouseSonar = TRUE;
                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
                     }
-                    SystemParametersInfo(SPI_SETMOUSESONAR, 0, (PVOID)pOptionData->bMouseSonar, 0);
+                    SystemParametersInfo(SPI_SETMOUSESONAR, 0, IntToPtr(pOptionData->bMouseSonar), 0);
                     break;
 
             }
@@ -1526,7 +1574,7 @@ OptionProc(IN HWND hwndDlg,
                 /* Set mouse speed */
                 if (pOptionData->ulOrigMouseSpeed != pOptionData->ulMouseSpeed)
                 {
-                    SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)pOptionData->ulMouseSpeed, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
+                    SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulMouseSpeed), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
                     pOptionData->ulOrigMouseSpeed = pOptionData->ulMouseSpeed;
                 }
 
@@ -1556,14 +1604,14 @@ OptionProc(IN HWND hwndDlg,
                 /* hide pointer while typing */
                 if (pOptionData->bOrigMouseVanish != pOptionData->bMouseVanish)
                 {
-                    SystemParametersInfo(SPI_SETMOUSEVANISH, 0, (PVOID)pOptionData->bMouseVanish, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
+                    SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bMouseVanish), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
                     pOptionData->bOrigMouseVanish = pOptionData->bMouseVanish;
                 }
 
                 /* show pointer with Ctrl-Key */
                 if (pOptionData->bOrigMouseSonar != pOptionData->bMouseSonar)
                 {
-                    SystemParametersInfo(SPI_SETMOUSESONAR, 0, (PVOID)pOptionData->bMouseSonar, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
+                    SystemParametersInfo(SPI_SETMOUSESONAR, 0, IntToPtr(pOptionData->bMouseSonar), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
                     pOptionData->bOrigMouseSonar = pOptionData->bMouseSonar;
                 }
                 return TRUE;
@@ -1571,12 +1619,12 @@ OptionProc(IN HWND hwndDlg,
             else if (lppsn->hdr.code == PSN_RESET)
             {
                 /* Set the original mouse speed */
-                SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)pOptionData->ulOrigMouseSpeed, 0);
+                SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulOrigMouseSpeed), 0);
                 SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->OrigMouseAccel, 0);
                 SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bOrigSnapToDefaultButton, 0, 0);
                 SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uOrigMouseTrails, 0, 0);
-                SystemParametersInfo(SPI_SETMOUSEVANISH, 0, (PVOID)pOptionData->bOrigMouseVanish, 0);
-                SystemParametersInfo(SPI_SETMOUSESONAR, 0, (PVOID)pOptionData->bOrigMouseSonar, 0);
+                SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bOrigMouseVanish), 0);
+                SystemParametersInfo(SPI_SETMOUSESONAR, 0,IntToPtr(pOptionData->bOrigMouseSonar), 0);
             }
             break;
 
@@ -1593,7 +1641,7 @@ OptionProc(IN HWND hwndDlg,
                     case TB_BOTTOM:
                     case TB_ENDTRACK:
                         pOptionData->ulMouseSpeed = (ULONG)SendDlgItemMessage(hwndDlg, IDC_SLIDER_MOUSE_SPEED, TBM_GETPOS, 0, 0) + 1;
-                        SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)pOptionData->ulMouseSpeed, SPIF_SENDCHANGE);
+                        SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulMouseSpeed), SPIF_SENDCHANGE);
                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
                         break;
 #if 0
@@ -1693,10 +1741,7 @@ WheelProc(IN HWND hwndDlg,
             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pWheelData);
 
             /* Get wheel scroll lines */
-            if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &pWheelData->uWheelScrollLines, 0))
-            {
-                pWheelData->uWheelScrollLines = DEFAULT_WHEEL_SCROLL_LINES;
-            }
+            SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &pWheelData->uWheelScrollLines, 0);
 
             ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, TRUE);
             SendDlgItemMessage(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES, UDM_SETRANGE, 0, MAKELONG((short)100, (short)0));
@@ -1749,13 +1794,29 @@ WheelProc(IN HWND hwndDlg,
     return FALSE;
 }
 
+static const struct
+{
+    WORD idDlg;
+    DLGPROC DlgProc;
+    UINT uiReplaceWith;
+} PropPages[] =
+{
+    { IDD_PAGE_BUTTON, ButtonProc, CPLPAGE_MOUSE_BUTTONS },
+    { IDD_PAGE_POINTER, PointerProc, 0 },
+    { IDD_PAGE_OPTION, OptionProc, CPLPAGE_MOUSE_PTRMOTION },
+    { IDD_PAGE_WHEEL, WheelProc, CPLPAGE_MOUSE_WHEEL },
+    { IDD_HARDWARE, MouseHardwareProc, 0 },
+};
 
 LONG APIENTRY
-MouseApplet(HWND hwnd, UINT uMsg, LONG lParam1, LONG lParam2)
+MouseApplet(HWND hwnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
 {
-    PROPSHEETPAGE psp[5];
+    HPROPSHEETPAGE hpsp[MAX_CPL_PAGES];
     PROPSHEETHEADER psh;
+    HPSXA hpsxa;
     TCHAR Caption[256];
+    UINT i;
+    LONG ret;
 
     UNREFERENCED_PARAMETER(lParam1);
     UNREFERENCED_PARAMETER(lParam2);
@@ -1766,21 +1827,40 @@ MouseApplet(HWND hwnd, UINT uMsg, LONG lParam1, LONG lParam2)
 
     ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
     psh.dwSize = sizeof(PROPSHEETHEADER);
-    psh.dwFlags =  PSH_PROPSHEETPAGE | PSH_PROPTITLE;
-    psh.hwndParent = NULL;
+    psh.dwFlags = PSH_PROPTITLE;
+    psh.hwndParent = hwnd;
     psh.hInstance = hApplet;
     psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON_1));
     psh.pszCaption = Caption;
-    psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
     psh.nStartPage = 0;
-    psh.ppsp = psp;
-
-    InitPropSheetPage(&psp[0], IDD_PAGE_BUTTON, ButtonProc);
-    InitPropSheetPage(&psp[1], IDD_PAGE_POINTER, PointerProc);
-    InitPropSheetPage(&psp[2], IDD_PAGE_OPTION, OptionProc);
-    InitPropSheetPage(&psp[3], IDD_PAGE_WHEEL, WheelProc);
-    InitPropSheetPage(&psp[4], IDD_HARDWARE, MouseHardwareProc);
-    return (LONG)(PropertySheet(&psh) != -1);
+    psh.phpage = hpsp;
+
+    /* Load additional pages provided by shell extensions */
+    hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Mouse"), MAX_CPL_PAGES - psh.nPages);
+
+    for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++)
+    {
+        /* Override the background page if requested by a shell extension */
+        if (PropPages[i].uiReplaceWith != 0 && hpsxa != NULL &&
+            SHReplaceFromPropSheetExtArray(hpsxa, PropPages[i].uiReplaceWith, PropSheetAddPage, (LPARAM)&psh) != 0)
+        {
+            /* The shell extension added one or more pages to replace a page.
+               Don't create the built-in page anymore! */
+            continue;
+        }
+
+        InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc);
+    }
+
+    if (hpsxa != NULL)
+        SHAddFromPropSheetExtArray(hpsxa, PropSheetAddPage, (LPARAM)&psh);
+
+    ret = (LONG)(PropertySheet(&psh) != -1);
+
+    if (hpsxa != NULL)
+        SHDestroyPropSheetExtArray(hpsxa);
+
+    return ret;
 }
 
 /* EOF */