- Fix the mouse wheel page.
[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 //detect slider changes - for apply stuff
30 // cursor icon shows - may need overriden items
31 // implement Pointer-APPLY
32 // implement Pointer-Browser
33 // add missing icons
34 // Options- pointer precision
35
36 #define WINVER 0x0501
37
38 #include <windows.h>
39 #include <winuser.h>
40 #include <devguid.h>
41 #include <commctrl.h>
42 #include <cpl.h>
43 #include <tchar.h>
44 #include <math.h>
45 #include <limits.h>
46
47 #include "main.h"
48 #include "resource.h"
49
50 #define DEFAULT_DOUBLE_CLICK_SPEED 500
51 #define DEFAULT_CLICK_LOCK_TIME 2200
52 #define DEFAULT_MOUSE_SENSITIVITY 16
53 #define DEFAULT_MOUSE_THRESHOLD1 6
54 #define DEFAULT_MOUSE_THRESHOLD2 10
55 #define MIN_DOUBLE_CLICK_SPEED 200
56 #define MAX_DOUBLE_CLICK_SPEED 900
57 #define DEFAULT_WHEEL_SCROLL_LINES 3
58
59
60 typedef struct _BUTTON_DATA
61 {
62 ULONG g_SwapMouseButtons;
63 ULONG g_OrigSwapMouseButtons;
64 ULONG g_DoubleClickSpeed; // = DEFAULT_DOUBLE_CLICK_SPEED;
65 ULONG g_OrigDoubleClickSpeed;
66 BOOL g_ClickLockEnabled; // = 0;
67 DWORD g_ClickLockTime; // = DEFAULT_CLICK_LOCK_TIME;
68
69 HICON hButtonLeft;
70 HICON hButtonRight;
71
72 HICON hIcon1;
73 HICON hIcon2;
74 BOOL bClicked;
75 } BUTTON_DATA, *PBUTTON_DATA;
76
77
78 typedef struct _WHEEL_DATA
79 {
80 UINT uWheelScrollLines;
81 } WHEEL_DATA, *PWHEEL_DATA;
82
83
84 ULONG g_Initialized = 0;
85
86 BOOL g_DropShadow = 0;
87
88 ULONG g_MouseSensitivity = DEFAULT_MOUSE_SENSITIVITY;
89 ULONG g_MouseSpeed = 1;
90 ULONG g_MouseThreshold1 = DEFAULT_MOUSE_THRESHOLD1;
91 ULONG g_MouseThreshold2 = DEFAULT_MOUSE_THRESHOLD2;
92 ULONG g_SnapToDefaultButton = 0;
93 ULONG g_MouseTrails = 0;
94 ULONG g_ShowPointer = 0;
95 ULONG g_HidePointer = 0;
96 ULONG g_ApplyCount = 0;
97
98
99 TCHAR g_CurrentScheme[MAX_PATH];
100 TCHAR g_szArrow[MAX_PATH];
101 TCHAR g_szHelp[MAX_PATH];
102 TCHAR g_szAppStarting[MAX_PATH];
103 TCHAR g_szWait[MAX_PATH];
104 TCHAR g_szCrosshair[MAX_PATH];
105 TCHAR g_szIBeam[MAX_PATH];
106 TCHAR g_szNWPen[MAX_PATH];
107 TCHAR g_szNo[MAX_PATH];
108 TCHAR g_szSizeNS[MAX_PATH];
109 TCHAR g_szSizeWE[MAX_PATH];
110 TCHAR g_szSizeNWSE[MAX_PATH];
111 TCHAR g_szSizeNESW[MAX_PATH];
112 TCHAR g_szSizeAll[MAX_PATH];
113 TCHAR g_szUpArrow[MAX_PATH];
114 TCHAR g_szHand[MAX_PATH];
115
116 TCHAR g_szNewScheme[MAX_PATH];
117
118
119 /* Property page dialog callback */
120 static INT_PTR CALLBACK
121 MouseHardwareProc(IN HWND hwndDlg,
122 IN UINT uMsg,
123 IN WPARAM wParam,
124 IN LPARAM lParam)
125 {
126 GUID Guids[1];
127 Guids[0] = GUID_DEVCLASS_MOUSE;
128
129 UNREFERENCED_PARAMETER(lParam);
130 UNREFERENCED_PARAMETER(wParam);
131
132 switch(uMsg)
133 {
134 case WM_INITDIALOG:
135 /* create the hardware page */
136 DeviceCreateHardwarePageEx(hwndDlg,
137 Guids,
138 sizeof(Guids) / sizeof(Guids[0]),
139 HWPD_STANDARDLIST);
140 break;
141 }
142
143 return FALSE;
144 }
145
146
147 static BOOL
148 InitializeMouse(VOID)
149 {
150 /* mouse trails */
151 SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &g_MouseTrails, 0);
152
153 /* snap to default button */
154 SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &g_SnapToDefaultButton, 0);
155
156 //FIXME
157 //pointer precision
158 // SPI_GETMOUSE?
159
160 /* mouse sensitivity */
161 SystemParametersInfo(SPI_GETMOUSESPEED, 0, &g_MouseSensitivity, 0);
162
163 /* hide pointer while typing */
164 SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &g_HidePointer, 0);
165
166
167
168 /* show pointer with Ctrl-Key */
169 SystemParametersInfo(SPI_GETMOUSESONAR, 0, &g_ShowPointer, 0);
170 return TRUE;
171 }
172
173
174 static INT_PTR CALLBACK
175 ClickLockProc(IN HWND hwndDlg,
176 IN UINT uMsg,
177 IN WPARAM wParam,
178 IN LPARAM lParam)
179 {
180 HWND hDlgCtrl;
181 int pos;
182
183 PBUTTON_DATA pButtonData;
184
185 pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
186
187 switch(uMsg)
188 {
189 case WM_INITDIALOG:
190 pButtonData = (PBUTTON_DATA)lParam;
191 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData);
192
193 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK);
194 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 10));
195 pos = (pButtonData->g_ClickLockTime - 200) / 200;
196 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos);
197 return TRUE;
198
199 case WM_COMMAND:
200 if (LOWORD(wParam) == IDOK)
201 {
202 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK);
203 pButtonData->g_ClickLockTime = (DWORD) (SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) * 200) + 200;
204 EndDialog(hwndDlg, TRUE);
205 }
206 else if (LOWORD(wParam) == IDCANCEL)
207 {
208 EndDialog(hwndDlg, FALSE);
209 }
210 break;
211 }
212
213 return FALSE;
214 }
215
216
217 static INT_PTR CALLBACK
218 ButtonProc(IN HWND hwndDlg,
219 IN UINT uMsg,
220 IN WPARAM wParam,
221 IN LPARAM lParam)
222 {
223 HWND hDlgCtrl;
224 LRESULT lResult;
225 LPPSHNOTIFY lppsn;
226
227 PBUTTON_DATA pButtonData;
228
229 pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
230
231 switch (uMsg)
232 {
233 case WM_INITDIALOG:
234 pButtonData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BUTTON_DATA));
235 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData);
236
237 pButtonData->g_SwapMouseButtons = GetSystemMetrics(SM_SWAPBUTTON);
238 pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons;
239 pButtonData->g_DoubleClickSpeed = GetDoubleClickTime();
240 pButtonData->g_OrigDoubleClickSpeed = pButtonData->g_DoubleClickSpeed;
241
242 /* Click lock time */
243 SystemParametersInfo(SPI_GETMOUSECLICKLOCK, 0, &pButtonData->g_ClickLockEnabled, 0);
244 SystemParametersInfo(SPI_GETMOUSECLICKLOCKTIME, 0, &pButtonData->g_ClickLockTime, 0);
245
246 /* Load mouse button icons */
247 pButtonData->hButtonLeft = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_LEFT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
248 pButtonData->hButtonRight = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_RIGHT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
249
250 /* Load folder icons */
251 pButtonData->hIcon1 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_CLOSED), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
252 pButtonData->hIcon2 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_OPEN), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
253
254 if (pButtonData->g_SwapMouseButtons)
255 {
256 SendDlgItemMessage(hwndDlg, IDC_SWAP_MOUSE_BUTTONS, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
257 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight);
258 }
259 else
260 {
261 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft);
262 }
263
264 if (pButtonData->g_ClickLockEnabled)
265 {
266 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_CLICK_LOCK);
267 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
268 }
269 else
270 {
271 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK);
272 EnableWindow(hDlgCtrl, FALSE);
273 }
274
275 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED);
276 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 14));
277 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, 14 - ((pButtonData->g_DoubleClickSpeed - 200) / 50));
278
279
280 SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hIcon1);
281 pButtonData->bClicked = TRUE;
282 return TRUE;
283
284 case WM_DESTROY:
285 DestroyIcon(pButtonData->hButtonLeft);
286 DestroyIcon(pButtonData->hButtonRight);
287 DestroyIcon(pButtonData->hIcon1);
288 DestroyIcon(pButtonData->hIcon2);
289 HeapFree(GetProcessHeap(), 0, pButtonData);
290 break;
291
292 case WM_COMMAND:
293 switch(LOWORD(wParam))
294 {
295 case IDC_SWAP_MOUSE_BUTTONS:
296 lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
297 if (lResult == BST_CHECKED)
298 {
299 pButtonData->g_SwapMouseButtons = FALSE;
300 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
301 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft);
302 }
303 else if (lResult == BST_UNCHECKED)
304 {
305 pButtonData->g_SwapMouseButtons = TRUE;
306 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
307 SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight);
308 }
309 SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_SwapMouseButtons, NULL, SPIF_SENDCHANGE);
310 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
311 break;
312
313 case IDC_CHECK_CLICK_LOCK:
314 lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
315 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK);
316 if (lResult == BST_CHECKED)
317 {
318 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
319 pButtonData->g_ClickLockEnabled = FALSE;
320 EnableWindow(hDlgCtrl, FALSE);
321 }
322 else if (lResult == BST_UNCHECKED)
323 {
324 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
325 EnableWindow(hDlgCtrl, TRUE);
326 pButtonData->g_ClickLockEnabled = TRUE;
327 }
328 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
329 break;
330
331 case IDC_BUTTON_CLICK_LOCK:
332 DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_CLICK_LOCK), hwndDlg, ClickLockProc, (LPARAM)pButtonData);
333 break;
334
335 case IDC_IMAGE_DOUBLE_CLICK_SPEED:
336 if (HIWORD(wParam) == STN_DBLCLK)
337 {
338 pButtonData->bClicked = !pButtonData->bClicked;
339 SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON,
340 (LPARAM)(pButtonData->bClicked ? pButtonData->hIcon1 : pButtonData->hIcon2));
341 }
342 break;
343 }
344 break;
345
346 case WM_NOTIFY:
347 lppsn = (LPPSHNOTIFY) lParam;
348 if (lppsn->hdr.code == PSN_APPLY)
349 {
350 #if (WINVER >= 0x0500)
351 SystemParametersInfo(SPI_SETMOUSECLICKLOCK, pButtonData->g_ClickLockEnabled, NULL, SPIF_SENDCHANGE);
352 if (pButtonData->g_ClickLockEnabled)
353 SystemParametersInfo(SPI_SETMOUSECLICKLOCKTIME, pButtonData->g_ClickLockTime, NULL, SPIF_SENDCHANGE);
354 #endif
355 SetWindowLong(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
356 }
357 else if (lppsn->hdr.code == PSN_RESET)
358 {
359 /* Reset swap mouse button setting */
360 SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, SPIF_SENDCHANGE);
361
362 /* Reset double click speed setting */
363 // SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_OrigDoubleClickSpeed, NULL, SPIF_SENDCHANGE);
364 SetDoubleClickTime(pButtonData->g_OrigDoubleClickSpeed);
365 }
366 return TRUE;
367
368 case WM_HSCROLL:
369 if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED))
370 {
371 switch (LOWORD(wParam))
372 {
373 case TB_LINEUP:
374 case TB_LINEDOWN:
375 case TB_PAGEUP:
376 case TB_PAGEDOWN:
377 case TB_TOP:
378 case TB_BOTTOM:
379 case TB_ENDTRACK:
380 lResult = SendDlgItemMessage(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED, TBM_GETPOS, 0, 0);
381 pButtonData->g_DoubleClickSpeed = (14 - (INT)lResult) * 50 + 200;
382 // SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE);
383 SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
384 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
385 break;
386
387 case TB_THUMBTRACK:
388 pButtonData->g_DoubleClickSpeed = (14 - (INT)HIWORD(wParam)) * 50 + 200;
389 // SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE);
390 SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
391 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
392 break;
393 }
394 }
395 break;
396 }
397
398 return FALSE;
399 }
400
401
402 #if 0
403 static BOOL
404 ReadActiveCursorScheme(VOID)
405 {
406 HKEY hCuKey;
407 HKEY hCuCursorKey;
408 DWORD dwIndex;
409 TCHAR szValueName[MAX_PATH];
410 DWORD dwValueName;
411 TCHAR szValueData[2000];
412 DWORD dwValueData;
413 LONG dwResult;
414
415 if (RegOpenCurrentUser(KEY_READ, &hCuKey) != ERROR_SUCCESS)
416 return FALSE;
417
418 if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors"), 0, KEY_READ, &hCuCursorKey) != ERROR_SUCCESS)
419 {
420 RegCloseKey(hCuKey);
421 return FALSE;
422 }
423
424 memset(g_szArrow, 0x0, sizeof(g_szArrow));
425 memset(g_szHelp, 0x0, sizeof(g_szHelp));
426 memset(g_szAppStarting, 0x0, sizeof(g_szAppStarting));
427 memset(g_szWait, 0x0, sizeof(g_szWait));
428 memset(g_szCrosshair, 0x0, sizeof(g_szCrosshair));
429 memset(g_szIBeam, 0x0, sizeof(g_szIBeam));
430 memset(g_szNWPen, 0x0, sizeof(g_szNWPen));
431 memset(g_szNo, 0x0, sizeof(g_szNo));
432 memset(g_szSizeNS, 0x0, sizeof(g_szSizeNS));
433 memset(g_szSizeWE, 0x0, sizeof(g_szSizeWE));
434 memset(g_szSizeNWSE, 0x0, sizeof(g_szSizeNWSE));
435 memset(g_szSizeNESW, 0x0, sizeof(g_szSizeNESW));
436 memset(g_szSizeAll, 0x0, sizeof(g_szSizeAll));
437 memset(g_szUpArrow, 0x0, sizeof(g_szUpArrow));
438 memset(g_szHand, 0x0, sizeof(g_szHand));
439
440 dwIndex = 0;
441 for (;;)
442 {
443 dwValueName = sizeof(szValueName) / sizeof(TCHAR);
444 dwValueData = sizeof(szValueData) / sizeof(TCHAR);
445 dwResult = RegEnumValue(hCuCursorKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (LPBYTE)szValueData, &dwValueData);
446 if (dwResult == ERROR_NO_MORE_ITEMS)
447 break;
448
449 if (_tcsicmp(_T("Arrow"), szValueName))
450 _tcsncpy(g_szArrow, szValueData, MAX_PATH);
451 else if (_tcsicmp(_T("Help"), szValueName))
452 _tcsncpy(g_szHelp, szValueData, MAX_PATH);
453 else if (_tcsicmp(_T("AppStarting"), szValueName))
454 _tcsncpy(g_szAppStarting, szValueData, MAX_PATH);
455 else if (_tcsicmp(_T("Wait"), szValueName))
456 _tcsncpy(g_szWait, szValueData, MAX_PATH);
457 else if (_tcsicmp(_T("Crosshair"), szValueName))
458 _tcsncpy(g_szCrosshair, szValueData, MAX_PATH);
459 else if (_tcsicmp(_T("IBeam"), szValueName))
460 _tcsncpy(g_szIBeam, szValueData, MAX_PATH);
461 else if (_tcsicmp(_T("NWPen"), szValueName))
462 _tcsncpy(g_szNWPen, szValueData, MAX_PATH);
463 else if (_tcscmp(_T("No"), szValueName))
464 _tcsncpy(g_szNo, szValueData, MAX_PATH);
465 else if (_tcsicmp(_T("SizeNS"), szValueName))
466 _tcsncpy(g_szSizeNS, szValueData, MAX_PATH);
467 else if (_tcsicmp(_T("SizeWE"), szValueName))
468 _tcsncpy(g_szSizeWE, szValueData, MAX_PATH);
469 else if (_tcsicmp(_T("SizeNWSE"), szValueName))
470 _tcsncpy(g_szSizeNWSE, szValueData, MAX_PATH);
471 else if (_tcsicmp(_T("SizeNESW"), szValueName))
472 _tcsncpy(g_szSizeNESW, szValueData, MAX_PATH);
473 else if (_tcsicmp(_T("SizeAll"), szValueName))
474 _tcsncpy(g_szSizeAll, szValueData, MAX_PATH);
475 else if (_tcsicmp(_T("UpArrow"), szValueName))
476 _tcsncpy(g_szUpArrow, szValueData, MAX_PATH);
477 else if (_tcsicmp(_T("Hand"), szValueName))
478 _tcsncpy(g_szHand, szValueData, MAX_PATH);
479
480 dwIndex++;
481 }
482
483 RegCloseKey(hCuCursorKey);
484 RegCloseKey(hCuKey);
485
486 return TRUE;
487 }
488 #endif
489
490
491 static BOOL
492 EnumerateCursorSchemes(HWND hwndDlg)
493 {
494 HKEY hCuKey;
495 HKEY hCuCursorKey;
496 DWORD dwIndex;
497 TCHAR szValueName[MAX_PATH];
498 DWORD dwValueName;
499 TCHAR szSystemScheme[MAX_PATH];
500 TCHAR szValueData[2000];
501 DWORD dwValueData;
502 LONG dwResult;
503 HWND hDlgCtrl;
504 LRESULT lResult;
505 BOOL ProcessedHKLM = FALSE;
506
507 if (RegOpenCurrentUser(KEY_READ, &hCuKey) != ERROR_SUCCESS)
508 return FALSE;
509
510 if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ, &hCuCursorKey) != ERROR_SUCCESS)
511 {
512 RegCloseKey(hCuKey);
513 return FALSE;
514 }
515
516 hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME);
517 SendMessage(hDlgCtrl, CB_RESETCONTENT, 0, 0);
518 dwIndex = 0;
519
520 for (;;)
521 {
522 dwValueName = sizeof(szValueName) / sizeof(TCHAR);
523 dwValueData = sizeof(szValueData) / sizeof(TCHAR);
524 dwResult = RegEnumValue(hCuCursorKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (LPBYTE)szValueData, &dwValueData);
525
526 if (dwResult == ERROR_NO_MORE_ITEMS)
527 {
528 if(!ProcessedHKLM)
529 {
530 RegCloseKey(hCuCursorKey);
531 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
532 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cursors\\Schemes"),
533 0, KEY_READ, &hCuCursorKey);
534 if (dwResult == ERROR_SUCCESS)
535 {
536 dwIndex = 0;
537 ProcessedHKLM = TRUE;
538 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
539 continue;
540 }
541 }
542 break;
543 }
544
545 if(_tcslen(szValueData) > 0)
546 {
547 TCHAR * copy = _tcsdup(szValueData);
548 if (ProcessedHKLM)
549 {
550 _tcscat(szValueName, TEXT(" "));
551 _tcscat(szValueName, szSystemScheme);
552 }
553 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValueName);
554 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)copy);
555 }
556
557 dwIndex++;
558 }
559
560 RegCloseKey(hCuCursorKey);
561 RegCloseKey(hCuKey);
562
563 LoadString(hApplet, IDS_NONE, szSystemScheme, MAX_PATH);
564 lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szSystemScheme);
565 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)NULL);
566 SendMessage(hDlgCtrl, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
567
568 return TRUE;
569 }
570
571
572 static VOID
573 RefreshCursorList(HWND hwndDlg)
574 {
575 TCHAR szCursorName[MAX_PATH];
576 HWND hDlgCtrl;
577 LV_ITEM listItem;
578 LV_COLUMN column;
579 INT index = 0;
580
581 hDlgCtrl = GetDlgItem(hwndDlg, IDC_LISTVIEW_CURSOR);
582 (void)ListView_DeleteAllItems(hDlgCtrl);
583
584 ZeroMemory(&column, sizeof(LV_COLUMN));
585 column.mask = LVCF_SUBITEM | LVCF_WIDTH;
586 column.iSubItem = 0;
587 column.cx = 200;
588
589 (void)ListView_InsertColumn(hDlgCtrl, 0, &column);
590
591 LoadString(hApplet, IDS_ARROW, szCursorName, MAX_PATH);
592
593 ZeroMemory(&listItem, sizeof(LV_ITEM));
594 listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
595 listItem.pszText = szCursorName;
596 listItem.state = 0;
597 listItem.iImage = -1;
598 listItem.iItem = index++;
599 listItem.lParam = 0;
600
601 (void)ListView_InsertItem(hDlgCtrl, &listItem);
602
603 LoadString(hApplet, IDS_HELP, szCursorName, MAX_PATH);
604 listItem.iItem = index++;
605 (void)ListView_InsertItem(hDlgCtrl, &listItem);
606
607 LoadString(hApplet, IDS_APPSTARTING, szCursorName, MAX_PATH);
608 listItem.iItem = index++;
609 (void)ListView_InsertItem(hDlgCtrl, &listItem);
610
611 LoadString(hApplet, IDS_WAIT, szCursorName, MAX_PATH);
612 listItem.iItem = index++;
613 (void)ListView_InsertItem(hDlgCtrl, &listItem);
614
615 LoadString(hApplet, IDS_CROSSHAIR, szCursorName, MAX_PATH);
616 listItem.iItem = index++;
617 (void)ListView_InsertItem(hDlgCtrl, &listItem);
618
619 LoadString(hApplet, IDS_IBEAM, szCursorName, MAX_PATH);
620 listItem.iItem = index++;
621 (void)ListView_InsertItem(hDlgCtrl, &listItem);
622
623 LoadString(hApplet, IDS_NWPEN, szCursorName, MAX_PATH);
624 listItem.iItem = index++;
625 (void)ListView_InsertItem(hDlgCtrl, &listItem);
626
627 LoadString(hApplet, IDS_NO, szCursorName, MAX_PATH);
628 listItem.iItem = index++;
629 (void)ListView_InsertItem(hDlgCtrl, &listItem);
630
631 LoadString(hApplet, IDS_SIZENS, szCursorName, MAX_PATH);
632 listItem.iItem = index++;
633 (void)ListView_InsertItem(hDlgCtrl, &listItem);
634
635
636 LoadString(hApplet, IDS_SIZENWSE, szCursorName, MAX_PATH);
637 listItem.iItem = index++;
638 (void)ListView_InsertItem(hDlgCtrl, &listItem);
639
640 LoadString(hApplet, IDS_SIZENESW, szCursorName, MAX_PATH);
641 listItem.iItem = index++;
642 (void)ListView_InsertItem(hDlgCtrl, &listItem);
643
644 LoadString(hApplet, IDS_SIZEALL, szCursorName, MAX_PATH);
645 listItem.iItem = index++;
646 (void)ListView_InsertItem(hDlgCtrl, &listItem);
647
648 LoadString(hApplet, IDS_UPARROW, szCursorName, MAX_PATH);
649 listItem.iItem = index++;
650 (void)ListView_InsertItem(hDlgCtrl, &listItem);
651
652 LoadString(hApplet, IDS_HAND, szCursorName, MAX_PATH);
653 listItem.iItem = index++;
654 (void)ListView_InsertItem(hDlgCtrl, &listItem);
655 }
656
657
658 static BOOL
659 DeleteUserCursorScheme(TCHAR * szScheme)
660 {
661 HKEY hCuKey;
662 HKEY hCuCursorKey;
663 LONG Result;
664
665 if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS)
666 return FALSE;
667
668 if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ | KEY_SET_VALUE, &hCuCursorKey) != ERROR_SUCCESS)
669 {
670 RegCloseKey(hCuKey);
671 return FALSE;
672 }
673
674 Result = RegDeleteValue(hCuCursorKey, szScheme);
675
676 RegCloseKey(hCuCursorKey);
677 RegCloseKey(hCuKey);
678
679 return (Result == ERROR_SUCCESS);
680 }
681
682
683 static INT_PTR CALLBACK
684 SaveSchemeProc(IN HWND hwndDlg,
685 IN UINT uMsg,
686 IN WPARAM wParam,
687 IN LPARAM lParam)
688 {
689 HWND hDlgCtrl;
690 UNREFERENCED_PARAMETER(lParam);
691
692 switch(uMsg)
693 {
694 case WM_COMMAND:
695 if (LOWORD(wParam) == IDOK)
696 {
697 hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_SCHEME_NAME);
698 SendMessage(hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)g_szNewScheme);
699 EndDialog(hwndDlg, TRUE);
700 }
701 else if (LOWORD(wParam) == IDCANCEL)
702 {
703 EndDialog(hwndDlg, FALSE);
704 }
705 break;
706 }
707
708 return FALSE;
709 }
710
711
712 static BOOL
713 BrowseCursor(TCHAR * szFileName, HWND hwndDlg)
714 {
715 //FIXME load text resources from string
716 OPENFILENAME ofn;
717 static TCHAR szFilter[] = _T("Cursors\0*.ani;*.cur\0Animated Cursors\0*.ani\0Static Cursors\0*.cur\0All Files\0*.*\0\0");
718
719 ZeroMemory(&ofn, sizeof(OPENFILENAME));
720
721 ofn.lStructSize = sizeof(OPENFILENAME);
722 ofn.hwndOwner = hwndDlg;
723 ofn.lpstrFilter = szFilter;
724 ofn.nFilterIndex = 1;
725 ofn.lpstrFile = szFileName;
726 ofn.nMaxFile = MAX_PATH;
727 ofn.lpstrInitialDir = _T("%WINDIR%\\Cursors");
728 ofn.lpstrTitle = _T("Browse");
729 ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
730
731 if (GetOpenFileName(&ofn))
732 return TRUE;
733 else
734 return FALSE;
735 }
736
737
738 static VOID
739 LoadCurrentCursorScheme(LPTSTR lpName, BOOL bSystem)
740 {
741 HKEY hCursorKey;
742 TCHAR szValue[2048];
743 TCHAR szRaw[256];
744 DWORD dwValueLen;
745 LONG lError;
746 LPTSTR ptrStart, ptrEnd;
747 INT_PTR len;
748 int i;
749
750 if (lpName == NULL)
751 {
752 memset(g_szArrow, 0x0, sizeof(g_szArrow));
753 memset(g_szHelp, 0x0, sizeof(g_szHelp));
754 memset(g_szAppStarting, 0x0, sizeof(g_szAppStarting));
755 memset(g_szWait, 0x0, sizeof(g_szWait));
756 memset(g_szCrosshair, 0x0, sizeof(g_szCrosshair));
757 memset(g_szIBeam, 0x0, sizeof(g_szIBeam));
758 memset(g_szNWPen, 0x0, sizeof(g_szNWPen));
759 memset(g_szNo, 0x0, sizeof(g_szNo));
760 memset(g_szSizeNS, 0x0, sizeof(g_szSizeNS));
761 memset(g_szSizeWE, 0x0, sizeof(g_szSizeWE));
762 memset(g_szSizeNWSE, 0x0, sizeof(g_szSizeNWSE));
763 memset(g_szSizeNESW, 0x0, sizeof(g_szSizeNESW));
764 memset(g_szSizeAll, 0x0, sizeof(g_szSizeAll));
765 memset(g_szUpArrow, 0x0, sizeof(g_szUpArrow));
766 memset(g_szHand, 0x0, sizeof(g_szHand));
767 }
768 else
769 {
770 if (bSystem)
771 {
772 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
773 _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cursors\\Schemes"),
774 0, KEY_READ, &hCursorKey))
775 return;
776 }
777 else
778 {
779 if (RegOpenKeyEx(HKEY_CURRENT_USER,
780 _T("Control Panel\\Cursors\\Schemes"),
781 0, KEY_READ, &hCursorKey) != ERROR_SUCCESS)
782 return;
783 }
784
785 dwValueLen = 2048 * sizeof(TCHAR);
786 lError = RegQueryValueEx(hCursorKey, lpName, NULL, NULL, (LPBYTE)szValue, &dwValueLen);
787
788 RegCloseKey(hCursorKey);
789
790 if (lError == ERROR_SUCCESS)
791 {
792 ptrStart = szValue;
793 for (i = 0; ; i++)
794 {
795 ptrEnd = _tcschr(ptrStart, TEXT(','));
796 if (ptrEnd != NULL)
797 {
798 len = (ptrEnd - ptrStart) / sizeof(TCHAR);
799 _tcsncpy(szRaw, ptrStart, len);
800 szRaw[len] = 0;
801 }
802 else
803 {
804 _tcscpy(szRaw, ptrStart);
805 }
806
807 switch (i)
808 {
809 case 0:
810 ExpandEnvironmentStrings(szRaw, g_szArrow, MAX_PATH);
811 break;
812
813 }
814
815
816
817 if (ptrEnd == NULL)
818 break;
819
820 ptrStart = ptrEnd + 1;
821 }
822 }
823 }
824 }
825
826
827 static INT_PTR CALLBACK
828 PointerProc(IN HWND hwndDlg,
829 IN UINT uMsg,
830 IN WPARAM wParam,
831 IN LPARAM lParam)
832 {
833 LPPSHNOTIFY lppsn;
834 TCHAR buffer[MAX_PATH];
835 TCHAR szSystemScheme[MAX_PATH];
836 HWND hDlgCtrl;
837 HDC memDC;
838 HCURSOR hCursor;
839 LRESULT lResult;
840
841 switch(uMsg)
842 {
843 case WM_INITDIALOG:
844 EnumerateCursorSchemes(hwndDlg);
845 RefreshCursorList(hwndDlg);
846 /* drop shadow */
847 SystemParametersInfo(SPI_GETDROPSHADOW, 0, &g_DropShadow, 0);
848 if (g_DropShadow)
849 {
850 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_DROP_SHADOW);
851 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
852 }
853 if ((INT)wParam == IDC_LISTVIEW_CURSOR)
854 return TRUE;
855 else
856 return FALSE;
857
858 case WM_NOTIFY:
859 lppsn = (LPPSHNOTIFY) lParam;
860 if (lppsn->hdr.code == PSN_APPLY)
861 {
862 #if (WINVER >= 0x0500)
863 SystemParametersInfo(SPI_SETDROPSHADOW, 0, (PVOID)g_DropShadow, SPIF_SENDCHANGE);
864 #endif
865 SetWindowLong(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
866 return TRUE;
867 }
868 break;
869
870 case WM_COMMAND:
871 switch(HIWORD(wParam))
872 {
873 case CBN_SELENDOK:
874 {
875 BOOL bEnable;
876 LPTSTR lpName;
877
878 wParam = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);
879 if(wParam == CB_ERR)
880 break;
881 SendMessage((HWND)lParam, CB_GETLBTEXT, wParam, (LPARAM)buffer);
882 LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
883 if(_tcsstr(buffer, szSystemScheme) || wParam == 0) //avoid the default scheme can be deleted
884 bEnable = FALSE;
885 else
886 bEnable = TRUE;
887
888 /* delete button */
889 hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_DELETE_SCHEME);
890 EnableWindow(hDlgCtrl, bEnable);
891
892 lpName = (LPTSTR)SendMessage((HWND)lParam, CB_GETITEMDATA, wParam, 0);
893 LoadCurrentCursorScheme(lpName, !bEnable);
894 break;
895 }
896 }
897
898 switch (LOWORD(wParam))
899 {
900 case IDC_BUTTON_SAVEAS_SCHEME:
901 if (DialogBox(hApplet, MAKEINTRESOURCE(IDD_CURSOR_SCHEME_SAVEAS), hwndDlg, SaveSchemeProc))
902 {
903 //FIXME
904 //save cursor scheme
905 }
906 break;
907
908 case IDC_BUTTON_USE_DEFAULT_CURSOR:
909 hDlgCtrl = GetDlgItem(hwndDlg, IDC_LISTVIEW_CURSOR);
910 lResult = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);
911 if (lResult != CB_ERR)
912 {
913 if ((INT)lResult == 0)
914 memset(g_szArrow, 0x0, MAX_PATH * sizeof(TCHAR));
915 else if ((INT)lResult == 1)
916 memset(g_szHelp, 0x0, MAX_PATH * sizeof(TCHAR));
917 else if ((INT)lResult == 2)
918 memset(g_szAppStarting, 0x0, MAX_PATH * sizeof(TCHAR));
919 else if ((INT)lResult == 3)
920 memset(g_szWait, 0x0, MAX_PATH * sizeof(TCHAR));
921 else if ((INT)lResult == 4)
922 memset(g_szCrosshair, 0x0, MAX_PATH * sizeof(TCHAR));
923 else if ((INT)lResult == 5)
924 memset(g_szIBeam, 0x0, MAX_PATH * sizeof(TCHAR));
925 else if ((INT)lResult == 6)
926 memset(g_szNWPen, 0x0, MAX_PATH * sizeof(TCHAR));
927 else if ((INT)lResult == 7)
928 memset(g_szNo, 0x0, MAX_PATH * sizeof(TCHAR));
929 else if ((INT)lResult == 8)
930 memset(g_szSizeNS, 0x0, MAX_PATH * sizeof(TCHAR));
931 else if ((INT)lResult == 9)
932 memset(g_szSizeWE,0x0, MAX_PATH * sizeof(TCHAR));
933 else if ((INT)lResult == 10)
934 memset(g_szSizeNWSE, 0x0, MAX_PATH * sizeof(TCHAR));
935 else if ((INT)lResult == 11)
936 memset(g_szSizeNESW, 0x0, MAX_PATH * sizeof(TCHAR));
937 else if ((INT)lResult == 12)
938 memset(g_szSizeAll, 0x0, MAX_PATH * sizeof(TCHAR));
939 else if ((INT)lResult == 13)
940 memset(g_szUpArrow, 0x0, MAX_PATH * sizeof(TCHAR));
941 else if ((INT)lResult == 14)
942 memset(g_szHand, 0x0, MAX_PATH * sizeof(TCHAR));
943 }
944 break;
945
946 case IDC_BUTTON_BROWSE_CURSOR:
947 memset(buffer, 0x0, sizeof(buffer));
948 hDlgCtrl = GetDlgItem(hwndDlg, IDC_LISTVIEW_CURSOR);
949 lResult = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);
950 if (lResult == CB_ERR)
951 MessageBox(hwndDlg, _T("CB_ERR"), _T(""),MB_ICONERROR);
952 if (BrowseCursor(buffer, hwndDlg))
953 {
954 if ((INT)lResult == 0)
955 _tcsncpy(g_szArrow, buffer, MAX_PATH);
956 else if ((INT)lResult == 1)
957 _tcsncpy(g_szHelp, buffer, MAX_PATH);
958 else if ((INT)lResult == 2)
959 _tcsncpy(g_szAppStarting, buffer, MAX_PATH);
960 else if ((INT)lResult == 3)
961 _tcsncpy(g_szWait, buffer, MAX_PATH);
962 else if ((INT)lResult == 4)
963 _tcsncpy(g_szCrosshair, buffer, MAX_PATH);
964 else if ((INT)lResult == 5)
965 _tcsncpy(g_szIBeam, buffer, MAX_PATH);
966 else if ((INT)lResult == 6)
967 _tcsncpy(g_szNWPen, buffer, MAX_PATH);
968 else if ((INT)lResult == 7)
969 _tcsncpy(g_szNo, buffer, MAX_PATH);
970 else if ((INT)lResult == 8)
971 _tcsncpy(g_szSizeNS, buffer, MAX_PATH);
972 else if ((INT)lResult == 9)
973 _tcsncpy(g_szSizeWE, buffer, MAX_PATH);
974 else if ((INT)lResult == 10)
975 _tcsncpy(g_szSizeNWSE, buffer, MAX_PATH);
976 else if ((INT)lResult == 11)
977 _tcsncpy(g_szSizeNESW, buffer, MAX_PATH);
978 else if ((INT)lResult == 12)
979 _tcsncpy(g_szSizeAll, buffer, MAX_PATH);
980 else if ((INT)lResult == 13)
981 _tcsncpy(g_szUpArrow, buffer, MAX_PATH);
982 else if ((INT)lResult == 14)
983 _tcsncpy(g_szHand, buffer, MAX_PATH);
984
985 //FIXME
986 //clear screen
987
988 hDlgCtrl = GetDlgItem(hwndDlg, IDC_IMAGE_CURRENT_CURSOR);
989 memDC = GetDC(hDlgCtrl);
990 hCursor = (HCURSOR) LoadImage(NULL, buffer, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE | LR_SHARED);
991 if (hCursor)
992 {
993 DrawIcon(memDC, 10, 10, (HICON)hCursor);
994 DestroyCursor(hCursor);
995 }
996 ReleaseDC(hDlgCtrl, memDC);
997 }
998 break;
999
1000 case IDC_BUTTON_DELETE_SCHEME:
1001 hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME);
1002 wParam = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);
1003 if(wParam == CB_ERR)
1004 break;
1005 SendMessage(hDlgCtrl, CB_GETLBTEXT, wParam, (LPARAM)buffer);
1006 if (DeleteUserCursorScheme(buffer))
1007 {
1008 SendMessage(hDlgCtrl, CB_DELETESTRING, wParam, 0);
1009 SendMessage(hDlgCtrl, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
1010 }
1011 break;
1012
1013 case IDC_CHECK_DROP_SHADOW:
1014 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_DROP_SHADOW))
1015 {
1016 g_DropShadow = 0;
1017 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
1018 }
1019 else
1020 {
1021 g_DropShadow = 1;
1022 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1023 }
1024 }
1025 break;
1026 }
1027
1028 return FALSE;
1029 }
1030
1031
1032 static INT_PTR CALLBACK
1033 OptionProc(IN HWND hwndDlg,
1034 IN UINT uMsg,
1035 IN WPARAM wParam,
1036 IN LPARAM lParam)
1037 {
1038 HWND hDlgCtrl;
1039 LPPSHNOTIFY lppsn;
1040 LRESULT lResult;
1041
1042 switch(uMsg)
1043 {
1044 case WM_INITDIALOG:
1045 if (InitializeMouse())
1046 {
1047 /* set mouse sensitivity */
1048 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_MOUSE_SENSITIVITY);
1049 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 19));
1050 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)g_MouseSensitivity-1);
1051
1052 if (g_MouseSpeed)
1053 {
1054 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_POINTER_PRECISION);
1055 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1056 }
1057
1058 if (g_SnapToDefaultButton)
1059 {
1060 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_SNAP_TO);
1061 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1062 }
1063
1064 /* set mouse trail */
1065 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL);
1066 SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 5));
1067 if (!g_MouseTrails)
1068 EnableWindow(hDlgCtrl, FALSE);
1069 else
1070 SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)g_MouseTrails-2);
1071
1072 if (g_ShowPointer)
1073 {
1074 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_SHOW_POINTER);
1075 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1076 }
1077
1078 if (g_HidePointer)
1079 {
1080 hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_HIDE_POINTER);
1081 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1082 }
1083 }
1084 break;
1085
1086 case WM_COMMAND:
1087 switch(LOWORD(wParam))
1088 {
1089 case IDC_CHECK_POINTER_PRECISION:
1090 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_POINTER_PRECISION))
1091 {
1092 g_MouseSpeed = 0;
1093 g_MouseThreshold1 = 0;
1094 g_MouseThreshold2 = 0;
1095 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
1096 }
1097 else
1098 {
1099 g_MouseSpeed = 1;
1100 g_MouseThreshold1 = 6;
1101 g_MouseThreshold2 = 10;
1102 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1103 }
1104 break;
1105
1106 case IDC_CHECK_SNAP_TO:
1107 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_SNAP_TO))
1108 {
1109 g_SnapToDefaultButton = 0;
1110 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
1111 }
1112 else
1113 {
1114 g_SnapToDefaultButton = 1;
1115 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1116 }
1117 break;
1118
1119 case IDC_CHECK_POINTER_TRAIL:
1120 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL);
1121 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_POINTER_TRAIL))
1122 {
1123 g_MouseTrails = 0;
1124 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
1125 EnableWindow(hDlgCtrl, FALSE);
1126 }
1127 else
1128 {
1129 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1130 EnableWindow(hDlgCtrl, TRUE);
1131 g_MouseTrails = (ULONG) SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) + 2;
1132 }
1133 break;
1134
1135 case IDC_CHECK_SHOW_POINTER:
1136 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_SHOW_POINTER))
1137 {
1138 g_ShowPointer = 0;
1139 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
1140 }
1141 else
1142 {
1143 g_ShowPointer = 1;
1144 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1145 }
1146 break;
1147
1148 case IDC_CHECK_HIDE_POINTER:
1149 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_HIDE_POINTER))
1150 {
1151 g_HidePointer = 0;
1152 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
1153 }
1154 else
1155 {
1156 g_HidePointer = 1;
1157 SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1158 }
1159 break;
1160 }
1161 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1162 break;
1163
1164 case WM_NOTIFY:
1165 lppsn = (LPPSHNOTIFY) lParam;
1166 if (lppsn->hdr.code == PSN_APPLY)
1167 {
1168 /* set snap to default button */
1169 SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, g_SnapToDefaultButton, 0, SPIF_SENDCHANGE);
1170
1171 /* set mouse trails */
1172 if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_POINTER_TRAIL))
1173 {
1174 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL);
1175 lResult = SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0);
1176 }
1177 else
1178 {
1179 lResult = 0;
1180 }
1181
1182 SystemParametersInfo(SPI_SETMOUSETRAILS, (UINT) lResult, 0, SPIF_SENDCHANGE);
1183
1184 //FIXME
1185 //pointer precision
1186 //SPI_SETMOUSE?
1187
1188 /* calc pos and set mouse sensitivity */
1189 hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_MOUSE_SENSITIVITY);
1190 lResult = SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) + 1;
1191 SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)g_MouseSensitivity, SPIF_SENDCHANGE);
1192
1193 /* hide pointer while typing */
1194 SystemParametersInfo(SPI_SETMOUSEVANISH, 0, (PVOID)g_HidePointer, SPIF_SENDCHANGE);
1195
1196 /* show pointer with Ctrl-Key */
1197 SystemParametersInfo(SPI_SETMOUSESONAR, 0, (PVOID)g_ShowPointer, SPIF_SENDCHANGE);
1198 SetWindowLong(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
1199 return TRUE;
1200 }
1201 break;
1202
1203 case WM_HSCROLL:
1204 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1205 break;
1206 }
1207
1208 return FALSE;
1209 }
1210
1211
1212 static VOID
1213 ShowDialogWheelControls(HWND hwndDlg, UINT uWheelScrollLines, BOOL bInit)
1214 {
1215 HWND hDlgCtrl;
1216
1217 if (uWheelScrollLines != WHEEL_PAGESCROLL)
1218 {
1219 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_LINES);
1220 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1221
1222 hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES);
1223 EnableWindow(hDlgCtrl, TRUE);
1224
1225 hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES);
1226 EnableWindow(hDlgCtrl, TRUE);
1227
1228 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_PAGE);
1229 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
1230 }
1231 else
1232 {
1233 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_LINES);
1234 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
1235
1236 hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES);
1237 EnableWindow(hDlgCtrl, FALSE);
1238
1239 hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES);
1240 EnableWindow(hDlgCtrl, FALSE);
1241
1242 hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_PAGE);
1243 SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
1244
1245 /* Set the default scroll lines value */
1246 if (bInit == TRUE)
1247 SetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, DEFAULT_WHEEL_SCROLL_LINES, FALSE);
1248 }
1249 }
1250
1251
1252 static INT_PTR CALLBACK
1253 WheelProc(IN HWND hwndDlg,
1254 IN UINT uMsg,
1255 IN WPARAM wParam,
1256 IN LPARAM lParam)
1257 {
1258 LPPSHNOTIFY lppsn;
1259 PWHEEL_DATA pWheelData;
1260
1261 pWheelData = (PWHEEL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
1262
1263 switch (uMsg)
1264 {
1265 case WM_INITDIALOG:
1266 pWheelData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WHEEL_DATA));
1267 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pWheelData);
1268
1269 /* Get wheel scroll lines */
1270 if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &pWheelData->uWheelScrollLines, 0))
1271 {
1272 pWheelData->uWheelScrollLines = DEFAULT_WHEEL_SCROLL_LINES;
1273 }
1274
1275 ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, TRUE);
1276 SendDlgItemMessage(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES, UDM_SETRANGE, 0, MAKELONG((short)100, (short)0));
1277 if (pWheelData->uWheelScrollLines != WHEEL_PAGESCROLL)
1278 {
1279 SetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, pWheelData->uWheelScrollLines, FALSE);
1280 }
1281 return TRUE;
1282
1283 case WM_DESTROY:
1284 HeapFree(GetProcessHeap(), 0, pWheelData);
1285 break;
1286
1287 case WM_COMMAND:
1288 switch (LOWORD(wParam))
1289 {
1290 case IDC_RADIO_WHEEL_SCROLL_LINES:
1291 pWheelData->uWheelScrollLines = GetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, NULL, FALSE);
1292 ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, FALSE);
1293 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1294 break;
1295
1296 case IDC_RADIO_WHEEL_SCROLL_PAGE:
1297 pWheelData->uWheelScrollLines = WHEEL_PAGESCROLL;
1298 ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, FALSE);
1299 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1300 break;
1301
1302 case IDC_EDIT_WHEEL_SCROLL_LINES:
1303 if (pWheelData && HIWORD(wParam) == EN_CHANGE)
1304 {
1305 pWheelData->uWheelScrollLines = GetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, NULL, FALSE);
1306 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1307 }
1308 break;
1309 }
1310 break;
1311
1312 case WM_NOTIFY:
1313 lppsn = (LPPSHNOTIFY)lParam;
1314 if (lppsn->hdr.code == PSN_APPLY)
1315 {
1316 SystemParametersInfo(SPI_SETWHEELSCROLLLINES, pWheelData->uWheelScrollLines,
1317 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
1318 return TRUE;
1319 }
1320 break;
1321 }
1322
1323 return FALSE;
1324 }
1325
1326
1327 LONG APIENTRY
1328 MouseApplet(HWND hwnd, UINT uMsg, LONG lParam1, LONG lParam2)
1329 {
1330 PROPSHEETPAGE psp[5];
1331 PROPSHEETHEADER psh;
1332 TCHAR Caption[256];
1333
1334 UNREFERENCED_PARAMETER(lParam1);
1335 UNREFERENCED_PARAMETER(lParam2);
1336 UNREFERENCED_PARAMETER(uMsg);
1337 UNREFERENCED_PARAMETER(hwnd);
1338
1339 LoadString(hApplet, IDS_CPLNAME_1, Caption, sizeof(Caption) / sizeof(TCHAR));
1340
1341 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
1342 psh.dwSize = sizeof(PROPSHEETHEADER);
1343 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
1344 psh.hwndParent = NULL;
1345 psh.hInstance = hApplet;
1346 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON_1));
1347 psh.pszCaption = Caption;
1348 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
1349 psh.nStartPage = 0;
1350 psh.ppsp = psp;
1351
1352 InitPropSheetPage(&psp[0], IDD_PAGE_BUTTON, ButtonProc);
1353 InitPropSheetPage(&psp[1], IDD_PAGE_POINTER, PointerProc);
1354 InitPropSheetPage(&psp[2], IDD_PAGE_OPTION, OptionProc);
1355 InitPropSheetPage(&psp[3], IDD_PAGE_WHEEL, WheelProc);
1356 InitPropSheetPage(&psp[4], IDD_HARDWARE, MouseHardwareProc);
1357 return (LONG)(PropertySheet(&psh) != -1);
1358 }
1359
1360 /* EOF */