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.
19 /* $Id: keyboard.c 54535 2011-11-29 14:55:58Z dgorbachev $
21 * PROJECT: ReactOS Main Control Panel
22 * FILE: dll/cpl/main/keyboard.c
23 * PURPOSE: Keyboard Control Panel
24 * PROGRAMMER: Eric Kohl
29 #define ID_BLINK_TIMER 345
31 typedef struct _SPEED_DATA
34 INT nOrigKeyboardDelay
;
35 DWORD dwKeyboardSpeed
;
36 DWORD dwOrigKeyboardSpeed
;
38 UINT uOrigCaretBlinkTime
;
41 } SPEED_DATA
, *PSPEED_DATA
;
43 /* Property page dialog callback */
44 static INT_PTR CALLBACK
45 KeyboardSpeedProc(IN HWND hwndDlg
,
50 PSPEED_DATA pSpeedData
;
52 pSpeedData
= (PSPEED_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
57 pSpeedData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SPEED_DATA
));
58 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSpeedData
);
60 /* Get current keyboard delay */
61 if (!SystemParametersInfo(SPI_GETKEYBOARDDELAY
,
63 &pSpeedData
->nKeyboardDelay
,
66 pSpeedData
->nKeyboardDelay
= 2;
69 pSpeedData
->nOrigKeyboardDelay
= pSpeedData
->nKeyboardDelay
;
71 /* Get current keyboard delay */
72 if (!SystemParametersInfo(SPI_GETKEYBOARDSPEED
,
74 &pSpeedData
->dwKeyboardSpeed
,
77 pSpeedData
->dwKeyboardSpeed
= 31;
80 pSpeedData
->dwOrigKeyboardSpeed
= pSpeedData
->dwKeyboardSpeed
;
82 pSpeedData
->fShowCursor
= TRUE
;
83 GetWindowRect(GetDlgItem(hwndDlg
, IDC_TEXT_CURSOR_BLINK
), &pSpeedData
->rcCursor
);
84 ScreenToClient(hwndDlg
, (LPPOINT
)&pSpeedData
->rcCursor
.left
);
85 ScreenToClient(hwndDlg
, (LPPOINT
)&pSpeedData
->rcCursor
.right
);
87 /* Get the caret blink time and save its original value */
88 pSpeedData
->uOrigCaretBlinkTime
= GetCaretBlinkTime();
89 pSpeedData
->uCaretBlinkTime
= pSpeedData
->uOrigCaretBlinkTime
;
91 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
, TBM_SETRANGE
, (WPARAM
)TRUE
, (LPARAM
)MAKELONG(0, 3));
92 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)(3 - pSpeedData
->nKeyboardDelay
));
94 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_RATE
, TBM_SETRANGE
, (WPARAM
)TRUE
, (LPARAM
)MAKELONG(0, 31));
95 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_RATE
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)pSpeedData
->dwKeyboardSpeed
);
97 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
, TBM_SETRANGE
, (WPARAM
)TRUE
, (LPARAM
)MAKELONG(0, 10));
98 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)(12 - (pSpeedData
->uCaretBlinkTime
/ 100)));
100 /* Start the blink timer */
101 SetTimer(hwndDlg
, ID_BLINK_TIMER
, pSpeedData
->uCaretBlinkTime
, NULL
);
105 if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
))
107 switch (LOWORD(wParam
))
116 pSpeedData
->nKeyboardDelay
= 3 - (INT
)SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
, TBM_GETPOS
, 0, 0);
117 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
118 pSpeedData
->nKeyboardDelay
,
121 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
125 pSpeedData
->nKeyboardDelay
= 3 - (INT
)HIWORD(wParam
);
126 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
127 pSpeedData
->nKeyboardDelay
,
130 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
134 else if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_SLIDER_REPEAT_RATE
))
136 switch (LOWORD(wParam
))
145 pSpeedData
->dwKeyboardSpeed
= (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_RATE
, TBM_GETPOS
, 0, 0);
146 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
147 pSpeedData
->dwKeyboardSpeed
,
150 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
154 pSpeedData
->dwKeyboardSpeed
= (DWORD
)HIWORD(wParam
);
155 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
156 pSpeedData
->dwKeyboardSpeed
,
159 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
163 else if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
))
165 switch (LOWORD(wParam
))
174 pSpeedData
->uCaretBlinkTime
= (12 - (UINT
)SendDlgItemMessage(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
, TBM_GETPOS
, 0, 0)) * 100;
175 KillTimer(hwndDlg
, ID_BLINK_TIMER
);
176 SetTimer(hwndDlg
, ID_BLINK_TIMER
, pSpeedData
->uCaretBlinkTime
, NULL
);
177 SetCaretBlinkTime(pSpeedData
->uCaretBlinkTime
);
178 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
182 pSpeedData
->uCaretBlinkTime
= (12 - (UINT
)HIWORD(wParam
)) * 100;
183 KillTimer(hwndDlg
, ID_BLINK_TIMER
);
184 SetTimer(hwndDlg
, ID_BLINK_TIMER
, pSpeedData
->uCaretBlinkTime
, NULL
);
185 SetCaretBlinkTime(pSpeedData
->uCaretBlinkTime
);
186 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
193 if (wParam
== ID_BLINK_TIMER
)
195 if (pSpeedData
->fShowCursor
)
197 HDC hDC
= GetDC(hwndDlg
);
198 HBRUSH hBrush
= GetSysColorBrush(COLOR_BTNTEXT
);
199 FillRect(hDC
, &pSpeedData
->rcCursor
, hBrush
);
200 DeleteObject(hBrush
);
201 ReleaseDC(hwndDlg
, hDC
);
205 InvalidateRect(hwndDlg
, &pSpeedData
->rcCursor
, TRUE
);
208 pSpeedData
->fShowCursor
= !pSpeedData
->fShowCursor
;
214 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
219 /* Set the new keyboard settings */
220 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
221 pSpeedData
->nKeyboardDelay
,
224 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
225 pSpeedData
->dwKeyboardSpeed
,
227 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
);
231 /* Restore the original settings */
232 SetCaretBlinkTime(pSpeedData
->uOrigCaretBlinkTime
);
233 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
234 pSpeedData
->nOrigKeyboardDelay
,
237 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
238 pSpeedData
->dwOrigKeyboardSpeed
,
250 KillTimer(hwndDlg
, ID_BLINK_TIMER
);
251 HeapFree(GetProcessHeap(), 0, pSpeedData
);
259 /* Property page dialog callback */
260 static INT_PTR CALLBACK
261 KeybHardwareProc(IN HWND hwndDlg
,
267 Guids
[0] = GUID_DEVCLASS_KEYBOARD
;
269 UNREFERENCED_PARAMETER(lParam
);
270 UNREFERENCED_PARAMETER(wParam
);
275 /* Create the hardware page */
276 DeviceCreateHardwarePageEx(hwndDlg
,
278 sizeof(Guids
) / sizeof(Guids
[0]),
288 KeyboardApplet(HWND hwnd
, UINT uMsg
, LPARAM wParam
, LPARAM lParam
)
290 HPROPSHEETPAGE hpsp
[MAX_CPL_PAGES
];
293 TCHAR szCaption
[256];
296 UNREFERENCED_PARAMETER(lParam
);
297 UNREFERENCED_PARAMETER(wParam
);
298 UNREFERENCED_PARAMETER(uMsg
);
299 UNREFERENCED_PARAMETER(hwnd
);
301 LoadString(hApplet
, IDS_CPLNAME_2
, szCaption
, sizeof(szCaption
) / sizeof(TCHAR
));
303 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
304 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
305 psh
.dwFlags
= PSH_PROPTITLE
;
306 psh
.hwndParent
= hwnd
;
307 psh
.hInstance
= hApplet
;
308 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDC_CPLICON_2
));
309 psh
.pszCaption
= szCaption
;
313 /* Load additional pages provided by shell extensions */
314 hpsxa
= SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE
, REGSTR_PATH_CONTROLSFOLDER
TEXT("\\Keyboard"), MAX_CPL_PAGES
- psh
.nPages
);
316 /* NOTE: The speed page (CPLPAGE_KEYBOARD_SPEED) cannot be replaced by
317 shell extensions since Win2k! */
318 InitPropSheetPage(&psh
, IDD_KEYBSPEED
, KeyboardSpeedProc
);
319 InitPropSheetPage(&psh
, IDD_HARDWARE
, KeybHardwareProc
);
322 SHAddFromPropSheetExtArray(hpsxa
, PropSheetAddPage
, (LPARAM
)&psh
);
324 ret
= (LONG
)(PropertySheet(&psh
) != -1);
327 SHDestroyPropSheetExtArray(hpsxa
);