1 /* $Id: keyboard.c 29170 2007-09-23 22:59:00Z ekohl $
3 * PROJECT: ReactOS Accessibility Control Panel
4 * LICENSE: GPL - See COPYING in the top level directory
5 * FILE: dll/cpl/access/keyboard.c
6 * PURPOSE: Keyboard-related accessibility settings
7 * COPYRIGHT: Copyright 2004 Johannes Anderwald (j_anderw@sbox.tugraz.at)
8 * Copyright 2007 Eric Kohl
15 static UINT nBounceArray
[BOUNCETICKS
] = {500, 700, 1000, 1500, 2000};
18 static UINT nDelayArray
[DELAYTICKS
] = {300, 700, 1000, 1500, 2000};
21 static UINT nRepeatArray
[REPEATTICKS
] = {300, 500, 700, 1000, 1500, 2000};
24 static UINT nWaitArray
[WAITTICKS
] = {0, 300, 500, 700, 1000, 1500, 2000, 5000, 10000, 20000};
28 EnableFilterKeysTest(PGLOBAL_DATA pGlobalData
)
30 pGlobalData
->filterKeys
.dwFlags
|= FKF_FILTERKEYSON
;
31 pGlobalData
->filterKeys
.dwFlags
&= ~FKF_INDICATOR
;
33 SystemParametersInfo(SPI_SETFILTERKEYS
,
35 &pGlobalData
->filterKeys
,
41 DisableFilterKeysTest(PGLOBAL_DATA pGlobalData
)
43 if (pGlobalData
->oldFilterKeys
.dwFlags
& FKF_FILTERKEYSON
)
45 pGlobalData
->filterKeys
.dwFlags
|= FKF_FILTERKEYSON
;
49 pGlobalData
->filterKeys
.dwFlags
&= ~FKF_FILTERKEYSON
;
52 if (pGlobalData
->oldFilterKeys
.dwFlags
& FKF_INDICATOR
)
54 pGlobalData
->filterKeys
.dwFlags
|= FKF_INDICATOR
;
58 pGlobalData
->filterKeys
.dwFlags
&= ~FKF_INDICATOR
;
61 SystemParametersInfo(SPI_SETFILTERKEYS
,
63 &pGlobalData
->filterKeys
,
68 /* Property page dialog callback */
70 StickyKeysDlgProc(HWND hwndDlg
,
75 PGLOBAL_DATA pGlobalData
;
77 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
82 pGlobalData
= (PGLOBAL_DATA
)lParam
;
83 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
85 memcpy(&pGlobalData
->oldStickyKeys
,
86 &pGlobalData
->stickyKeys
,
89 CheckDlgButton(hwndDlg
,
90 IDC_STICKY_ACTIVATE_CHECK
,
91 pGlobalData
->stickyKeys
.dwFlags
& SKF_HOTKEYACTIVE
? BST_CHECKED
: BST_UNCHECKED
);
93 CheckDlgButton(hwndDlg
,
94 IDC_STICKY_LOCK_CHECK
,
95 pGlobalData
->stickyKeys
.dwFlags
& SKF_TRISTATE
? BST_CHECKED
: BST_UNCHECKED
);
97 CheckDlgButton(hwndDlg
,
98 IDC_STICKY_UNLOCK_CHECK
,
99 pGlobalData
->stickyKeys
.dwFlags
& SKF_TWOKEYSOFF
? BST_CHECKED
: BST_UNCHECKED
);
101 CheckDlgButton(hwndDlg
,
102 IDC_STICKY_SOUND_CHECK
,
103 pGlobalData
->stickyKeys
.dwFlags
& SKF_AUDIBLEFEEDBACK
? BST_CHECKED
: BST_UNCHECKED
);
105 CheckDlgButton(hwndDlg
,
106 IDC_STICKY_STATUS_CHECK
,
107 pGlobalData
->stickyKeys
.dwFlags
& SKF_INDICATOR
? BST_CHECKED
: BST_UNCHECKED
);
111 switch (LOWORD(wParam
))
113 case IDC_STICKY_ACTIVATE_CHECK
:
114 pGlobalData
->stickyKeys
.dwFlags
^= SKF_HOTKEYACTIVE
;
117 case IDC_STICKY_LOCK_CHECK
:
118 pGlobalData
->stickyKeys
.dwFlags
^= SKF_TRISTATE
;
121 case IDC_STICKY_UNLOCK_CHECK
:
122 pGlobalData
->stickyKeys
.dwFlags
^= SKF_TWOKEYSOFF
;
125 case IDC_STICKY_SOUND_CHECK
:
126 pGlobalData
->stickyKeys
.dwFlags
^= SKF_AUDIBLEFEEDBACK
;
129 case IDC_STICKY_STATUS_CHECK
:
130 pGlobalData
->stickyKeys
.dwFlags
^= SKF_INDICATOR
;
135 (pGlobalData
->stickyKeys
.dwFlags
!= pGlobalData
->oldStickyKeys
.dwFlags
));
139 EndDialog(hwndDlg
, FALSE
);
153 AddComboBoxTime(HWND hwnd
, INT nId
, INT nTimeMs
)
158 if (LoadString(hApplet
, IDS_SECONDS
, szSeconds
, 20) == 0)
159 lstrcpy(szSeconds
, L
"Seconds");
161 _stprintf(szBuffer
, _T("%d.%d %s"),
162 nTimeMs
/ 1000, (nTimeMs
% 1000) / 100,
165 SendDlgItemMessage(hwnd
, nId
, CB_ADDSTRING
, 0, (LPARAM
)szBuffer
);
170 BounceKeysDlgProc(HWND hwndDlg
,
175 PGLOBAL_DATA pGlobalData
;
178 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
183 pGlobalData
= (PGLOBAL_DATA
)lParam
;
184 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
186 /* Determine the current bounce time */
187 if (pGlobalData
->filterKeys
.iBounceMSec
== 0)
188 pGlobalData
->filterKeys
.iBounceMSec
= nBounceArray
[0];
190 for (n
= 0; n
< BOUNCETICKS
; n
++)
192 if (pGlobalData
->filterKeys
.iBounceMSec
< nBounceArray
[n
])
197 for (i
= 0; i
< BOUNCETICKS
; i
++)
199 AddComboBoxTime(hwndDlg
, IDC_BOUNCE_TIME_COMBO
, nBounceArray
[i
]);
202 SendDlgItemMessage(hwndDlg
, IDC_BOUNCE_TIME_COMBO
, CB_SETCURSEL
, n
, 0);
206 switch (LOWORD(wParam
))
208 case IDC_BOUNCE_TIME_COMBO
:
209 if (HIWORD(wParam
) == CBN_SELCHANGE
)
211 i
= SendDlgItemMessage(hwndDlg
, IDC_BOUNCE_TIME_COMBO
, CB_GETCURSEL
, 0, 0);
214 pGlobalData
->filterKeys
.iBounceMSec
= nBounceArray
[i
];
219 case IDC_BOUNCE_TEST_EDIT
:
220 switch (HIWORD(wParam
))
223 EnableFilterKeysTest(pGlobalData
);
227 DisableFilterKeysTest(pGlobalData
);
233 EndDialog(hwndDlg
, TRUE
);
237 EndDialog(hwndDlg
, FALSE
);
251 RepeatKeysDlgProc(HWND hwndDlg
,
256 PGLOBAL_DATA pGlobalData
;
259 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
264 pGlobalData
= (PGLOBAL_DATA
)lParam
;
265 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
267 CheckRadioButton(hwndDlg
,
268 IDC_REPEAT_NOREPEAT_RADIO
,
269 IDC_REPEAT_REPEAT_RADIO
,
270 (pGlobalData
->filterKeys
.iDelayMSec
== 0) ? IDC_REPEAT_NOREPEAT_RADIO
: IDC_REPEAT_REPEAT_RADIO
);
272 /* Initialize the delay combobox */
273 for (n
= 0; n
< DELAYTICKS
; n
++)
275 if (pGlobalData
->filterKeys
.iDelayMSec
< nDelayArray
[n
])
280 for (i
= 0; i
< DELAYTICKS
; i
++)
282 AddComboBoxTime(hwndDlg
, IDC_REPEAT_DELAY_COMBO
, nDelayArray
[i
]);
285 SendDlgItemMessage(hwndDlg
, IDC_REPEAT_DELAY_COMBO
, CB_SETCURSEL
, n
, 0);
287 /* Initialize the repeat combobox */
288 for (n
= 0; n
< REPEATTICKS
; n
++)
290 if (pGlobalData
->filterKeys
.iRepeatMSec
< nRepeatArray
[n
])
295 for (i
= 0; i
< REPEATTICKS
; i
++)
297 AddComboBoxTime(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
, nRepeatArray
[i
]);
300 SendDlgItemMessage(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
, CB_SETCURSEL
, n
, 0);
302 /* Disable the delay and repeat comboboxes if needed */
303 if (pGlobalData
->filterKeys
.iDelayMSec
== 0)
305 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_DELAY_COMBO
), FALSE
);
306 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
), FALSE
);
309 /* Initialize the wait combobox */
310 for (n
= 0; n
< WAITTICKS
; n
++)
312 if (pGlobalData
->filterKeys
.iWaitMSec
< nWaitArray
[n
])
317 for (i
= 0; i
< WAITTICKS
; i
++)
319 AddComboBoxTime(hwndDlg
, IDC_REPEAT_WAIT_COMBO
, nWaitArray
[i
]);
322 SendDlgItemMessage(hwndDlg
, IDC_REPEAT_WAIT_COMBO
, CB_SETCURSEL
, n
, 0);
326 switch (LOWORD(wParam
))
328 case IDC_REPEAT_NOREPEAT_RADIO
:
329 pGlobalData
->filterKeys
.iDelayMSec
= 0;
330 pGlobalData
->filterKeys
.iRepeatMSec
= 0;
331 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_DELAY_COMBO
), FALSE
);
332 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
), FALSE
);
335 case IDC_REPEAT_REPEAT_RADIO
:
336 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_DELAY_COMBO
), TRUE
);
337 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
), TRUE
);
340 case IDC_REPEAT_DELAY_COMBO
:
341 if (HIWORD(wParam
) == CBN_SELCHANGE
)
343 i
= SendDlgItemMessage(hwndDlg
, IDC_REPEAT_DELAY_COMBO
, CB_GETCURSEL
, 0, 0);
346 pGlobalData
->filterKeys
.iDelayMSec
= nDelayArray
[i
];
351 case IDC_REPEAT_REPEAT_COMBO
:
352 if (HIWORD(wParam
) == CBN_SELCHANGE
)
354 i
= SendDlgItemMessage(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
, CB_GETCURSEL
, 0, 0);
357 pGlobalData
->filterKeys
.iRepeatMSec
= nRepeatArray
[i
];
362 case IDC_REPEAT_WAIT_COMBO
:
363 if (HIWORD(wParam
) == CBN_SELCHANGE
)
365 i
= SendDlgItemMessage(hwndDlg
, IDC_REPEAT_WAIT_COMBO
, CB_GETCURSEL
, 0, 0);
368 pGlobalData
->filterKeys
.iWaitMSec
= nWaitArray
[i
];
373 case IDC_REPEAT_TEST_EDIT
:
374 switch (HIWORD(wParam
))
377 EnableFilterKeysTest(pGlobalData
);
381 DisableFilterKeysTest(pGlobalData
);
387 EndDialog(hwndDlg
, TRUE
);
391 EndDialog(hwndDlg
, FALSE
);
404 /* Property page dialog callback */
406 FilterKeysDlgProc(HWND hwndDlg
,
411 PGLOBAL_DATA pGlobalData
;
413 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
418 pGlobalData
= (PGLOBAL_DATA
)lParam
;
419 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
421 memcpy(&pGlobalData
->oldFilterKeys
,
422 &pGlobalData
->filterKeys
,
425 CheckDlgButton(hwndDlg
,
426 IDC_FILTER_ACTIVATE_CHECK
,
427 pGlobalData
->filterKeys
.dwFlags
& FKF_HOTKEYACTIVE
? BST_CHECKED
: BST_UNCHECKED
);
429 if (pGlobalData
->filterKeys
.iBounceMSec
!= 0)
431 CheckRadioButton(hwndDlg
, IDC_FILTER_BOUNCE_RADIO
, IDC_FILTER_REPEAT_RADIO
, IDC_FILTER_BOUNCE_RADIO
);
432 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_BOUNCE_BUTTON
), TRUE
);
433 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_REPEAT_BUTTON
), FALSE
);
437 CheckRadioButton(hwndDlg
, IDC_FILTER_BOUNCE_RADIO
, IDC_FILTER_REPEAT_RADIO
, IDC_FILTER_REPEAT_RADIO
);
438 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_BOUNCE_BUTTON
), FALSE
);
439 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_REPEAT_BUTTON
), TRUE
);
442 CheckDlgButton(hwndDlg
,
443 IDC_FILTER_SOUND_CHECK
,
444 pGlobalData
->filterKeys
.dwFlags
& FKF_CLICKON
? BST_CHECKED
: BST_UNCHECKED
);
446 CheckDlgButton(hwndDlg
,
447 IDC_FILTER_STATUS_CHECK
,
448 pGlobalData
->filterKeys
.dwFlags
& FKF_INDICATOR
? BST_CHECKED
: BST_UNCHECKED
);
452 switch (LOWORD(wParam
))
454 case IDC_FILTER_ACTIVATE_CHECK
:
455 pGlobalData
->filterKeys
.dwFlags
^= FKF_HOTKEYACTIVE
;
458 case IDC_FILTER_BOUNCE_RADIO
:
459 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_BOUNCE_BUTTON
), TRUE
);
460 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_REPEAT_BUTTON
), FALSE
);
463 case IDC_FILTER_REPEAT_RADIO
:
464 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_BOUNCE_BUTTON
), FALSE
);
465 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_REPEAT_BUTTON
), TRUE
);
468 case IDC_FILTER_BOUNCE_BUTTON
:
469 DialogBoxParam(hApplet
,
470 MAKEINTRESOURCE(IDD_BOUNCEKEYSOPTIONS
),
472 (DLGPROC
)BounceKeysDlgProc
,
473 (LPARAM
)pGlobalData
);
476 case IDC_FILTER_TEST_EDIT
:
477 switch (HIWORD(wParam
))
480 EnableFilterKeysTest(pGlobalData
);
484 DisableFilterKeysTest(pGlobalData
);
489 case IDC_FILTER_SOUND_CHECK
:
490 pGlobalData
->filterKeys
.dwFlags
^= FKF_CLICKON
;
493 case IDC_FILTER_REPEAT_BUTTON
:
494 DialogBoxParam(hApplet
,
495 MAKEINTRESOURCE(IDD_REPEATKEYSOPTIONS
),
497 (DLGPROC
)RepeatKeysDlgProc
,
498 (LPARAM
)pGlobalData
);
501 case IDC_FILTER_STATUS_CHECK
:
502 pGlobalData
->filterKeys
.dwFlags
^= FKF_INDICATOR
;
507 (pGlobalData
->filterKeys
.dwFlags
!= pGlobalData
->oldFilterKeys
.dwFlags
));
511 EndDialog(hwndDlg
, FALSE
);
524 /* Property page dialog callback */
526 ToggleKeysDlgProc(HWND hwndDlg
,
531 PGLOBAL_DATA pGlobalData
;
533 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
538 pGlobalData
= (PGLOBAL_DATA
)lParam
;
539 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
541 memcpy(&pGlobalData
->oldToggleKeys
,
542 &pGlobalData
->toggleKeys
,
545 CheckDlgButton(hwndDlg
,
546 IDC_TOGGLE_ACTIVATE_CHECK
,
547 pGlobalData
->toggleKeys
.dwFlags
& TKF_HOTKEYACTIVE
? BST_CHECKED
: BST_UNCHECKED
);
551 switch (LOWORD(wParam
))
553 case IDC_TOGGLE_ACTIVATE_CHECK
:
554 pGlobalData
->toggleKeys
.dwFlags
^= TKF_HOTKEYACTIVE
;
559 (pGlobalData
->toggleKeys
.dwFlags
!= pGlobalData
->oldToggleKeys
.dwFlags
));
563 EndDialog(hwndDlg
, FALSE
);
576 /* Property page dialog callback */
578 KeyboardPageProc(HWND hwndDlg
,
583 PGLOBAL_DATA pGlobalData
;
586 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
591 pGlobalData
= (PGLOBAL_DATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
592 if (pGlobalData
== NULL
)
595 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
597 CheckDlgButton(hwndDlg
,
599 pGlobalData
->stickyKeys
.dwFlags
& SKF_STICKYKEYSON
? BST_CHECKED
: BST_UNCHECKED
);
601 CheckDlgButton(hwndDlg
,
603 pGlobalData
->filterKeys
.dwFlags
& FKF_FILTERKEYSON
? BST_CHECKED
: BST_UNCHECKED
);
605 CheckDlgButton(hwndDlg
,
607 pGlobalData
->toggleKeys
.dwFlags
& TKF_TOGGLEKEYSON
? BST_CHECKED
: BST_UNCHECKED
);
609 CheckDlgButton(hwndDlg
,
611 pGlobalData
->bKeyboardPref
? BST_CHECKED
: BST_UNCHECKED
);
615 switch (LOWORD(wParam
))
618 pGlobalData
->stickyKeys
.dwFlags
^= SKF_STICKYKEYSON
;
619 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
622 case IDC_STICKY_BUTTON
:
623 if (DialogBoxParam(hApplet
,
624 MAKEINTRESOURCE(IDD_STICKYKEYSOPTIONS
),
626 (DLGPROC
)StickyKeysDlgProc
,
627 (LPARAM
)pGlobalData
))
628 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
632 pGlobalData
->filterKeys
.dwFlags
^= FKF_FILTERKEYSON
;
633 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
636 case IDC_FILTER_BUTTON
:
637 if (DialogBoxParam(hApplet
,
638 MAKEINTRESOURCE(IDD_FILTERKEYSOPTIONS
),
640 (DLGPROC
)FilterKeysDlgProc
,
641 (LPARAM
)pGlobalData
))
642 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
646 pGlobalData
->toggleKeys
.dwFlags
^= TKF_TOGGLEKEYSON
;
647 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
650 case IDC_TOGGLE_BUTTON
:
651 if (DialogBoxParam(hApplet
,
652 MAKEINTRESOURCE(IDD_TOGGLEKEYSOPTIONS
),
654 (DLGPROC
)ToggleKeysDlgProc
,
655 (LPARAM
)pGlobalData
))
656 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
659 case IDC_KEYBOARD_EXTRA
:
660 pGlobalData
->bKeyboardPref
= !pGlobalData
->bKeyboardPref
;
661 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
670 lppsn
= (LPPSHNOTIFY
)lParam
;
671 if (lppsn
->hdr
.code
== PSN_APPLY
)
673 SystemParametersInfo(SPI_SETSTICKYKEYS
,
675 &pGlobalData
->stickyKeys
,
676 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
/*0*/);
678 SystemParametersInfo(SPI_SETFILTERKEYS
,
680 &pGlobalData
->filterKeys
,
681 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
/*0*/);
683 SystemParametersInfo(SPI_SETTOGGLEKEYS
,
685 &pGlobalData
->toggleKeys
,
686 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
/*0*/);
688 SystemParametersInfo(SPI_SETKEYBOARDPREF
,
689 pGlobalData
->bKeyboardPref
,
691 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
/*0*/);