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