LRESULT HookWnd::OnHookKeyUp(WPARAM wParam, LPARAM lParam) { TRACE("KeyUp 0x%x\n", wParam); // check the key that the user had released // if it the special key then tell the user that the key is no longer down if (IsSpecialKey(wParam)) { // the key is no longer down // but was it down at all to start with? - (sanity check) if ((_keyState & ACTION_MAINKEY_DOWN) == ACTION_MAINKEY_DOWN) { // remove the fact that the key was pressed. // do that next time we come around here we don't do it again _keyState &= ~ACTION_MAINKEY_DOWN; // execute the command _application.ExecuteCurrentAction(); // we are hidding the current action _actions.CurrentActionReset(); // hide the window _display.Hide(); // tell the system that we can now accept key press hook_RejectKeyboad(FALSE); _display.Inactive(); } } switch (wParam) { case VK_SHIFT: case VK_RSHIFT: case VK_LSHIFT: _keyState &= ~ACTION_SHIFT_DOWN; _keyState &= ~ACTION_LSHIFT_DOWN; break; default: break; } /** * The WM_KEYUP message is posted to the window with the keyboard focus when a nonsystem key is released. * A nonsystem key is a key that is pressed when the ALT key is not pressed, * or a keyboard key that is pressed when a window has the keyboard focus. */ return 0L; }
/* * Process a keypress event * * Also appears in "main-x11.c". */ static void react_keypress(XKeyEvent *xev) { int i, n, mc, ms, mo, mx; uint ks1; XKeyEvent *ev = (XKeyEvent*)(xev); KeySym ks; char buf[128]; char msg[128]; /* Check for "normal" keypresses */ n = XLookupString(ev, buf, 125, &ks, NULL); /* Terminate */ buf[n] = '\0'; /* Hack -- Ignore "modifier keys" */ if (IsModifierKey(ks)) return; /* Hack -- convert into an unsigned int */ ks1 = (uint)(ks); /* Extract four "modifier flags" */ mc = (ev->state & ControlMask) ? TRUE : FALSE; ms = (ev->state & ShiftMask) ? TRUE : FALSE; mo = (ev->state & Mod1Mask) ? TRUE : FALSE; mx = (ev->state & Mod2Mask) ? TRUE : FALSE; /* Normal keys with no modifiers */ if (n && !mo && !mx && !IsSpecialKey(ks)) { /* Enqueue the normal key(s) */ for (i = 0; buf[i]; i++) Term_keypress(buf[i]); /* All done */ return; } /* Handle a few standard keys (bypass modifiers) XXX XXX XXX */ switch (ks1) { case XK_Escape: { Term_keypress(ESCAPE); return; } case XK_Return: { Term_keypress('\r'); return; } case XK_Tab: { Term_keypress('\t'); return; } case XK_Delete: case XK_BackSpace: { Term_keypress('\010'); return; } } /* Hack -- Use the KeySym */ if (ks) { sprintf(msg, "%c%s%s%s%s_%lX%c", 31, mc ? "N" : "", ms ? "S" : "", mo ? "O" : "", mx ? "M" : "", (unsigned long)(ks), 13); } /* Hack -- Use the Keycode */ else { sprintf(msg, "%c%s%s%s%sK_%X%c", 31, mc ? "N" : "", ms ? "S" : "", mo ? "O" : "", mx ? "M" : "", ev->keycode, 13); } /* Enqueue the "macro trigger" string */ for (i = 0; msg[i]; i++) Term_keypress(msg[i]); /* Hack -- auto-define macros as needed */ if (n && (macro_find_exact(msg) < 0)) { /* Create a macro */ macro_add(msg, buf); } }
/** * Is this "special" key handled by the focused control? (bypassing * the dialog manager) */ gcc_pure static bool CheckSpecialKey(ContainerWindow *container, const Event &event) { return IsSpecialKey(event.GetKeyCode()) && CheckKey(container, event); }
LRESULT HookWnd::OnHookKeyDown(WPARAM wParam, LPARAM lParam) { TRACE("KeyDown 0x%x\n", wParam); /** * The WM_KEYDOWN message is posted to the window with the keyboard focus when a nonsystem key is pressed. * A nonsystem key is a key that is pressed when the ALT key is not pressed. */ // if it is the special key then tell the system that from now own // we need to record keys and prevent any other key from passing accross. if (IsSpecialKey(wParam)) { // only do it if the key was NOT down previously. // otherwise we will forever be reseting if ((_keyState & ACTION_MAINKEY_DOWN) != ACTION_MAINKEY_DOWN) { // we need to save the last forground window // because showing our dialog box will change things a bit. _application.SetLastForegroundWindow( ); // tell the system to no longer accept any more key _keyState |= ACTION_MAINKEY_DOWN; hook_RejectKeyboad(TRUE); _display.Active(); // reset the last command _actions.CurrentActionReset(); _display.Show( _actions.ToChar() ); } } // if the special key is not down then we don't need to go any further if ((_keyState & ACTION_MAINKEY_DOWN) != ACTION_MAINKEY_DOWN) { return 0L; } switch (wParam) { case VK_BACK: // backspace _actions.CurrentActionBack(); _display.Show( _actions.ToChar() ); break; case 0x0A: // linefeed case VK_TAB: // tab case VK_RETURN: // carriage return case VK_CLEAR: break; case VK_ESCAPE: _actions.CurrentActionReset(); _display.Show( _actions.ToChar() ); break; case VK_DOWN: _actions.down(); _display.Show( _actions.ToChar() ); break; case VK_CAPITAL: break; case VK_UP: _actions.up(); _display.Show( _actions.ToChar() ); break; case VK_SHIFT: case VK_RSHIFT: _keyState |= ACTION_SHIFT_DOWN; break; case VK_LSHIFT: _keyState |= (ACTION_SHIFT_DOWN | ACTION_LSHIFT_DOWN); break; default: { BYTE ks[256]; memset(ks, 0, sizeof(ks)); GetKeyboardState(ks); WORD w; UINT scan = 0; ks[VK_SHIFT] = 1; if ((_keyState & ACTION_SHIFT_DOWN) == ACTION_SHIFT_DOWN) { // force the shift key down. // the low level keyboad does not alway pass the key(shift) before the letter key // so we might not know that the shift key is pressed. // so we set it here. ks[VK_SHIFT] = 129; } if (0 != ToAscii(wParam, scan, ks, &w, 0)) { const auto c = static_cast<TCHAR>(CHAR(w)); // add the current character to the list of items _actions.CurrentActionAdd(c); // make sure that the window is visible // This will also force a refresh of the window _display.Show( _actions.ToChar() ); } } break; } return 0L; }