* Sync up to trunk head (r65120).
[reactos.git] / dll / cpl / access / keyboard.c
1 /*
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
8 */
9
10 #include "access.h"
11
12 #define BOUNCETICKS 5
13 static UINT nBounceArray[BOUNCETICKS] = {500, 700, 1000, 1500, 2000};
14
15 #define DELAYTICKS 5
16 static UINT nDelayArray[DELAYTICKS] = {300, 700, 1000, 1500, 2000};
17
18 #define REPEATTICKS 6
19 static UINT nRepeatArray[REPEATTICKS] = {300, 500, 700, 1000, 1500, 2000};
20
21 #define WAITTICKS 10
22 static UINT nWaitArray[WAITTICKS] = {0, 300, 500, 700, 1000, 1500, 2000, 5000, 10000, 20000};
23
24
25 static VOID
26 EnableFilterKeysTest(PGLOBAL_DATA pGlobalData)
27 {
28 pGlobalData->filterKeys.dwFlags |= FKF_FILTERKEYSON;
29 pGlobalData->filterKeys.dwFlags &= ~FKF_INDICATOR;
30
31 SystemParametersInfo(SPI_SETFILTERKEYS,
32 sizeof(FILTERKEYS),
33 &pGlobalData->filterKeys,
34 0);
35 }
36
37
38 static VOID
39 DisableFilterKeysTest(PGLOBAL_DATA pGlobalData)
40 {
41 if (pGlobalData->oldFilterKeys.dwFlags & FKF_FILTERKEYSON)
42 {
43 pGlobalData->filterKeys.dwFlags |= FKF_FILTERKEYSON;
44 }
45 else
46 {
47 pGlobalData->filterKeys.dwFlags &= ~FKF_FILTERKEYSON;
48 }
49
50 if (pGlobalData->oldFilterKeys.dwFlags & FKF_INDICATOR)
51 {
52 pGlobalData->filterKeys.dwFlags |= FKF_INDICATOR;
53 }
54 else
55 {
56 pGlobalData->filterKeys.dwFlags &= ~FKF_INDICATOR;
57 }
58
59 SystemParametersInfo(SPI_SETFILTERKEYS,
60 sizeof(FILTERKEYS),
61 &pGlobalData->filterKeys,
62 0);
63 }
64
65
66 /* Property page dialog callback */
67 INT_PTR CALLBACK
68 StickyKeysDlgProc(HWND hwndDlg,
69 UINT uMsg,
70 WPARAM wParam,
71 LPARAM lParam)
72 {
73 PGLOBAL_DATA pGlobalData;
74
75 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
76
77 switch (uMsg)
78 {
79 case WM_INITDIALOG:
80 pGlobalData = (PGLOBAL_DATA)lParam;
81 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
82
83 memcpy(&pGlobalData->oldStickyKeys,
84 &pGlobalData->stickyKeys,
85 sizeof(STICKYKEYS));
86
87 CheckDlgButton(hwndDlg,
88 IDC_STICKY_ACTIVATE_CHECK,
89 pGlobalData->stickyKeys.dwFlags & SKF_HOTKEYACTIVE ? BST_CHECKED : BST_UNCHECKED);
90
91 CheckDlgButton(hwndDlg,
92 IDC_STICKY_LOCK_CHECK,
93 pGlobalData->stickyKeys.dwFlags & SKF_TRISTATE ? BST_CHECKED : BST_UNCHECKED);
94
95 CheckDlgButton(hwndDlg,
96 IDC_STICKY_UNLOCK_CHECK,
97 pGlobalData->stickyKeys.dwFlags & SKF_TWOKEYSOFF ? BST_CHECKED : BST_UNCHECKED);
98
99 CheckDlgButton(hwndDlg,
100 IDC_STICKY_SOUND_CHECK,
101 pGlobalData->stickyKeys.dwFlags & SKF_AUDIBLEFEEDBACK ? BST_CHECKED : BST_UNCHECKED);
102
103 CheckDlgButton(hwndDlg,
104 IDC_STICKY_STATUS_CHECK,
105 pGlobalData->stickyKeys.dwFlags & SKF_INDICATOR ? BST_CHECKED : BST_UNCHECKED);
106 break;
107
108 case WM_COMMAND:
109 switch (LOWORD(wParam))
110 {
111 case IDC_STICKY_ACTIVATE_CHECK:
112 pGlobalData->stickyKeys.dwFlags ^= SKF_HOTKEYACTIVE;
113 break;
114
115 case IDC_STICKY_LOCK_CHECK:
116 pGlobalData->stickyKeys.dwFlags ^= SKF_TRISTATE;
117 break;
118
119 case IDC_STICKY_UNLOCK_CHECK:
120 pGlobalData->stickyKeys.dwFlags ^= SKF_TWOKEYSOFF;
121 break;
122
123 case IDC_STICKY_SOUND_CHECK:
124 pGlobalData->stickyKeys.dwFlags ^= SKF_AUDIBLEFEEDBACK;
125 break;
126
127 case IDC_STICKY_STATUS_CHECK:
128 pGlobalData->stickyKeys.dwFlags ^= SKF_INDICATOR;
129 break;
130
131 case IDOK:
132 EndDialog(hwndDlg,
133 (pGlobalData->stickyKeys.dwFlags != pGlobalData->oldStickyKeys.dwFlags));
134 break;
135
136 case IDCANCEL:
137 EndDialog(hwndDlg, FALSE);
138 break;
139
140 default:
141 break;
142 }
143 break;
144 }
145
146 return FALSE;
147 }
148
149
150 static VOID
151 AddComboBoxTime(HWND hwnd, INT nId, INT nTimeMs)
152 {
153 TCHAR szBuffer[32];
154 TCHAR szSeconds[20];
155
156 if (LoadString(hApplet, IDS_SECONDS, szSeconds, 20) == 0)
157 lstrcpy(szSeconds, L"Seconds");
158
159 _stprintf(szBuffer, _T("%d.%d %s"),
160 nTimeMs / 1000, (nTimeMs % 1000) / 100,
161 szSeconds);
162
163 SendDlgItemMessage(hwnd, nId, CB_ADDSTRING, 0, (LPARAM)szBuffer);
164 }
165
166
167 INT_PTR CALLBACK
168 BounceKeysDlgProc(HWND hwndDlg,
169 UINT uMsg,
170 WPARAM wParam,
171 LPARAM lParam)
172 {
173 PGLOBAL_DATA pGlobalData;
174 INT i, n;
175
176 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
177
178 switch (uMsg)
179 {
180 case WM_INITDIALOG:
181 pGlobalData = (PGLOBAL_DATA)lParam;
182 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
183
184 /* Determine the current bounce time */
185 if (pGlobalData->filterKeys.iBounceMSec == 0)
186 pGlobalData->filterKeys.iBounceMSec = nBounceArray[0];
187
188 for (n = 0; n < BOUNCETICKS; n++)
189 {
190 if (pGlobalData->filterKeys.iBounceMSec < nBounceArray[n])
191 break;
192 }
193 n--;
194
195 for (i = 0; i < BOUNCETICKS; i++)
196 {
197 AddComboBoxTime(hwndDlg, IDC_BOUNCE_TIME_COMBO, nBounceArray[i]);
198 }
199
200 SendDlgItemMessage(hwndDlg, IDC_BOUNCE_TIME_COMBO, CB_SETCURSEL, n, 0);
201 break;
202
203 case WM_COMMAND:
204 switch (LOWORD(wParam))
205 {
206 case IDC_BOUNCE_TIME_COMBO:
207 if (HIWORD(wParam) == CBN_SELCHANGE)
208 {
209 i = SendDlgItemMessage(hwndDlg, IDC_BOUNCE_TIME_COMBO, CB_GETCURSEL, 0, 0);
210 if (i != CB_ERR)
211 {
212 pGlobalData->filterKeys.iBounceMSec = nBounceArray[i];
213 }
214 }
215 break;
216
217 case IDC_BOUNCE_TEST_EDIT:
218 switch (HIWORD(wParam))
219 {
220 case EN_SETFOCUS:
221 EnableFilterKeysTest(pGlobalData);
222 break;
223
224 case EN_KILLFOCUS:
225 DisableFilterKeysTest(pGlobalData);
226 break;
227 }
228 break;
229
230 case IDOK:
231 EndDialog(hwndDlg, TRUE);
232 break;
233
234 case IDCANCEL:
235 EndDialog(hwndDlg, FALSE);
236 break;
237
238 default:
239 break;
240 }
241 break;
242 }
243
244 return FALSE;
245 }
246
247
248 INT_PTR CALLBACK
249 RepeatKeysDlgProc(HWND hwndDlg,
250 UINT uMsg,
251 WPARAM wParam,
252 LPARAM lParam)
253 {
254 PGLOBAL_DATA pGlobalData;
255 INT i, n;
256
257 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
258
259 switch (uMsg)
260 {
261 case WM_INITDIALOG:
262 pGlobalData = (PGLOBAL_DATA)lParam;
263 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
264
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);
269
270 /* Initialize the delay combobox */
271 for (n = 0; n < DELAYTICKS; n++)
272 {
273 if (pGlobalData->filterKeys.iDelayMSec < nDelayArray[n])
274 break;
275 }
276 n--;
277
278 for (i = 0; i < DELAYTICKS; i++)
279 {
280 AddComboBoxTime(hwndDlg, IDC_REPEAT_DELAY_COMBO, nDelayArray[i]);
281 }
282
283 SendDlgItemMessage(hwndDlg, IDC_REPEAT_DELAY_COMBO, CB_SETCURSEL, n, 0);
284
285 /* Initialize the repeat combobox */
286 for (n = 0; n < REPEATTICKS; n++)
287 {
288 if (pGlobalData->filterKeys.iRepeatMSec < nRepeatArray[n])
289 break;
290 }
291 n--;
292
293 for (i = 0; i < REPEATTICKS; i++)
294 {
295 AddComboBoxTime(hwndDlg, IDC_REPEAT_REPEAT_COMBO, nRepeatArray[i]);
296 }
297
298 SendDlgItemMessage(hwndDlg, IDC_REPEAT_REPEAT_COMBO, CB_SETCURSEL, n, 0);
299
300 /* Disable the delay and repeat comboboxes if needed */
301 if (pGlobalData->filterKeys.iDelayMSec == 0)
302 {
303 EnableWindow(GetDlgItem(hwndDlg, IDC_REPEAT_DELAY_COMBO), FALSE);
304 EnableWindow(GetDlgItem(hwndDlg, IDC_REPEAT_REPEAT_COMBO), FALSE);
305 }
306
307 /* Initialize the wait combobox */
308 for (n = 0; n < WAITTICKS; n++)
309 {
310 if (pGlobalData->filterKeys.iWaitMSec < nWaitArray[n])
311 break;
312 }
313 n--;
314
315 for (i = 0; i < WAITTICKS; i++)
316 {
317 AddComboBoxTime(hwndDlg, IDC_REPEAT_WAIT_COMBO, nWaitArray[i]);
318 }
319
320 SendDlgItemMessage(hwndDlg, IDC_REPEAT_WAIT_COMBO, CB_SETCURSEL, n, 0);
321 break;
322
323 case WM_COMMAND:
324 switch (LOWORD(wParam))
325 {
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);
331 break;
332
333 case IDC_REPEAT_REPEAT_RADIO:
334 EnableWindow(GetDlgItem(hwndDlg, IDC_REPEAT_DELAY_COMBO), TRUE);
335 EnableWindow(GetDlgItem(hwndDlg, IDC_REPEAT_REPEAT_COMBO), TRUE);
336 break;
337
338 case IDC_REPEAT_DELAY_COMBO:
339 if (HIWORD(wParam) == CBN_SELCHANGE)
340 {
341 i = SendDlgItemMessage(hwndDlg, IDC_REPEAT_DELAY_COMBO, CB_GETCURSEL, 0, 0);
342 if (i != CB_ERR)
343 {
344 pGlobalData->filterKeys.iDelayMSec = nDelayArray[i];
345 }
346 }
347 break;
348
349 case IDC_REPEAT_REPEAT_COMBO:
350 if (HIWORD(wParam) == CBN_SELCHANGE)
351 {
352 i = SendDlgItemMessage(hwndDlg, IDC_REPEAT_REPEAT_COMBO, CB_GETCURSEL, 0, 0);
353 if (i != CB_ERR)
354 {
355 pGlobalData->filterKeys.iRepeatMSec = nRepeatArray[i];
356 }
357 }
358 break;
359
360 case IDC_REPEAT_WAIT_COMBO:
361 if (HIWORD(wParam) == CBN_SELCHANGE)
362 {
363 i = SendDlgItemMessage(hwndDlg, IDC_REPEAT_WAIT_COMBO, CB_GETCURSEL, 0, 0);
364 if (i != CB_ERR)
365 {
366 pGlobalData->filterKeys.iWaitMSec = nWaitArray[i];
367 }
368 }
369 break;
370
371 case IDC_REPEAT_TEST_EDIT:
372 switch (HIWORD(wParam))
373 {
374 case EN_SETFOCUS:
375 EnableFilterKeysTest(pGlobalData);
376 break;
377
378 case EN_KILLFOCUS:
379 DisableFilterKeysTest(pGlobalData);
380 break;
381 }
382 break;
383
384 case IDOK:
385 EndDialog(hwndDlg, TRUE);
386 break;
387
388 case IDCANCEL:
389 EndDialog(hwndDlg, FALSE);
390 break;
391
392 default:
393 break;
394 }
395 break;
396 }
397
398 return FALSE;
399 }
400
401
402 /* Property page dialog callback */
403 INT_PTR CALLBACK
404 FilterKeysDlgProc(HWND hwndDlg,
405 UINT uMsg,
406 WPARAM wParam,
407 LPARAM lParam)
408 {
409 PGLOBAL_DATA pGlobalData;
410
411 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
412
413 switch (uMsg)
414 {
415 case WM_INITDIALOG:
416 pGlobalData = (PGLOBAL_DATA)lParam;
417 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
418
419 memcpy(&pGlobalData->oldFilterKeys,
420 &pGlobalData->filterKeys,
421 sizeof(FILTERKEYS));
422
423 CheckDlgButton(hwndDlg,
424 IDC_FILTER_ACTIVATE_CHECK,
425 pGlobalData->filterKeys.dwFlags & FKF_HOTKEYACTIVE ? BST_CHECKED : BST_UNCHECKED);
426
427 if (pGlobalData->filterKeys.iBounceMSec != 0)
428 {
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);
432 }
433 else
434 {
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);
438 }
439
440 CheckDlgButton(hwndDlg,
441 IDC_FILTER_SOUND_CHECK,
442 pGlobalData->filterKeys.dwFlags & FKF_CLICKON ? BST_CHECKED : BST_UNCHECKED);
443
444 CheckDlgButton(hwndDlg,
445 IDC_FILTER_STATUS_CHECK,
446 pGlobalData->filterKeys.dwFlags & FKF_INDICATOR ? BST_CHECKED : BST_UNCHECKED);
447 break;
448
449 case WM_COMMAND:
450 switch (LOWORD(wParam))
451 {
452 case IDC_FILTER_ACTIVATE_CHECK:
453 pGlobalData->filterKeys.dwFlags ^= FKF_HOTKEYACTIVE;
454 break;
455
456 case IDC_FILTER_BOUNCE_RADIO:
457 EnableWindow(GetDlgItem(hwndDlg, IDC_FILTER_BOUNCE_BUTTON), TRUE);
458 EnableWindow(GetDlgItem(hwndDlg, IDC_FILTER_REPEAT_BUTTON), FALSE);
459 break;
460
461 case IDC_FILTER_REPEAT_RADIO:
462 EnableWindow(GetDlgItem(hwndDlg, IDC_FILTER_BOUNCE_BUTTON), FALSE);
463 EnableWindow(GetDlgItem(hwndDlg, IDC_FILTER_REPEAT_BUTTON), TRUE);
464 break;
465
466 case IDC_FILTER_BOUNCE_BUTTON:
467 DialogBoxParam(hApplet,
468 MAKEINTRESOURCE(IDD_BOUNCEKEYSOPTIONS),
469 hwndDlg,
470 (DLGPROC)BounceKeysDlgProc,
471 (LPARAM)pGlobalData);
472 break;
473
474 case IDC_FILTER_TEST_EDIT:
475 switch (HIWORD(wParam))
476 {
477 case EN_SETFOCUS:
478 EnableFilterKeysTest(pGlobalData);
479 break;
480
481 case EN_KILLFOCUS:
482 DisableFilterKeysTest(pGlobalData);
483 break;
484 }
485 break;
486
487 case IDC_FILTER_SOUND_CHECK:
488 pGlobalData->filterKeys.dwFlags ^= FKF_CLICKON;
489 break;
490
491 case IDC_FILTER_REPEAT_BUTTON:
492 DialogBoxParam(hApplet,
493 MAKEINTRESOURCE(IDD_REPEATKEYSOPTIONS),
494 hwndDlg,
495 (DLGPROC)RepeatKeysDlgProc,
496 (LPARAM)pGlobalData);
497 break;
498
499 case IDC_FILTER_STATUS_CHECK:
500 pGlobalData->filterKeys.dwFlags ^= FKF_INDICATOR;
501 break;
502
503 case IDOK:
504 EndDialog(hwndDlg,
505 (pGlobalData->filterKeys.dwFlags != pGlobalData->oldFilterKeys.dwFlags));
506 break;
507
508 case IDCANCEL:
509 EndDialog(hwndDlg, FALSE);
510 break;
511
512 default:
513 break;
514 }
515 break;
516 }
517
518 return FALSE;
519 }
520
521
522 /* Property page dialog callback */
523 INT_PTR CALLBACK
524 ToggleKeysDlgProc(HWND hwndDlg,
525 UINT uMsg,
526 WPARAM wParam,
527 LPARAM lParam)
528 {
529 PGLOBAL_DATA pGlobalData;
530
531 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
532
533 switch (uMsg)
534 {
535 case WM_INITDIALOG:
536 pGlobalData = (PGLOBAL_DATA)lParam;
537 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
538
539 memcpy(&pGlobalData->oldToggleKeys,
540 &pGlobalData->toggleKeys,
541 sizeof(TOGGLEKEYS));
542
543 CheckDlgButton(hwndDlg,
544 IDC_TOGGLE_ACTIVATE_CHECK,
545 pGlobalData->toggleKeys.dwFlags & TKF_HOTKEYACTIVE ? BST_CHECKED : BST_UNCHECKED);
546 break;
547
548 case WM_COMMAND:
549 switch (LOWORD(wParam))
550 {
551 case IDC_TOGGLE_ACTIVATE_CHECK:
552 pGlobalData->toggleKeys.dwFlags ^= TKF_HOTKEYACTIVE;
553 break;
554
555 case IDOK:
556 EndDialog(hwndDlg,
557 (pGlobalData->toggleKeys.dwFlags != pGlobalData->oldToggleKeys.dwFlags));
558 break;
559
560 case IDCANCEL:
561 EndDialog(hwndDlg, FALSE);
562 break;
563
564 default:
565 break;
566 }
567 break;
568 }
569
570 return FALSE;
571 }
572
573
574 /* Property page dialog callback */
575 INT_PTR CALLBACK
576 KeyboardPageProc(HWND hwndDlg,
577 UINT uMsg,
578 WPARAM wParam,
579 LPARAM lParam)
580 {
581 PGLOBAL_DATA pGlobalData;
582 LPPSHNOTIFY lppsn;
583
584 pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
585
586 switch (uMsg)
587 {
588 case WM_INITDIALOG:
589 pGlobalData = (PGLOBAL_DATA)((LPPROPSHEETPAGE)lParam)->lParam;
590 if (pGlobalData == NULL)
591 return FALSE;
592
593 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData);
594
595 CheckDlgButton(hwndDlg,
596 IDC_STICKY_BOX,
597 pGlobalData->stickyKeys.dwFlags & SKF_STICKYKEYSON ? BST_CHECKED : BST_UNCHECKED);
598
599 CheckDlgButton(hwndDlg,
600 IDC_FILTER_BOX,
601 pGlobalData->filterKeys.dwFlags & FKF_FILTERKEYSON ? BST_CHECKED : BST_UNCHECKED);
602
603 CheckDlgButton(hwndDlg,
604 IDC_TOGGLE_BOX,
605 pGlobalData->toggleKeys.dwFlags & TKF_TOGGLEKEYSON ? BST_CHECKED : BST_UNCHECKED);
606
607 CheckDlgButton(hwndDlg,
608 IDC_KEYBOARD_EXTRA,
609 pGlobalData->bKeyboardPref ? BST_CHECKED : BST_UNCHECKED);
610 return TRUE;
611
612 case WM_COMMAND:
613 switch (LOWORD(wParam))
614 {
615 case IDC_STICKY_BOX:
616 pGlobalData->stickyKeys.dwFlags ^= SKF_STICKYKEYSON;
617 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
618 break;
619
620 case IDC_STICKY_BUTTON:
621 if (DialogBoxParam(hApplet,
622 MAKEINTRESOURCE(IDD_STICKYKEYSOPTIONS),
623 hwndDlg,
624 (DLGPROC)StickyKeysDlgProc,
625 (LPARAM)pGlobalData))
626 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
627 break;
628
629 case IDC_FILTER_BOX:
630 pGlobalData->filterKeys.dwFlags ^= FKF_FILTERKEYSON;
631 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
632 break;
633
634 case IDC_FILTER_BUTTON:
635 if (DialogBoxParam(hApplet,
636 MAKEINTRESOURCE(IDD_FILTERKEYSOPTIONS),
637 hwndDlg,
638 (DLGPROC)FilterKeysDlgProc,
639 (LPARAM)pGlobalData))
640 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
641 break;
642
643 case IDC_TOGGLE_BOX:
644 pGlobalData->toggleKeys.dwFlags ^= TKF_TOGGLEKEYSON;
645 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
646 break;
647
648 case IDC_TOGGLE_BUTTON:
649 if (DialogBoxParam(hApplet,
650 MAKEINTRESOURCE(IDD_TOGGLEKEYSOPTIONS),
651 hwndDlg,
652 (DLGPROC)ToggleKeysDlgProc,
653 (LPARAM)pGlobalData))
654 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
655 break;
656
657 case IDC_KEYBOARD_EXTRA:
658 pGlobalData->bKeyboardPref = !pGlobalData->bKeyboardPref;
659 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
660 break;
661
662 default:
663 break;
664 }
665 break;
666
667 case WM_NOTIFY:
668 lppsn = (LPPSHNOTIFY)lParam;
669 if (lppsn->hdr.code == PSN_APPLY)
670 {
671 SystemParametersInfo(SPI_SETSTICKYKEYS,
672 sizeof(STICKYKEYS),
673 &pGlobalData->stickyKeys,
674 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE /*0*/);
675
676 SystemParametersInfo(SPI_SETFILTERKEYS,
677 sizeof(FILTERKEYS),
678 &pGlobalData->filterKeys,
679 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE /*0*/);
680
681 SystemParametersInfo(SPI_SETTOGGLEKEYS,
682 sizeof(TOGGLEKEYS),
683 &pGlobalData->toggleKeys,
684 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE /*0*/);
685
686 SystemParametersInfo(SPI_SETKEYBOARDPREF,
687 pGlobalData->bKeyboardPref,
688 NULL,
689 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE /*0*/);
690
691 return TRUE;
692 }
693 break;
694 }
695
696 return FALSE;
697 }