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