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.
21 * PROJECT: ReactOS Main Control Panel
22 * FILE: lib/cpl/main/keyboard.c
23 * PURPOSE: Keyboard Control Panel
24 * PROGRAMMER: Eric Kohl
38 #define ID_BLINK_TIMER 345
40 typedef struct _SPEED_DATA
43 INT nOrigKeyboardDelay
;
44 DWORD dwKeyboardSpeed
;
45 DWORD dwOrigKeyboardSpeed
;
47 UINT uOrigCaretBlinkTime
;
50 } SPEED_DATA
, *PSPEED_DATA
;
52 /* Property page dialog callback */
53 static INT_PTR CALLBACK
54 KeyboardSpeedProc(IN HWND hwndDlg
,
59 PSPEED_DATA pSpeedData
;
61 pSpeedData
= (PSPEED_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
66 pSpeedData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(SPEED_DATA
));
67 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSpeedData
);
69 /* Get current keyboard delay */
70 if (!SystemParametersInfo(SPI_GETKEYBOARDDELAY
,
72 &pSpeedData
->nKeyboardDelay
,
75 pSpeedData
->nKeyboardDelay
= 2;
78 pSpeedData
->nOrigKeyboardDelay
= pSpeedData
->nKeyboardDelay
;
80 /* Get current keyboard delay */
81 if (!SystemParametersInfo(SPI_GETKEYBOARDSPEED
,
83 &pSpeedData
->dwKeyboardSpeed
,
86 pSpeedData
->dwKeyboardSpeed
= 31;
89 pSpeedData
->dwOrigKeyboardSpeed
= pSpeedData
->dwKeyboardSpeed
;
91 pSpeedData
->fShowCursor
= TRUE
;
92 GetWindowRect(GetDlgItem(hwndDlg
, IDC_TEXT_CURSOR_BLINK
), &pSpeedData
->rcCursor
);
93 ScreenToClient(hwndDlg
, (LPPOINT
)&pSpeedData
->rcCursor
.left
);
94 ScreenToClient(hwndDlg
, (LPPOINT
)&pSpeedData
->rcCursor
.right
);
96 /* Get the caret blink time and save its original value */
97 pSpeedData
->uOrigCaretBlinkTime
= GetCaretBlinkTime();
98 pSpeedData
->uCaretBlinkTime
= pSpeedData
->uOrigCaretBlinkTime
;
100 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
, TBM_SETRANGE
, (WPARAM
)TRUE
, (LPARAM
)MAKELONG(0, 3));
101 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)(3 - pSpeedData
->nKeyboardDelay
));
103 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_RATE
, TBM_SETRANGE
, (WPARAM
)TRUE
, (LPARAM
)MAKELONG(0, 31));
104 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_RATE
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)pSpeedData
->dwKeyboardSpeed
);
106 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
, TBM_SETRANGE
, (WPARAM
)TRUE
, (LPARAM
)MAKELONG(0, 10));
107 SendDlgItemMessage(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
, TBM_SETPOS
, (WPARAM
)TRUE
, (LPARAM
)(12 - (pSpeedData
->uCaretBlinkTime
/ 100)));
109 /* Start the blink timer */
110 SetTimer(hwndDlg
, ID_BLINK_TIMER
, pSpeedData
->uCaretBlinkTime
, NULL
);
114 if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
))
116 switch (LOWORD(wParam
))
125 pSpeedData
->nKeyboardDelay
= 3 - (INT
)SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_DELAY
, TBM_GETPOS
, 0, 0);
126 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
127 pSpeedData
->nKeyboardDelay
,
130 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
134 pSpeedData
->nKeyboardDelay
= 3 - (INT
)HIWORD(wParam
);
135 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
136 pSpeedData
->nKeyboardDelay
,
139 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
143 else if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_SLIDER_REPEAT_RATE
))
145 switch (LOWORD(wParam
))
154 pSpeedData
->dwKeyboardSpeed
= (DWORD
)SendDlgItemMessage(hwndDlg
, IDC_SLIDER_REPEAT_RATE
, TBM_GETPOS
, 0, 0);
155 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
156 pSpeedData
->dwKeyboardSpeed
,
159 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
163 pSpeedData
->dwKeyboardSpeed
= (DWORD
)HIWORD(wParam
);
164 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
165 pSpeedData
->dwKeyboardSpeed
,
168 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
172 else if ((HWND
)lParam
== GetDlgItem(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
))
174 switch (LOWORD(wParam
))
183 pSpeedData
->uCaretBlinkTime
= (12 - (UINT
)SendDlgItemMessage(hwndDlg
, IDC_SLIDER_CURSOR_BLINK
, TBM_GETPOS
, 0, 0)) * 100;
184 KillTimer(hwndDlg
, ID_BLINK_TIMER
);
185 SetTimer(hwndDlg
, ID_BLINK_TIMER
, pSpeedData
->uCaretBlinkTime
, NULL
);
186 SetCaretBlinkTime(pSpeedData
->uCaretBlinkTime
);
187 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
191 pSpeedData
->uCaretBlinkTime
= (12 - (UINT
)HIWORD(wParam
)) * 100;
192 KillTimer(hwndDlg
, ID_BLINK_TIMER
);
193 SetTimer(hwndDlg
, ID_BLINK_TIMER
, pSpeedData
->uCaretBlinkTime
, NULL
);
194 SetCaretBlinkTime(pSpeedData
->uCaretBlinkTime
);
195 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
202 if (wParam
== ID_BLINK_TIMER
)
204 if (pSpeedData
->fShowCursor
)
206 HDC hDC
= GetDC(hwndDlg
);
207 HBRUSH hBrush
= GetSysColorBrush(COLOR_BTNTEXT
);
208 FillRect(hDC
, &pSpeedData
->rcCursor
, hBrush
);
209 DeleteObject(hBrush
);
210 ReleaseDC(hwndDlg
, hDC
);
214 InvalidateRect(hwndDlg
, &pSpeedData
->rcCursor
, TRUE
);
217 pSpeedData
->fShowCursor
= !pSpeedData
->fShowCursor
;
223 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
228 /* Set the new keyboard settings */
229 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
230 pSpeedData
->nKeyboardDelay
,
233 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
234 pSpeedData
->dwKeyboardSpeed
,
236 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
);
240 /* Restore the original settings */
241 SetCaretBlinkTime(pSpeedData
->uOrigCaretBlinkTime
);
242 SystemParametersInfo(SPI_SETKEYBOARDDELAY
,
243 pSpeedData
->nOrigKeyboardDelay
,
246 SystemParametersInfo(SPI_SETKEYBOARDSPEED
,
247 pSpeedData
->dwOrigKeyboardSpeed
,
259 KillTimer(hwndDlg
, ID_BLINK_TIMER
);
260 HeapFree(GetProcessHeap(), 0, pSpeedData
);
268 /* Property page dialog callback */
269 static INT_PTR CALLBACK
270 KeybHardwareProc(IN HWND hwndDlg
,
276 Guids
[0] = GUID_DEVCLASS_KEYBOARD
;
278 UNREFERENCED_PARAMETER(lParam
);
279 UNREFERENCED_PARAMETER(wParam
);
284 /* Create the hardware page */
285 DeviceCreateHardwarePageEx(hwndDlg
,
287 sizeof(Guids
) / sizeof(Guids
[0]),
297 KeyboardApplet(HWND hwnd
, UINT uMsg
, LPARAM wParam
, LPARAM lParam
)
299 HPROPSHEETPAGE hpsp
[MAX_CPL_PAGES
];
302 TCHAR szCaption
[256];
305 UNREFERENCED_PARAMETER(lParam
);
306 UNREFERENCED_PARAMETER(wParam
);
307 UNREFERENCED_PARAMETER(uMsg
);
308 UNREFERENCED_PARAMETER(hwnd
);
310 LoadString(hApplet
, IDS_CPLNAME_2
, szCaption
, sizeof(szCaption
) / sizeof(TCHAR
));
312 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
313 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
314 psh
.dwFlags
= PSH_PROPTITLE
;
315 psh
.hwndParent
= hwnd
;
316 psh
.hInstance
= hApplet
;
317 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDC_CPLICON_2
));
318 psh
.pszCaption
= szCaption
;
322 /* Load additional pages provided by shell extensions */
323 hpsxa
= SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE
, REGSTR_PATH_CONTROLSFOLDER
TEXT("\\Keyboard"), MAX_CPL_PAGES
- psh
.nPages
);
325 /* NOTE: The speed page (CPLPAGE_KEYBOARD_SPEED) cannot be replaced by
326 shell extensions since Win2k! */
327 InitPropSheetPage(&psh
, IDD_KEYBSPEED
, KeyboardSpeedProc
);
328 InitPropSheetPage(&psh
, IDD_HARDWARE
, KeybHardwareProc
);
331 SHAddFromPropSheetExtArray(hpsxa
, PropSheetAddPage
, (LPARAM
)&psh
);
333 ret
= (LONG
)(PropertySheet(&psh
) != -1);
336 SHDestroyPropSheetExtArray(hpsxa
);