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