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: lib/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 <windows.h> 32 #include <winuser.h> 33 #include <devguid.h> 34 #include <commctrl.h> 35 #include <cpl.h> 36 #include <tchar.h> 37 #include <math.h> 38 #include <limits.h> 39 #include <shlobj.h> 40 #include <cplext.h> 41 #include <regstr.h> 42 43 #include <stdio.h> 44 45 #include "main.h" 46 #include "resource.h" 47 48 #define DEFAULT_DOUBLE_CLICK_SPEED 500 49 #define DEFAULT_CLICK_LOCK_TIME 2200 50 #define DEFAULT_MOUSE_SPEED 10 51 #define DEFAULT_MOUSE_ACCELERATION 1 52 #define DEFAULT_MOUSE_THRESHOLD1 6 53 #define DEFAULT_MOUSE_THRESHOLD2 10 54 #define MIN_DOUBLE_CLICK_SPEED 200 55 #define MAX_DOUBLE_CLICK_SPEED 900 56 #define DEFAULT_WHEEL_SCROLL_LINES 3 57 58 typedef struct _BUTTON_DATA 59 { 60 ULONG g_SwapMouseButtons; 61 ULONG g_OrigSwapMouseButtons; 62 ULONG g_DoubleClickSpeed; // = DEFAULT_DOUBLE_CLICK_SPEED; 63 ULONG g_OrigDoubleClickSpeed; 64 BOOL g_ClickLockEnabled; // = 0; 65 DWORD g_ClickLockTime; // = DEFAULT_CLICK_LOCK_TIME; 66 67 HICON hButtonLeft; 68 HICON hButtonRight; 69 70 HICON hIcon1; 71 HICON hIcon2; 72 BOOL bClicked; 73 } BUTTON_DATA, *PBUTTON_DATA; 74 75 76 typedef struct _POINTER_DATA 77 { 78 BOOL bCursorShadow; 79 BOOL bOrigCursorShadow; 80 81 INT cxCursor; 82 INT cyCursor; 83 } POINTER_DATA, *PPOINTER_DATA; 84 85 86 typedef struct _MOUSE_ACCEL 87 { 88 INT nThreshold1; 89 INT nThreshold2; 90 INT nAcceleration; 91 } MOUSE_ACCEL; 92 93 typedef struct _OPTION_DATA 94 { 95 ULONG ulMouseSpeed; 96 ULONG ulOrigMouseSpeed; 97 98 MOUSE_ACCEL MouseAccel; 99 MOUSE_ACCEL OrigMouseAccel; 100 101 BOOL bSnapToDefaultButton; 102 BOOL bOrigSnapToDefaultButton; 103 104 UINT uMouseTrails; 105 UINT uOrigMouseTrails; 106 107 BOOL bMouseVanish; 108 BOOL bOrigMouseVanish; 109 110 BOOL bMouseSonar; 111 BOOL bOrigMouseSonar; 112 } OPTION_DATA, *POPTION_DATA; 113 114 115 typedef struct _WHEEL_DATA 116 { 117 UINT uWheelScrollLines; 118 } WHEEL_DATA, *PWHEEL_DATA; 119 120 121 typedef struct _CURSOR_DATA 122 { 123 UINT uStringId; 124 UINT uDefaultCursorId; 125 LPTSTR lpValueName; 126 HCURSOR hCursor; 127 TCHAR szCursorName[MAX_PATH]; 128 TCHAR szCursorPath[MAX_PATH]; 129 } CURSOR_DATA, *PCURSOR_DATA; 130 131 132 CURSOR_DATA g_CursorData[] = 133 {{IDS_ARROW, 100/*OCR_NORMAL*/, _T("Arrow"), 0, _T(""), _T("")}, 134 {IDS_HELP, 112/*OCR_HELP*/, _T("Help"), 0, _T(""), _T("")}, 135 {IDS_APPSTARTING, 111/*OCR_APPSTARTING*/, _T("AppStarting"), 0, _T(""), _T("")}, 136 {IDS_WAIT, 102/*OCR_WAIT*/, _T("Wait"), 0, _T(""), _T("")}, 137 {IDS_CROSSHAIR, 103/*OCR_CROSS*/, _T("Crosshair"), 0, _T(""), _T("")}, 138 {IDS_IBEAM, 101/*OCR_IBEAM*/, _T("IBeam"), 0, _T(""), _T("")}, 139 {IDS_NWPEN, 113/*OCR_NWPEN*/, _T("NWPen"), 0, _T(""), _T("")}, 140 {IDS_NO, 110/*OCR_NO*/, _T("No"), 0, _T(""), _T("")}, 141 {IDS_SIZENS, 108/*OCR_SIZENS*/, _T("SizeNS"), 0, _T(""), _T("")}, 142 {IDS_SIZEWE, 107/*OCR_SIZEWE*/, _T("SizeWE"), 0, _T(""), _T("")}, 143 {IDS_SIZENWSE, 105/*OCR_SIZENWSE*/, _T("SizeNWSE"), 0, _T(""), _T("")}, 144 {IDS_SIZENESW, 106/*OCR_SIZENESW*/, _T("SizeNESW"), 0, _T(""), _T("")}, 145 {IDS_SIZEALL, 109/*OCR_SIZEALL*/, _T("SizeAll"), 0, _T(""), _T("")}, 146 {IDS_UPARROW, 104/*OCR_UP*/, _T("UpArrow"), 0, _T(""), _T("")}, 147 {IDS_HAND, 114/*OCR_HAND*/, _T("Hand"), 0, _T(""), _T("")}}; 148 149 150 #if 0 151 static VOID 152 DebugMsg(LPTSTR fmt, ...) 153 { 154 TCHAR szBuffer[2048]; 155 va_list marker; 156 157 va_start(marker, fmt); 158 _vstprintf(szBuffer, fmt, marker); 159 va_end(marker); 160 161 MessageBox(NULL, szBuffer, _T("Debug message"), MB_OK); 162 } 163 #endif 164 165 166 /* Property page dialog callback */ 167 static INT_PTR CALLBACK 168 MouseHardwareProc(IN HWND hwndDlg, 169 IN UINT uMsg, 170 IN WPARAM wParam, 171 IN LPARAM lParam) 172 { 173 GUID Guids[1]; 174 Guids[0] = GUID_DEVCLASS_MOUSE; 175 176 UNREFERENCED_PARAMETER(lParam); 177 UNREFERENCED_PARAMETER(wParam); 178 179 switch(uMsg) 180 { 181 case WM_INITDIALOG: 182 /* create the hardware page */ 183 DeviceCreateHardwarePageEx(hwndDlg, 184 Guids, 185 sizeof(Guids) / sizeof(Guids[0]), 186 HWPD_STANDARDLIST); 187 break; 188 } 189 190 return FALSE; 191 } 192 193 194 static INT_PTR CALLBACK 195 ClickLockProc(IN HWND hwndDlg, 196 IN UINT uMsg, 197 IN WPARAM wParam, 198 IN LPARAM lParam) 199 { 200 HWND hDlgCtrl; 201 int pos; 202 static HICON hIcon; 203 204 PBUTTON_DATA pButtonData; 205 206 pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 207 208 switch(uMsg) 209 { 210 case WM_INITDIALOG: 211 pButtonData = (PBUTTON_DATA)lParam; 212 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData); 213 214 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK); 215 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 10)); 216 pos = (pButtonData->g_ClickLockTime - 200) / 200; 217 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos); 218 219 hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOOK_KEY), 220 IMAGE_ICON, 16, 16, 0); 221 SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); 222 return TRUE; 223 224 case WM_COMMAND: 225 if (LOWORD(wParam) == IDOK) 226 { 227 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK); 228 pButtonData->g_ClickLockTime = (DWORD) (SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) * 200) + 200; 229 EndDialog(hwndDlg, TRUE); 230 if (hIcon) DestroyIcon(hIcon); 231 } 232 else if (LOWORD(wParam) == IDCANCEL) 233 { 234 EndDialog(hwndDlg, FALSE); 235 if (hIcon) DestroyIcon(hIcon); 236 } 237 break; 238 } 239 240 return FALSE; 241 } 242 243 244 static INT_PTR CALLBACK 245 ButtonProc(IN HWND hwndDlg, 246 IN UINT uMsg, 247 IN WPARAM wParam, 248 IN LPARAM lParam) 249 { 250 HWND hDlgCtrl; 251 LRESULT lResult; 252 LPPSHNOTIFY lppsn; 253 254 PBUTTON_DATA pButtonData; 255 256 pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 257 258 switch (uMsg) 259 { 260 case WM_INITDIALOG: 261 pButtonData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BUTTON_DATA)); 262 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData); 263 264 pButtonData->g_SwapMouseButtons = GetSystemMetrics(SM_SWAPBUTTON); 265 pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons; 266 pButtonData->g_DoubleClickSpeed = GetDoubleClickTime(); 267 pButtonData->g_OrigDoubleClickSpeed = pButtonData->g_DoubleClickSpeed; 268 269 /* Click lock time */ 270 SystemParametersInfo(SPI_GETMOUSECLICKLOCK, 0, &pButtonData->g_ClickLockEnabled, 0); 271 SystemParametersInfo(SPI_GETMOUSECLICKLOCKTIME, 0, &pButtonData->g_ClickLockTime, 0); 272 273 /* Load mouse button icons */ 274 pButtonData->hButtonLeft = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_LEFT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); 275 pButtonData->hButtonRight = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_RIGHT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); 276 277 /* Load folder icons */ 278 pButtonData->hIcon1 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_CLOSED), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); 279 pButtonData->hIcon2 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_OPEN), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); 280 281 if (pButtonData->g_SwapMouseButtons) 282 { 283 SendDlgItemMessage(hwndDlg, IDC_SWAP_MOUSE_BUTTONS, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 284 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight); 285 } 286 else 287 { 288 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft); 289 } 290 291 if (pButtonData->g_ClickLockEnabled) 292 { 293 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_CLICK_LOCK); 294 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 295 } 296 else 297 { 298 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK); 299 EnableWindow(hDlgCtrl, FALSE); 300 } 301 302 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED); 303 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 14)); 304 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, 14 - ((pButtonData->g_DoubleClickSpeed - 200) / 50)); 305 306 307 SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hIcon1); 308 pButtonData->bClicked = TRUE; 309 return TRUE; 310 311 case WM_DESTROY: 312 DestroyIcon(pButtonData->hButtonLeft); 313 DestroyIcon(pButtonData->hButtonRight); 314 DestroyIcon(pButtonData->hIcon1); 315 DestroyIcon(pButtonData->hIcon2); 316 HeapFree(GetProcessHeap(), 0, pButtonData); 317 break; 318 319 case WM_COMMAND: 320 switch(LOWORD(wParam)) 321 { 322 case IDC_SWAP_MOUSE_BUTTONS: 323 lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0); 324 if (lResult == BST_CHECKED) 325 { 326 pButtonData->g_SwapMouseButtons = FALSE; 327 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 328 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft); 329 } 330 else if (lResult == BST_UNCHECKED) 331 { 332 pButtonData->g_SwapMouseButtons = TRUE; 333 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 334 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight); 335 } 336 //SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_SwapMouseButtons, NULL, 0); 337 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 338 break; 339 340 case IDC_CHECK_CLICK_LOCK: 341 lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0); 342 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK); 343 if (lResult == BST_CHECKED) 344 { 345 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); 346 pButtonData->g_ClickLockEnabled = FALSE; 347 EnableWindow(hDlgCtrl, FALSE); 348 } 349 else if (lResult == BST_UNCHECKED) 350 { 351 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 352 pButtonData->g_ClickLockEnabled = TRUE; 353 EnableWindow(hDlgCtrl, TRUE); 354 } 355 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 356 break; 357 358 case IDC_BUTTON_CLICK_LOCK: 359 DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_CLICK_LOCK), hwndDlg, ClickLockProc, (LPARAM)pButtonData); 360 break; 361 362 case IDC_IMAGE_DOUBLE_CLICK_SPEED: 363 if (HIWORD(wParam) == STN_DBLCLK) 364 { 365 pButtonData->bClicked = !pButtonData->bClicked; 366 SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON, 367 (LPARAM)(pButtonData->bClicked ? pButtonData->hIcon1 : pButtonData->hIcon2)); 368 } 369 break; 370 } 371 break; 372 373 case WM_NOTIFY: 374 lppsn = (LPPSHNOTIFY) lParam; 375 if (lppsn->hdr.code == PSN_APPLY) 376 { 377 if (pButtonData->g_OrigSwapMouseButtons != pButtonData->g_SwapMouseButtons) 378 { 379 pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons; 380 SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 381 382 } 383 SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 384 //SetDoubleClickTime(pButtonData->g_DoubleClickSpeed); 385 386 #if (WINVER >= 0x0500) 387 SystemParametersInfo(SPI_SETMOUSECLICKLOCK, 0, UlongToPtr(pButtonData->g_ClickLockEnabled), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 388 if (pButtonData->g_ClickLockEnabled) 389 SystemParametersInfo(SPI_SETMOUSECLICKLOCKTIME, pButtonData->g_ClickLockTime, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 390 #endif 391 } 392 else if (lppsn->hdr.code == PSN_RESET) 393 { 394 /* Reset swap mouse button setting */ 395 SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, 0); 396 397 /* Reset double click speed setting */ 398 SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_OrigDoubleClickSpeed, NULL, 0); 399 //SetDoubleClickTime(pButtonData->g_OrigDoubleClickSpeed); 400 } 401 return TRUE; 402 403 case WM_HSCROLL: 404 if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED)) 405 { 406 switch (LOWORD(wParam)) 407 { 408 case TB_LINEUP: 409 case TB_LINEDOWN: 410 case TB_PAGEUP: 411 case TB_PAGEDOWN: 412 case TB_TOP: 413 case TB_BOTTOM: 414 case TB_ENDTRACK: 415 lResult = SendDlgItemMessage(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED, TBM_GETPOS, 0, 0); 416 pButtonData->g_DoubleClickSpeed = (14 - (INT)lResult) * 50 + 200; 417 //SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 418 SetDoubleClickTime(pButtonData->g_DoubleClickSpeed); 419 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 420 break; 421 422 case TB_THUMBTRACK: 423 pButtonData->g_DoubleClickSpeed = (14 - (INT)HIWORD(wParam)) * 50 + 200; 424 //SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, 0); 425 SetDoubleClickTime(pButtonData->g_DoubleClickSpeed); 426 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 427 break; 428 } 429 } 430 break; 431 } 432 433 return FALSE; 434 } 435 436 437 static VOID 438 CompressPath(LPTSTR lpShortPath, LPTSTR lpPath) 439 { 440 TCHAR szUserProfile[MAX_PATH]; 441 TCHAR szSystemRoot[MAX_PATH]; 442 TCHAR szProgramFiles[MAX_PATH]; 443 DWORD dwUserProfile; 444 DWORD dwSystemRoot; 445 DWORD dwProgramFiles; 446 447 dwUserProfile = GetEnvironmentVariable(_T("USERPROFILE"), szUserProfile, MAX_PATH); 448 dwSystemRoot = GetEnvironmentVariable(_T("SystemRoot"), szSystemRoot, MAX_PATH); 449 dwProgramFiles = GetEnvironmentVariable(_T("ProgramFiles"), szProgramFiles, MAX_PATH); 450 451 if (dwUserProfile > 0 && _tcsncmp(lpPath, szUserProfile, dwUserProfile) == 0) 452 { 453 _tcscpy(lpShortPath, _T("%USERPROFILE%")); 454 _tcscat(lpShortPath, &lpPath[dwUserProfile]); 455 } 456 else if (dwSystemRoot > 0 && _tcsncmp(lpPath, szSystemRoot, dwSystemRoot) == 0) 457 { 458 _tcscpy(lpShortPath, _T("%SystemRoot%")); 459 _tcscat(lpShortPath, &lpPath[dwSystemRoot]); 460 } 461 else if (dwProgramFiles > 0 && _tcsncmp(lpPath, szProgramFiles, dwProgramFiles) == 0) 462 { 463 _tcscpy(lpShortPath, _T("%ProgramFiles%")); 464 _tcscat(lpShortPath, &lpPath[dwProgramFiles]); 465 } 466 else 467 { 468 _tcscpy(lpShortPath, lpPath); 469 } 470 } 471 472 473 static BOOL 474 EnumerateCursorSchemes(HWND hwndDlg) 475 { 476 HKEY hCursorKey; 477 DWORD dwIndex; 478 TCHAR szValueName[MAX_PATH]; 479 DWORD dwValueName; 480 TCHAR szSystemScheme[MAX_PATH]; 481 TCHAR szValueData[2000]; 482 TCHAR szTempData[2000]; 483 DWORD dwValueData; 484 LONG lError; 485 HWND hDlgCtrl; 486 LRESULT lResult; 487 488 hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME); 489 SendMessage(hDlgCtrl, CB_RESETCONTENT, 0, 0); 490 491 /* Read the users cursor schemes */ 492 lError = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Cursors\\Schemes"), 493 0, KEY_READ | KEY_QUERY_VALUE , &hCursorKey); 494 if (lError == ERROR_SUCCESS) 495 { 496 for (dwIndex = 0;; dwIndex++) 497 { 498 dwValueName = sizeof(szValueName) / sizeof(TCHAR); 499 dwValueData = sizeof(szValueData) / sizeof(TCHAR); 500 lError = RegEnumValue(hCursorKey, dwIndex, szValueName, &dwValueName, 501 NULL, NULL, (LPBYTE)szValueData, &dwValueData); 502 if (lError == ERROR_NO_MORE_ITEMS) 503 break; 504 505 ExpandEnvironmentStrings(szValueData, szTempData, 2000); 506 507 if (_tcslen(szTempData) > 0) 508 { 509 LPTSTR lpCopy, lpStart; 510 511 /* Remove quotation marks */ 512 if (szTempData[0] == _T('"')) 513 { 514 lpStart = szValueData + 1; 515 szTempData[_tcslen(szTempData) - 1] = 0; 516 } 517 else 518 { 519 lpStart = szTempData; 520 } 521 522 lpCopy = _tcsdup(lpStart); 523 524 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValueName); 525 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)lpCopy); 526 } 527 } 528 529 RegCloseKey(hCursorKey); 530 } 531 532 /* Read the system cursor schemes */ 533 lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 534 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cursors\\Schemes"), 535 0, KEY_READ | KEY_QUERY_VALUE , &hCursorKey); 536 if (lError == ERROR_SUCCESS) 537 { 538 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 539 540 for (dwIndex = 0;; dwIndex++) 541 { 542 dwValueName = sizeof(szValueName) / sizeof(TCHAR); 543 dwValueData = sizeof(szValueData) / sizeof(TCHAR); 544 lError = RegEnumValue(hCursorKey, dwIndex, szValueName, &dwValueName, 545 NULL, NULL, (LPBYTE)szValueData, &dwValueData); 546 if (lError == ERROR_NO_MORE_ITEMS) 547 break; 548 549 if (_tcslen(szValueData) > 0) 550 { 551 LPTSTR lpCopy, lpStart; 552 553 /* Remove quotation marks */ 554 if (szValueData[0] == _T('"')) 555 { 556 lpStart = szValueData + 1; 557 szValueData[_tcslen(szValueData) - 1] = 0; 558 } 559 else 560 { 561 lpStart = szValueData; 562 } 563 564 lpCopy = _tcsdup(lpStart); 565 566 _tcscat(szValueName, TEXT(" ")); 567 _tcscat(szValueName, szSystemScheme); 568 569 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValueName); 570 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)lpCopy); 571 } 572 } 573 574 RegCloseKey(hCursorKey); 575 } 576 577 /* Add the "(none)" entry */ 578 LoadString(hApplet, IDS_NONE, szSystemScheme, MAX_PATH); 579 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szSystemScheme); 580 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)NULL); 581 582 return TRUE; 583 } 584 585 586 static VOID 587 RefreshCursorList(HWND hwndDlg, BOOL bInit) 588 { 589 INT index; 590 INT i; 591 INT nSel; 592 593 nSel = bInit ? 0 : SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0); 594 595 if (bInit) 596 { 597 SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_RESETCONTENT, 0, 0); 598 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 599 { 600 LoadString(hApplet, index, g_CursorData[i].szCursorName, MAX_PATH); 601 SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_ADDSTRING, 0, (LPARAM)i); 602 } 603 604 SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_SETCURSEL, nSel, 0); 605 } 606 else 607 { 608 InvalidateRect(GetDlgItem(hwndDlg, IDC_LISTBOX_CURSOR), NULL, FALSE); 609 } 610 611 SendDlgItemMessage(hwndDlg, IDC_IMAGE_CURRENT_CURSOR, STM_SETIMAGE, IMAGE_CURSOR, 612 (LPARAM)g_CursorData[nSel].hCursor); 613 614 EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), (g_CursorData[nSel].szCursorPath[0] != 0)); 615 } 616 617 618 static BOOL 619 DeleteUserCursorScheme(HWND hwndDlg) 620 { 621 TCHAR szSchemeName[MAX_PATH]; 622 TCHAR szTitle[128]; 623 TCHAR szRawText[256]; 624 TCHAR szText[256]; 625 HWND hDlgCtrl; 626 HKEY hCuKey; 627 HKEY hCuCursorKey; 628 LONG lResult; 629 INT nSel; 630 631 hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME); 632 nSel = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0); 633 if (nSel == CB_ERR) 634 return FALSE; 635 636 SendMessage(hDlgCtrl, CB_GETLBTEXT, nSel, (LPARAM)szSchemeName); 637 638 LoadString(hApplet, IDS_REMOVE_TITLE, szTitle, 128); 639 LoadString(hApplet, IDS_REMOVE_TEXT, szRawText, 256); 640 641 _stprintf(szText, szRawText, szSchemeName); 642 643 /* Confirm scheme removal */ 644 if (MessageBox(hwndDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO) 645 return TRUE; 646 647 if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS) 648 return FALSE; 649 650 if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ | KEY_SET_VALUE, &hCuCursorKey) != ERROR_SUCCESS) 651 { 652 RegCloseKey(hCuKey); 653 return FALSE; 654 } 655 656 lResult = RegDeleteValue(hCuCursorKey, szSchemeName); 657 658 RegCloseKey(hCuCursorKey); 659 RegCloseKey(hCuKey); 660 661 if (lResult == ERROR_SUCCESS) 662 { 663 SendMessage(hDlgCtrl, CB_DELETESTRING, nSel, 0); 664 SendMessage(hDlgCtrl, CB_SETCURSEL, (WPARAM)0, (LPARAM)0); 665 } 666 667 return (lResult == ERROR_SUCCESS); 668 } 669 670 671 static INT_PTR CALLBACK 672 SaveSchemeProc(IN HWND hwndDlg, 673 IN UINT uMsg, 674 IN WPARAM wParam, 675 IN LPARAM lParam) 676 { 677 LPTSTR pSchemeName; 678 679 switch (uMsg) 680 { 681 case WM_INITDIALOG: 682 pSchemeName = (LPTSTR)lParam; 683 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSchemeName); 684 SendDlgItemMessage(hwndDlg, IDC_EDIT_SCHEME_NAME, WM_SETTEXT, 685 0, (LPARAM)pSchemeName); 686 break; 687 688 case WM_COMMAND: 689 if (LOWORD(wParam) == IDOK) 690 { 691 pSchemeName = (LPTSTR)GetWindowLongPtr(hwndDlg, DWLP_USER); 692 SendDlgItemMessage(hwndDlg, IDC_EDIT_SCHEME_NAME, WM_GETTEXT, 693 (WPARAM)MAX_PATH, (LPARAM)pSchemeName); 694 EndDialog(hwndDlg, TRUE); 695 } 696 else if (LOWORD(wParam) == IDCANCEL) 697 { 698 EndDialog(hwndDlg, FALSE); 699 } 700 break; 701 } 702 703 return FALSE; 704 } 705 706 707 static BOOL 708 SaveCursorScheme(HWND hwndDlg) 709 { 710 TCHAR szSystemScheme[MAX_PATH]; 711 TCHAR szSchemeName[MAX_PATH]; 712 TCHAR szNewSchemeName[MAX_PATH]; 713 TCHAR szTempPath[MAX_PATH]; 714 TCHAR szTitle[128]; 715 TCHAR szText[256]; 716 INT nSel; 717 INT index, i, nLength; 718 LPTSTR lpSchemeData; 719 HKEY hCuKey; 720 HKEY hCuCursorKey; 721 LONG lError = ERROR_SUCCESS; 722 BOOL bSchemeExists; 723 724 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 725 726 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0); 727 if (nSel == CB_ERR) 728 return FALSE; 729 730 if (nSel == 0) 731 { 732 szSchemeName[0] = 0; 733 } 734 else 735 { 736 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)szNewSchemeName); 737 738 if (_tcsstr(szNewSchemeName, szSystemScheme)) 739 { 740 szNewSchemeName[_tcslen(szNewSchemeName) - _tcslen(szSystemScheme) - 1] = 0; 741 } 742 } 743 744 /* Ask for a name for the new cursor scheme */ 745 if (!DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_CURSOR_SCHEME_SAVEAS), 746 hwndDlg, SaveSchemeProc, (LPARAM)szNewSchemeName)) 747 return TRUE; 748 749 /* Check all non-system schemes for the new name */ 750 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCOUNT, 0, 0); 751 if (nSel == CB_ERR) 752 return FALSE; 753 754 bSchemeExists = FALSE; 755 for (i = 0; i < nSel; i++) 756 { 757 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, i, (LPARAM)szSchemeName); 758 if (_tcsstr(szSchemeName, szSystemScheme) == NULL) 759 { 760 if (_tcscmp(szSchemeName, szNewSchemeName) == 0) 761 { 762 bSchemeExists = TRUE; 763 break; 764 } 765 } 766 } 767 768 if (bSchemeExists) 769 { 770 LoadString(hApplet, IDS_OVERWRITE_TITLE, szTitle, 128); 771 LoadString(hApplet, IDS_OVERWRITE_TEXT, szText, 256); 772 773 /* Confirm scheme overwrite */ 774 if (MessageBox(hwndDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO) 775 return TRUE; 776 } 777 778 /* Save the cursor scheme */ 779 nLength = 0; 780 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 781 { 782 if (i > 0) 783 nLength++; 784 nLength += _tcslen(g_CursorData[i].szCursorPath); 785 } 786 nLength++; 787 788 lpSchemeData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(TCHAR)); 789 790 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 791 { 792 CompressPath(szTempPath, g_CursorData[i].szCursorPath); 793 if (i > 0) 794 _tcscat(lpSchemeData, _T(",")); 795 _tcscat(lpSchemeData, szTempPath); 796 } 797 798 if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS) 799 return FALSE; 800 801 if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ | KEY_SET_VALUE, &hCuCursorKey) != ERROR_SUCCESS) 802 { 803 RegCloseKey(hCuKey); 804 return FALSE; 805 } 806 807 lError = RegSetValueEx(hCuCursorKey, szNewSchemeName, 0, 808 REG_EXPAND_SZ, (LPBYTE)lpSchemeData, 809 (_tcslen(lpSchemeData) + 1) * sizeof(TCHAR)); 810 811 RegCloseKey(hCuCursorKey); 812 RegCloseKey(hCuKey); 813 814 /* Add the new scheme to the scheme list and select it */ 815 if (lError == ERROR_SUCCESS) 816 { 817 LPTSTR copy = _tcsdup(lpSchemeData); 818 819 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_ADDSTRING, (WPARAM)0, (LPARAM)szNewSchemeName); 820 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETITEMDATA, (WPARAM)nSel, (LPARAM)copy); 821 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETCURSEL, (WPARAM)nSel, (LPARAM)0); 822 } 823 824 HeapFree(GetProcessHeap(), 0, lpSchemeData); 825 826 return (lError == ERROR_SUCCESS); 827 } 828 829 830 static BOOL 831 BrowseCursor(HWND hwndDlg) 832 { 833 TCHAR szFileName[MAX_PATH]; 834 TCHAR szFilter[MAX_PATH]; 835 TCHAR szTitle[MAX_PATH]; 836 OPENFILENAME ofn; 837 INT nSel; 838 839 LoadString(hApplet, IDS_BROWSE_FILTER, szFilter, MAX_PATH); 840 LoadString(hApplet, IDS_BROWSE_TITLE, szTitle, MAX_PATH); 841 842 memset(szFileName, 0x0, sizeof(szFileName)); 843 nSel = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0); 844 if (nSel == LB_ERR) 845 { 846 MessageBox(hwndDlg, _T("LB_ERR"), _T(""), MB_ICONERROR); 847 return FALSE; 848 } 849 850 ZeroMemory(&ofn, sizeof(OPENFILENAME)); 851 ofn.lStructSize = sizeof(OPENFILENAME); 852 ofn.hwndOwner = hwndDlg; 853 ofn.lpstrFilter = szFilter; 854 ofn.nFilterIndex = 1; 855 ofn.lpstrFile = szFileName; 856 ofn.nMaxFile = MAX_PATH; 857 ofn.lpstrInitialDir = _T("%WINDIR%\\Cursors"); 858 ofn.lpstrTitle = szTitle; 859 ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST; 860 861 if (!GetOpenFileName(&ofn)) 862 return FALSE; 863 864 /* Store the new cursor file path */ 865 _tcsncpy(g_CursorData[nSel].szCursorPath, szFileName, MAX_PATH); 866 867 return TRUE; 868 } 869 870 871 static VOID 872 LoadCursorScheme(LPTSTR lpName, BOOL bSystem) 873 { 874 UINT index, i; 875 876 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 877 { 878 if (g_CursorData[i].hCursor != NULL) 879 { 880 DestroyCursor(g_CursorData[i].hCursor); 881 g_CursorData[i].hCursor = 0; 882 } 883 g_CursorData[i].szCursorPath[0] = 0; 884 } 885 886 if (lpName != NULL) 887 { 888 LPTSTR pStart = lpName; 889 LPTSTR pEnd = pStart; 890 INT nLength; 891 892 i = 0; 893 while (pEnd) 894 { 895 pEnd = _tcschr(pStart, _T(',')); 896 if (pEnd) 897 nLength = ((INT_PTR)pEnd - (INT_PTR)pStart) / sizeof(TCHAR); 898 else 899 nLength = _tcslen(pStart); 900 901 _tcsncpy(g_CursorData[i].szCursorPath, pStart, nLength); 902 g_CursorData[i].szCursorPath[nLength] = 0; 903 904 pStart = pStart + (nLength + 1); 905 i++; 906 } 907 908 } 909 910 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 911 { 912 if (g_CursorData[i].szCursorPath[0] == 0) 913 g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(g_CursorData[i].uDefaultCursorId), 914 IMAGE_CURSOR, 0, 0, 915 LR_DEFAULTSIZE | LR_SHARED); 916 else 917 g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, g_CursorData[i].szCursorPath, 918 IMAGE_CURSOR, 0, 0, 919 LR_LOADFROMFILE | LR_DEFAULTSIZE); 920 } 921 } 922 923 924 static VOID 925 ReloadCurrentCursorScheme(VOID) 926 { 927 UINT index, i; 928 929 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 930 { 931 if (g_CursorData[i].hCursor != NULL) 932 DestroyCursor(g_CursorData[i].hCursor); 933 934 if (g_CursorData[i].szCursorPath[0] == 0) 935 g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(g_CursorData[i].uDefaultCursorId), 936 IMAGE_CURSOR, 0, 0, 937 LR_DEFAULTSIZE | LR_SHARED); 938 else 939 g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, g_CursorData[i].szCursorPath, 940 IMAGE_CURSOR, 0, 0, 941 LR_LOADFROMFILE | LR_DEFAULTSIZE); 942 } 943 } 944 945 946 static VOID 947 OnDrawItem(UINT idCtl, 948 LPDRAWITEMSTRUCT lpdis, 949 PPOINTER_DATA pPointerData) 950 { 951 RECT rc; 952 953 if (lpdis->itemState & ODS_SELECTED) 954 { 955 FillRect(lpdis->hDC, 956 &lpdis->rcItem, 957 (HBRUSH)(COLOR_HIGHLIGHT + 1)); 958 SetBkColor(lpdis->hDC, 959 GetSysColor(COLOR_HIGHLIGHT)); 960 SetTextColor(lpdis->hDC, 961 GetSysColor(COLOR_HIGHLIGHTTEXT)); 962 } 963 else 964 { 965 FillRect(lpdis->hDC, 966 &lpdis->rcItem, 967 (HBRUSH)(COLOR_WINDOW + 1)); 968 SetBkColor(lpdis->hDC, 969 GetSysColor(COLOR_WINDOW)); 970 SetTextColor(lpdis->hDC, 971 GetSysColor(COLOR_WINDOWTEXT)); 972 } 973 974 if (lpdis->itemID != (UINT)-1) 975 { 976 CopyRect(&rc, &lpdis->rcItem); 977 rc.left += 5; 978 DrawText(lpdis->hDC, 979 g_CursorData[lpdis->itemData].szCursorName, 980 -1, 981 &rc, 982 DT_SINGLELINE | DT_VCENTER | DT_LEFT); 983 984 if (g_CursorData[lpdis->itemData].hCursor != NULL) 985 { 986 DrawIcon(lpdis->hDC, 987 lpdis->rcItem.right - pPointerData->cxCursor - 4, 988 lpdis->rcItem.top + 2, 989 g_CursorData[lpdis->itemData].hCursor); 990 } 991 } 992 993 if (lpdis->itemState & ODS_FOCUS) 994 { 995 CopyRect(&rc, &lpdis->rcItem); 996 InflateRect(&rc, -1, -1); 997 DrawFocusRect(lpdis->hDC, &rc); 998 } 999 } 1000 1001 1002 static VOID 1003 LoadNewCursorScheme(HWND hwndDlg) 1004 { 1005 TCHAR buffer[MAX_PATH]; 1006 TCHAR szSystemScheme[MAX_PATH]; 1007 HWND hDlgCtrl; 1008 BOOL bEnable; 1009 LPTSTR lpName; 1010 INT nSel; 1011 1012 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0); 1013 if (nSel == CB_ERR) 1014 return; 1015 1016 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)buffer); 1017 1018 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 1019 if (_tcsstr(buffer, szSystemScheme) || nSel == 0) //avoid the default scheme can be deleted 1020 bEnable = FALSE; 1021 else 1022 bEnable = TRUE; 1023 1024 /* delete button */ 1025 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_DELETE_SCHEME); 1026 EnableWindow(hDlgCtrl, bEnable); 1027 1028 lpName = (LPTSTR)SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETITEMDATA, nSel, 0); 1029 LoadCursorScheme(lpName, !bEnable); 1030 RefreshCursorList(hwndDlg, FALSE); 1031 } 1032 1033 1034 static VOID 1035 LoadInitialCursorScheme(HWND hwndDlg) 1036 { 1037 TCHAR szSchemeName[256]; 1038 TCHAR szSystemScheme[256]; 1039 TCHAR szCursorPath[256]; 1040 HKEY hCursorKey; 1041 LONG lError; 1042 DWORD dwDataSize; 1043 DWORD dwSchemeSource = 0; 1044 UINT index, i; 1045 DWORD dwType; 1046 INT nSel; 1047 1048 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 1049 { 1050 g_CursorData[i].hCursor = 0; 1051 g_CursorData[i].szCursorPath[0] = 0; 1052 } 1053 1054 lError = RegOpenKeyEx(HKEY_CURRENT_USER, 1055 _T("Control Panel\\Cursors"), 1056 0, 1057 KEY_READ | KEY_QUERY_VALUE, 1058 &hCursorKey); 1059 if (lError != ERROR_SUCCESS) 1060 return; 1061 1062 dwDataSize = sizeof(DWORD); 1063 lError = RegQueryValueEx(hCursorKey, 1064 _T("Scheme Source"), 1065 NULL, 1066 NULL, 1067 (LPBYTE)&dwSchemeSource, 1068 &dwDataSize); 1069 1070 if (dwSchemeSource != 0) 1071 { 1072 dwDataSize = 256 * sizeof(TCHAR); 1073 lError = RegQueryValueEx(hCursorKey, 1074 NULL, 1075 NULL, 1076 NULL, 1077 (LPBYTE)szSchemeName, 1078 &dwDataSize); 1079 1080 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 1081 { 1082 dwDataSize = MAX_PATH * sizeof(TCHAR); 1083 lError = RegQueryValueEx(hCursorKey, 1084 g_CursorData[i].lpValueName, 1085 NULL, 1086 &dwType, 1087 (LPBYTE)szCursorPath, 1088 &dwDataSize); 1089 if (lError == ERROR_SUCCESS) 1090 { 1091 if (dwType == REG_EXPAND_SZ) 1092 { 1093 ExpandEnvironmentStrings(szCursorPath, g_CursorData[i].szCursorPath, MAX_PATH); 1094 } 1095 else 1096 { 1097 _tcscpy(g_CursorData[i].szCursorPath, szCursorPath); 1098 } 1099 } 1100 } 1101 } 1102 1103 RegCloseKey(hCursorKey); 1104 1105 ReloadCurrentCursorScheme(); 1106 RefreshCursorList(hwndDlg, TRUE); 1107 1108 /* Build the full scheme name */ 1109 if (dwSchemeSource == 0) 1110 { 1111 LoadString(hApplet, IDS_NONE, szSchemeName, MAX_PATH); 1112 } 1113 else if (dwSchemeSource == 2) 1114 { 1115 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 1116 _tcscat(szSchemeName, _T(" ")); 1117 _tcscat(szSchemeName, szSystemScheme); 1118 } 1119 1120 /* Search and select the curent scheme name from the scheme list */ 1121 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_FINDSTRINGEXACT, -1, (LPARAM)szSchemeName); 1122 if (nSel != CB_ERR) 1123 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETCURSEL, (WPARAM)nSel, (LPARAM)0); 1124 1125 /* Enable /disable delete button */ 1126 EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_DELETE_SCHEME), (dwSchemeSource == 1)); 1127 } 1128 1129 1130 static BOOL 1131 ApplyCursorScheme(HWND hwndDlg) 1132 { 1133 TCHAR szSchemeName[MAX_PATH]; 1134 TCHAR szSystemScheme[MAX_PATH]; 1135 TCHAR szTempPath[MAX_PATH]; 1136 LPTSTR lpSchemeData; 1137 DWORD dwNameLength; 1138 DWORD dwSchemeSource; 1139 UINT index, i; 1140 HKEY hCursorKey; 1141 INT nSel; 1142 1143 nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0); 1144 if (nSel == CB_ERR) 1145 return FALSE; 1146 1147 lpSchemeData = (LPTSTR)SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETITEMDATA, nSel, 0); 1148 if (lpSchemeData == NULL) 1149 { 1150 /* "None" cursor scheme */ 1151 dwSchemeSource = 0; 1152 szSchemeName[0] = 0; 1153 dwNameLength = 0; 1154 } 1155 else 1156 { 1157 SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)szSchemeName); 1158 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH); 1159 1160 if (_tcsstr(szSchemeName, szSystemScheme)) 1161 { 1162 /* System scheme */ 1163 dwSchemeSource = 2; 1164 szSchemeName[_tcslen(szSchemeName) - _tcslen(szSystemScheme) - 1] = 0; 1165 } 1166 else 1167 { 1168 /* User scheme */ 1169 dwSchemeSource = 1; 1170 } 1171 1172 dwNameLength = (_tcslen(szSchemeName) + 1) * sizeof(TCHAR); 1173 } 1174 1175 if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Cursors"), 0, 1176 KEY_READ | KEY_SET_VALUE, &hCursorKey) != ERROR_SUCCESS) 1177 return FALSE; 1178 1179 RegSetValueEx(hCursorKey, NULL, 0, REG_SZ, 1180 (LPBYTE)szSchemeName, dwNameLength); 1181 1182 RegSetValueEx(hCursorKey, _T("Scheme Source"), 0, REG_DWORD, 1183 (LPBYTE)&dwSchemeSource, sizeof(DWORD)); 1184 1185 for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++) 1186 { 1187 CompressPath(szTempPath, g_CursorData[i].szCursorPath); 1188 RegSetValueEx(hCursorKey, g_CursorData[i].lpValueName, 0, 1189 REG_EXPAND_SZ, (LPBYTE)szTempPath, 1190 (_tcslen(szTempPath) + 1) * sizeof(TCHAR)); 1191 } 1192 1193 RegCloseKey(hCursorKey); 1194 1195 /* Force the system to reload its cursors */ 1196 SystemParametersInfo(SPI_SETCURSORS, 0, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1197 1198 return TRUE; 1199 } 1200 1201 1202 static INT_PTR CALLBACK 1203 PointerProc(IN HWND hwndDlg, 1204 IN UINT uMsg, 1205 IN WPARAM wParam, 1206 IN LPARAM lParam) 1207 { 1208 PPOINTER_DATA pPointerData; 1209 LPPSHNOTIFY lppsn; 1210 INT nSel; 1211 1212 pPointerData = (PPOINTER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 1213 1214 switch (uMsg) 1215 { 1216 case WM_INITDIALOG: 1217 pPointerData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POINTER_DATA)); 1218 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pPointerData); 1219 1220 pPointerData->cxCursor = GetSystemMetrics(SM_CXCURSOR); 1221 pPointerData->cyCursor = GetSystemMetrics(SM_CYCURSOR); 1222 1223 EnumerateCursorSchemes(hwndDlg); 1224 LoadInitialCursorScheme(hwndDlg); 1225 1226 /* Get cursor shadow setting */ 1227 SystemParametersInfo(SPI_GETCURSORSHADOW, 0, &pPointerData->bCursorShadow, 0); 1228 pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow; 1229 1230 if (pPointerData->bCursorShadow) 1231 { 1232 SendDlgItemMessage(hwndDlg, IDC_CHECK_CURSOR_SHADOW, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 1233 } 1234 1235 if ((INT)wParam == IDC_LISTBOX_CURSOR) 1236 return TRUE; 1237 else 1238 return FALSE; 1239 1240 case WM_MEASUREITEM: 1241 ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = GetSystemMetrics(SM_CYCURSOR) + 4; 1242 break; 1243 1244 case WM_DRAWITEM: 1245 if (wParam == IDC_LISTBOX_CURSOR) 1246 OnDrawItem((UINT)wParam, (LPDRAWITEMSTRUCT)lParam, pPointerData); 1247 return TRUE; 1248 1249 case WM_DESTROY: 1250 HeapFree(GetProcessHeap(), 0, pPointerData); 1251 break; 1252 1253 case WM_NOTIFY: 1254 lppsn = (LPPSHNOTIFY) lParam; 1255 if (lppsn->hdr.code == PSN_APPLY) 1256 { 1257 ApplyCursorScheme(hwndDlg); 1258 //#if (WINVER >= 0x0500) 1259 if (pPointerData->bOrigCursorShadow != pPointerData->bCursorShadow) 1260 { 1261 SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1262 pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow; 1263 } 1264 //#endif 1265 return TRUE; 1266 } 1267 else if (lppsn->hdr.code == PSN_RESET) 1268 { 1269 //#if (WINVER >= 0x0500) 1270 SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bOrigCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE); 1271 //#endif 1272 } 1273 break; 1274 1275 case WM_COMMAND: 1276 switch (LOWORD(wParam)) 1277 { 1278 case IDC_COMBO_CURSOR_SCHEME: 1279 if (HIWORD(wParam) == CBN_SELENDOK) 1280 { 1281 LoadNewCursorScheme(hwndDlg); 1282 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1283 } 1284 break; 1285 1286 case IDC_LISTBOX_CURSOR: 1287 switch (HIWORD(wParam)) 1288 { 1289 case LBN_SELCHANGE: 1290 nSel = SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0); 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(0, 19)); 1434 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pOptionData->ulMouseSpeed - 1); 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) + 1; 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 == TRUE) 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 const struct 1798 { 1799 WORD idDlg; 1800 DLGPROC DlgProc; 1801 UINT uiReplaceWith; 1802 } PropPages[] = 1803 { 1804 { IDD_PAGE_BUTTON, ButtonProc, CPLPAGE_MOUSE_BUTTONS }, 1805 { IDD_PAGE_POINTER, PointerProc, 0 }, 1806 { IDD_PAGE_OPTION, OptionProc, CPLPAGE_MOUSE_PTRMOTION }, 1807 { IDD_PAGE_WHEEL, WheelProc, CPLPAGE_MOUSE_WHEEL }, 1808 { IDD_HARDWARE, MouseHardwareProc, 0 }, 1809 }; 1810 1811 LONG APIENTRY 1812 MouseApplet(HWND hwnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2) 1813 { 1814 HPROPSHEETPAGE hpsp[MAX_CPL_PAGES]; 1815 PROPSHEETHEADER psh; 1816 HPSXA hpsxa; 1817 TCHAR Caption[256]; 1818 UINT i; 1819 LONG ret; 1820 1821 UNREFERENCED_PARAMETER(lParam1); 1822 UNREFERENCED_PARAMETER(lParam2); 1823 UNREFERENCED_PARAMETER(uMsg); 1824 UNREFERENCED_PARAMETER(hwnd); 1825 1826 LoadString(hApplet, IDS_CPLNAME_1, Caption, sizeof(Caption) / sizeof(TCHAR)); 1827 1828 ZeroMemory(&psh, sizeof(PROPSHEETHEADER)); 1829 psh.dwSize = sizeof(PROPSHEETHEADER); 1830 psh.dwFlags = PSH_PROPTITLE; 1831 psh.hwndParent = hwnd; 1832 psh.hInstance = hApplet; 1833 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON_1)); 1834 psh.pszCaption = Caption; 1835 psh.nStartPage = 0; 1836 psh.phpage = hpsp; 1837 1838 /* Load additional pages provided by shell extensions */ 1839 hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Mouse"), MAX_CPL_PAGES - psh.nPages); 1840 1841 for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++) 1842 { 1843 /* Override the background page if requested by a shell extension */ 1844 if (PropPages[i].uiReplaceWith != 0 && hpsxa != NULL && 1845 SHReplaceFromPropSheetExtArray(hpsxa, PropPages[i].uiReplaceWith, PropSheetAddPage, (LPARAM)&psh) != 0) 1846 { 1847 /* The shell extension added one or more pages to replace a page. 1848 Don't create the built-in page anymore! */ 1849 continue; 1850 } 1851 1852 InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc); 1853 } 1854 1855 if (hpsxa != NULL) 1856 SHAddFromPropSheetExtArray(hpsxa, PropSheetAddPage, (LPARAM)&psh); 1857 1858 ret = (LONG)(PropertySheet(&psh) != -1); 1859 1860 if (hpsxa != NULL) 1861 SHDestroyPropSheetExtArray(hpsxa); 1862 1863 return ret; 1864 } 1865 1866 /* EOF */ 1867