// ************************************************************************** // Filterkeys dialogs // Process the filterkeys dialogs // ************************************************************************** #include "Access.h" #define SWAP(A, B) ( A ^= B, B ^= A, A ^= B ) // Prototypes BOOL WINAPI BKDlg (HWND, UINT, WPARAM, LPARAM); BOOL WINAPI RKDlg (HWND, UINT, WPARAM, LPARAM); BOOL WINAPI NotificationDlg (HWND, UINT, WPARAM, LPARAM); // Times are in milliseconds #define DELAYSIZE 5 UINT uDelayTable[] = { 300, 700, 1000, 1500, 2000 }; // Times are in milliseconds #define RATESIZE 6 UINT uRateTable[] = { 300, 500, 700, 1000, 1500, 2000 }; // Times are in milliseconds #define BOUNCESIZE 5 UINT uBounceTable[] = { 500, 700, 1000, 1500, 2000 }; // Times are in milliseconds #define ACCEPTSIZE 7 UINT uAcceptTable[] = { 0, 300, 500, 700, 1000, 1400, 2000 }; // ************************************************************************* // Process the scrolling messages from our trackbars. // GENERIC CODE - called for any TrackBar handler. // Passed in the hwnd, wParam, hwndScroll // we can do all handling and return the new trackbar value without // knowing what control it is. // Returns -1 to mean don't do anything // ************************************************************************* int HandleScroll (HWND hwnd, WPARAM wParam, HWND hwndScroll) { int nCurSliderPos = (int) SendMessage( hwndScroll, TBM_GETPOS, 0, 0); int nMaxVal = (int) SendMessage( hwndScroll, TBM_GETRANGEMAX, 0, 0); int nMinVal = (int) SendMessage( hwndScroll, TBM_GETRANGEMIN, 0, 0); switch (LOWORD(wParam)) { case TB_LINEUP: case TB_LINEDOWN: case TB_THUMBTRACK: case TB_THUMBPOSITION: case SB_ENDSCROLL: break; case TB_PAGEUP: if (hwndScroll == GetDlgItem(hwnd, IDC_RK_DELAYRATE) || hwndScroll == GetDlgItem(hwnd, IDC_BK_BOUNCERATE)) nCurSliderPos--; break; case TB_PAGEDOWN: if (hwndScroll == GetDlgItem(hwnd, IDC_RK_DELAYRATE) || hwndScroll == GetDlgItem(hwnd, IDC_BK_BOUNCERATE)) nCurSliderPos++; break; case TB_BOTTOM: nCurSliderPos = nMaxVal; break; case TB_TOP: nCurSliderPos = nMinVal; break; } if (nCurSliderPos < nMinVal) { nCurSliderPos = nMinVal; } if (nCurSliderPos > nMaxVal) { nCurSliderPos = nMaxVal; } SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM) hwnd, 0); return(nCurSliderPos); } void TestFilterKeys (BOOL fTurnTestOn) { DWORD dwFlagsOrig = g_fk.dwFlags; if ((dwFlagsOrig & FKF_FILTERKEYSON) != 0) { // If the user already has FilterKyes on, just leave it on. return; } if (fTurnTestOn) { g_fk.dwFlags &= ~FKF_INDICATOR; g_fk.dwFlags |= FKF_FILTERKEYSON; } else { // Restore the user's original settings. i.e. - do nothing } AccessSystemParametersInfo(SPI_SETFILTERKEYS, sizeof(g_fk), &g_fk, 0); g_fk.dwFlags = dwFlagsOrig; } // **************************************************************************** // Main filter keys dialog handler // **************************************************************************** BOOL WINAPI FilterKeyDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { FILTERKEYS fk; BOOL fProcessed = TRUE; switch (uMsg) { case WM_INITDIALOG: // Setup hotkey CheckDlgButton(hwnd, IDC_FK_HOTKEY, (g_fk.dwFlags & FKF_HOTKEYACTIVE) ? TRUE : FALSE); // Setup the radio buttons for SLOW vs BOUNCE keys if (0 != g_fk.iBounceMSec) { // Bounce keys enabeled CheckRadioButton(hwnd, IDC_FK_BOUNCE, IDC_FK_REPEAT, IDC_FK_BOUNCE); EnableWindow(GetDlgItem(hwnd, IDC_BK_SETTINGS), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_RK_SETTINGS), FALSE); } else { // Slow key enabled CheckRadioButton(hwnd, IDC_FK_BOUNCE, IDC_FK_REPEAT, IDC_FK_REPEAT); EnableWindow(GetDlgItem(hwnd, IDC_BK_SETTINGS), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RK_SETTINGS), TRUE); } CheckDlgButton(hwnd, IDC_FK_SOUND, (g_fk.dwFlags & FKF_CLICKON) ? TRUE : FALSE); CheckDlgButton(hwnd, IDC_FK_STATUS, (g_fk.dwFlags & FKF_INDICATOR) ? TRUE : FALSE); #ifdef HIDE_STATUS if (g_fWinNT) { ShowWindow(GetDlgItem(hwnd, IDC_FK_STATUS), SW_HIDE); } #endif break; case WM_HELP: WinHelp(((LPHELPINFO) lParam)->hItemHandle, __TEXT("access.hlp"), HELP_WM_HELP, (DWORD) (LPSTR) g_aIds); break; case WM_CONTEXTMENU: WinHelp((HWND) wParam, __TEXT("access.hlp"), HELP_CONTEXTMENU, (DWORD) (LPSTR) g_aIds); break; case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_FK_HOTKEY: g_fk.dwFlags ^= FKF_HOTKEYACTIVE; break; case IDC_FK_REPEAT: g_fk.iBounceMSec = 0; if (g_fk.iDelayMSec == 0) { g_fk.iDelayMSec = g_nLastRepeatDelay; g_fk.iRepeatMSec = g_nLastRepeatRate; g_fk.iWaitMSec = g_nLastWait; } CheckRadioButton(hwnd, IDC_FK_REPEAT, IDC_FK_BOUNCE, IDC_FK_REPEAT); EnableWindow(GetDlgItem(hwnd, IDC_BK_SETTINGS), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RK_SETTINGS), TRUE); break; case IDC_FK_BOUNCE: g_fk.iDelayMSec = 0; g_fk.iRepeatMSec = 0; g_fk.iWaitMSec = 0; if (g_fk.iBounceMSec == 0) { g_fk.iBounceMSec = g_dwLastBounceKeySetting; } CheckRadioButton(hwnd, IDC_FK_REPEAT, IDC_FK_BOUNCE, IDC_FK_BOUNCE); EnableWindow(GetDlgItem(hwnd, IDC_BK_SETTINGS), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_RK_SETTINGS), FALSE); break; // Settings dialogs case IDC_RK_SETTINGS: // This is RepeatKeys fk = g_fk; if (DialogBox(g_hinst, MAKEINTRESOURCE(IDD_ADVCHARREPEAT), hwnd, RKDlg) == IDCANCEL) { g_fk = fk; } break; case IDC_BK_SETTINGS: // This is BounceKeys fk = g_fk; if (DialogBox(g_hinst, MAKEINTRESOURCE(IDD_ADVKEYBOUNCE), hwnd, BKDlg) == IDCANCEL) { g_fk = fk; } break; case IDC_FK_SOUND: g_fk.dwFlags ^= FKF_CLICKON; break; case IDC_FK_STATUS: g_fk.dwFlags ^= FKF_INDICATOR; break; // The test edit box is a special control for us. When we get the // focus we turn on the current filterkeys settings, when we // leave the text box, we turn them back to what they were. case IDC_FK_TESTBOX: switch (HIWORD(wParam)) { case EN_SETFOCUS: TestFilterKeys(TRUE); break; case EN_KILLFOCUS: TestFilterKeys(FALSE); break; } break; case IDOK: if (g_dwLastBounceKeySetting == 0) g_dwLastBounceKeySetting = uBounceTable[0]; EndDialog(hwnd, IDOK); break; case IDCANCEL: EndDialog(hwnd, IDCANCEL); break; } break; default: fProcessed = FALSE; break; } return(fProcessed); } void PutNumInEdit (HWND hwndEdit, int nNum) { TCHAR szBuf[10], szBuf2[10]; wsprintf(szBuf, __TEXT("%d.%d"), nNum / 1000, (nNum % 1000) / 100); GetNumberFormat(LOCALE_USER_DEFAULT, 0, szBuf, NULL, szBuf2, 6); SetWindowText(hwndEdit, szBuf2); } // ************************************************************************** // BKDlg // Process the BounceKeys dialog. // ************************************************************************** BOOL WINAPI BKDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int i; BOOL fProcessed = TRUE; switch (uMsg) { case WM_INITDIALOG: // Determine the bounce. SendDlgItemMessage(hwnd, IDC_BK_BOUNCERATE, TBM_SETRANGE, TRUE, MAKELONG(1, BOUNCESIZE)); // Make sure its a valide value. if (g_dwLastBounceKeySetting == 0) g_dwLastBounceKeySetting = 500; if (g_fk.iBounceMSec == 0) g_fk.iBounceMSec = g_dwLastBounceKeySetting; // Find the current value in our table for (i = 0; i < BOUNCESIZE; i++) { if (uBounceTable[i] >= g_fk.iBounceMSec) break; } // If invalid value, make it valid. SendDlgItemMessage(hwnd, IDC_BK_BOUNCERATE, TBM_SETPOS, TRUE, i + 1); PutNumInEdit(GetDlgItem(hwnd, IDC_BK_TIME), uBounceTable[i]); break; // Handle the track bars. case WM_HSCROLL: i = HandleScroll(hwnd, wParam, (HWND)lParam); if (i == -1) return(TRUE); g_fk.iBounceMSec = uBounceTable[--i]; PutNumInEdit(GetDlgItem(hwnd, IDC_BK_TIME), g_fk.iBounceMSec); break; case WM_HELP: // F1 WinHelp(((LPHELPINFO) lParam)->hItemHandle, __TEXT("access.hlp"), HELP_WM_HELP, (DWORD) (LPSTR) g_aIds); break; case WM_CONTEXTMENU: // right mouse click WinHelp((HWND) wParam, __TEXT("access.hlp"), HELP_CONTEXTMENU, (DWORD) (LPSTR) g_aIds); break; case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { // The test edit box is a special control for us. When we get the // focus we turn on the current filterkeys settings, when we // leave the text box, we turn them back to what they were. case IDC_BK_TESTBOX: switch (HIWORD(wParam)) { case EN_SETFOCUS: TestFilterKeys(TRUE); break; case EN_KILLFOCUS: TestFilterKeys(FALSE); break; } break; case IDOK: // Save the last known valid setting. g_dwLastBounceKeySetting = g_fk.iBounceMSec; EndDialog(hwnd, IDOK); break; case IDCANCEL: EndDialog(hwnd, IDCANCEL); break; } break; default: fProcessed = FALSE; break; } return(fProcessed); } // ************************************************************************** // RKDlg // Process the RepeatKeys dialog. // ************************************************************************** BOOL WINAPI RKDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int i; BOOL fProcessed = TRUE; static s_fRepeating = TRUE; static DWORD s_nLastRepeatDelayOld; static DWORD s_nLastRepeatRateOld; static DWORD s_nLastWaitOld; switch(uMsg) { case WM_INITDIALOG: s_nLastRepeatDelayOld = g_nLastRepeatDelay; s_nLastRepeatRateOld = g_nLastRepeatRate; s_nLastWaitOld = g_nLastWait; s_fRepeating = (0 != g_fk.iDelayMSec); CheckRadioButton(hwnd, IDC_RK_NOREPEAT, IDC_RK_REPEAT, s_fRepeating ? IDC_RK_REPEAT : IDC_RK_NOREPEAT); if (!s_fRepeating) { // Set FilterKey values to LastRepeat values // so the sliders will still get initialized correctly g_fk.iDelayMSec = g_nLastRepeatDelay; g_fk.iRepeatMSec = g_nLastRepeatRate; } // Initialize the Acceptance slider to last valid state SendDlgItemMessage(hwnd, IDC_RK_ACCEPTRATE, TBM_SETRANGE, TRUE, MAKELONG(1, ACCEPTSIZE)); for (i = 0; i < ACCEPTSIZE; i++) { if (uAcceptTable[i] >= g_fk.iWaitMSec) break; } SendDlgItemMessage(hwnd, IDC_RK_ACCEPTRATE, TBM_SETPOS, TRUE, i + 1); if (i < 0) i = 0; if (i >= ACCEPTSIZE) i = ACCEPTSIZE - 1; PutNumInEdit(GetDlgItem(hwnd, IDC_RK_WAITTIME), uAcceptTable[i]); g_fk.iWaitMSec = uAcceptTable[i]; // Initialize the Delay slider SendDlgItemMessage(hwnd, IDC_RK_DELAYRATE, TBM_SETRANGE, TRUE, MAKELONG(1, DELAYSIZE)); for (i = 0; i < DELAYSIZE; i++) { if (uDelayTable[i] >= g_fk.iDelayMSec) break; } SendDlgItemMessage(hwnd, IDC_RK_DELAYRATE, TBM_SETPOS, TRUE, i + 1); if (i < 0) i = 0; if (i >= DELAYSIZE) i = DELAYSIZE - 1; PutNumInEdit(GetDlgItem(hwnd, IDC_RK_DELAYTIME), uDelayTable[i]); g_fk.iDelayMSec = uDelayTable[i]; // Initialize the Repeat Rate Slider Note -1 is set via the checkbox. SendDlgItemMessage(hwnd, IDC_RK_REPEATRATE, TBM_SETRANGE, TRUE, MAKELONG(1, RATESIZE)); for (i = 0; i < RATESIZE; i++) { if (uRateTable[i] >= g_fk.iRepeatMSec) break; } SendDlgItemMessage(hwnd, IDC_RK_REPEATRATE, TBM_SETPOS, TRUE, i + 1); if (i < 0) i = 0; if (i >= RATESIZE) i = RATESIZE -1; PutNumInEdit(GetDlgItem(hwnd, IDC_RK_REPEATTIME), uRateTable[i]); g_fk.iRepeatMSec = uRateTable[i]; // Now cleanup from initialization. Disable controls // that usable... Swap back any params needed if (!s_fRepeating) { EnableWindow(GetDlgItem(hwnd, IDC_RK_REPEATRATE), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RK_DELAYRATE), FALSE); // If we're not repeating, now set the value to 0 // which indicates max repeat rate. g_fk.iDelayMSec = 0; g_fk.iRepeatMSec = 0; } break; case WM_HSCROLL: switch (GetWindowLong((HWND) lParam, GWL_ID)) { case IDC_RK_ACCEPTRATE: i = HandleScroll(hwnd, wParam, (HWND)lParam); if (i == -1) return TRUE; g_fk.iWaitMSec = uAcceptTable[--i]; PutNumInEdit(GetDlgItem(hwnd, IDC_RK_WAITTIME), g_fk.iWaitMSec); break; case IDC_RK_DELAYRATE: i = HandleScroll(hwnd, wParam, (HWND)lParam); if (i == -1) return TRUE; g_fk.iDelayMSec = uDelayTable[--i]; PutNumInEdit(GetDlgItem(hwnd, IDC_RK_DELAYTIME), g_fk.iDelayMSec); g_nLastRepeatDelay = g_fk.iDelayMSec; break; case IDC_RK_REPEATRATE: i = HandleScroll(hwnd, wParam, (HWND)lParam); if (i == -1) return TRUE; g_fk.iRepeatMSec = uRateTable[--i]; PutNumInEdit(GetDlgItem(hwnd, IDC_RK_REPEATTIME), g_fk.iRepeatMSec); g_nLastRepeatRate = g_fk.iRepeatMSec; break; } break; case WM_HELP: // F1 WinHelp(((LPHELPINFO) lParam)->hItemHandle, __TEXT("access.hlp"), HELP_WM_HELP, (DWORD) (LPSTR) g_aIds); break; case WM_CONTEXTMENU: // right mouse click WinHelp((HWND) wParam, __TEXT("access.hlp"), HELP_CONTEXTMENU, (DWORD) (LPSTR) g_aIds); break; case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { // Turn on repeat keys - We're disabling via CPL rather than any flags in the call case IDC_RK_REPEAT: if (!s_fRepeating) { g_fk.iDelayMSec = g_nLastRepeatDelay; g_fk.iRepeatMSec = g_nLastRepeatRate; } // Now that we have valid parameters, continue with setting the sliders. s_fRepeating = TRUE; CheckRadioButton(hwnd, IDC_RK_NOREPEAT, IDC_RK_REPEAT, IDC_RK_REPEAT); if (g_fk.iRepeatMSec == 0) { g_fk.iRepeatMSec = 300; SendDlgItemMessage(hwnd, IDC_RK_REPEATRATE, TBM_SETPOS, TRUE, 1); PutNumInEdit(GetDlgItem(hwnd, IDC_RK_REPEATTIME), g_fk.iRepeatMSec); } EnableWindow(GetDlgItem(hwnd, IDC_RK_REPEATRATE), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_RK_DELAYRATE), TRUE); break; // Turn OFF repeat keys case IDC_RK_NOREPEAT: s_fRepeating = FALSE; CheckRadioButton(hwnd, IDC_RK_NOREPEAT, IDC_RK_REPEAT, IDC_RK_NOREPEAT); g_fk.iDelayMSec = 0; g_fk.iRepeatMSec = 0; EnableWindow(GetDlgItem(hwnd, IDC_RK_DELAYRATE), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RK_REPEATRATE), FALSE); break; // Process the test box - turnon filterkeys while inside it. case IDC_RK_TESTBOX: switch (HIWORD(wParam)) { case EN_SETFOCUS: TestFilterKeys(TRUE); break; case EN_KILLFOCUS: TestFilterKeys(FALSE); break; } break; case IDOK: // Save off repeating values to registry EndDialog(hwnd, IDOK); break; case IDCANCEL: g_nLastRepeatDelay = s_nLastRepeatDelayOld; g_nLastRepeatRate = s_nLastRepeatRateOld; g_nLastWait = s_nLastWaitOld; EndDialog(hwnd, IDCANCEL); break; } break; default: fProcessed = FALSE; break; } return(fProcessed); } ///////////////////////////////// End of File /////////////////////////////////