ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mouse.c
Go to the documentation of this file.
00001 /*
00002  *  ReactOS
00003  *  Copyright (C) 2004, 2007 ReactOS Team
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License along
00016  *  with this program; if not, write to the Free Software Foundation, Inc.,
00017  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00018  */
00019 /* $Id: mouse.c 56254 2012-03-28 07:09:53Z tkreuzer $
00020  *
00021  * PROJECT:         ReactOS Main Control Panel
00022  * FILE:            dll/cpl/main/mouse.c
00023  * PURPOSE:         Mouse Control Panel
00024  * PROGRAMMER:      Eric Kohl
00025  *                  Johannes Anderwald
00026  */
00027 
00028 // TODO:
00029 //  Add missing icons
00030 
00031 #include "main.h"
00032 
00033 #define DEFAULT_DOUBLE_CLICK_SPEED  500
00034 #define DEFAULT_CLICK_LOCK_TIME     2200
00035 #define DEFAULT_MOUSE_SPEED     10
00036 #define DEFAULT_MOUSE_ACCELERATION  1
00037 #define DEFAULT_MOUSE_THRESHOLD1    6
00038 #define DEFAULT_MOUSE_THRESHOLD2    10
00039 #define MIN_DOUBLE_CLICK_SPEED      200
00040 #define MAX_DOUBLE_CLICK_SPEED      900
00041 #define DEFAULT_WHEEL_SCROLL_LINES  3
00042 
00043 typedef struct _BUTTON_DATA
00044 {
00045     ULONG g_SwapMouseButtons;
00046     ULONG g_OrigSwapMouseButtons;
00047     ULONG g_DoubleClickSpeed; // = DEFAULT_DOUBLE_CLICK_SPEED;
00048     ULONG g_OrigDoubleClickSpeed;
00049     BOOL g_ClickLockEnabled;  // = 0;
00050     DWORD g_ClickLockTime;    // = DEFAULT_CLICK_LOCK_TIME;
00051 
00052     HICON hButtonLeft;
00053     HICON hButtonRight;
00054 
00055     HICON hIcon1;
00056     HICON hIcon2;
00057     BOOL bClicked;
00058 } BUTTON_DATA, *PBUTTON_DATA;
00059 
00060 
00061 typedef struct _POINTER_DATA
00062 {
00063     BOOL bCursorShadow;
00064     BOOL bOrigCursorShadow;
00065 
00066     INT cxCursor;
00067     INT cyCursor;
00068 } POINTER_DATA, *PPOINTER_DATA;
00069 
00070 
00071 typedef struct _MOUSE_ACCEL
00072 {
00073     INT nThreshold1;
00074     INT nThreshold2;
00075     INT nAcceleration;
00076 } MOUSE_ACCEL;
00077 
00078 typedef struct _OPTION_DATA
00079 {
00080     ULONG ulMouseSpeed;
00081     ULONG ulOrigMouseSpeed;
00082 
00083     MOUSE_ACCEL MouseAccel;
00084     MOUSE_ACCEL OrigMouseAccel;
00085 
00086     BOOL bSnapToDefaultButton;
00087     BOOL bOrigSnapToDefaultButton;
00088 
00089     UINT uMouseTrails;
00090     UINT uOrigMouseTrails;
00091 
00092     BOOL bMouseVanish;
00093     BOOL bOrigMouseVanish;
00094 
00095     BOOL bMouseSonar;
00096     BOOL bOrigMouseSonar;
00097 } OPTION_DATA, *POPTION_DATA;
00098 
00099 
00100 typedef struct _WHEEL_DATA
00101 {
00102     UINT uWheelScrollLines;
00103 } WHEEL_DATA, *PWHEEL_DATA;
00104 
00105 
00106 typedef struct _CURSOR_DATA
00107 {
00108     UINT uStringId;
00109     UINT uDefaultCursorId;
00110     LPTSTR lpValueName;
00111     HCURSOR hCursor;
00112     TCHAR szCursorName[MAX_PATH];
00113     TCHAR szCursorPath[MAX_PATH];
00114 } CURSOR_DATA, *PCURSOR_DATA;
00115 
00116 
00117 CURSOR_DATA g_CursorData[] =
00118 {{IDS_ARROW,       100/*OCR_NORMAL*/,      _T("Arrow"),       0, _T(""), _T("")},
00119  {IDS_HELP,        112/*OCR_HELP*/,        _T("Help"),        0, _T(""), _T("")},
00120  {IDS_APPSTARTING, 111/*OCR_APPSTARTING*/, _T("AppStarting"), 0, _T(""), _T("")},
00121  {IDS_WAIT,        102/*OCR_WAIT*/,        _T("Wait"),        0, _T(""), _T("")},
00122  {IDS_CROSSHAIR,   103/*OCR_CROSS*/,       _T("Crosshair"),   0, _T(""), _T("")},
00123  {IDS_IBEAM,       101/*OCR_IBEAM*/,       _T("IBeam"),       0, _T(""), _T("")},
00124  {IDS_NWPEN,       113/*OCR_NWPEN*/,       _T("NWPen"),       0, _T(""), _T("")},
00125  {IDS_NO,          110/*OCR_NO*/,          _T("No"),          0, _T(""), _T("")},
00126  {IDS_SIZENS,      108/*OCR_SIZENS*/,      _T("SizeNS"),      0, _T(""), _T("")},
00127  {IDS_SIZEWE,      107/*OCR_SIZEWE*/,      _T("SizeWE"),      0, _T(""), _T("")},
00128  {IDS_SIZENWSE,    105/*OCR_SIZENWSE*/,    _T("SizeNWSE"),    0, _T(""), _T("")},
00129  {IDS_SIZENESW,    106/*OCR_SIZENESW*/,    _T("SizeNESW"),    0, _T(""), _T("")},
00130  {IDS_SIZEALL,     109/*OCR_SIZEALL*/,     _T("SizeAll"),     0, _T(""), _T("")},
00131  {IDS_UPARROW,     104/*OCR_UP*/,          _T("UpArrow"),     0, _T(""), _T("")},
00132  {IDS_HAND,        114/*OCR_HAND*/,        _T("Hand"),        0, _T(""), _T("")}};
00133 
00134 
00135 #if 0
00136 static VOID
00137 DebugMsg(LPTSTR fmt, ...)
00138 {
00139     TCHAR szBuffer[2048];
00140     va_list marker;
00141 
00142     va_start(marker, fmt);
00143     _vstprintf(szBuffer, fmt, marker);
00144     va_end(marker);
00145 
00146     MessageBox(NULL, szBuffer, _T("Debug message"), MB_OK);
00147 }
00148 #endif
00149 
00150 
00151 /* Property page dialog callback */
00152 static INT_PTR CALLBACK
00153 MouseHardwareProc(IN HWND hwndDlg,
00154                   IN UINT uMsg,
00155                   IN WPARAM wParam,
00156                   IN LPARAM lParam)
00157 {
00158     GUID Guids[1];
00159     Guids[0] = GUID_DEVCLASS_MOUSE;
00160 
00161     UNREFERENCED_PARAMETER(lParam);
00162     UNREFERENCED_PARAMETER(wParam);
00163 
00164     switch(uMsg)
00165     {
00166         case WM_INITDIALOG:
00167             /* create the hardware page */
00168             DeviceCreateHardwarePageEx(hwndDlg,
00169                                        Guids,
00170                                        sizeof(Guids) / sizeof(Guids[0]),
00171                                        HWPD_STANDARDLIST);
00172             break;
00173     }
00174 
00175     return FALSE;
00176 }
00177 
00178 
00179 static INT_PTR CALLBACK
00180 ClickLockProc(IN HWND hwndDlg,
00181               IN UINT uMsg,
00182               IN WPARAM wParam,
00183               IN LPARAM lParam)
00184 {
00185     HWND hDlgCtrl;
00186     int pos;
00187     static HICON hIcon;
00188 
00189     PBUTTON_DATA pButtonData;
00190 
00191     pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
00192 
00193     switch(uMsg)
00194     {
00195         case WM_INITDIALOG:
00196             pButtonData = (PBUTTON_DATA)lParam;
00197             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData);
00198 
00199             hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK);
00200             SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 10));
00201             pos = (pButtonData->g_ClickLockTime - 200) / 200;
00202             SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos);
00203 
00204             hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOOK_KEY),
00205                               IMAGE_ICON, 16, 16, 0);
00206             SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
00207             return TRUE;
00208 
00209         case WM_COMMAND:
00210             if (LOWORD(wParam) == IDOK)
00211             {
00212                 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK);
00213                 pButtonData->g_ClickLockTime = (DWORD) (SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) * 200) + 200;
00214                 EndDialog(hwndDlg, TRUE);
00215                 if (hIcon) DestroyIcon(hIcon);
00216             }
00217             else if (LOWORD(wParam) == IDCANCEL)
00218             {
00219                 EndDialog(hwndDlg, FALSE);
00220                 if (hIcon) DestroyIcon(hIcon);
00221             }
00222             break;
00223     }
00224 
00225     return FALSE;
00226 }
00227 
00228 
00229 static INT_PTR CALLBACK
00230 ButtonProc(IN HWND hwndDlg,
00231            IN UINT uMsg,
00232            IN WPARAM wParam,
00233            IN LPARAM lParam)
00234 {
00235     HWND hDlgCtrl;
00236     LRESULT lResult;
00237     LPPSHNOTIFY lppsn;
00238 
00239     PBUTTON_DATA pButtonData;
00240 
00241     pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
00242 
00243     switch (uMsg)
00244     {
00245         case WM_INITDIALOG:
00246             pButtonData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BUTTON_DATA));
00247             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData);
00248 
00249             pButtonData->g_SwapMouseButtons = GetSystemMetrics(SM_SWAPBUTTON);
00250             pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons;
00251             pButtonData->g_DoubleClickSpeed = GetDoubleClickTime();
00252             pButtonData->g_OrigDoubleClickSpeed = pButtonData->g_DoubleClickSpeed;
00253 
00254             /* Click lock time */
00255             SystemParametersInfo(SPI_GETMOUSECLICKLOCK, 0, &pButtonData->g_ClickLockEnabled, 0);
00256             SystemParametersInfo(SPI_GETMOUSECLICKLOCKTIME, 0, &pButtonData->g_ClickLockTime, 0);
00257 
00258             /* Load mouse button icons */
00259             pButtonData->hButtonLeft = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_LEFT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
00260             pButtonData->hButtonRight = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_RIGHT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
00261 
00262             /* Load folder icons */
00263             pButtonData->hIcon1 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_CLOSED), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
00264             pButtonData->hIcon2 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_OPEN), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
00265 
00266             if (pButtonData->g_SwapMouseButtons)
00267             {
00268                 SendDlgItemMessage(hwndDlg, IDC_SWAP_MOUSE_BUTTONS, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
00269                 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight);
00270             }
00271             else
00272             {
00273                 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft);
00274             }
00275 
00276             if (pButtonData->g_ClickLockEnabled)
00277             {
00278                 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_CLICK_LOCK);
00279                 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
00280             }
00281             else
00282             {
00283                 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK);
00284                 EnableWindow(hDlgCtrl, FALSE);
00285             }
00286 
00287             hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED);
00288             SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 14));
00289             SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, 14 - ((pButtonData->g_DoubleClickSpeed - 200) / 50));
00290 
00291 
00292             SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hIcon1);
00293             pButtonData->bClicked = TRUE;
00294             return TRUE;
00295 
00296         case WM_DESTROY:
00297             DestroyIcon(pButtonData->hButtonLeft);
00298             DestroyIcon(pButtonData->hButtonRight);
00299             DestroyIcon(pButtonData->hIcon1);
00300             DestroyIcon(pButtonData->hIcon2);
00301             HeapFree(GetProcessHeap(), 0, pButtonData);
00302             break;
00303 
00304         case WM_COMMAND:
00305             switch(LOWORD(wParam))
00306             {
00307                 case IDC_SWAP_MOUSE_BUTTONS:
00308                     lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
00309                     if (lResult == BST_CHECKED)
00310                     {
00311                         pButtonData->g_SwapMouseButtons = FALSE;
00312                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
00313                         SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft);
00314                     }
00315                     else if (lResult == BST_UNCHECKED)
00316                     {
00317                         pButtonData->g_SwapMouseButtons = TRUE;
00318                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
00319                         SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight);
00320                     }
00321                     //SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_SwapMouseButtons, NULL, 0);
00322                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
00323                     break;
00324 
00325                 case IDC_CHECK_CLICK_LOCK:
00326                     lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
00327                     hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK);
00328                     if (lResult == BST_CHECKED)
00329                     {
00330                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
00331                         pButtonData->g_ClickLockEnabled = FALSE;
00332                         EnableWindow(hDlgCtrl, FALSE);
00333                     }
00334                     else if (lResult == BST_UNCHECKED)
00335                     {
00336                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
00337                         pButtonData->g_ClickLockEnabled = TRUE;
00338                         EnableWindow(hDlgCtrl, TRUE);
00339                     }
00340                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
00341                     break;
00342 
00343                 case IDC_BUTTON_CLICK_LOCK:
00344                     DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_CLICK_LOCK), hwndDlg, ClickLockProc, (LPARAM)pButtonData);
00345                     break;
00346 
00347                 case IDC_IMAGE_DOUBLE_CLICK_SPEED:
00348                     if (HIWORD(wParam) == STN_DBLCLK)
00349                     {
00350                         pButtonData->bClicked = !pButtonData->bClicked;
00351                         SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON,
00352                                            (LPARAM)(pButtonData->bClicked ? pButtonData->hIcon1 : pButtonData->hIcon2));
00353                     }
00354                     break;
00355             }
00356             break;
00357 
00358         case WM_NOTIFY:
00359             lppsn = (LPPSHNOTIFY) lParam;
00360             if (lppsn->hdr.code == PSN_APPLY)
00361             {
00362                 if (pButtonData->g_OrigSwapMouseButtons != pButtonData->g_SwapMouseButtons)
00363                 {
00364                     pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons;
00365                     SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
00366 
00367                 }
00368                 SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
00369                 //SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
00370 
00371 #if (WINVER >= 0x0500)
00372                 SystemParametersInfo(SPI_SETMOUSECLICKLOCK, 0, UlongToPtr(pButtonData->g_ClickLockEnabled), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
00373                 if (pButtonData->g_ClickLockEnabled)
00374                    SystemParametersInfo(SPI_SETMOUSECLICKLOCKTIME, pButtonData->g_ClickLockTime, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
00375 #endif
00376             }
00377             else if (lppsn->hdr.code == PSN_RESET)
00378             {
00379                 /* Reset swap mouse button setting */
00380                 SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, 0);
00381 
00382                 /* Reset double click speed setting */
00383                 SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_OrigDoubleClickSpeed, NULL, 0);
00384                 //SetDoubleClickTime(pButtonData->g_OrigDoubleClickSpeed);
00385             }
00386             return TRUE;
00387 
00388         case WM_HSCROLL:
00389             if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED))
00390             {
00391                 switch (LOWORD(wParam))
00392                 {
00393                     case TB_LINEUP:
00394                     case TB_LINEDOWN:
00395                     case TB_PAGEUP:
00396                     case TB_PAGEDOWN:
00397                     case TB_TOP:
00398                     case TB_BOTTOM:
00399                     case TB_ENDTRACK:
00400                         lResult = SendDlgItemMessage(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED, TBM_GETPOS, 0, 0);
00401                         pButtonData->g_DoubleClickSpeed = (14 - (INT)lResult) * 50 + 200;
00402                         //SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
00403                         SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
00404                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
00405                         break;
00406 
00407                     case TB_THUMBTRACK:
00408                         pButtonData->g_DoubleClickSpeed = (14 - (INT)HIWORD(wParam)) * 50 + 200;
00409                         //SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, 0);
00410                         SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
00411                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
00412                         break;
00413                 }
00414             }
00415             break;
00416     }
00417 
00418     return FALSE;
00419 }
00420 
00421 
00422 static VOID
00423 CompressPath(LPTSTR lpShortPath, LPTSTR lpPath)
00424 {
00425     TCHAR szUserProfile[MAX_PATH];
00426     TCHAR szSystemRoot[MAX_PATH];
00427     TCHAR szProgramFiles[MAX_PATH];
00428     DWORD dwUserProfile;
00429     DWORD dwSystemRoot;
00430     DWORD dwProgramFiles;
00431 
00432     dwUserProfile = GetEnvironmentVariable(_T("USERPROFILE"), szUserProfile, MAX_PATH);
00433     dwSystemRoot = GetEnvironmentVariable(_T("SystemRoot"), szSystemRoot, MAX_PATH);
00434     dwProgramFiles = GetEnvironmentVariable(_T("ProgramFiles"), szProgramFiles, MAX_PATH);
00435 
00436     if (dwUserProfile > 0 && _tcsncmp(lpPath, szUserProfile, dwUserProfile) == 0)
00437     {
00438         _tcscpy(lpShortPath, _T("%USERPROFILE%"));
00439         _tcscat(lpShortPath, &lpPath[dwUserProfile]);
00440     }
00441     else if (dwSystemRoot > 0 && _tcsncmp(lpPath, szSystemRoot, dwSystemRoot) == 0)
00442     {
00443         _tcscpy(lpShortPath, _T("%SystemRoot%"));
00444         _tcscat(lpShortPath, &lpPath[dwSystemRoot]);
00445     }
00446     else if (dwProgramFiles > 0 && _tcsncmp(lpPath, szProgramFiles, dwProgramFiles) == 0)
00447     {
00448         _tcscpy(lpShortPath, _T("%ProgramFiles%"));
00449         _tcscat(lpShortPath, &lpPath[dwProgramFiles]);
00450     }
00451     else
00452     {
00453         _tcscpy(lpShortPath, lpPath);
00454     }
00455 }
00456 
00457 
00458 static BOOL
00459 EnumerateCursorSchemes(HWND hwndDlg)
00460 {
00461     HKEY hCursorKey;
00462     DWORD dwIndex;
00463     TCHAR szValueName[MAX_PATH];
00464     DWORD dwValueName;
00465     TCHAR szSystemScheme[MAX_PATH];
00466     TCHAR szValueData[2000];
00467     TCHAR szTempData[2000];
00468     DWORD dwValueData;
00469     LONG lError;
00470     HWND hDlgCtrl;
00471     LRESULT lResult;
00472 
00473     hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME);
00474     SendMessage(hDlgCtrl, CB_RESETCONTENT, 0, 0);
00475 
00476     /* Read the users cursor schemes */
00477     lError = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Cursors\\Schemes"),
00478                           0, KEY_READ | KEY_QUERY_VALUE , &hCursorKey);
00479     if (lError == ERROR_SUCCESS)
00480     {
00481         for (dwIndex = 0;; dwIndex++)
00482         {
00483             dwValueName = sizeof(szValueName) / sizeof(TCHAR);
00484             dwValueData = sizeof(szValueData) / sizeof(TCHAR);
00485             lError = RegEnumValue(hCursorKey, dwIndex, szValueName, &dwValueName,
00486                                   NULL, NULL, (LPBYTE)szValueData, &dwValueData);
00487             if (lError == ERROR_NO_MORE_ITEMS)
00488                 break;
00489 
00490             ExpandEnvironmentStrings(szValueData, szTempData, 2000);
00491 
00492             if (_tcslen(szTempData) > 0)
00493             {
00494                 LPTSTR lpCopy, lpStart;
00495 
00496                 /* Remove quotation marks */
00497                 if (szTempData[0] == _T('"'))
00498                 {
00499                     lpStart = szValueData + 1;
00500                     szTempData[_tcslen(szTempData) - 1] = 0;
00501                 }
00502                 else
00503                 {
00504                     lpStart = szTempData;
00505                 }
00506 
00507                 lpCopy = _tcsdup(lpStart);
00508 
00509                 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValueName);
00510                 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)lpCopy);
00511             }
00512         }
00513 
00514         RegCloseKey(hCursorKey);
00515     }
00516 
00517     /* Read the system cursor schemes */
00518     lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00519                           _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cursors\\Schemes"),
00520                           0, KEY_READ | KEY_QUERY_VALUE , &hCursorKey);
00521     if (lError == ERROR_SUCCESS)
00522     {
00523         LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
00524 
00525         for (dwIndex = 0;; dwIndex++)
00526         {
00527             dwValueName = sizeof(szValueName) / sizeof(TCHAR);
00528             dwValueData = sizeof(szValueData) / sizeof(TCHAR);
00529             lError = RegEnumValue(hCursorKey, dwIndex, szValueName, &dwValueName,
00530                                   NULL, NULL, (LPBYTE)szValueData, &dwValueData);
00531             if (lError == ERROR_NO_MORE_ITEMS)
00532                 break;
00533 
00534             if (_tcslen(szValueData) > 0)
00535             {
00536                 LPTSTR lpCopy, lpStart;
00537 
00538                 /* Remove quotation marks */
00539                 if (szValueData[0] == _T('"'))
00540                 {
00541                     lpStart = szValueData + 1;
00542                     szValueData[_tcslen(szValueData) - 1] = 0;
00543                 }
00544                 else
00545                 {
00546                     lpStart = szValueData;
00547                 }
00548 
00549                 lpCopy = _tcsdup(lpStart);
00550 
00551                 _tcscat(szValueName, TEXT(" "));
00552                 _tcscat(szValueName, szSystemScheme);
00553 
00554                 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValueName);
00555                 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)lpCopy);
00556             }
00557         }
00558 
00559         RegCloseKey(hCursorKey);
00560     }
00561 
00562     /* Add the "(none)" entry */
00563     LoadString(hApplet, IDS_NONE, szSystemScheme, MAX_PATH);
00564     lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szSystemScheme);
00565     SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)NULL);
00566 
00567     return TRUE;
00568 }
00569 
00570 
00571 static VOID
00572 RefreshCursorList(HWND hwndDlg, BOOL bInit)
00573 {
00574     INT index;
00575     INT i;
00576     INT nSel;
00577 
00578     nSel = bInit ? 0 : SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0);
00579 
00580     if (bInit)
00581     {
00582         SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_RESETCONTENT, 0, 0);
00583         for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
00584         {
00585             LoadString(hApplet, index, g_CursorData[i].szCursorName, MAX_PATH);
00586             SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_ADDSTRING, 0, (LPARAM)i);
00587         }
00588 
00589         SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_SETCURSEL, nSel, 0);
00590     }
00591     else
00592     {
00593         InvalidateRect(GetDlgItem(hwndDlg, IDC_LISTBOX_CURSOR), NULL, FALSE);
00594     }
00595 
00596     SendDlgItemMessage(hwndDlg, IDC_IMAGE_CURRENT_CURSOR, STM_SETIMAGE, IMAGE_CURSOR,
00597                        (LPARAM)g_CursorData[nSel].hCursor);
00598 
00599     EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), (g_CursorData[nSel].szCursorPath[0] != 0));
00600 }
00601 
00602 
00603 static BOOL
00604 DeleteUserCursorScheme(HWND hwndDlg)
00605 {
00606     TCHAR szSchemeName[MAX_PATH];
00607     TCHAR szTitle[128];
00608     TCHAR szRawText[256];
00609     TCHAR szText[256];
00610     HWND hDlgCtrl;
00611     HKEY hCuKey;
00612     HKEY hCuCursorKey;
00613     LONG lResult;
00614     INT nSel;
00615 
00616     hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME);
00617     nSel = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);
00618     if (nSel == CB_ERR)
00619         return FALSE;
00620 
00621     SendMessage(hDlgCtrl, CB_GETLBTEXT, nSel, (LPARAM)szSchemeName);
00622 
00623     LoadString(hApplet, IDS_REMOVE_TITLE, szTitle, 128);
00624     LoadString(hApplet, IDS_REMOVE_TEXT, szRawText, 256);
00625 
00626     _stprintf(szText, szRawText, szSchemeName);
00627 
00628     /* Confirm scheme removal */
00629     if (MessageBox(hwndDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO)
00630         return TRUE;
00631 
00632     if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS)
00633         return FALSE;
00634 
00635     if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ | KEY_SET_VALUE, &hCuCursorKey) != ERROR_SUCCESS)
00636     {
00637         RegCloseKey(hCuKey);
00638         return FALSE;
00639     }
00640 
00641     lResult = RegDeleteValue(hCuCursorKey, szSchemeName);
00642 
00643     RegCloseKey(hCuCursorKey);
00644     RegCloseKey(hCuKey);
00645 
00646     if (lResult == ERROR_SUCCESS)
00647     {
00648         SendMessage(hDlgCtrl, CB_DELETESTRING, nSel, 0);
00649         SendMessage(hDlgCtrl, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
00650     }
00651 
00652     return (lResult == ERROR_SUCCESS);
00653 }
00654 
00655 
00656 static INT_PTR CALLBACK
00657 SaveSchemeProc(IN HWND hwndDlg,
00658                IN UINT uMsg,
00659                IN WPARAM wParam,
00660                IN LPARAM lParam)
00661 {
00662     LPTSTR pSchemeName;
00663 
00664     switch (uMsg)
00665     {
00666         case WM_INITDIALOG:
00667             pSchemeName = (LPTSTR)lParam;
00668             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSchemeName);
00669             SendDlgItemMessage(hwndDlg, IDC_EDIT_SCHEME_NAME, WM_SETTEXT,
00670                                0, (LPARAM)pSchemeName);
00671             break;
00672 
00673         case WM_COMMAND:
00674             if (LOWORD(wParam) == IDOK)
00675             {
00676                 pSchemeName = (LPTSTR)GetWindowLongPtr(hwndDlg, DWLP_USER);
00677                 SendDlgItemMessage(hwndDlg, IDC_EDIT_SCHEME_NAME, WM_GETTEXT,
00678                                    (WPARAM)MAX_PATH, (LPARAM)pSchemeName);
00679                 EndDialog(hwndDlg, TRUE);
00680             }
00681             else if (LOWORD(wParam) == IDCANCEL)
00682             {
00683                 EndDialog(hwndDlg, FALSE);
00684             }
00685             break;
00686     }
00687 
00688     return FALSE;
00689 }
00690 
00691 
00692 static BOOL
00693 SaveCursorScheme(HWND hwndDlg)
00694 {
00695     TCHAR szSystemScheme[MAX_PATH];
00696     TCHAR szSchemeName[MAX_PATH];
00697     TCHAR szNewSchemeName[MAX_PATH];
00698     TCHAR szTempPath[MAX_PATH];
00699     TCHAR szTitle[128];
00700     TCHAR szText[256];
00701     INT nSel;
00702     INT index, i, nLength;
00703     LPTSTR lpSchemeData;
00704     HKEY hCuKey;
00705     HKEY hCuCursorKey;
00706     LONG lError = ERROR_SUCCESS;
00707     BOOL bSchemeExists;
00708 
00709     LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
00710 
00711     nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0);
00712     if (nSel == CB_ERR)
00713        return FALSE;
00714 
00715     if (nSel == 0)
00716     {
00717         szSchemeName[0] = 0;
00718     }
00719     else
00720     {
00721         SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)szNewSchemeName);
00722 
00723         if (_tcsstr(szNewSchemeName, szSystemScheme))
00724         {
00725             szNewSchemeName[_tcslen(szNewSchemeName) - _tcslen(szSystemScheme) - 1] = 0;
00726         }
00727     }
00728 
00729     /* Ask for a name for the new cursor scheme */
00730     if (!DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_CURSOR_SCHEME_SAVEAS),
00731                         hwndDlg, SaveSchemeProc, (LPARAM)szNewSchemeName))
00732         return TRUE;
00733 
00734     /* Check all non-system schemes for the new name */
00735     nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCOUNT, 0, 0);
00736     if (nSel == CB_ERR)
00737         return FALSE;
00738 
00739     bSchemeExists = FALSE;
00740     for (i = 0; i < nSel; i++)
00741     {
00742         SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, i, (LPARAM)szSchemeName);
00743         if (_tcsstr(szSchemeName, szSystemScheme) == NULL)
00744         {
00745             if (_tcscmp(szSchemeName, szNewSchemeName) == 0)
00746             {
00747                 bSchemeExists = TRUE;
00748                 break;
00749             }
00750         }
00751     }
00752 
00753     if (bSchemeExists)
00754     {
00755         LoadString(hApplet, IDS_OVERWRITE_TITLE, szTitle, 128);
00756         LoadString(hApplet, IDS_OVERWRITE_TEXT, szText, 256);
00757 
00758          /* Confirm scheme overwrite */
00759         if (MessageBox(hwndDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO)
00760             return TRUE;
00761     }
00762 
00763     /* Save the cursor scheme */
00764     nLength = 0;
00765     for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
00766     {
00767         if (i > 0)
00768             nLength++;
00769         nLength += _tcslen(g_CursorData[i].szCursorPath);
00770     }
00771     nLength++;
00772 
00773     lpSchemeData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(TCHAR));
00774 
00775     for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
00776     {
00777         CompressPath(szTempPath, g_CursorData[i].szCursorPath);
00778         if (i > 0)
00779             _tcscat(lpSchemeData, _T(","));
00780         _tcscat(lpSchemeData, szTempPath);
00781     }
00782 
00783     if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS)
00784         return FALSE;
00785 
00786     if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ | KEY_SET_VALUE, &hCuCursorKey) != ERROR_SUCCESS)
00787     {
00788         RegCloseKey(hCuKey);
00789         return FALSE;
00790     }
00791 
00792     lError = RegSetValueEx(hCuCursorKey, szNewSchemeName, 0,
00793                            REG_EXPAND_SZ, (LPBYTE)lpSchemeData,
00794                            (_tcslen(lpSchemeData) + 1) * sizeof(TCHAR));
00795 
00796     RegCloseKey(hCuCursorKey);
00797     RegCloseKey(hCuKey);
00798 
00799     /* Add the new scheme to the scheme list and select it */
00800     if (lError == ERROR_SUCCESS)
00801     {
00802         LPTSTR copy = _tcsdup(lpSchemeData);
00803 
00804         nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_ADDSTRING, (WPARAM)0, (LPARAM)szNewSchemeName);
00805         SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETITEMDATA, (WPARAM)nSel, (LPARAM)copy);
00806         SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETCURSEL, (WPARAM)nSel, (LPARAM)0);
00807     }
00808 
00809     HeapFree(GetProcessHeap(), 0, lpSchemeData);
00810 
00811     return (lError == ERROR_SUCCESS);
00812 }
00813 
00814 
00815 static BOOL
00816 BrowseCursor(HWND hwndDlg)
00817 {
00818     TCHAR szFileName[MAX_PATH];
00819     TCHAR szFilter[MAX_PATH];
00820     TCHAR szTitle[MAX_PATH];
00821     OPENFILENAME ofn;
00822     INT nSel;
00823 
00824     LoadString(hApplet, IDS_BROWSE_FILTER, szFilter, MAX_PATH);
00825     LoadString(hApplet, IDS_BROWSE_TITLE, szTitle, MAX_PATH);
00826 
00827     memset(szFileName, 0x0, sizeof(szFileName));
00828     nSel = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0);
00829     if (nSel == LB_ERR)
00830     {
00831         MessageBox(hwndDlg, _T("LB_ERR"), _T(""), MB_ICONERROR);
00832         return FALSE;
00833     }
00834 
00835     ZeroMemory(&ofn, sizeof(OPENFILENAME));
00836     ofn.lStructSize = sizeof(OPENFILENAME);
00837     ofn.hwndOwner = hwndDlg;
00838     ofn.lpstrFilter = szFilter;
00839     ofn.nFilterIndex = 1;
00840     ofn.lpstrFile = szFileName;
00841     ofn.nMaxFile = MAX_PATH;
00842     ofn.lpstrInitialDir = _T("%WINDIR%\\Cursors");
00843     ofn.lpstrTitle = szTitle;
00844     ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
00845 
00846     if (!GetOpenFileName(&ofn))
00847         return FALSE;
00848 
00849     /* Store the new cursor file path */
00850     _tcsncpy(g_CursorData[nSel].szCursorPath, szFileName, MAX_PATH);
00851 
00852     return TRUE;
00853 }
00854 
00855 
00856 static VOID
00857 LoadCursorScheme(LPTSTR lpName, BOOL bSystem)
00858 {
00859     UINT index, i;
00860 
00861     for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
00862     {
00863         if (g_CursorData[i].hCursor != NULL)
00864         {
00865             DestroyCursor(g_CursorData[i].hCursor);
00866             g_CursorData[i].hCursor = 0;
00867         }
00868         g_CursorData[i].szCursorPath[0] = 0;
00869     }
00870 
00871     if (lpName != NULL)
00872     {
00873         LPTSTR pStart = lpName;
00874         LPTSTR pEnd = pStart;
00875         INT nLength;
00876 
00877         i = 0;
00878         while (pEnd)
00879         {
00880             pEnd = _tcschr(pStart, _T(','));
00881             if (pEnd)
00882                 nLength = ((INT_PTR)pEnd - (INT_PTR)pStart) / sizeof(TCHAR);
00883             else
00884                 nLength = _tcslen(pStart);
00885 
00886             _tcsncpy(g_CursorData[i].szCursorPath, pStart, nLength);
00887             g_CursorData[i].szCursorPath[nLength] = 0;
00888 
00889             pStart = pStart + (nLength + 1);
00890             i++;
00891         }
00892 
00893     }
00894 
00895     for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
00896     {
00897         if (g_CursorData[i].szCursorPath[0] == 0)
00898             g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(g_CursorData[i].uDefaultCursorId),
00899                                                          IMAGE_CURSOR, 0, 0,
00900                                                          LR_DEFAULTSIZE | LR_SHARED);
00901         else
00902             g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, g_CursorData[i].szCursorPath,
00903                                                          IMAGE_CURSOR, 0, 0,
00904                                                          LR_LOADFROMFILE | LR_DEFAULTSIZE);
00905     }
00906 }
00907 
00908 
00909 static VOID
00910 ReloadCurrentCursorScheme(VOID)
00911 {
00912     UINT index, i;
00913 
00914     for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
00915     {
00916         if (g_CursorData[i].hCursor != NULL)
00917             DestroyCursor(g_CursorData[i].hCursor);
00918 
00919         if (g_CursorData[i].szCursorPath[0] == 0)
00920             g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(g_CursorData[i].uDefaultCursorId),
00921                                                          IMAGE_CURSOR, 0, 0,
00922                                                          LR_DEFAULTSIZE | LR_SHARED);
00923         else
00924             g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, g_CursorData[i].szCursorPath,
00925                                                          IMAGE_CURSOR, 0, 0,
00926                                                          LR_LOADFROMFILE | LR_DEFAULTSIZE);
00927     }
00928 }
00929 
00930 
00931 static VOID
00932 OnDrawItem(UINT idCtl,
00933            LPDRAWITEMSTRUCT lpdis,
00934            PPOINTER_DATA pPointerData)
00935 {
00936     RECT rc;
00937 
00938     if (lpdis->itemState & ODS_SELECTED)
00939     {
00940         FillRect(lpdis->hDC,
00941                  &lpdis->rcItem,
00942                  (HBRUSH)(COLOR_HIGHLIGHT + 1));
00943         SetBkColor(lpdis->hDC,
00944                    GetSysColor(COLOR_HIGHLIGHT));
00945         SetTextColor(lpdis->hDC,
00946                    GetSysColor(COLOR_HIGHLIGHTTEXT));
00947     }
00948     else
00949     {
00950         FillRect(lpdis->hDC,
00951                  &lpdis->rcItem,
00952                  (HBRUSH)(COLOR_WINDOW + 1));
00953         SetBkColor(lpdis->hDC,
00954                    GetSysColor(COLOR_WINDOW));
00955         SetTextColor(lpdis->hDC,
00956                    GetSysColor(COLOR_WINDOWTEXT));
00957     }
00958 
00959     if (lpdis->itemID != (UINT)-1)
00960     {
00961         CopyRect(&rc, &lpdis->rcItem);
00962         rc.left += 5;
00963         DrawText(lpdis->hDC,
00964                  g_CursorData[lpdis->itemData].szCursorName,
00965                  -1,
00966                  &rc,
00967                  DT_SINGLELINE | DT_VCENTER | DT_LEFT);
00968 
00969         if (g_CursorData[lpdis->itemData].hCursor != NULL)
00970         {
00971             DrawIcon(lpdis->hDC,
00972                      lpdis->rcItem.right - pPointerData->cxCursor - 4,
00973                      lpdis->rcItem.top + 2,
00974                      g_CursorData[lpdis->itemData].hCursor);
00975         }
00976     }
00977 
00978     if (lpdis->itemState & ODS_FOCUS)
00979     {
00980         CopyRect(&rc, &lpdis->rcItem);
00981         InflateRect(&rc, -1, -1);
00982         DrawFocusRect(lpdis->hDC, &rc);
00983     }
00984 }
00985 
00986 
00987 static VOID
00988 LoadNewCursorScheme(HWND hwndDlg)
00989 {
00990     TCHAR buffer[MAX_PATH];
00991     TCHAR szSystemScheme[MAX_PATH];
00992     HWND hDlgCtrl;
00993     BOOL bEnable;
00994     LPTSTR lpName;
00995     INT nSel;
00996 
00997     nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0);
00998     if (nSel == CB_ERR)
00999        return;
01000 
01001     SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)buffer);
01002 
01003     LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
01004     if (_tcsstr(buffer, szSystemScheme) || nSel == 0) // Avoid the default scheme - Can be deleted
01005         bEnable = FALSE;
01006     else
01007         bEnable = TRUE;
01008 
01009     /* Delete button */
01010     hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_DELETE_SCHEME);
01011     EnableWindow(hDlgCtrl, bEnable);
01012 
01013     lpName = (LPTSTR)SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETITEMDATA, nSel, 0);
01014     LoadCursorScheme(lpName, !bEnable);
01015     RefreshCursorList(hwndDlg, FALSE);
01016 }
01017 
01018 
01019 static VOID
01020 LoadInitialCursorScheme(HWND hwndDlg)
01021 {
01022     TCHAR szSchemeName[256];
01023     TCHAR szSystemScheme[256];
01024     TCHAR szCursorPath[256];
01025     HKEY hCursorKey;
01026     LONG lError;
01027     DWORD dwDataSize;
01028     DWORD dwSchemeSource = 0;
01029     UINT index, i;
01030     DWORD dwType;
01031     INT nSel;
01032 
01033     for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
01034     {
01035         g_CursorData[i].hCursor = 0;
01036         g_CursorData[i].szCursorPath[0] = 0;
01037     }
01038 
01039     lError = RegOpenKeyEx(HKEY_CURRENT_USER,
01040                           _T("Control Panel\\Cursors"),
01041                           0,
01042                           KEY_READ | KEY_QUERY_VALUE,
01043                           &hCursorKey);
01044     if (lError != ERROR_SUCCESS)
01045         return;
01046 
01047     dwDataSize = sizeof(DWORD);
01048     lError = RegQueryValueEx(hCursorKey,
01049                              _T("Scheme Source"),
01050                              NULL,
01051                              NULL,
01052                              (LPBYTE)&dwSchemeSource,
01053                              &dwDataSize);
01054 
01055     if (dwSchemeSource != 0)
01056     {
01057         dwDataSize = 256 * sizeof(TCHAR);
01058         lError = RegQueryValueEx(hCursorKey,
01059                                  NULL,
01060                                  NULL,
01061                                  NULL,
01062                                  (LPBYTE)szSchemeName,
01063                                  &dwDataSize);
01064 
01065         for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
01066         {
01067             dwDataSize = MAX_PATH * sizeof(TCHAR);
01068             lError = RegQueryValueEx(hCursorKey,
01069                                      g_CursorData[i].lpValueName,
01070                                      NULL,
01071                                      &dwType,
01072                                      (LPBYTE)szCursorPath,
01073                                      &dwDataSize);
01074             if (lError == ERROR_SUCCESS)
01075             {
01076                 if (dwType == REG_EXPAND_SZ)
01077                 {
01078                     ExpandEnvironmentStrings(szCursorPath, g_CursorData[i].szCursorPath, MAX_PATH);
01079                 }
01080                 else
01081                 {
01082                     _tcscpy(g_CursorData[i].szCursorPath, szCursorPath);
01083                 }
01084             }
01085         }
01086     }
01087 
01088     RegCloseKey(hCursorKey);
01089 
01090     ReloadCurrentCursorScheme();
01091     RefreshCursorList(hwndDlg, TRUE);
01092 
01093     /* Build the full scheme name */
01094     if (dwSchemeSource == 0)
01095     {
01096         LoadString(hApplet, IDS_NONE, szSchemeName, MAX_PATH);
01097     }
01098     else if (dwSchemeSource == 2)
01099     {
01100         LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
01101         _tcscat(szSchemeName, _T(" "));
01102         _tcscat(szSchemeName, szSystemScheme);
01103     }
01104 
01105     /* Search and select the curent scheme name from the scheme list */
01106     nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_FINDSTRINGEXACT, -1, (LPARAM)szSchemeName);
01107     if (nSel != CB_ERR)
01108         SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETCURSEL, (WPARAM)nSel, (LPARAM)0);
01109 
01110     /* Enable /disable delete button */
01111     EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_DELETE_SCHEME), (dwSchemeSource == 1));
01112 }
01113 
01114 
01115 static BOOL
01116 ApplyCursorScheme(HWND hwndDlg)
01117 {
01118     TCHAR szSchemeName[MAX_PATH];
01119     TCHAR szSystemScheme[MAX_PATH];
01120     TCHAR szTempPath[MAX_PATH];
01121     LPTSTR lpSchemeData;
01122     DWORD dwNameLength;
01123     DWORD dwSchemeSource;
01124     UINT index, i;
01125     HKEY hCursorKey;
01126     INT nSel;
01127 
01128     nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0);
01129     if (nSel == CB_ERR)
01130        return FALSE;
01131 
01132     lpSchemeData = (LPTSTR)SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETITEMDATA, nSel, 0);
01133     if (lpSchemeData == NULL)
01134     {
01135         /* "None" cursor scheme */
01136         dwSchemeSource = 0;
01137         szSchemeName[0] = 0;
01138         dwNameLength = 0;
01139     }
01140     else
01141     {
01142         SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)szSchemeName);
01143         LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
01144 
01145         if (_tcsstr(szSchemeName, szSystemScheme))
01146         {
01147             /* System scheme */
01148             dwSchemeSource = 2;
01149             szSchemeName[_tcslen(szSchemeName) - _tcslen(szSystemScheme) - 1] = 0;
01150         }
01151         else
01152         {
01153             /* User scheme */
01154             dwSchemeSource = 1;
01155         }
01156 
01157         dwNameLength = (_tcslen(szSchemeName) + 1) * sizeof(TCHAR);
01158     }
01159 
01160     if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Cursors"), 0,
01161                      KEY_READ | KEY_SET_VALUE, &hCursorKey) != ERROR_SUCCESS)
01162         return FALSE;
01163 
01164     RegSetValueEx(hCursorKey, NULL, 0, REG_SZ,
01165                   (LPBYTE)szSchemeName, dwNameLength);
01166 
01167     RegSetValueEx(hCursorKey, _T("Scheme Source"), 0, REG_DWORD,
01168                   (LPBYTE)&dwSchemeSource, sizeof(DWORD));
01169 
01170     for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
01171     {
01172         CompressPath(szTempPath, g_CursorData[i].szCursorPath);
01173         RegSetValueEx(hCursorKey, g_CursorData[i].lpValueName, 0,
01174                       REG_EXPAND_SZ, (LPBYTE)szTempPath,
01175                       (_tcslen(szTempPath) + 1) * sizeof(TCHAR));
01176     }
01177 
01178     RegCloseKey(hCursorKey);
01179 
01180     /* Force the system to reload its cursors */
01181     SystemParametersInfo(SPI_SETCURSORS, 0, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01182 
01183     return TRUE;
01184 }
01185 
01186 
01187 static INT_PTR CALLBACK
01188 PointerProc(IN HWND hwndDlg,
01189             IN UINT uMsg,
01190             IN WPARAM wParam,
01191             IN LPARAM lParam)
01192 {
01193     PPOINTER_DATA pPointerData;
01194     LPPSHNOTIFY lppsn;
01195     INT nSel;
01196 
01197     pPointerData = (PPOINTER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
01198 
01199     switch (uMsg)
01200     {
01201         case WM_INITDIALOG:
01202             pPointerData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POINTER_DATA));
01203             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pPointerData);
01204 
01205             pPointerData->cxCursor = GetSystemMetrics(SM_CXCURSOR);
01206             pPointerData->cyCursor = GetSystemMetrics(SM_CYCURSOR);
01207 
01208             EnumerateCursorSchemes(hwndDlg);
01209             LoadInitialCursorScheme(hwndDlg);
01210 
01211             /* Get cursor shadow setting */
01212             SystemParametersInfo(SPI_GETCURSORSHADOW, 0, &pPointerData->bCursorShadow, 0);
01213             pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow;
01214 
01215             if (pPointerData->bCursorShadow)
01216             {
01217                 SendDlgItemMessage(hwndDlg, IDC_CHECK_CURSOR_SHADOW, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01218             }
01219 
01220             if ((INT)wParam == IDC_LISTBOX_CURSOR)
01221                 return TRUE;
01222             else
01223                 return FALSE;
01224 
01225         case WM_MEASUREITEM:
01226             ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = GetSystemMetrics(SM_CYCURSOR) + 4;
01227             break;
01228 
01229         case WM_DRAWITEM:
01230             if (wParam == IDC_LISTBOX_CURSOR)
01231                 OnDrawItem((UINT)wParam, (LPDRAWITEMSTRUCT)lParam, pPointerData);
01232             return TRUE;
01233 
01234         case WM_DESTROY:
01235             HeapFree(GetProcessHeap(), 0, pPointerData);
01236             break;
01237 
01238         case WM_NOTIFY:
01239             lppsn = (LPPSHNOTIFY) lParam;
01240             if (lppsn->hdr.code == PSN_APPLY)
01241             {
01242                 ApplyCursorScheme(hwndDlg);
01243 //#if (WINVER >= 0x0500)
01244                 if (pPointerData->bOrigCursorShadow != pPointerData->bCursorShadow)
01245                 {
01246                     SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01247                     pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow;
01248                 }
01249 //#endif
01250                 return TRUE;
01251             }
01252             else if (lppsn->hdr.code == PSN_RESET)
01253             {
01254 //#if (WINVER >= 0x0500)
01255                 SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bOrigCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01256 //#endif
01257             }
01258             break;
01259 
01260         case WM_COMMAND:
01261             switch (LOWORD(wParam))
01262             {
01263                 case IDC_COMBO_CURSOR_SCHEME:
01264                     if (HIWORD(wParam) == CBN_SELENDOK)
01265                     {
01266                         LoadNewCursorScheme(hwndDlg);
01267                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01268                     }
01269                     break;
01270 
01271                 case IDC_LISTBOX_CURSOR:
01272                     switch (HIWORD(wParam))
01273                     {
01274                         case LBN_SELCHANGE:
01275                             nSel = SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0);
01276                             SendDlgItemMessage(hwndDlg, IDC_IMAGE_CURRENT_CURSOR, STM_SETIMAGE, IMAGE_CURSOR,
01277                                                (LPARAM)g_CursorData[nSel].hCursor);
01278                             EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR),
01279                                          (g_CursorData[nSel].szCursorPath[0] != 0));
01280                             break;
01281 
01282                         case LBN_DBLCLK:
01283                             if (BrowseCursor(hwndDlg))
01284                             {
01285                                 /* Update cursor list and preview */
01286                                 ReloadCurrentCursorScheme();
01287                                 RefreshCursorList(hwndDlg, FALSE);
01288 
01289                                 /* Enable the "Set Default" button */
01290                                 EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), TRUE);
01291 
01292                                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01293                             }
01294                             break;
01295                     }
01296                     break;
01297 
01298                 case IDC_BUTTON_SAVEAS_SCHEME:
01299                     SaveCursorScheme(hwndDlg);
01300                     break;
01301 
01302                 case IDC_BUTTON_USE_DEFAULT_CURSOR:
01303                     nSel = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0);
01304                     if (nSel != LB_ERR)
01305                     {
01306                         /* Clean the path of the currently selected cursor */
01307                         memset(g_CursorData[nSel].szCursorPath, 0x0, MAX_PATH * sizeof(TCHAR));
01308 
01309                         /* Update cursor list and preview */
01310                         ReloadCurrentCursorScheme();
01311                         RefreshCursorList(hwndDlg, FALSE);
01312 
01313                         /* Disable the "Set Default" button */
01314                         EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), FALSE);
01315 
01316                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01317                     }
01318                     break;
01319 
01320                 case IDC_BUTTON_BROWSE_CURSOR:
01321                     if (BrowseCursor(hwndDlg))
01322                     {
01323                         /* Update cursor list and preview */
01324                         ReloadCurrentCursorScheme();
01325                         RefreshCursorList(hwndDlg, FALSE);
01326 
01327                         /* Enable the "Set Default" button */
01328                         EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), TRUE);
01329 
01330                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01331                     }
01332                     break;
01333 
01334                 case IDC_BUTTON_DELETE_SCHEME:
01335                     DeleteUserCursorScheme(hwndDlg);
01336                     break;
01337 
01338                 case IDC_CHECK_CURSOR_SHADOW:
01339                     if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_CURSOR_SHADOW))
01340                     {
01341                         pPointerData->bCursorShadow = FALSE;
01342                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
01343 //#if (WINVER >= 0x0500)
01344 //                        SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bCursorShadow, 0);
01345 //#endif
01346 //                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01347                     }
01348                     else
01349                     {
01350                         pPointerData->bCursorShadow = TRUE;
01351                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01352                     }
01353 //#if (WINVER >= 0x0500)
01354                     //SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bCursorShadow, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01355 //#endif
01356                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01357                     break;
01358             }
01359             break;
01360     }
01361 
01362     return FALSE;
01363 }
01364 
01365 
01366 static INT_PTR CALLBACK
01367 OptionProc(IN HWND hwndDlg,
01368            IN UINT uMsg,
01369            IN WPARAM wParam,
01370            IN LPARAM lParam)
01371 {
01372     POPTION_DATA pOptionData;
01373     HWND hDlgCtrl;
01374     LPPSHNOTIFY lppsn;
01375 
01376     pOptionData = (POPTION_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
01377 
01378     switch(uMsg)
01379     {
01380         case WM_INITDIALOG:
01381             pOptionData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OPTION_DATA));
01382             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pOptionData);
01383 
01384             /* Get mouse sensitivity */
01385             if (!SystemParametersInfo(SPI_GETMOUSESPEED, 0, &pOptionData->ulMouseSpeed, 0))
01386                 pOptionData->ulMouseSpeed = DEFAULT_MOUSE_SPEED;
01387             pOptionData->ulOrigMouseSpeed = pOptionData->ulMouseSpeed;
01388 
01389 
01390             if (!SystemParametersInfo(SPI_GETMOUSE, 0, &pOptionData->MouseAccel, 0))
01391             {
01392                 pOptionData->MouseAccel.nAcceleration = DEFAULT_MOUSE_ACCELERATION;
01393                 pOptionData->MouseAccel.nThreshold1 = DEFAULT_MOUSE_THRESHOLD1;
01394                 pOptionData->MouseAccel.nThreshold2 = DEFAULT_MOUSE_THRESHOLD2;
01395             }
01396             pOptionData->OrigMouseAccel.nAcceleration = pOptionData->MouseAccel.nAcceleration;
01397             pOptionData->OrigMouseAccel.nThreshold1 = pOptionData->MouseAccel.nThreshold1;
01398             pOptionData->OrigMouseAccel.nThreshold2 = pOptionData->MouseAccel.nThreshold2;
01399 
01400             /* Snap to default button */
01401             SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &pOptionData->bSnapToDefaultButton, 0);
01402             pOptionData->bOrigSnapToDefaultButton = pOptionData->bSnapToDefaultButton;
01403 
01404             /* Mouse trails */
01405             SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &pOptionData->uMouseTrails, 0);
01406             pOptionData->uOrigMouseTrails = pOptionData->uMouseTrails;
01407 
01408             /* Hide pointer while typing */
01409             SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &pOptionData->bMouseVanish, 0);
01410             pOptionData->bOrigMouseVanish = pOptionData->bMouseVanish;
01411 
01412             /* Show pointer with Ctrl-Key */
01413             SystemParametersInfo(SPI_GETMOUSESONAR, 0, &pOptionData->bMouseSonar, 0);
01414             pOptionData->bOrigMouseSonar = pOptionData->bMouseSonar;
01415 
01416             /* Set mouse speed */
01417             hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_MOUSE_SPEED);
01418             SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(1, 20));
01419             SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pOptionData->ulMouseSpeed);
01420 
01421             if (pOptionData->MouseAccel.nAcceleration)
01422             {
01423                 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_POINTER_PRECISION);
01424                 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01425             }
01426 
01427             if (pOptionData->bSnapToDefaultButton)
01428             {
01429                 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_SNAP_TO);
01430                 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01431             }
01432 
01433             /* Set mouse trail */
01434             hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL);
01435             SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 5));
01436             if (pOptionData->uMouseTrails < 2)
01437             {
01438                 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)5);
01439                 EnableWindow(hDlgCtrl, FALSE);
01440                 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_SHORT), FALSE);
01441                 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_LONG), FALSE);
01442             }
01443             else
01444             {
01445                 SendDlgItemMessage(hwndDlg, IDC_CHECK_POINTER_TRAIL, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01446                 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pOptionData->uMouseTrails - 2);
01447             }
01448 
01449             if (pOptionData->bMouseVanish)
01450             {
01451                 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_HIDE_POINTER);
01452                 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01453             }
01454 
01455             if (pOptionData->bMouseSonar)
01456             {
01457                 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_SHOW_POINTER);
01458                 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01459             }
01460 
01461             break;
01462 
01463         case WM_DESTROY:
01464             HeapFree(GetProcessHeap(), 0, pOptionData);
01465             break;
01466 
01467         case WM_COMMAND:
01468             switch(LOWORD(wParam))
01469             {
01470                 case IDC_CHECK_POINTER_PRECISION:
01471                     if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_POINTER_PRECISION))
01472                     {
01473                         pOptionData->MouseAccel.nAcceleration = 0;
01474                         pOptionData->MouseAccel.nThreshold1 = 0;
01475                         pOptionData->MouseAccel.nThreshold2 = 0;
01476                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
01477                     }
01478                     else
01479                     {
01480                         pOptionData->MouseAccel.nAcceleration = 1;
01481                         pOptionData->MouseAccel.nThreshold1 = 6;
01482                         pOptionData->MouseAccel.nThreshold2 = 10;
01483                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01484                     }
01485                     SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->MouseAccel, 0);
01486                     break;
01487 
01488                 case IDC_CHECK_SNAP_TO:
01489                     if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_SNAP_TO))
01490                     {
01491                         pOptionData->bSnapToDefaultButton = 0;
01492                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
01493                     }
01494                     else
01495                     {
01496                         pOptionData->bSnapToDefaultButton = 1;
01497                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01498                     }
01499                     SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bSnapToDefaultButton, 0, 0);
01500                     break;
01501 
01502                 case IDC_CHECK_POINTER_TRAIL:
01503                     hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL);
01504                     if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_POINTER_TRAIL))
01505                     {
01506                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
01507                         EnableWindow(hDlgCtrl, FALSE);
01508                         EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_SHORT), FALSE);
01509                         EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_LONG), FALSE);
01510                         pOptionData->uMouseTrails = 0;
01511                     }
01512                     else
01513                     {
01514                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01515                         EnableWindow(hDlgCtrl, TRUE);
01516                         EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_SHORT), TRUE);
01517                         EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_LONG), TRUE);
01518                         pOptionData->uMouseTrails = (UINT)SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) + 2;
01519                     }
01520                     SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, 0);
01521                     break;
01522 
01523                 case IDC_CHECK_HIDE_POINTER:
01524                     if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_HIDE_POINTER))
01525                     {
01526                         pOptionData->bMouseVanish = FALSE;
01527                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
01528                     }
01529                     else
01530                     {
01531                         pOptionData->bMouseVanish = TRUE;
01532                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01533                     }
01534                     SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bMouseVanish), 0);
01535                     break;
01536 
01537                 case IDC_CHECK_SHOW_POINTER:
01538                     if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_SHOW_POINTER))
01539                     {
01540                         pOptionData->bMouseSonar = FALSE;
01541                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
01542                     }
01543                     else
01544                     {
01545                         pOptionData->bMouseSonar = TRUE;
01546                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01547                     }
01548                     SystemParametersInfo(SPI_SETMOUSESONAR, 0, IntToPtr(pOptionData->bMouseSonar), 0);
01549                     break;
01550 
01551             }
01552             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01553             break;
01554 
01555         case WM_NOTIFY:
01556             lppsn = (LPPSHNOTIFY)lParam;
01557             if (lppsn->hdr.code == PSN_APPLY)
01558             {
01559                 /* Set mouse speed */
01560                 if (pOptionData->ulOrigMouseSpeed != pOptionData->ulMouseSpeed)
01561                 {
01562                     SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulMouseSpeed), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01563                     pOptionData->ulOrigMouseSpeed = pOptionData->ulMouseSpeed;
01564                 }
01565 
01566                 if (pOptionData->OrigMouseAccel.nAcceleration != pOptionData->MouseAccel.nAcceleration)
01567                 {
01568                     SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->MouseAccel, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01569                     pOptionData->OrigMouseAccel.nAcceleration = pOptionData->MouseAccel.nAcceleration;
01570                     pOptionData->OrigMouseAccel.nThreshold1 = pOptionData->MouseAccel.nThreshold1;
01571                     pOptionData->OrigMouseAccel.nThreshold2 = pOptionData->MouseAccel.nThreshold2;
01572                 }
01573 
01574 
01575                 /* Set snap to default button */
01576                 if (pOptionData->bOrigSnapToDefaultButton != pOptionData->bSnapToDefaultButton)
01577                 {
01578                     SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bSnapToDefaultButton, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01579                     pOptionData->bOrigSnapToDefaultButton = pOptionData->bSnapToDefaultButton;
01580                 }
01581 
01582                 /* Set mouse trails setting */
01583                 if (pOptionData->uOrigMouseTrails != pOptionData->uMouseTrails)
01584                 {
01585                     SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01586                     pOptionData->uOrigMouseTrails = pOptionData->uMouseTrails;
01587                 }
01588 
01589                 /* Hide pointer while typing */
01590                 if (pOptionData->bOrigMouseVanish != pOptionData->bMouseVanish)
01591                 {
01592                     SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bMouseVanish), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01593                     pOptionData->bOrigMouseVanish = pOptionData->bMouseVanish;
01594                 }
01595 
01596                 /* Show pointer with Ctrl-Key */
01597                 if (pOptionData->bOrigMouseSonar != pOptionData->bMouseSonar)
01598                 {
01599                     SystemParametersInfo(SPI_SETMOUSESONAR, 0, IntToPtr(pOptionData->bMouseSonar), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01600                     pOptionData->bOrigMouseSonar = pOptionData->bMouseSonar;
01601                 }
01602                 return TRUE;
01603             }
01604             else if (lppsn->hdr.code == PSN_RESET)
01605             {
01606                 /* Set the original mouse speed */
01607                 SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulOrigMouseSpeed), 0);
01608                 SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->OrigMouseAccel, 0);
01609                 SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bOrigSnapToDefaultButton, 0, 0);
01610                 SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uOrigMouseTrails, 0, 0);
01611                 SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bOrigMouseVanish), 0);
01612                 SystemParametersInfo(SPI_SETMOUSESONAR, 0,IntToPtr(pOptionData->bOrigMouseSonar), 0);
01613             }
01614             break;
01615 
01616         case WM_HSCROLL:
01617             if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_MOUSE_SPEED))
01618             {
01619                 switch (LOWORD(wParam))
01620                 {
01621                     case TB_LINEUP:
01622                     case TB_LINEDOWN:
01623                     case TB_PAGEUP:
01624                     case TB_PAGEDOWN:
01625                     case TB_TOP:
01626                     case TB_BOTTOM:
01627                     case TB_ENDTRACK:
01628                         pOptionData->ulMouseSpeed = (ULONG)SendDlgItemMessage(hwndDlg, IDC_SLIDER_MOUSE_SPEED, TBM_GETPOS, 0, 0);
01629                         SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulMouseSpeed), SPIF_SENDCHANGE);
01630                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01631                         break;
01632 #if 0
01633                     case TB_THUMBTRACK:
01634                         pOptionData->ulMouseSpeed = (ULONG)HIWORD(wParam) + 1;
01635                         SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)pOptionData->ulMouseSpeed, SPIF_SENDCHANGE);
01636                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01637                         break;
01638 #endif
01639                 }
01640             }
01641             else if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL))
01642             {
01643                 switch (LOWORD(wParam))
01644                 {
01645                     case TB_LINEUP:
01646                     case TB_LINEDOWN:
01647                     case TB_PAGEUP:
01648                     case TB_PAGEDOWN:
01649                     case TB_TOP:
01650                     case TB_BOTTOM:
01651                     case TB_ENDTRACK:
01652                         pOptionData->uMouseTrails = (ULONG)SendDlgItemMessage(hwndDlg, IDC_SLIDER_POINTER_TRAIL, TBM_GETPOS, 0, 0) + 2;
01653                         SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, SPIF_UPDATEINIFILE);
01654                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01655                         break;
01656 
01657                     case TB_THUMBTRACK:
01658                         pOptionData->uMouseTrails = (ULONG)HIWORD(wParam) + 2;
01659                         SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, SPIF_UPDATEINIFILE);
01660                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01661                         break;
01662                 }
01663             }
01664             break;
01665     }
01666 
01667     return FALSE;
01668 }
01669 
01670 
01671 static VOID
01672 ShowDialogWheelControls(HWND hwndDlg, UINT uWheelScrollLines, BOOL bInit)
01673 {
01674     HWND hDlgCtrl;
01675 
01676     if (uWheelScrollLines != WHEEL_PAGESCROLL)
01677     {
01678         hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_LINES);
01679         SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01680 
01681         hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES);
01682         EnableWindow(hDlgCtrl, TRUE);
01683 
01684         hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES);
01685         EnableWindow(hDlgCtrl, TRUE);
01686 
01687         hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_PAGE);
01688         SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
01689     }
01690     else
01691     {
01692         hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_LINES);
01693         SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
01694 
01695         hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES);
01696         EnableWindow(hDlgCtrl, FALSE);
01697 
01698         hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES);
01699         EnableWindow(hDlgCtrl, FALSE);
01700 
01701         hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_PAGE);
01702         SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
01703 
01704         /* Set the default scroll lines value */
01705         if (bInit == TRUE)
01706             SetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, DEFAULT_WHEEL_SCROLL_LINES, FALSE);
01707     }
01708 }
01709 
01710 
01711 static INT_PTR CALLBACK
01712 WheelProc(IN HWND hwndDlg,
01713           IN UINT uMsg,
01714           IN WPARAM wParam,
01715           IN LPARAM lParam)
01716 {
01717     LPPSHNOTIFY lppsn;
01718     PWHEEL_DATA pWheelData;
01719 
01720     pWheelData = (PWHEEL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
01721 
01722     switch (uMsg)
01723     {
01724         case WM_INITDIALOG:
01725             pWheelData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WHEEL_DATA));
01726             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pWheelData);
01727 
01728             /* Get wheel scroll lines */
01729             SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &pWheelData->uWheelScrollLines, 0);
01730 
01731             ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, TRUE);
01732             SendDlgItemMessage(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES, UDM_SETRANGE, 0, MAKELONG((short)100, (short)0));
01733             if (pWheelData->uWheelScrollLines != WHEEL_PAGESCROLL)
01734             {
01735                 SetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, pWheelData->uWheelScrollLines, FALSE);
01736             }
01737             return TRUE;
01738 
01739         case WM_DESTROY:
01740             HeapFree(GetProcessHeap(), 0, pWheelData);
01741             break;
01742 
01743         case WM_COMMAND:
01744             switch (LOWORD(wParam))
01745             {
01746                 case IDC_RADIO_WHEEL_SCROLL_LINES:
01747                     pWheelData->uWheelScrollLines = GetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, NULL, FALSE);
01748                     ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, FALSE);
01749                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01750                     break;
01751 
01752                 case IDC_RADIO_WHEEL_SCROLL_PAGE:
01753                     pWheelData->uWheelScrollLines = WHEEL_PAGESCROLL;
01754                     ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, FALSE);
01755                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01756                     break;
01757 
01758                 case IDC_EDIT_WHEEL_SCROLL_LINES:
01759                     if (pWheelData && HIWORD(wParam) == EN_CHANGE)
01760                     {
01761                         pWheelData->uWheelScrollLines = GetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, NULL, FALSE);
01762                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
01763                     }
01764                     break;
01765             }
01766             break;
01767 
01768         case WM_NOTIFY:
01769             lppsn = (LPPSHNOTIFY)lParam;
01770             if (lppsn->hdr.code == PSN_APPLY)
01771             {
01772                 SystemParametersInfo(SPI_SETWHEELSCROLLLINES, pWheelData->uWheelScrollLines,
01773                                      0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
01774                 return TRUE;
01775             }
01776             break;
01777     }
01778 
01779     return FALSE;
01780 }
01781 
01782 static const struct
01783 {
01784     WORD idDlg;
01785     DLGPROC DlgProc;
01786     UINT uiReplaceWith;
01787 } PropPages[] =
01788 {
01789     { IDD_PAGE_BUTTON, ButtonProc, CPLPAGE_MOUSE_BUTTONS },
01790     { IDD_PAGE_POINTER, PointerProc, 0 },
01791     { IDD_PAGE_OPTION, OptionProc, CPLPAGE_MOUSE_PTRMOTION },
01792     { IDD_PAGE_WHEEL, WheelProc, CPLPAGE_MOUSE_WHEEL },
01793     { IDD_HARDWARE, MouseHardwareProc, 0 },
01794 };
01795 
01796 LONG APIENTRY
01797 MouseApplet(HWND hwnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
01798 {
01799     HPROPSHEETPAGE hpsp[MAX_CPL_PAGES];
01800     PROPSHEETHEADER psh;
01801     HPSXA hpsxa;
01802     TCHAR Caption[256];
01803     UINT i;
01804     LONG ret;
01805 
01806     UNREFERENCED_PARAMETER(lParam1);
01807     UNREFERENCED_PARAMETER(lParam2);
01808     UNREFERENCED_PARAMETER(uMsg);
01809     UNREFERENCED_PARAMETER(hwnd);
01810 
01811     LoadString(hApplet, IDS_CPLNAME_1, Caption, sizeof(Caption) / sizeof(TCHAR));
01812 
01813     ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
01814     psh.dwSize = sizeof(PROPSHEETHEADER);
01815     psh.dwFlags = PSH_PROPTITLE;
01816     psh.hwndParent = hwnd;
01817     psh.hInstance = hApplet;
01818     psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON_1));
01819     psh.pszCaption = Caption;
01820     psh.nStartPage = 0;
01821     psh.phpage = hpsp;
01822 
01823     /* Load additional pages provided by shell extensions */
01824     hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Mouse"), MAX_CPL_PAGES - psh.nPages);
01825 
01826     for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++)
01827     {
01828         /* Override the background page if requested by a shell extension */
01829         if (PropPages[i].uiReplaceWith != 0 && hpsxa != NULL &&
01830             SHReplaceFromPropSheetExtArray(hpsxa, PropPages[i].uiReplaceWith, PropSheetAddPage, (LPARAM)&psh) != 0)
01831         {
01832             /* The shell extension added one or more pages to replace a page.
01833                Don't create the built-in page anymore! */
01834             continue;
01835         }
01836 
01837         InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc);
01838     }
01839 
01840     if (hpsxa != NULL)
01841         SHAddFromPropSheetExtArray(hpsxa, PropSheetAddPage, (LPARAM)&psh);
01842 
01843     ret = (LONG)(PropertySheet(&psh) != -1);
01844 
01845     if (hpsxa != NULL)
01846         SHDestroyPropSheetExtArray(hpsxa);
01847 
01848     return ret;
01849 }
01850 
01851 /* EOF */

Generated on Sat May 26 2012 04:15:59 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.