3 * Copyright (C) 2004, 2007 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * PROJECT: ReactOS Main Control Panel
21 * FILE: dll/cpl/main/keyboard.c
22 * PURPOSE: Keyboard Control Panel
23 * PROGRAMMER: Eric Kohl
28 #define ID_BLINK_TIMER 345
30 typedef struct _SPEED_DATA
33 INT nOrigKeyboardDelay
;
34 DWORD dwKeyboardSpeed
;
35 DWORD dwOrigKeyboardSpeed
;
37 UINT uOrigCaretBlinkTime
;
40 } SPEED_DATA
, *PSPEED_DATA
;
42 /* Property page dialog callback */
43 static INT_PTR CALLBACK
44 KeyboardSpeedProc(IN HWND hwndDlg
,
49 PSPEED_DATA pSpeedData
;
51 pSpeedData
= (PSPEED_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
56 pSpeedData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SPEED_DATA
));
57 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSpeedData
);
59 /* Get current keyboard delay */
60 if (!SystemParametersInfo(SPI_GETKEYBOARDDELAY
,
62 &pSpeedData
->nKeyboardDelay
,
65 pSpeedData
->nKeyboardDelay
= 2;
68 pSpeedData
->nOrigKeyboardDelay
= pSpeedData
->nKeyboardDelay
;
70 /* Get current keyboard delay */
71 if (!SystemParametersInfo(SPI_GETKEYBOARDSPEED
,
73 &pSpeedData
->dwKeyboardSpeed
,
76 pSpeedData
->dwKeyboardSpeed
= 31;
79 pSpeedData
->dwOrigKeyboardSpeed
= pSpeedData
->dwKeyboardSpeed
;
81 pSpeedData
->fShowCursor
= TRUE
;
82 GetWindowRect(GetDlgItem(hwndDlg
, IDC_TEXT_CURSOR_BLINK
), &pSpeedData
->rcCursor
);
83 ScreenToClient(hwndDlg
, (LPPOINT
)&pSpeedData
->rcCursor
.left
);
84 ScreenToClient(hwndDlg
, (LPPOINT
)&pSpeedData
->rcCursor
.right
);
86 /* Get the caret blink time and save its original value */
87 pSpeedData
->uOrigCaretBlinkTime
= GetCaretBlinkTime();
88 pSpeedData
->uCaretBlinkTime
= pSpeedData
->uOrigCaretBlinkTime
;
90 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
, TBM_SETRANGE
, (WPARAM
)TRUE
, (LPARAM
)MAKELONG(0, 3));
91 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)(3 - pSpeedData
->nKeyboardDelay
));
93 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_RATE
, TBM_SETRANGE
, (WPARAM
)TRUE
, (LPARAM
)MAKELONG(0, 31));
94 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_RATE
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)pSpeedData
->dwKeyboardSpeed
);
96 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
, TBM_SETRANGE
, (WPARAM
)TRUE
, (LPARAM
)MAKELONG(0, 10));
97 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)(12 - (pSpeedData
->uCaretBlinkTime
/ 100)));
99 /* Start the blink timer */
100 SetTimer(hwndDlg
, ID_BLINK_TIMER
, pSpeedData
->uCaretBlinkTime
, NULL
);
104 if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
))
106 switch (LOWORD(wParam
))
115 pSpeedData
->nKeyboardDelay
= 3 - (INT
)SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
, TBM_GETPOS
, 0, 0);
116 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
117 pSpeedData
->nKeyboardDelay
,
120 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
124 pSpeedData
->nKeyboardDelay
= 3 - (INT
)HIWORD(wParam
);
125 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
126 pSpeedData
->nKeyboardDelay
,
129 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
133 else if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_SLIDER_REPEAT_RATE
))
135 switch (LOWORD(wParam
))
144 pSpeedData
->dwKeyboardSpeed
= (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_RATE
, TBM_GETPOS
, 0, 0);
145 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
146 pSpeedData
->dwKeyboardSpeed
,
149 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
153 pSpeedData
->dwKeyboardSpeed
= (DWORD
)HIWORD(wParam
);
154 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
155 pSpeedData
->dwKeyboardSpeed
,
158 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
162 else if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
))
164 switch (LOWORD(wParam
))
173 pSpeedData
->uCaretBlinkTime
= (12 - (UINT
)SendDlgItemMessage(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
, TBM_GETPOS
, 0, 0)) * 100;
174 KillTimer(hwndDlg
, ID_BLINK_TIMER
);
175 SetTimer(hwndDlg
, ID_BLINK_TIMER
, pSpeedData
->uCaretBlinkTime
, NULL
);
176 SetCaretBlinkTime(pSpeedData
->uCaretBlinkTime
);
177 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
181 pSpeedData
->uCaretBlinkTime
= (12 - (UINT
)HIWORD(wParam
)) * 100;
182 KillTimer(hwndDlg
, ID_BLINK_TIMER
);
183 SetTimer(hwndDlg
, ID_BLINK_TIMER
, pSpeedData
->uCaretBlinkTime
, NULL
);
184 SetCaretBlinkTime(pSpeedData
->uCaretBlinkTime
);
185 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
192 if (wParam
== ID_BLINK_TIMER
)
194 if (pSpeedData
->fShowCursor
)
196 HDC hDC
= GetDC(hwndDlg
);
197 HBRUSH hBrush
= GetSysColorBrush(COLOR_BTNTEXT
);
198 FillRect(hDC
, &pSpeedData
->rcCursor
, hBrush
);
199 DeleteObject(hBrush
);
200 ReleaseDC(hwndDlg
, hDC
);
204 InvalidateRect(hwndDlg
, &pSpeedData
->rcCursor
, TRUE
);
207 pSpeedData
->fShowCursor
= !pSpeedData
->fShowCursor
;
213 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
218 /* Set the new keyboard settings */
219 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
220 pSpeedData
->nKeyboardDelay
,
223 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
224 pSpeedData
->dwKeyboardSpeed
,
226 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
);
230 /* Restore the original settings */
231 SetCaretBlinkTime(pSpeedData
->uOrigCaretBlinkTime
);
232 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
233 pSpeedData
->nOrigKeyboardDelay
,
236 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
237 pSpeedData
->dwOrigKeyboardSpeed
,
249 KillTimer(hwndDlg
, ID_BLINK_TIMER
);
250 HeapFree(GetProcessHeap(), 0, pSpeedData
);
258 /* Property page dialog callback */
259 static INT_PTR CALLBACK
260 KeybHardwareProc(IN HWND hwndDlg
,
266 Guids
[0] = GUID_DEVCLASS_KEYBOARD
;
268 UNREFERENCED_PARAMETER(lParam
);
269 UNREFERENCED_PARAMETER(wParam
);
274 /* Create the hardware page */
275 DeviceCreateHardwarePageEx(hwndDlg
,
277 sizeof(Guids
) / sizeof(Guids
[0]),
286 PropSheetProc(HWND hwndDlg
, UINT uMsg
, LPARAM lParam
)
288 // NOTE: This callback is needed to set large icon correctly.
292 case PSCB_INITIALIZED
:
294 hIcon
= LoadIconW(hApplet
, MAKEINTRESOURCEW(IDC_CPLICON_2
));
295 SendMessageW(hwndDlg
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
303 KeyboardApplet(HWND hwnd
, UINT uMsg
, LPARAM wParam
, LPARAM lParam
)
305 HPROPSHEETPAGE hpsp
[MAX_CPL_PAGES
];
308 TCHAR szCaption
[256];
311 UNREFERENCED_PARAMETER(lParam
);
312 UNREFERENCED_PARAMETER(wParam
);
313 UNREFERENCED_PARAMETER(uMsg
);
314 UNREFERENCED_PARAMETER(hwnd
);
316 LoadString(hApplet
, IDS_CPLNAME_2
, szCaption
, sizeof(szCaption
) / sizeof(TCHAR
));
318 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
319 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
320 psh
.dwFlags
= PSH_PROPTITLE
| PSH_USEICONID
| PSH_USECALLBACK
;
321 psh
.hwndParent
= hwnd
;
322 psh
.hInstance
= hApplet
;
323 psh
.pszIcon
= MAKEINTRESOURCE(IDC_CPLICON_2
);
324 psh
.pszCaption
= szCaption
;
327 psh
.pfnCallback
= PropSheetProc
;
329 /* Load additional pages provided by shell extensions */
330 hpsxa
= SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE
, REGSTR_PATH_CONTROLSFOLDER
TEXT("\\Keyboard"), MAX_CPL_PAGES
- psh
.nPages
);
332 /* NOTE: The speed page (CPLPAGE_KEYBOARD_SPEED) cannot be replaced by
333 shell extensions since Win2k! */
334 InitPropSheetPage(&psh
, IDD_KEYBSPEED
, KeyboardSpeedProc
);
335 InitPropSheetPage(&psh
, IDD_HARDWARE
, KeybHardwareProc
);
338 SHAddFromPropSheetExtArray(hpsxa
, PropSheetAddPage
, (LPARAM
)&psh
);
340 ret
= (LONG
)(PropertySheet(&psh
) != -1);
343 SHDestroyPropSheetExtArray(hpsxa
);