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 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 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 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 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 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 } 698