2 * PROJECT: ReactOS Accessibility Control Panel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/access/keyboard.c
5 * PURPOSE: Keyboard-related accessibility settings
6 * COPYRIGHT: Copyright 2004 Johannes Anderwald (johannes.anderwald@reactos.org)
7 * Copyright 2007 Eric Kohl
13 static UINT nBounceArray
[BOUNCETICKS
] = {500, 700, 1000, 1500, 2000};
16 static UINT nDelayArray
[DELAYTICKS
] = {300, 700, 1000, 1500, 2000};
19 static UINT nRepeatArray
[REPEATTICKS
] = {300, 500, 700, 1000, 1500, 2000};
22 static UINT nWaitArray
[WAITTICKS
] = {0, 300, 500, 700, 1000, 1500, 2000, 5000, 10000, 20000};
26 EnableFilterKeysTest(PGLOBAL_DATA pGlobalData
)
28 pGlobalData
->filterKeys
.dwFlags
|= FKF_FILTERKEYSON
;
29 pGlobalData
->filterKeys
.dwFlags
&= ~FKF_INDICATOR
;
31 SystemParametersInfo(SPI_SETFILTERKEYS
,
33 &pGlobalData
->filterKeys
,
39 DisableFilterKeysTest(PGLOBAL_DATA pGlobalData
)
41 if (pGlobalData
->oldFilterKeys
.dwFlags
& FKF_FILTERKEYSON
)
43 pGlobalData
->filterKeys
.dwFlags
|= FKF_FILTERKEYSON
;
47 pGlobalData
->filterKeys
.dwFlags
&= ~FKF_FILTERKEYSON
;
50 if (pGlobalData
->oldFilterKeys
.dwFlags
& FKF_INDICATOR
)
52 pGlobalData
->filterKeys
.dwFlags
|= FKF_INDICATOR
;
56 pGlobalData
->filterKeys
.dwFlags
&= ~FKF_INDICATOR
;
59 SystemParametersInfo(SPI_SETFILTERKEYS
,
61 &pGlobalData
->filterKeys
,
66 /* Property page dialog callback */
68 StickyKeysDlgProc(HWND hwndDlg
,
73 PGLOBAL_DATA pGlobalData
;
75 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
80 pGlobalData
= (PGLOBAL_DATA
)lParam
;
81 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
83 memcpy(&pGlobalData
->oldStickyKeys
,
84 &pGlobalData
->stickyKeys
,
87 CheckDlgButton(hwndDlg
,
88 IDC_STICKY_ACTIVATE_CHECK
,
89 pGlobalData
->stickyKeys
.dwFlags
& SKF_HOTKEYACTIVE
? BST_CHECKED
: BST_UNCHECKED
);
91 CheckDlgButton(hwndDlg
,
92 IDC_STICKY_LOCK_CHECK
,
93 pGlobalData
->stickyKeys
.dwFlags
& SKF_TRISTATE
? BST_CHECKED
: BST_UNCHECKED
);
95 CheckDlgButton(hwndDlg
,
96 IDC_STICKY_UNLOCK_CHECK
,
97 pGlobalData
->stickyKeys
.dwFlags
& SKF_TWOKEYSOFF
? BST_CHECKED
: BST_UNCHECKED
);
99 CheckDlgButton(hwndDlg
,
100 IDC_STICKY_SOUND_CHECK
,
101 pGlobalData
->stickyKeys
.dwFlags
& SKF_AUDIBLEFEEDBACK
? BST_CHECKED
: BST_UNCHECKED
);
103 CheckDlgButton(hwndDlg
,
104 IDC_STICKY_STATUS_CHECK
,
105 pGlobalData
->stickyKeys
.dwFlags
& SKF_INDICATOR
? BST_CHECKED
: BST_UNCHECKED
);
109 switch (LOWORD(wParam
))
111 case IDC_STICKY_ACTIVATE_CHECK
:
112 pGlobalData
->stickyKeys
.dwFlags
^= SKF_HOTKEYACTIVE
;
115 case IDC_STICKY_LOCK_CHECK
:
116 pGlobalData
->stickyKeys
.dwFlags
^= SKF_TRISTATE
;
119 case IDC_STICKY_UNLOCK_CHECK
:
120 pGlobalData
->stickyKeys
.dwFlags
^= SKF_TWOKEYSOFF
;
123 case IDC_STICKY_SOUND_CHECK
:
124 pGlobalData
->stickyKeys
.dwFlags
^= SKF_AUDIBLEFEEDBACK
;
127 case IDC_STICKY_STATUS_CHECK
:
128 pGlobalData
->stickyKeys
.dwFlags
^= SKF_INDICATOR
;
133 (pGlobalData
->stickyKeys
.dwFlags
!= pGlobalData
->oldStickyKeys
.dwFlags
));
137 EndDialog(hwndDlg
, FALSE
);
151 AddComboBoxTime(HWND hwnd
, INT nId
, INT nTimeMs
)
156 if (LoadString(hApplet
, IDS_SECONDS
, szSeconds
, 20) == 0)
157 lstrcpy(szSeconds
, L
"Seconds");
159 _stprintf(szBuffer
, _T("%d.%d %s"),
160 nTimeMs
/ 1000, (nTimeMs
% 1000) / 100,
163 SendDlgItemMessage(hwnd
, nId
, CB_ADDSTRING
, 0, (LPARAM
)szBuffer
);
168 BounceKeysDlgProc(HWND hwndDlg
,
173 PGLOBAL_DATA pGlobalData
;
176 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
181 pGlobalData
= (PGLOBAL_DATA
)lParam
;
182 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
184 /* Determine the current bounce time */
185 if (pGlobalData
->filterKeys
.iBounceMSec
== 0)
186 pGlobalData
->filterKeys
.iBounceMSec
= nBounceArray
[0];
188 for (n
= 0; n
< BOUNCETICKS
; n
++)
190 if (pGlobalData
->filterKeys
.iBounceMSec
< nBounceArray
[n
])
195 for (i
= 0; i
< BOUNCETICKS
; i
++)
197 AddComboBoxTime(hwndDlg
, IDC_BOUNCE_TIME_COMBO
, nBounceArray
[i
]);
200 SendDlgItemMessage(hwndDlg
, IDC_BOUNCE_TIME_COMBO
, CB_SETCURSEL
, n
, 0);
204 switch (LOWORD(wParam
))
206 case IDC_BOUNCE_TIME_COMBO
:
207 if (HIWORD(wParam
) == CBN_SELCHANGE
)
209 i
= SendDlgItemMessage(hwndDlg
, IDC_BOUNCE_TIME_COMBO
, CB_GETCURSEL
, 0, 0);
212 pGlobalData
->filterKeys
.iBounceMSec
= nBounceArray
[i
];
217 case IDC_BOUNCE_TEST_EDIT
:
218 switch (HIWORD(wParam
))
221 EnableFilterKeysTest(pGlobalData
);
225 DisableFilterKeysTest(pGlobalData
);
231 EndDialog(hwndDlg
, TRUE
);
235 EndDialog(hwndDlg
, FALSE
);
249 RepeatKeysDlgProc(HWND hwndDlg
,
254 PGLOBAL_DATA pGlobalData
;
257 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
262 pGlobalData
= (PGLOBAL_DATA
)lParam
;
263 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
265 CheckRadioButton(hwndDlg
,
266 IDC_REPEAT_NOREPEAT_RADIO
,
267 IDC_REPEAT_REPEAT_RADIO
,
268 (pGlobalData
->filterKeys
.iDelayMSec
== 0) ? IDC_REPEAT_NOREPEAT_RADIO
: IDC_REPEAT_REPEAT_RADIO
);
270 /* Initialize the delay combobox */
271 for (n
= 0; n
< DELAYTICKS
; n
++)
273 if (pGlobalData
->filterKeys
.iDelayMSec
< nDelayArray
[n
])
278 for (i
= 0; i
< DELAYTICKS
; i
++)
280 AddComboBoxTime(hwndDlg
, IDC_REPEAT_DELAY_COMBO
, nDelayArray
[i
]);
283 SendDlgItemMessage(hwndDlg
, IDC_REPEAT_DELAY_COMBO
, CB_SETCURSEL
, n
, 0);
285 /* Initialize the repeat combobox */
286 for (n
= 0; n
< REPEATTICKS
; n
++)
288 if (pGlobalData
->filterKeys
.iRepeatMSec
< nRepeatArray
[n
])
293 for (i
= 0; i
< REPEATTICKS
; i
++)
295 AddComboBoxTime(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
, nRepeatArray
[i
]);
298 SendDlgItemMessage(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
, CB_SETCURSEL
, n
, 0);
300 /* Disable the delay and repeat comboboxes if needed */
301 if (pGlobalData
->filterKeys
.iDelayMSec
== 0)
303 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_DELAY_COMBO
), FALSE
);
304 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
), FALSE
);
307 /* Initialize the wait combobox */
308 for (n
= 0; n
< WAITTICKS
; n
++)
310 if (pGlobalData
->filterKeys
.iWaitMSec
< nWaitArray
[n
])
315 for (i
= 0; i
< WAITTICKS
; i
++)
317 AddComboBoxTime(hwndDlg
, IDC_REPEAT_WAIT_COMBO
, nWaitArray
[i
]);
320 SendDlgItemMessage(hwndDlg
, IDC_REPEAT_WAIT_COMBO
, CB_SETCURSEL
, n
, 0);
324 switch (LOWORD(wParam
))
326 case IDC_REPEAT_NOREPEAT_RADIO
:
327 pGlobalData
->filterKeys
.iDelayMSec
= 0;
328 pGlobalData
->filterKeys
.iRepeatMSec
= 0;
329 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_DELAY_COMBO
), FALSE
);
330 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
), FALSE
);
333 case IDC_REPEAT_REPEAT_RADIO
:
334 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_DELAY_COMBO
), TRUE
);
335 EnableWindow(GetDlgItem(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
), TRUE
);
338 case IDC_REPEAT_DELAY_COMBO
:
339 if (HIWORD(wParam
) == CBN_SELCHANGE
)
341 i
= SendDlgItemMessage(hwndDlg
, IDC_REPEAT_DELAY_COMBO
, CB_GETCURSEL
, 0, 0);
344 pGlobalData
->filterKeys
.iDelayMSec
= nDelayArray
[i
];
349 case IDC_REPEAT_REPEAT_COMBO
:
350 if (HIWORD(wParam
) == CBN_SELCHANGE
)
352 i
= SendDlgItemMessage(hwndDlg
, IDC_REPEAT_REPEAT_COMBO
, CB_GETCURSEL
, 0, 0);
355 pGlobalData
->filterKeys
.iRepeatMSec
= nRepeatArray
[i
];
360 case IDC_REPEAT_WAIT_COMBO
:
361 if (HIWORD(wParam
) == CBN_SELCHANGE
)
363 i
= SendDlgItemMessage(hwndDlg
, IDC_REPEAT_WAIT_COMBO
, CB_GETCURSEL
, 0, 0);
366 pGlobalData
->filterKeys
.iWaitMSec
= nWaitArray
[i
];
371 case IDC_REPEAT_TEST_EDIT
:
372 switch (HIWORD(wParam
))
375 EnableFilterKeysTest(pGlobalData
);
379 DisableFilterKeysTest(pGlobalData
);
385 EndDialog(hwndDlg
, TRUE
);
389 EndDialog(hwndDlg
, FALSE
);
402 /* Property page dialog callback */
404 FilterKeysDlgProc(HWND hwndDlg
,
409 PGLOBAL_DATA pGlobalData
;
411 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
416 pGlobalData
= (PGLOBAL_DATA
)lParam
;
417 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
419 memcpy(&pGlobalData
->oldFilterKeys
,
420 &pGlobalData
->filterKeys
,
423 CheckDlgButton(hwndDlg
,
424 IDC_FILTER_ACTIVATE_CHECK
,
425 pGlobalData
->filterKeys
.dwFlags
& FKF_HOTKEYACTIVE
? BST_CHECKED
: BST_UNCHECKED
);
427 if (pGlobalData
->filterKeys
.iBounceMSec
!= 0)
429 CheckRadioButton(hwndDlg
, IDC_FILTER_BOUNCE_RADIO
, IDC_FILTER_REPEAT_RADIO
, IDC_FILTER_BOUNCE_RADIO
);
430 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_BOUNCE_BUTTON
), TRUE
);
431 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_REPEAT_BUTTON
), FALSE
);
435 CheckRadioButton(hwndDlg
, IDC_FILTER_BOUNCE_RADIO
, IDC_FILTER_REPEAT_RADIO
, IDC_FILTER_REPEAT_RADIO
);
436 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_BOUNCE_BUTTON
), FALSE
);
437 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_REPEAT_BUTTON
), TRUE
);
440 CheckDlgButton(hwndDlg
,
441 IDC_FILTER_SOUND_CHECK
,
442 pGlobalData
->filterKeys
.dwFlags
& FKF_CLICKON
? BST_CHECKED
: BST_UNCHECKED
);
444 CheckDlgButton(hwndDlg
,
445 IDC_FILTER_STATUS_CHECK
,
446 pGlobalData
->filterKeys
.dwFlags
& FKF_INDICATOR
? BST_CHECKED
: BST_UNCHECKED
);
450 switch (LOWORD(wParam
))
452 case IDC_FILTER_ACTIVATE_CHECK
:
453 pGlobalData
->filterKeys
.dwFlags
^= FKF_HOTKEYACTIVE
;
456 case IDC_FILTER_BOUNCE_RADIO
:
457 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_BOUNCE_BUTTON
), TRUE
);
458 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_REPEAT_BUTTON
), FALSE
);
461 case IDC_FILTER_REPEAT_RADIO
:
462 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_BOUNCE_BUTTON
), FALSE
);
463 EnableWindow(GetDlgItem(hwndDlg
, IDC_FILTER_REPEAT_BUTTON
), TRUE
);
466 case IDC_FILTER_BOUNCE_BUTTON
:
467 DialogBoxParam(hApplet
,
468 MAKEINTRESOURCE(IDD_BOUNCEKEYSOPTIONS
),
470 (DLGPROC
)BounceKeysDlgProc
,
471 (LPARAM
)pGlobalData
);
474 case IDC_FILTER_TEST_EDIT
:
475 switch (HIWORD(wParam
))
478 EnableFilterKeysTest(pGlobalData
);
482 DisableFilterKeysTest(pGlobalData
);
487 case IDC_FILTER_SOUND_CHECK
:
488 pGlobalData
->filterKeys
.dwFlags
^= FKF_CLICKON
;
491 case IDC_FILTER_REPEAT_BUTTON
:
492 DialogBoxParam(hApplet
,
493 MAKEINTRESOURCE(IDD_REPEATKEYSOPTIONS
),
495 (DLGPROC
)RepeatKeysDlgProc
,
496 (LPARAM
)pGlobalData
);
499 case IDC_FILTER_STATUS_CHECK
:
500 pGlobalData
->filterKeys
.dwFlags
^= FKF_INDICATOR
;
505 (pGlobalData
->filterKeys
.dwFlags
!= pGlobalData
->oldFilterKeys
.dwFlags
));
509 EndDialog(hwndDlg
, FALSE
);
522 /* Property page dialog callback */
524 ToggleKeysDlgProc(HWND hwndDlg
,
529 PGLOBAL_DATA pGlobalData
;
531 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
536 pGlobalData
= (PGLOBAL_DATA
)lParam
;
537 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
539 memcpy(&pGlobalData
->oldToggleKeys
,
540 &pGlobalData
->toggleKeys
,
543 CheckDlgButton(hwndDlg
,
544 IDC_TOGGLE_ACTIVATE_CHECK
,
545 pGlobalData
->toggleKeys
.dwFlags
& TKF_HOTKEYACTIVE
? BST_CHECKED
: BST_UNCHECKED
);
549 switch (LOWORD(wParam
))
551 case IDC_TOGGLE_ACTIVATE_CHECK
:
552 pGlobalData
->toggleKeys
.dwFlags
^= TKF_HOTKEYACTIVE
;
557 (pGlobalData
->toggleKeys
.dwFlags
!= pGlobalData
->oldToggleKeys
.dwFlags
));
561 EndDialog(hwndDlg
, FALSE
);
574 /* Property page dialog callback */
576 KeyboardPageProc(HWND hwndDlg
,
581 PGLOBAL_DATA pGlobalData
;
584 pGlobalData
= (PGLOBAL_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
589 pGlobalData
= (PGLOBAL_DATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
590 if (pGlobalData
== NULL
)
593 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
595 CheckDlgButton(hwndDlg
,
597 pGlobalData
->stickyKeys
.dwFlags
& SKF_STICKYKEYSON
? BST_CHECKED
: BST_UNCHECKED
);
599 CheckDlgButton(hwndDlg
,
601 pGlobalData
->filterKeys
.dwFlags
& FKF_FILTERKEYSON
? BST_CHECKED
: BST_UNCHECKED
);
603 CheckDlgButton(hwndDlg
,
605 pGlobalData
->toggleKeys
.dwFlags
& TKF_TOGGLEKEYSON
? BST_CHECKED
: BST_UNCHECKED
);
607 CheckDlgButton(hwndDlg
,
609 pGlobalData
->bKeyboardPref
? BST_CHECKED
: BST_UNCHECKED
);
613 switch (LOWORD(wParam
))
616 pGlobalData
->stickyKeys
.dwFlags
^= SKF_STICKYKEYSON
;
617 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
620 case IDC_STICKY_BUTTON
:
621 if (DialogBoxParam(hApplet
,
622 MAKEINTRESOURCE(IDD_STICKYKEYSOPTIONS
),
624 (DLGPROC
)StickyKeysDlgProc
,
625 (LPARAM
)pGlobalData
))
626 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
630 pGlobalData
->filterKeys
.dwFlags
^= FKF_FILTERKEYSON
;
631 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
634 case IDC_FILTER_BUTTON
:
635 if (DialogBoxParam(hApplet
,
636 MAKEINTRESOURCE(IDD_FILTERKEYSOPTIONS
),
638 (DLGPROC
)FilterKeysDlgProc
,
639 (LPARAM
)pGlobalData
))
640 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
644 pGlobalData
->toggleKeys
.dwFlags
^= TKF_TOGGLEKEYSON
;
645 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
648 case IDC_TOGGLE_BUTTON
:
649 if (DialogBoxParam(hApplet
,
650 MAKEINTRESOURCE(IDD_TOGGLEKEYSOPTIONS
),
652 (DLGPROC
)ToggleKeysDlgProc
,
653 (LPARAM
)pGlobalData
))
654 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
657 case IDC_KEYBOARD_EXTRA
:
658 pGlobalData
->bKeyboardPref
= !pGlobalData
->bKeyboardPref
;
659 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
668 lppsn
= (LPPSHNOTIFY
)lParam
;
669 if (lppsn
->hdr
.code
== PSN_APPLY
)
671 SystemParametersInfo(SPI_SETSTICKYKEYS
,
673 &pGlobalData
->stickyKeys
,
674 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
/*0*/);
676 SystemParametersInfo(SPI_SETFILTERKEYS
,
678 &pGlobalData
->filterKeys
,
679 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
/*0*/);
681 SystemParametersInfo(SPI_SETTOGGLEKEYS
,
683 &pGlobalData
->toggleKeys
,
684 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
/*0*/);
686 SystemParametersInfo(SPI_SETKEYBOARDPREF
,
687 pGlobalData
->bKeyboardPref
,
689 SPIF_UPDATEINIFILE
| SPIF_SENDCHANGE
/*0*/);