1 /* 2 * ReactOS 3 * Copyright (C) 2004, 2007 ReactOS Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 /* $Id$ 20 * 21 * PROJECT: ReactOS Main Control Panel 22 * FILE: dll/cpl/main/mouse.c 23 * PURPOSE: Mouse Control Panel 24 * PROGRAMMER: Eric Kohl 25 * Johannes Anderwald 26 */ 27 28 // TODO: 29 // Add missing icons 30 31 #include "main.h" 32 33 #define DEFAULT_DOUBLE_CLICK_SPEED 500 34 #define DEFAULT_CLICK_LOCK_TIME 2200 35 #define DEFAULT_MOUSE_SPEED 10 36 #define DEFAULT_MOUSE_ACCELERATION 1 37 #define DEFAULT_MOUSE_THRESHOLD1 6 38 #define DEFAULT_MOUSE_THRESHOLD2 10 39 #define MIN_DOUBLE_CLICK_SPEED 200 40 #define MAX_DOUBLE_CLICK_SPEED 900 41 #define DEFAULT_WHEEL_SCROLL_LINES 3 42 43 typedef struct _BUTTON_DATA 44 { 45 ULONG g_SwapMouseButtons; 46 ULONG g_OrigSwapMouseButtons; 47 ULONG g_DoubleClickSpeed; // = DEFAULT_DOUBLE_CLICK_SPEED; 48 ULONG g_OrigDoubleClickSpeed; 49 BOOL g_ClickLockEnabled; // = 0; 50 DWORD g_ClickLockTime; // = DEFAULT_CLICK_LOCK_TIME; 51 52 HICON hButtonLeft; 53 HICON hButtonRight; 54 55 HICON hIcon1; 56 HICON hIcon2; 57 BOOL bClicked; 58 } BUTTON_DATA, *PBUTTON_DATA; 59 60 61 typedef struct _POINTER_DATA 62 { 63 BOOL bCursorShadow; 64 BOOL bOrigCursorShadow; 65 66 INT cxCursor; 67 INT cyCursor; 68 } POINTER_DATA, *PPOINTER_DATA; 69 70 71 typedef struct _MOUSE_ACCEL 72 { 73 INT nThreshold1; 74 INT nThreshold2; 75 INT nAcceleration; 76 } MOUSE_ACCEL; 77 78 typedef struct _OPTION_DATA 79 { 80 ULONG ulMouseSpeed; 81 ULONG ulOrigMouseSpeed; 82 83 MOUSE_ACCEL MouseAccel; 84 MOUSE_ACCEL OrigMouseAccel; 85 86 BOOL bSnapToDefaultButton; 87 BOOL bOrigSnapToDefaultButton; 88 89 UINT uMouseTrails; 90 UINT uOrigMouseTrails; 91 92 BOOL bMouseVanish; 93 BOOL bOrigMouseVanish; 94 95 BOOL bMouseSonar; 96 BOOL bOrigMouseSonar; 97 } OPTION_DATA, *POPTION_DATA; 98 99 100 typedef struct _WHEEL_DATA 101 { 102 UINT uWheelScrollLines; 103 } WHEEL_DATA, *PWHEEL_DATA; 104 105 106 typedef struct _CURSOR_DATA 107 { 108 UINT uStringId; 109 UINT uDefaultCursorId; 110 LPTSTR lpValueName; 111 HCURSOR hCursor; 112 TCHAR szCursorName[MAX_PATH]; 113 TCHAR szCursorPath[MAX_PATH]; 114 } CURSOR_DATA, *PCURSOR_DATA; 115 116 117 CURSOR_DATA g_CursorData[] = 118 {{IDS_ARROW, 100/*OCR_NORMAL*/, _T("Arrow"), 0, _T(""), _T("")}, 119 {IDS_HELP, 112/*OCR_HELP*/, _T("Help"), 0, _T(""), _T("")}, 120 {IDS_APPSTARTING, 111/*OCR_APPSTARTING*/, _T("AppStarting"), 0, _T(""), _T("")}, 121 {IDS_WAIT, 102/*OCR_WAIT*/, _T("Wait"), 0, _T(""), _T("")}, 122 {IDS_CROSSHAIR, 103/*OCR_CROSS*/, _T("Crosshair"), 0, _T(""), _T("")}, 123 {IDS_IBEAM, 101/*OCR_IBEAM*/, _T("IBeam"), 0, _T(""), _T("")}, 124 {IDS_NWPEN, 113/*OCR_NWPEN*/, _T("NWPen"), 0, _T(""), _T("")}, 125 {IDS_NO, 110/*OCR_NO*/, _T("No"), 0, _T(""), _T("")}, 126 {IDS_SIZENS, 108/*OCR_SIZENS*/, _T("SizeNS"), 0, _T(""), _T("")}, 127 {IDS_SIZEWE, 107/*OCR_SIZEWE*/, _T("SizeWE"), 0, _T(""), _T("")}, 128 {IDS_SIZENWSE, 105/*OCR_SIZENWSE*/, _T("SizeNWSE"), 0, _T(""), _T("")}, 129 {IDS_SIZENESW, 106/*OCR_SIZENESW*/, _T("SizeNESW"), 0, _T(""), _T("")}, 130 {IDS_SIZEALL, 109/*OCR_SIZEALL*/, _T("SizeAll"), 0, _T(""), _T("")}, 131 {IDS_UPARROW, 104/*OCR_UP*/, _T("UpArrow"), 0, _T(""), _T("")}, 132 {IDS_HAND, 114/*OCR_HAND*/, _T("Hand"), 0, _T(""), _T("")}}; 133 134 135 #if 0 136 static VOID 137 DebugMsg(LPTSTR fmt, ...) 138 { 139 TCHAR szBuffer[2048]; 140 va_list marker; 141 142 va_start(marker, fmt); 143 _vstprintf(szBuffer, fmt, marker); 144 va_end(marker); 145 146 MessageBox(NULL, szBuffer, _T("Debug message"), MB_OK); 147 } 148 #endif 149 150 151 /* Property page dialog callback */ 152 static INT_PTR CALLBACK 153 MouseHardwareProc(IN HWND hwndDlg, 154 IN UINT uMsg, 155 IN WPARAM wParam, 156 IN LPARAM lParam) 157 { 158 GUID Guids[1]; 159 Guids[0] = GUID_DEVCLASS_MOUSE; 160 161 UNREFERENCED_PARAMETER(lParam); 162 UNREFERENCED_PARAMETER(wParam); 163 164 switch(uMsg) 165 { 166 case WM_INITDIALOG: 167 /* create the hardware page */ 168 DeviceCreateHardwarePageEx(hwndDlg, 169 Guids, 170 sizeof(Guids) / sizeof(Guids[0]), 171 HWPD_STANDARDLIST); 172 break; 173 } 174 175 return FALSE; 176 } 177 178 179 static INT_PTR CALLBACK 180 ClickLockProc(IN HWND hwndDlg, 181 IN UINT uMsg, 182 IN WPARAM wParam, 183 IN LPARAM lParam) 184 { 185 HWND hDlgCtrl; 186 int pos; 187 static HICON hIcon; 188 189 PBUTTON_DATA pButtonData; 190 191 pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 192 193 switch(uMsg) 194 { 195 case WM_INITDIALOG: 196 pButtonData = (PBUTTON_DATA)lParam; 197 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData); 198 199 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK); 200 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 10)); 201 pos = (pButtonData->g_ClickLockTime - 200) / 200; 202 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos); 203 204 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOOK_KEY), 205 IMAGE_ICON, 16, 16, 0); 206 SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); 207 return TRUE; 208 209 case WM_COMMAND: 210 if (LOWORD(wParam) == IDOK) 211 { 212 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK); 213 pButtonData->g_ClickLockTime = (DWORD) (SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) * 200) + 200; 214 EndDialog(hwndDlg, TRUE); 215 if (hIcon) DestroyIcon(hIcon); 216 } 217 else if (LOWORD(wParam) == IDCANCEL) 218 { 219 EndDialog(hwndDlg, FALSE); 220 if (hIcon) DestroyIcon(hIcon); 221 } 222 break; 223 } 224 225 return FALSE; 226 } 227 228 229 static INT_PTR CALLBACK 230 ButtonProc(IN HWND hwndDlg, 231 IN UINT uMsg, 232 IN WPARAM wParam, 233 IN LPARAM lParam) 234 { 235 HWND hDlgCtrl; 236 LRESULT lResult; 237 LPPSHNOTIFY lppsn; 238 239 PBUTTON_DATA pButtonData; 240 241 pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 242 243 switch (uMsg) 244 { 245 case WM_INITDIALOG: 246 pButtonData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BUTTON_DATA)); 247 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData); 248 249 pButtonData->g_SwapMouseButtons = GetSystemMetrics(SM_SWAPBUTTON); 250 pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons; 251 pButtonData->g_DoubleClickSpeed = GetDoubleClickTime(); 252 pButtonData->g_OrigDoubleClickSpeed = pButtonData->g_DoubleClickSpeed; 253 254 /* Click lock time */ 255 SystemParametersInfo(SPI_GETMOUSECLICKLOCK, 0, &pButtonData->g_ClickLockEnabled, 0); 256 SystemParametersInfo(SPI_GETMOUSECLICKLOCKTIME, 0, &pButtonData->g_ClickLockTime, 0); 257 258 /* Load mouse button icons */ 259 pButtonData->hButtonLeft = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_LEFT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); 260 pButtonData->hButtonRight = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_RIGHT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); 261 262 /* Load folder icons */ 263 pButtonData->hIcon1 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_CLOSED), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); 264 pButtonData->hIcon2 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_OPEN), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); 265 266 if (pButtonData->g_SwapMouseButtons) 267 { 268 SendDlgItemMessage(hwndDlg, IDC_SWAP_MOUSE_BUTTONS, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 269 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight); 270 } 271 else 272 { 273 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft); 274 } 275 276 if (pButtonData->g_ClickLockEnabled) 277 { 278 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_CLICK_LOCK); 279 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 280 } 281 else 282 { 283 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK); 284 EnableWindow(hDlgCtrl, FALSE); 285 } 286 287 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED); 288 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 14)); 289 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, 14 - ((pButtonData->g_DoubleClickSpeed - 200) / 50)); 290 291 292 SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hIcon1); 293 pButtonData->bClicked = TRUE; 294 return TRUE; 295 296 case WM_DESTROY: 297 DestroyIcon(pButtonData->hButtonLeft); 298 DestroyIcon(pButtonData->hButtonRight); 299 DestroyIcon(pButtonData->hIcon1); 300 DestroyIcon(pButtonData->hIcon2); 301 HeapFree(GetProcessHeap(), 0, pButtonData); 302 break; 303 304 case WM_COMMAND: 305 switch(LOWORD(wParam)) 306 { 307 case IDC_SWAP_MOUSE_BUTTONS: 308 lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0); 309 if (lResult == BST_CHECKED) 310 { 311 pButtonData->g_SwapMouseButtons = FALSE; 312 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 313 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft); 314 } 315 else if (lResult == BST_UNCHECKED) 316 { 317 pButtonData->g_SwapMouseButtons = TRUE; 318 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 319 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight); 320 } 321 //SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_SwapMouseButtons, NULL, 0); 322 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 323 break; 324 325 case IDC_CHECK_CLICK_LOCK: 326 lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0); 327 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK); 328 if (lResult == BST_CHECKED) 329 { 330 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 331 pButtonData->g_ClickLockEnabled = FALSE; 332 EnableWindow(hDlgCtrl, FALSE); 333 } 334 else if (lResult == BST_UNCHECKED) 335 { 336 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 337 pButtonData->g_ClickLockEnabled = TRUE; 338 EnableWindow(hDlgCtrl, TRUE); 339 } 340 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 341 break; 342 343 case IDC_BUTTON_CLICK_LOCK: 344 DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_CLICK_LOCK), hwndDlg, ClickLockProc, (LPARAM)pButtonData); 345 break; 346 347 case IDC_IMAGE_DOUBLE_CLICK_SPEED: 348 if (HIWORD(wParam) == STN_DBLCLK) 349 { 350 pButtonData->bClicked = !pButtonData->bClicked; 351 SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON, 352 (LPARAM)(pButtonData->bClicked ? pButtonData->hIcon1 : pButtonData->hIcon2)); 353 } 354 break; 355 } 356 break; 357 358 case WM_NOTIFY: 359 lppsn = (LPPSHNOTIFY) lParam; 360 if (lppsn->hdr.code == PSN_APPLY) 361 { 362 if (pButtonData->g_OrigSwapMouseButtons != pButtonData->g_SwapMouseButtons) 363 { 364 pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons; 365 SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 366 367 } 368 SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 369 //SetDoubleClickTime(pButtonData->g_DoubleClickSpeed); 370 371 #if (WINVER >= 0x0500) 372 SystemParametersInfo(SPI_SETMOUSECLICKLOCK, 0, UlongToPtr(pButtonData->g_ClickLockEnabled), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 373 if (pButtonData->g_ClickLockEnabled) 374 SystemParametersInfo(SPI_SETMOUSECLICKLOCKTIME, pButtonData->g_ClickLockTime, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 375 #endif 376 } 377 else if (lppsn->hdr.code == PSN_RESET) 378 { 379 /* Reset swap mouse button setting */ 380 SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, 0); 381 382 /* Reset double click speed setting */ 383 SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_OrigDoubleClickSpeed, NULL, 0); 384 //SetDoubleClickTime(pButtonData->g_OrigDoubleClickSpeed); 385 } 386 return TRUE; 387 388 case WM_HSCROLL: 389 if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED)) 390 { 391 switch (LOWORD(wParam)) 392 { 393 case TB_LINEUP: 394 case TB_LINEDOWN: 395 case TB_PAGEUP: 396 case TB_PAGEDOWN: 397 case TB_TOP: 398 case TB_BOTTOM: 399 case TB_ENDTRACK: 400 lResult = SendDlgItemMessage(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED, TBM_GETPOS, 0, 0); 401 pButtonData->g_DoubleClickSpeed = (14 - (INT)lResult) * 50 + 200; 402 //SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 403 SetDoubleClickTime(pButtonData->g_DoubleClickSpeed); 404 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 405 break; 406 407 case TB_THUMBTRACK: 408 pButtonData->g_DoubleClickSpeed = (14 - (INT)HIWORD(wParam)) * 50 + 200; 409 //SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, 0); 410 SetDoubleClickTime(pButtonData->g_DoubleClickSpeed); 411 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 412 break; 413 } 414 } 415 break; 416 } 417 418 return FALSE; 419 } 420 421 422 static VOID 423 CompressPath(LPTSTR lpShortPath, LPTSTR lpPath) 424 { 425 TCHAR szUserProfile[MAX_PATH]; 426 TCHAR szSystemRoot[MAX_PATH]; 427 TCHAR szProgramFiles[MAX_PATH]; 428 DWORD dwUserProfile; 429 DWORD dwSystemRoot; 430 DWORD dwProgramFiles; 431 432 dwUserProfile = GetEnvironmentVariable(_T("USERPROFILE"), szUserProfile, MAX_PATH); 433 dwSystemRoot = GetEnvironmentVariable(_T("SystemRoot"), szSystemRoot, MAX_PATH); 434 dwProgramFiles = GetEnvironmentVariable(_T("ProgramFiles"), szProgramFiles, MAX_PATH); 435 436 if (dwUserProfile > 0 && _tcsncmp(lpPath, szUserProfile, dwUserProfile) == 0) 437 { 438 _tcscpy(lpShortPath, _T("%USERPROFILE%")); 439 _tcscat(lpShortPath, &lpPath[dwUserProfile]); 440 } 441 else if (dwSystemRoot > 0 && _tcsncmp(lpPath, szSystemRoot, dwSystemRoot) == 0) 442 { 443 _tcscpy(lpShortPath, _T("%SystemRoot%")); 444 _tcscat(lpShortPath, &lpPath[dwSystemRoot]); 445 } 446 else if (dwProgramFiles > 0 && _tcsncmp(lpPath, szProgramFiles, dwProgramFiles) == 0) 447 { 448 _tcscpy(lpShortPath, _T("%ProgramFiles%")); 449 _tcscat(lpShortPath, &lpPath[dwProgramFiles]); 450 } 451 else 452 { 453 _tcscpy(lpShortPath, lpPath); 454 } 455 } 456 457 458 static BOOL 459 EnumerateCursorSchemes(HWND hwndDlg) 460 { 461 HKEY hCursorKey; 462 DWORD dwIndex; 463 TCHAR szValueName[MAX_PATH]; 464 DWORD dwValueName; 465 TCHAR szSystemScheme[MAX_PATH]; 466 TCHAR szValueData[2000]; 467 TCHAR szTempData[2000]; 468 DWORD dwValueData; 469 LONG lError; 470 HWND hDlgCtrl; 471 LRESULT lResult; 472 473 hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME); 474 SendMessage(hDlgCtrl, CB_RESETCONTENT, 0, 0); 475 476 /* Read the users cursor schemes */ 477 lError = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Cursors\\Schemes"), 478 0, KEY_READ | KEY_QUERY_VALUE , &hCursorKey); 479 if (lError == ERROR_SUCCESS) 480 { 481 for (dwIndex = 0;; dwIndex++) 482 { 483 dwValueName = sizeof(szValueName) / sizeof(TCHAR); 484 dwValueData = sizeof(szValueData) / sizeof(TCHAR); 485 lError = RegEnumValue(hCursorKey, dwIndex, szValueName, &dwValueName, 486 NULL, NULL, (LPBYTE)szValueData, &dwValueData); 487 if (lError == ERROR_NO_MORE_ITEMS) 488 break; 489 490 ExpandEnvironmentStrings(szValueData, szTempData, 2000); 491 492 if (_tcslen(szTempData) > 0) 493 { 494 LPTSTR lpCopy, lpStart; 495 496 /* Remove quotation marks */ 497 if (szTempData[0] == _T('"')) 498 { 499 lpStart = szValueData + 1; 500 szTempData[_tcslen(szTempData) - 1] = 0; 501 } 502 else 503 { 504 lpStart = szTempData; 505 } 506 507 lpCopy = _tcsdup(lpStart); 508 509 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValueName); 510 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)lpCopy); 511 } 512 } 513 514 RegCloseKey(hCursorKey); 515 } 516 517 /* Read the system cursor schemes */ 518 lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 519 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cursors\\Schemes"), 520 0, KEY_READ | KEY_QUERY_VALUE , &hCursorKey); 521 if (lError == ERROR_SUCCESS) 522 { 523 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 524 525 for (dwIndex = 0;; dwIndex++) 526 { 527 dwValueName = sizeof(szValueName) / sizeof(TCHAR); 528 dwValueData = sizeof(szValueData) / sizeof(TCHAR); 529 lError = RegEnumValue(hCursorKey, dwIndex, szValueName, &dwValueName, 530 NULL, NULL, (LPBYTE)szValueData, &dwValueData); 531 if (lError == ERROR_NO_MORE_ITEMS) 532 break; 533 534 if (_tcslen(szValueData) > 0) 535 { 536 LPTSTR lpCopy, lpStart; 537 538 /* Remove quotation marks */ 539 if (szValueData[0] == _T('"')) 540 { 541 lpStart = szValueData + 1; 542 szValueData[_tcslen(szValueData) - 1] = 0; 543 } 544 else 545 { 546 lpStart = szValueData; 547 } 548 549 lpCopy = _tcsdup(lpStart); 550 551 _tcscat(szValueName, TEXT(" ")); 552 _tcscat(szValueName, szSystemScheme); 553 554 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValueName); 555 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)lpCopy); 556 } 557 } 558 559 RegCloseKey(hCursorKey); 560 } 561 562 /* Add the "(none)" entry */ 563 LoadString(hApplet, IDS_NONE, szSystemScheme, MAX_PATH); 564 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szSystemScheme); 565 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)NULL); 566 567 return TRUE; 568 } 569 570 571 static VOID 572 RefreshCursorList(HWND hwndDlg, BOOL bInit) 573 { 574 INT index; 575 INT i; 576 INT nSel; 577 578 nSel = bInit ? 0 : SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0); 579 580 if (bInit) 581 { 582 SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_RESETCONTENT, 0, 0); 583 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 584 { 585 LoadString(hApplet, index, g_CursorData[i].szCursorName, MAX_PATH); 586 SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_ADDSTRING, 0, (LPARAM)i); 587 } 588 589 SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_SETCURSEL, nSel, 0); 590 } 591 else 592 { 593 InvalidateRect(GetDlgItem(hwndDlg, IDC_LISTBOX_CURSOR), NULL, FALSE); 594 } 595 596 SendDlgItemMessage(hwndDlg, IDC_IMAGE_CURRENT_CURSOR, STM_SETIMAGE, IMAGE_CURSOR, 597 (LPARAM)g_CursorData[nSel].hCursor); 598 599 EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), (g_CursorData[nSel].szCursorPath[0] != 0)); 600 } 601 602 603 static BOOL 604 DeleteUserCursorScheme(HWND hwndDlg) 605 { 606 TCHAR szSchemeName[MAX_PATH]; 607 TCHAR szTitle[128]; 608 TCHAR szRawText[256]; 609 TCHAR szText[256]; 610 HWND hDlgCtrl; 611 HKEY hCuKey; 612 HKEY hCuCursorKey; 613 LONG lResult; 614 INT nSel; 615 616 hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME); 617 nSel = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0); 618 if (nSel == CB_ERR) 619 return FALSE; 620 621 SendMessage(hDlgCtrl, CB_GETLBTEXT, nSel, (LPARAM)szSchemeName); 622 623 LoadString(hApplet, IDS_REMOVE_TITLE, szTitle, 128); 624 LoadString(hApplet, IDS_REMOVE_TEXT, szRawText, 256); 625 626 _stprintf(szText, szRawText, szSchemeName); 627 628 /* Confirm scheme removal */ 629 if (MessageBox(hwndDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO) 630 return TRUE; 631 632 if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS) 633 return FALSE; 634 635 if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ | KEY_SET_VALUE, &hCuCursorKey) != ERROR_SUCCESS) 636 { 637 RegCloseKey(hCuKey); 638 return FALSE; 639 } 640 641 lResult = RegDeleteValue(hCuCursorKey, szSchemeName); 642 643 RegCloseKey(hCuCursorKey); 644 RegCloseKey(hCuKey); 645 646 if (lResult == ERROR_SUCCESS) 647 { 648 SendMessage(hDlgCtrl, CB_DELETESTRING, nSel, 0); 649 SendMessage(hDlgCtrl, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); 650 } 651 652 return (lResult == ERROR_SUCCESS); 653 } 654 655 656 static INT_PTR CALLBACK 657 SaveSchemeProc(IN HWND hwndDlg, 658 IN UINT uMsg, 659 IN WPARAM wParam, 660 IN LPARAM lParam) 661 { 662 LPTSTR pSchemeName; 663 664 switch (uMsg) 665 { 666 case WM_INITDIALOG: 667 pSchemeName = (LPTSTR)lParam; 668 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSchemeName); 669 SendDlgItemMessage(hwndDlg, IDC_EDIT_SCHEME_NAME, WM_SETTEXT, 670 0, (LPARAM)pSchemeName); 671 break; 672 673 case WM_COMMAND: 674 if (LOWORD(wParam) == IDOK) 675 { 676 pSchemeName = (LPTSTR)GetWindowLongPtr(hwndDlg, DWLP_USER); 677 SendDlgItemMessage(hwndDlg, IDC_EDIT_SCHEME_NAME, WM_GETTEXT, 678 (WPARAM)MAX_PATH, (LPARAM)pSchemeName); 679 EndDialog(hwndDlg, TRUE); 680 } 681 else if (LOWORD(wParam) == IDCANCEL) 682 { 683 EndDialog(hwndDlg, FALSE); 684 } 685 break; 686 } 687 688 return FALSE; 689 } 690 691 692 static BOOL 693 SaveCursorScheme(HWND hwndDlg) 694 { 695 TCHAR szSystemScheme[MAX_PATH]; 696 TCHAR szSchemeName[MAX_PATH]; 697 TCHAR szNewSchemeName[MAX_PATH]; 698 TCHAR szTempPath[MAX_PATH]; 699 TCHAR szTitle[128]; 700 TCHAR szText[256]; 701 INT nSel; 702 INT index, i, nLength; 703 LPTSTR lpSchemeData; 704 HKEY hCuKey; 705 HKEY hCuCursorKey; 706 LONG lError = ERROR_SUCCESS; 707 BOOL bSchemeExists; 708 709 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 710 711 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0); 712 if (nSel == CB_ERR) 713 return FALSE; 714 715 if (nSel == 0) 716 { 717 szSchemeName[0] = 0; 718 } 719 else 720 { 721 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)szNewSchemeName); 722 723 if (_tcsstr(szNewSchemeName, szSystemScheme)) 724 { 725 szNewSchemeName[_tcslen(szNewSchemeName) - _tcslen(szSystemScheme) - 1] = 0; 726 } 727 } 728 729 /* Ask for a name for the new cursor scheme */ 730 if (!DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_CURSOR_SCHEME_SAVEAS), 731 hwndDlg, SaveSchemeProc, (LPARAM)szNewSchemeName)) 732 return TRUE; 733 734 /* Check all non-system schemes for the new name */ 735 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCOUNT, 0, 0); 736 if (nSel == CB_ERR) 737 return FALSE; 738 739 bSchemeExists = FALSE; 740 for (i = 0; i < nSel; i++) 741 { 742 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, i, (LPARAM)szSchemeName); 743 if (_tcsstr(szSchemeName, szSystemScheme) == NULL) 744 { 745 if (_tcscmp(szSchemeName, szNewSchemeName) == 0) 746 { 747 bSchemeExists = TRUE; 748 break; 749 } 750 } 751 } 752 753 if (bSchemeExists) 754 { 755 LoadString(hApplet, IDS_OVERWRITE_TITLE, szTitle, 128); 756 LoadString(hApplet, IDS_OVERWRITE_TEXT, szText, 256); 757 758 /* Confirm scheme overwrite */ 759 if (MessageBox(hwndDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO) 760 return TRUE; 761 } 762 763 /* Save the cursor scheme */ 764 nLength = 0; 765 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 766 { 767 if (i > 0) 768 nLength++; 769 nLength += _tcslen(g_CursorData[i].szCursorPath); 770 } 771 nLength++; 772 773 lpSchemeData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(TCHAR)); 774 775 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 776 { 777 CompressPath(szTempPath, g_CursorData[i].szCursorPath); 778 if (i > 0) 779 _tcscat(lpSchemeData, _T(",")); 780 _tcscat(lpSchemeData, szTempPath); 781 } 782 783 if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS) 784 return FALSE; 785 786 if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ | KEY_SET_VALUE, &hCuCursorKey) != ERROR_SUCCESS) 787 { 788 RegCloseKey(hCuKey); 789 return FALSE; 790 } 791 792 lError = RegSetValueEx(hCuCursorKey, szNewSchemeName, 0, 793 REG_EXPAND_SZ, (LPBYTE)lpSchemeData, 794 (_tcslen(lpSchemeData) + 1) * sizeof(TCHAR)); 795 796 RegCloseKey(hCuCursorKey); 797 RegCloseKey(hCuKey); 798 799 /* Add the new scheme to the scheme list and select it */ 800 if (lError == ERROR_SUCCESS) 801 { 802 LPTSTR copy = _tcsdup(lpSchemeData); 803 804 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_ADDSTRING, (WPARAM)0, (LPARAM)szNewSchemeName); 805 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETITEMDATA, (WPARAM)nSel, (LPARAM)copy); 806 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETCURSEL, (WPARAM)nSel, (LPARAM)0); 807 } 808 809 HeapFree(GetProcessHeap(), 0, lpSchemeData); 810 811 return (lError == ERROR_SUCCESS); 812 } 813 814 815 static BOOL 816 BrowseCursor(HWND hwndDlg) 817 { 818 TCHAR szFileName[MAX_PATH]; 819 TCHAR szFilter[MAX_PATH]; 820 TCHAR szTitle[MAX_PATH]; 821 OPENFILENAME ofn; 822 INT nSel; 823 824 LoadString(hApplet, IDS_BROWSE_FILTER, szFilter, MAX_PATH); 825 LoadString(hApplet, IDS_BROWSE_TITLE, szTitle, MAX_PATH); 826 827 memset(szFileName, 0x0, sizeof(szFileName)); 828 nSel = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0); 829 if (nSel == LB_ERR) 830 { 831 MessageBox(hwndDlg, _T("LB_ERR"), _T(""), MB_ICONERROR); 832 return FALSE; 833 } 834 835 ZeroMemory(&ofn, sizeof(OPENFILENAME)); 836 ofn.lStructSize = sizeof(OPENFILENAME); 837 ofn.hwndOwner = hwndDlg; 838 ofn.lpstrFilter = szFilter; 839 ofn.nFilterIndex = 1; 840 ofn.lpstrFile = szFileName; 841 ofn.nMaxFile = MAX_PATH; 842 ofn.lpstrInitialDir = _T("%WINDIR%\\Cursors"); 843 ofn.lpstrTitle = szTitle; 844 ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST; 845 846 if (!GetOpenFileName(&ofn)) 847 return FALSE; 848 849 /* Store the new cursor file path */ 850 _tcsncpy(g_CursorData[nSel].szCursorPath, szFileName, MAX_PATH); 851 852 return TRUE; 853 } 854 855 856 static VOID 857 LoadCursorScheme(LPTSTR lpName, BOOL bSystem) 858 { 859 UINT index, i; 860 861 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 862 { 863 if (g_CursorData[i].hCursor != NULL) 864 { 865 DestroyCursor(g_CursorData[i].hCursor); 866 g_CursorData[i].hCursor = 0; 867 } 868 g_CursorData[i].szCursorPath[0] = 0; 869 } 870 871 if (lpName != NULL) 872 { 873 LPTSTR pStart = lpName; 874 LPTSTR pEnd = pStart; 875 INT nLength; 876 877 i = 0; 878 while (pEnd) 879 { 880 pEnd = _tcschr(pStart, _T(',')); 881 if (pEnd) 882 nLength = ((INT_PTR)pEnd - (INT_PTR)pStart) / sizeof(TCHAR); 883 else 884 nLength = _tcslen(pStart); 885 886 _tcsncpy(g_CursorData[i].szCursorPath, pStart, nLength); 887 g_CursorData[i].szCursorPath[nLength] = 0; 888 889 pStart = pStart + (nLength + 1); 890 i++; 891 } 892 893 } 894 895 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 896 { 897 if (g_CursorData[i].szCursorPath[0] == 0) 898 g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(g_CursorData[i].uDefaultCursorId), 899 IMAGE_CURSOR, 0, 0, 900 LR_DEFAULTSIZE | LR_SHARED); 901 else 902 g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, g_CursorData[i].szCursorPath, 903 IMAGE_CURSOR, 0, 0, 904 LR_LOADFROMFILE | LR_DEFAULTSIZE); 905 } 906 } 907 908 909 static VOID 910 ReloadCurrentCursorScheme(VOID) 911 { 912 UINT index, i; 913 914 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 915 { 916 if (g_CursorData[i].hCursor != NULL) 917 DestroyCursor(g_CursorData[i].hCursor); 918 919 if (g_CursorData[i].szCursorPath[0] == 0) 920 g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(g_CursorData[i].uDefaultCursorId), 921 IMAGE_CURSOR, 0, 0, 922 LR_DEFAULTSIZE | LR_SHARED); 923 else 924 g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, g_CursorData[i].szCursorPath, 925 IMAGE_CURSOR, 0, 0, 926 LR_LOADFROMFILE | LR_DEFAULTSIZE); 927 } 928 } 929 930 931 static VOID 932 OnDrawItem(UINT idCtl, 933 LPDRAWITEMSTRUCT lpdis, 934 PPOINTER_DATA pPointerData) 935 { 936 RECT rc; 937 938 if (lpdis->itemState & ODS_SELECTED) 939 { 940 FillRect(lpdis->hDC, 941 &lpdis->rcItem, 942 (HBRUSH)(COLOR_HIGHLIGHT + 1)); 943 SetBkColor(lpdis->hDC, 944 GetSysColor(COLOR_HIGHLIGHT)); 945 SetTextColor(lpdis->hDC, 946 GetSysColor(COLOR_HIGHLIGHTTEXT)); 947 } 948 else 949 { 950 FillRect(lpdis->hDC, 951 &lpdis->rcItem, 952 (HBRUSH)(COLOR_WINDOW + 1)); 953 SetBkColor(lpdis->hDC, 954 GetSysColor(COLOR_WINDOW)); 955 SetTextColor(lpdis->hDC, 956 GetSysColor(COLOR_WINDOWTEXT)); 957 } 958 959 if (lpdis->itemID != (UINT)-1) 960 { 961 CopyRect(&rc, &lpdis->rcItem); 962 rc.left += 5; 963 DrawText(lpdis->hDC, 964 g_CursorData[lpdis->itemData].szCursorName, 965 -1, 966 &rc, 967 DT_SINGLELINE | DT_VCENTER | DT_LEFT); 968 969 if (g_CursorData[lpdis->itemData].hCursor != NULL) 970 { 971 DrawIcon(lpdis->hDC, 972 lpdis->rcItem.right - pPointerData->cxCursor - 4, 973 lpdis->rcItem.top + 2, 974 g_CursorData[lpdis->itemData].hCursor); 975 } 976 } 977 978 if (lpdis->itemState & ODS_FOCUS) 979 { 980 CopyRect(&rc, &lpdis->rcItem); 981 InflateRect(&rc, -1, -1); 982 DrawFocusRect(lpdis->hDC, &rc); 983 } 984 } 985 986 987 static VOID 988 LoadNewCursorScheme(HWND hwndDlg) 989 { 990 TCHAR buffer[MAX_PATH]; 991 TCHAR szSystemScheme[MAX_PATH]; 992 HWND hDlgCtrl; 993 BOOL bEnable; 994 LPTSTR lpName; 995 INT nSel; 996 997 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0); 998 if (nSel == CB_ERR) 999 return; 1000 1001 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)buffer); 1002 1003 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 1004 if (_tcsstr(buffer, szSystemScheme) || nSel == 0) // Avoid the default scheme - Can be deleted 1005 bEnable = FALSE; 1006 else 1007 bEnable = TRUE; 1008 1009 /* Delete button */ 1010 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_DELETE_SCHEME); 1011 EnableWindow(hDlgCtrl, bEnable); 1012 1013 lpName = (LPTSTR)SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETITEMDATA, nSel, 0); 1014 LoadCursorScheme(lpName, !bEnable); 1015 RefreshCursorList(hwndDlg, FALSE); 1016 } 1017 1018 1019 static VOID 1020 LoadInitialCursorScheme(HWND hwndDlg) 1021 { 1022 TCHAR szSchemeName[256]; 1023 TCHAR szSystemScheme[256]; 1024 TCHAR szCursorPath[256]; 1025 HKEY hCursorKey; 1026 LONG lError; 1027 DWORD dwDataSize; 1028 DWORD dwSchemeSource = 0; 1029 UINT index, i; 1030 DWORD dwType; 1031 INT nSel; 1032 1033 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 1034 { 1035 g_CursorData[i].hCursor = 0; 1036 g_CursorData[i].szCursorPath[0] = 0; 1037 } 1038 1039 lError = RegOpenKeyEx(HKEY_CURRENT_USER, 1040 _T("Control Panel\\Cursors"), 1041 0, 1042 KEY_READ | KEY_QUERY_VALUE, 1043 &hCursorKey); 1044 if (lError != ERROR_SUCCESS) 1045 return; 1046 1047 dwDataSize = sizeof(DWORD); 1048 lError = RegQueryValueEx(hCursorKey, 1049 _T("Scheme Source"), 1050 NULL, 1051 NULL, 1052 (LPBYTE)&dwSchemeSource, 1053 &dwDataSize); 1054 1055 if (dwSchemeSource != 0) 1056 { 1057 dwDataSize = 256 * sizeof(TCHAR); 1058 lError = RegQueryValueEx(hCursorKey, 1059 NULL, 1060 NULL, 1061 NULL, 1062 (LPBYTE)szSchemeName, 1063 &dwDataSize); 1064 1065 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 1066 { 1067 dwDataSize = MAX_PATH * sizeof(TCHAR); 1068 lError = RegQueryValueEx(hCursorKey, 1069 g_CursorData[i].lpValueName, 1070 NULL, 1071 &dwType, 1072 (LPBYTE)szCursorPath, 1073 &dwDataSize); 1074 if (lError == ERROR_SUCCESS) 1075 { 1076 if (dwType == REG_EXPAND_SZ) 1077 { 1078 ExpandEnvironmentStrings(szCursorPath, g_CursorData[i].szCursorPath, MAX_PATH); 1079 } 1080 else 1081 { 1082 _tcscpy(g_CursorData[i].szCursorPath, szCursorPath); 1083 } 1084 } 1085 } 1086 } 1087 1088 RegCloseKey(hCursorKey); 1089 1090 ReloadCurrentCursorScheme(); 1091 RefreshCursorList(hwndDlg, TRUE); 1092 1093 /* Build the full scheme name */ 1094 if (dwSchemeSource == 0) 1095 { 1096 LoadString(hApplet, IDS_NONE, szSchemeName, MAX_PATH); 1097 } 1098 else if (dwSchemeSource == 2) 1099 { 1100 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 1101 _tcscat(szSchemeName, _T(" ")); 1102 _tcscat(szSchemeName, szSystemScheme); 1103 } 1104 1105 /* Search and select the curent scheme name from the scheme list */ 1106 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_FINDSTRINGEXACT, -1, (LPARAM)szSchemeName); 1107 if (nSel != CB_ERR) 1108 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETCURSEL, (WPARAM)nSel, (LPARAM)0); 1109 1110 /* Enable /disable delete button */ 1111 EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_DELETE_SCHEME), (dwSchemeSource == 1)); 1112 } 1113 1114 1115 static BOOL 1116 ApplyCursorScheme(HWND hwndDlg) 1117 { 1118 TCHAR szSchemeName[MAX_PATH]; 1119 TCHAR szSystemScheme[MAX_PATH]; 1120 TCHAR szTempPath[MAX_PATH]; 1121 LPTSTR lpSchemeData; 1122 DWORD dwNameLength; 1123 DWORD dwSchemeSource; 1124 UINT index, i; 1125 HKEY hCursorKey; 1126 INT nSel; 1127 1128 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0); 1129 if (nSel == CB_ERR) 1130 return FALSE; 1131 1132 lpSchemeData = (LPTSTR)SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETITEMDATA, nSel, 0); 1133 if (lpSchemeData == NULL) 1134 { 1135 /* "None" cursor scheme */ 1136 dwSchemeSource = 0; 1137 szSchemeName[0] = 0; 1138 dwNameLength = 0; 1139 } 1140 else 1141 { 1142 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)szSchemeName); 1143 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 1144 1145 if (_tcsstr(szSchemeName, szSystemScheme)) 1146 { 1147 /* System scheme */ 1148 dwSchemeSource = 2; 1149 szSchemeName[_tcslen(szSchemeName) - _tcslen(szSystemScheme) - 1] = 0; 1150 } 1151 else 1152 { 1153 /* User scheme */ 1154 dwSchemeSource = 1; 1155 } 1156 1157 dwNameLength = (_tcslen(szSchemeName) + 1) * sizeof(TCHAR); 1158 } 1159 1160 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Cursors"), 0, 1161 KEY_READ | KEY_SET_VALUE, &hCursorKey) != ERROR_SUCCESS) 1162 return FALSE; 1163 1164 RegSetValueEx(hCursorKey, NULL, 0, REG_SZ, 1165 (LPBYTE)szSchemeName, dwNameLength); 1166 1167 RegSetValueEx(hCursorKey, _T("Scheme Source"), 0, REG_DWORD, 1168 (LPBYTE)&dwSchemeSource, sizeof(DWORD)); 1169 1170 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 1171 { 1172 CompressPath(szTempPath, g_CursorData[i].szCursorPath); 1173 RegSetValueEx(hCursorKey, g_CursorData[i].lpValueName, 0, 1174 REG_EXPAND_SZ, (LPBYTE)szTempPath, 1175 (_tcslen(szTempPath) + 1) * sizeof(TCHAR)); 1176 } 1177 1178 RegCloseKey(hCursorKey); 1179 1180 /* Force the system to reload its cursors */ 1181 SystemParametersInfo(SPI_SETCURSORS, 0, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1182 1183 return TRUE; 1184 } 1185 1186 1187 static INT_PTR CALLBACK 1188 PointerProc(IN HWND hwndDlg, 1189 IN UINT uMsg, 1190 IN WPARAM wParam, 1191 IN LPARAM lParam) 1192 { 1193 PPOINTER_DATA pPointerData; 1194 LPPSHNOTIFY lppsn; 1195 INT nSel; 1196 1197 pPointerData = (PPOINTER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 1198 1199 switch (uMsg) 1200 { 1201 case WM_INITDIALOG: 1202 pPointerData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POINTER_DATA)); 1203 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pPointerData); 1204 1205 pPointerData->cxCursor = GetSystemMetrics(SM_CXCURSOR); 1206 pPointerData->cyCursor = GetSystemMetrics(SM_CYCURSOR); 1207 1208 EnumerateCursorSchemes(hwndDlg); 1209 LoadInitialCursorScheme(hwndDlg); 1210 1211 /* Get cursor shadow setting */ 1212 SystemParametersInfo(SPI_GETCURSORSHADOW, 0, &pPointerData->bCursorShadow, 0); 1213 pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow; 1214 1215 if (pPointerData->bCursorShadow) 1216 { 1217 SendDlgItemMessage(hwndDlg, IDC_CHECK_CURSOR_SHADOW, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1218 } 1219 1220 if ((INT)wParam == IDC_LISTBOX_CURSOR) 1221 return TRUE; 1222 else 1223 return FALSE; 1224 1225 case WM_MEASUREITEM: 1226 ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = GetSystemMetrics(SM_CYCURSOR) + 4; 1227 break; 1228 1229 case WM_DRAWITEM: 1230 if (wParam == IDC_LISTBOX_CURSOR) 1231 OnDrawItem((UINT)wParam, (LPDRAWITEMSTRUCT)lParam, pPointerData); 1232 return TRUE; 1233 1234 case WM_DESTROY: 1235 HeapFree(GetProcessHeap(), 0, pPointerData); 1236 break; 1237 1238 case WM_NOTIFY: 1239 lppsn = (LPPSHNOTIFY) lParam; 1240 if (lppsn->hdr.code == PSN_APPLY) 1241 { 1242 ApplyCursorScheme(hwndDlg); 1243 //#if (WINVER >= 0x0500) 1244 if (pPointerData->bOrigCursorShadow != pPointerData->bCursorShadow) 1245 { 1246 SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1247 pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow; 1248 } 1249 //#endif 1250 return TRUE; 1251 } 1252 else if (lppsn->hdr.code == PSN_RESET) 1253 { 1254 //#if (WINVER >= 0x0500) 1255 SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bOrigCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1256 //#endif 1257 } 1258 break; 1259 1260 case WM_COMMAND: 1261 switch (LOWORD(wParam)) 1262 { 1263 case IDC_COMBO_CURSOR_SCHEME: 1264 if (HIWORD(wParam) == CBN_SELENDOK) 1265 { 1266 LoadNewCursorScheme(hwndDlg); 1267 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1268 } 1269 break; 1270 1271 case IDC_LISTBOX_CURSOR: 1272 switch (HIWORD(wParam)) 1273 { 1274 case LBN_SELCHANGE: 1275 nSel = SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0); 1276 SendDlgItemMessage(hwndDlg, IDC_IMAGE_CURRENT_CURSOR, STM_SETIMAGE, IMAGE_CURSOR, 1277 (LPARAM)g_CursorData[nSel].hCursor); 1278 EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), 1279 (g_CursorData[nSel].szCursorPath[0] != 0)); 1280 break; 1281 1282 case LBN_DBLCLK: 1283 if (BrowseCursor(hwndDlg)) 1284 { 1285 /* Update cursor list and preview */ 1286 ReloadCurrentCursorScheme(); 1287 RefreshCursorList(hwndDlg, FALSE); 1288 1289 /* Enable the "Set Default" button */ 1290 EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), TRUE); 1291 1292 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1293 } 1294 break; 1295 } 1296 break; 1297 1298 case IDC_BUTTON_SAVEAS_SCHEME: 1299 SaveCursorScheme(hwndDlg); 1300 break; 1301 1302 case IDC_BUTTON_USE_DEFAULT_CURSOR: 1303 nSel = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0); 1304 if (nSel != LB_ERR) 1305 { 1306 /* Clean the path of the currently selected cursor */ 1307 memset(g_CursorData[nSel].szCursorPath, 0x0, MAX_PATH * sizeof(TCHAR)); 1308 1309 /* Update cursor list and preview */ 1310 ReloadCurrentCursorScheme(); 1311 RefreshCursorList(hwndDlg, FALSE); 1312 1313 /* Disable the "Set Default" button */ 1314 EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), FALSE); 1315 1316 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1317 } 1318 break; 1319 1320 case IDC_BUTTON_BROWSE_CURSOR: 1321 if (BrowseCursor(hwndDlg)) 1322 { 1323 /* Update cursor list and preview */ 1324 ReloadCurrentCursorScheme(); 1325 RefreshCursorList(hwndDlg, FALSE); 1326 1327 /* Enable the "Set Default" button */ 1328 EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), TRUE); 1329 1330 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1331 } 1332 break; 1333 1334 case IDC_BUTTON_DELETE_SCHEME: 1335 DeleteUserCursorScheme(hwndDlg); 1336 break; 1337 1338 case IDC_CHECK_CURSOR_SHADOW: 1339 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_CURSOR_SHADOW)) 1340 { 1341 pPointerData->bCursorShadow = FALSE; 1342 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 1343 //#if (WINVER >= 0x0500) 1344 // SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bCursorShadow, 0); 1345 //#endif 1346 // PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1347 } 1348 else 1349 { 1350 pPointerData->bCursorShadow = TRUE; 1351 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1352 } 1353 //#if (WINVER >= 0x0500) 1354 //SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bCursorShadow, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1355 //#endif 1356 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1357 break; 1358 } 1359 break; 1360 } 1361 1362 return FALSE; 1363 } 1364 1365 1366 static INT_PTR CALLBACK 1367 OptionProc(IN HWND hwndDlg, 1368 IN UINT uMsg, 1369 IN WPARAM wParam, 1370 IN LPARAM lParam) 1371 { 1372 POPTION_DATA pOptionData; 1373 HWND hDlgCtrl; 1374 LPPSHNOTIFY lppsn; 1375 1376 pOptionData = (POPTION_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 1377 1378 switch(uMsg) 1379 { 1380 case WM_INITDIALOG: 1381 pOptionData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OPTION_DATA)); 1382 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pOptionData); 1383 1384 /* Get mouse sensitivity */ 1385 if (!SystemParametersInfo(SPI_GETMOUSESPEED, 0, &pOptionData->ulMouseSpeed, 0)) 1386 pOptionData->ulMouseSpeed = DEFAULT_MOUSE_SPEED; 1387 pOptionData->ulOrigMouseSpeed = pOptionData->ulMouseSpeed; 1388 1389 1390 if (!SystemParametersInfo(SPI_GETMOUSE, 0, &pOptionData->MouseAccel, 0)) 1391 { 1392 pOptionData->MouseAccel.nAcceleration = DEFAULT_MOUSE_ACCELERATION; 1393 pOptionData->MouseAccel.nThreshold1 = DEFAULT_MOUSE_THRESHOLD1; 1394 pOptionData->MouseAccel.nThreshold2 = DEFAULT_MOUSE_THRESHOLD2; 1395 } 1396 pOptionData->OrigMouseAccel.nAcceleration = pOptionData->MouseAccel.nAcceleration; 1397 pOptionData->OrigMouseAccel.nThreshold1 = pOptionData->MouseAccel.nThreshold1; 1398 pOptionData->OrigMouseAccel.nThreshold2 = pOptionData->MouseAccel.nThreshold2; 1399 1400 /* Snap to default button */ 1401 SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &pOptionData->bSnapToDefaultButton, 0); 1402 pOptionData->bOrigSnapToDefaultButton = pOptionData->bSnapToDefaultButton; 1403 1404 /* Mouse trails */ 1405 SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &pOptionData->uMouseTrails, 0); 1406 pOptionData->uOrigMouseTrails = pOptionData->uMouseTrails; 1407 1408 /* Hide pointer while typing */ 1409 SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &pOptionData->bMouseVanish, 0); 1410 pOptionData->bOrigMouseVanish = pOptionData->bMouseVanish; 1411 1412 /* Show pointer with Ctrl-Key */ 1413 SystemParametersInfo(SPI_GETMOUSESONAR, 0, &pOptionData->bMouseSonar, 0); 1414 pOptionData->bOrigMouseSonar = pOptionData->bMouseSonar; 1415 1416 /* Set mouse speed */ 1417 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_MOUSE_SPEED); 1418 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 19)); 1419 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pOptionData->ulMouseSpeed - 1); 1420 1421 if (pOptionData->MouseAccel.nAcceleration) 1422 { 1423 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_POINTER_PRECISION); 1424 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1425 } 1426 1427 if (pOptionData->bSnapToDefaultButton) 1428 { 1429 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_SNAP_TO); 1430 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1431 } 1432 1433 /* Set mouse trail */ 1434 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL); 1435 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 5)); 1436 if (pOptionData->uMouseTrails < 2) 1437 { 1438 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)5); 1439 EnableWindow(hDlgCtrl, FALSE); 1440 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_SHORT), FALSE); 1441 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_LONG), FALSE); 1442 } 1443 else 1444 { 1445 SendDlgItemMessage(hwndDlg, IDC_CHECK_POINTER_TRAIL, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1446 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pOptionData->uMouseTrails - 2); 1447 } 1448 1449 if (pOptionData->bMouseVanish) 1450 { 1451 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_HIDE_POINTER); 1452 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1453 } 1454 1455 if (pOptionData->bMouseSonar) 1456 { 1457 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_SHOW_POINTER); 1458 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1459 } 1460 1461 break; 1462 1463 case WM_DESTROY: 1464 HeapFree(GetProcessHeap(), 0, pOptionData); 1465 break; 1466 1467 case WM_COMMAND: 1468 switch(LOWORD(wParam)) 1469 { 1470 case IDC_CHECK_POINTER_PRECISION: 1471 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_POINTER_PRECISION)) 1472 { 1473 pOptionData->MouseAccel.nAcceleration = 0; 1474 pOptionData->MouseAccel.nThreshold1 = 0; 1475 pOptionData->MouseAccel.nThreshold2 = 0; 1476 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 1477 } 1478 else 1479 { 1480 pOptionData->MouseAccel.nAcceleration = 1; 1481 pOptionData->MouseAccel.nThreshold1 = 6; 1482 pOptionData->MouseAccel.nThreshold2 = 10; 1483 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1484 } 1485 SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->MouseAccel, 0); 1486 break; 1487 1488 case IDC_CHECK_SNAP_TO: 1489 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_SNAP_TO)) 1490 { 1491 pOptionData->bSnapToDefaultButton = 0; 1492 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 1493 } 1494 else 1495 { 1496 pOptionData->bSnapToDefaultButton = 1; 1497 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1498 } 1499 SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bSnapToDefaultButton, 0, 0); 1500 break; 1501 1502 case IDC_CHECK_POINTER_TRAIL: 1503 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL); 1504 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_POINTER_TRAIL)) 1505 { 1506 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 1507 EnableWindow(hDlgCtrl, FALSE); 1508 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_SHORT), FALSE); 1509 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_LONG), FALSE); 1510 pOptionData->uMouseTrails = 0; 1511 } 1512 else 1513 { 1514 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1515 EnableWindow(hDlgCtrl, TRUE); 1516 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_SHORT), TRUE); 1517 EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_LONG), TRUE); 1518 pOptionData->uMouseTrails = (UINT)SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) + 2; 1519 } 1520 SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, 0); 1521 break; 1522 1523 case IDC_CHECK_HIDE_POINTER: 1524 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_HIDE_POINTER)) 1525 { 1526 pOptionData->bMouseVanish = FALSE; 1527 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 1528 } 1529 else 1530 { 1531 pOptionData->bMouseVanish = TRUE; 1532 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1533 } 1534 SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bMouseVanish), 0); 1535 break; 1536 1537 case IDC_CHECK_SHOW_POINTER: 1538 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_SHOW_POINTER)) 1539 { 1540 pOptionData->bMouseSonar = FALSE; 1541 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 1542 } 1543 else 1544 { 1545 pOptionData->bMouseSonar = TRUE; 1546 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1547 } 1548 SystemParametersInfo(SPI_SETMOUSESONAR, 0, IntToPtr(pOptionData->bMouseSonar), 0); 1549 break; 1550 1551 } 1552 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1553 break; 1554 1555 case WM_NOTIFY: 1556 lppsn = (LPPSHNOTIFY)lParam; 1557 if (lppsn->hdr.code == PSN_APPLY) 1558 { 1559 /* Set mouse speed */ 1560 if (pOptionData->ulOrigMouseSpeed != pOptionData->ulMouseSpeed) 1561 { 1562 SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulMouseSpeed), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1563 pOptionData->ulOrigMouseSpeed = pOptionData->ulMouseSpeed; 1564 } 1565 1566 if (pOptionData->OrigMouseAccel.nAcceleration != pOptionData->MouseAccel.nAcceleration) 1567 { 1568 SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->MouseAccel, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1569 pOptionData->OrigMouseAccel.nAcceleration = pOptionData->MouseAccel.nAcceleration; 1570 pOptionData->OrigMouseAccel.nThreshold1 = pOptionData->MouseAccel.nThreshold1; 1571 pOptionData->OrigMouseAccel.nThreshold2 = pOptionData->MouseAccel.nThreshold2; 1572 } 1573 1574 1575 /* Set snap to default button */ 1576 if (pOptionData->bOrigSnapToDefaultButton != pOptionData->bSnapToDefaultButton) 1577 { 1578 SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bSnapToDefaultButton, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1579 pOptionData->bOrigSnapToDefaultButton = pOptionData->bSnapToDefaultButton; 1580 } 1581 1582 /* Set mouse trails setting */ 1583 if (pOptionData->uOrigMouseTrails != pOptionData->uMouseTrails) 1584 { 1585 SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1586 pOptionData->uOrigMouseTrails = pOptionData->uMouseTrails; 1587 } 1588 1589 /* Hide pointer while typing */ 1590 if (pOptionData->bOrigMouseVanish != pOptionData->bMouseVanish) 1591 { 1592 SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bMouseVanish), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1593 pOptionData->bOrigMouseVanish = pOptionData->bMouseVanish; 1594 } 1595 1596 /* Show pointer with Ctrl-Key */ 1597 if (pOptionData->bOrigMouseSonar != pOptionData->bMouseSonar) 1598 { 1599 SystemParametersInfo(SPI_SETMOUSESONAR, 0, IntToPtr(pOptionData->bMouseSonar), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1600 pOptionData->bOrigMouseSonar = pOptionData->bMouseSonar; 1601 } 1602 return TRUE; 1603 } 1604 else if (lppsn->hdr.code == PSN_RESET) 1605 { 1606 /* Set the original mouse speed */ 1607 SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulOrigMouseSpeed), 0); 1608 SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->OrigMouseAccel, 0); 1609 SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bOrigSnapToDefaultButton, 0, 0); 1610 SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uOrigMouseTrails, 0, 0); 1611 SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bOrigMouseVanish), 0); 1612 SystemParametersInfo(SPI_SETMOUSESONAR, 0,IntToPtr(pOptionData->bOrigMouseSonar), 0); 1613 } 1614 break; 1615 1616 case WM_HSCROLL: 1617 if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_MOUSE_SPEED)) 1618 { 1619 switch (LOWORD(wParam)) 1620 { 1621 case TB_LINEUP: 1622 case TB_LINEDOWN: 1623 case TB_PAGEUP: 1624 case TB_PAGEDOWN: 1625 case TB_TOP: 1626 case TB_BOTTOM: 1627 case TB_ENDTRACK: 1628 pOptionData->ulMouseSpeed = (ULONG)SendDlgItemMessage(hwndDlg, IDC_SLIDER_MOUSE_SPEED, TBM_GETPOS, 0, 0) + 1; 1629 SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulMouseSpeed), SPIF_SENDCHANGE); 1630 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1631 break; 1632 #if 0 1633 case TB_THUMBTRACK: 1634 pOptionData->ulMouseSpeed = (ULONG)HIWORD(wParam) + 1; 1635 SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)pOptionData->ulMouseSpeed, SPIF_SENDCHANGE); 1636 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1637 break; 1638 #endif 1639 } 1640 } 1641 else if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL)) 1642 { 1643 switch (LOWORD(wParam)) 1644 { 1645 case TB_LINEUP: 1646 case TB_LINEDOWN: 1647 case TB_PAGEUP: 1648 case TB_PAGEDOWN: 1649 case TB_TOP: 1650 case TB_BOTTOM: 1651 case TB_ENDTRACK: 1652 pOptionData->uMouseTrails = (ULONG)SendDlgItemMessage(hwndDlg, IDC_SLIDER_POINTER_TRAIL, TBM_GETPOS, 0, 0) + 2; 1653 SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, SPIF_UPDATEINIFILE); 1654 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1655 break; 1656 1657 case TB_THUMBTRACK: 1658 pOptionData->uMouseTrails = (ULONG)HIWORD(wParam) + 2; 1659 SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, SPIF_UPDATEINIFILE); 1660 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1661 break; 1662 } 1663 } 1664 break; 1665 } 1666 1667 return FALSE; 1668 } 1669 1670 1671 static VOID 1672 ShowDialogWheelControls(HWND hwndDlg, UINT uWheelScrollLines, BOOL bInit) 1673 { 1674 HWND hDlgCtrl; 1675 1676 if (uWheelScrollLines != WHEEL_PAGESCROLL) 1677 { 1678 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_LINES); 1679 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1680 1681 hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES); 1682 EnableWindow(hDlgCtrl, TRUE); 1683 1684 hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES); 1685 EnableWindow(hDlgCtrl, TRUE); 1686 1687 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_PAGE); 1688 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 1689 } 1690 else 1691 { 1692 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_LINES); 1693 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 1694 1695 hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES); 1696 EnableWindow(hDlgCtrl, FALSE); 1697 1698 hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES); 1699 EnableWindow(hDlgCtrl, FALSE); 1700 1701 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_PAGE); 1702 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1703 1704 /* Set the default scroll lines value */ 1705 if (bInit == TRUE) 1706 SetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, DEFAULT_WHEEL_SCROLL_LINES, FALSE); 1707 } 1708 } 1709 1710 1711 static INT_PTR CALLBACK 1712 WheelProc(IN HWND hwndDlg, 1713 IN UINT uMsg, 1714 IN WPARAM wParam, 1715 IN LPARAM lParam) 1716 { 1717 LPPSHNOTIFY lppsn; 1718 PWHEEL_DATA pWheelData; 1719 1720 pWheelData = (PWHEEL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 1721 1722 switch (uMsg) 1723 { 1724 case WM_INITDIALOG: 1725 pWheelData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WHEEL_DATA)); 1726 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pWheelData); 1727 1728 /* Get wheel scroll lines */ 1729 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &pWheelData->uWheelScrollLines, 0); 1730 1731 ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, TRUE); 1732 SendDlgItemMessage(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES, UDM_SETRANGE, 0, MAKELONG((short)100, (short)0)); 1733 if (pWheelData->uWheelScrollLines != WHEEL_PAGESCROLL) 1734 { 1735 SetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, pWheelData->uWheelScrollLines, FALSE); 1736 } 1737 return TRUE; 1738 1739 case WM_DESTROY: 1740 HeapFree(GetProcessHeap(), 0, pWheelData); 1741 break; 1742 1743 case WM_COMMAND: 1744 switch (LOWORD(wParam)) 1745 { 1746 case IDC_RADIO_WHEEL_SCROLL_LINES: 1747 pWheelData->uWheelScrollLines = GetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, NULL, FALSE); 1748 ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, FALSE); 1749 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1750 break; 1751 1752 case IDC_RADIO_WHEEL_SCROLL_PAGE: 1753 pWheelData->uWheelScrollLines = WHEEL_PAGESCROLL; 1754 ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, FALSE); 1755 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1756 break; 1757 1758 case IDC_EDIT_WHEEL_SCROLL_LINES: 1759 if (pWheelData && HIWORD(wParam) == EN_CHANGE) 1760 { 1761 pWheelData->uWheelScrollLines = GetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, NULL, FALSE); 1762 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1763 } 1764 break; 1765 } 1766 break; 1767 1768 case WM_NOTIFY: 1769 lppsn = (LPPSHNOTIFY)lParam; 1770 if (lppsn->hdr.code == PSN_APPLY) 1771 { 1772 SystemParametersInfo(SPI_SETWHEELSCROLLLINES, pWheelData->uWheelScrollLines, 1773 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1774 return TRUE; 1775 } 1776 break; 1777 } 1778 1779 return FALSE; 1780 } 1781 1782 static const struct 1783 { 1784 WORD idDlg; 1785 DLGPROC DlgProc; 1786 UINT uiReplaceWith; 1787 } PropPages[] = 1788 { 1789 { IDD_PAGE_BUTTON, ButtonProc, CPLPAGE_MOUSE_BUTTONS }, 1790 { IDD_PAGE_POINTER, PointerProc, 0 }, 1791 { IDD_PAGE_OPTION, OptionProc, CPLPAGE_MOUSE_PTRMOTION }, 1792 { IDD_PAGE_WHEEL, WheelProc, CPLPAGE_MOUSE_WHEEL }, 1793 { IDD_HARDWARE, MouseHardwareProc, 0 }, 1794 }; 1795 1796 LONG APIENTRY 1797 MouseApplet(HWND hwnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2) 1798 { 1799 HPROPSHEETPAGE hpsp[MAX_CPL_PAGES]; 1800 PROPSHEETHEADER psh; 1801 HPSXA hpsxa; 1802 TCHAR Caption[256]; 1803 UINT i; 1804 LONG ret; 1805 1806 UNREFERENCED_PARAMETER(lParam1); 1807 UNREFERENCED_PARAMETER(lParam2); 1808 UNREFERENCED_PARAMETER(uMsg); 1809 UNREFERENCED_PARAMETER(hwnd); 1810 1811 LoadString(hApplet, IDS_CPLNAME_1, Caption, sizeof(Caption) / sizeof(TCHAR)); 1812 1813 ZeroMemory(&psh, sizeof(PROPSHEETHEADER)); 1814 psh.dwSize = sizeof(PROPSHEETHEADER); 1815 psh.dwFlags = PSH_PROPTITLE; 1816 psh.hwndParent = hwnd; 1817 psh.hInstance = hApplet; 1818 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON_1)); 1819 psh.pszCaption = Caption; 1820 psh.nStartPage = 0; 1821 psh.phpage = hpsp; 1822 1823 /* Load additional pages provided by shell extensions */ 1824 hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Mouse"), MAX_CPL_PAGES - psh.nPages); 1825 1826 for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++) 1827 { 1828 /* Override the background page if requested by a shell extension */ 1829 if (PropPages[i].uiReplaceWith != 0 && hpsxa != NULL && 1830 SHReplaceFromPropSheetExtArray(hpsxa, PropPages[i].uiReplaceWith, PropSheetAddPage, (LPARAM)&psh) != 0) 1831 { 1832 /* The shell extension added one or more pages to replace a page. 1833 Don't create the built-in page anymore! */ 1834 continue; 1835 } 1836 1837 InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc); 1838 } 1839 1840 if (hpsxa != NULL) 1841 SHAddFromPropSheetExtArray(hpsxa, PropSheetAddPage, (LPARAM)&psh); 1842 1843 ret = (LONG)(PropertySheet(&psh) != -1); 1844 1845 if (hpsxa != NULL) 1846 SHDestroyPropSheetExtArray(hpsxa); 1847 1848 return ret; 1849 } 1850 1851 /* EOF */ 1852