void KeyListener::ProcessInput() { MSG msg = {0}; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) { if (msg.message == WM_HOTKEY) { std::cout << "Hot Key Triggered: " << msg.wParam << std::endl; ProcessHotKey(msg.wParam); } } }
// true - запретить передачу в консоль, сами обработали // pRCon may be NULL, pszChars may be NULL bool CConEmuCtrl::ProcessHotKeyMsg(UINT messg, WPARAM wParam, LPARAM lParam, const wchar_t *pszChars, CRealConsole* pRCon) { _ASSERTE((messg == WM_KEYDOWN || messg == WM_SYSKEYDOWN) || (messg == WM_KEYUP || messg == WM_SYSKEYUP)); WARNING("CConEmuCtrl:: Наверное нужно еще какие-то пляски с бубном при отпускании хоткеев"); WARNING("CConEmuCtrl:: Ибо в CConEmuMain::OnKeyboard была запутанная логика с sm_SkipSingleHostkey, sw_SkipSingleHostkey, sl_SkipSingleHostkey"); // Обновить и подготовить "r.Event.KeyEvent.dwControlKeyState" UpdateControlKeyState(); DWORD vk = (DWORD)(wParam & 0xFF); bool bKeyDown = (messg == WM_KEYDOWN || messg == WM_SYSKEYDOWN); bool bKeyUp = (messg == WM_KEYUP || messg == WM_SYSKEYUP); if (mn_DoubleKeyConsoleNum && (!(vk >= '0' && vk <= '9'))) { //if (!(vk >= '0' && vk <= '9')) // ResetDoubleKeyConsoleNum(); int nNewIdx = -1; // попытка активации одной кнопкой if (mn_DoubleKeyConsoleNum>='1' && mn_DoubleKeyConsoleNum<='9') nNewIdx = mn_DoubleKeyConsoleNum - '1'; else if (mn_DoubleKeyConsoleNum=='0') nNewIdx = 9; ResetDoubleKeyConsoleNum(); if (nNewIdx >= 0) gpConEmu->ConActivate(nNewIdx); } if (bKeyUp) { if ((mb_InWinTabSwitch && (vk == VK_RWIN || vk == VK_LWIN)) || (mb_InCtrlTabSwitch && (vk == VK_CONTROL || vk == VK_LCONTROL || vk == VK_RCONTROL))) { mb_InWinTabSwitch = mb_InCtrlTabSwitch = FALSE; gpConEmu->TabCommand(ctc_SwitchCommit); WARNING("CConEmuCtrl:: В фар отпускание кнопки таки пропустим?"); } } // На сами модификаторы - действий не вешается if (vk == VK_LWIN || vk == VK_RWIN /*|| vk == VK_APPS*/ || vk == VK_SHIFT || vk == VK_LSHIFT || vk == VK_RSHIFT || vk == VK_CONTROL || vk == VK_LCONTROL || vk == VK_RCONTROL || vk == VK_MENU || vk == VK_LMENU || vk == VK_RMENU) { if (pRCon) { // Однако, если это был одиночный обработанный модификатор - его нужно "пофиксить", // чтобы на его отпускание не выполнился Far-макрос например if (bKeyUp) { FixSingleModifier(vk, pRCon); } else { _ASSERTE(bKeyDown); int ModCount = 0; if (bLAlt) ModCount++; if (bRAlt) ModCount++; if (bLCtrl) ModCount++; if (bRCtrl) ModCount++; if (bLShift || bRShift) ModCount++; if ((ModCount == 1) && (vk != VK_APPS) && (vk != VK_LWIN)) { mb_LastSingleModifier = FALSE; mn_LastSingleModifier = (vk == VK_LMENU || vk == VK_RMENU || vk == VK_MENU) ? VK_MENU : (vk == VK_LCONTROL || vk == VK_RCONTROL || vk == VK_CONTROL) ? VK_CONTROL : (vk == VK_LSHIFT || vk == VK_RSHIFT || vk == VK_SHIFT) ? VK_SHIFT : 0; if (!mn_LastSingleModifier) { // Win и прочие модификаторы здесь не интересуют } else { mn_SingleModifierFixState = dwControlKeyState; switch (mn_LastSingleModifier) { case VK_MENU: mn_SingleModifierFixKey = VK_CONTROL; mn_SingleModifierFixState |= (LEFT_CTRL_PRESSED); break; case VK_CONTROL: mn_SingleModifierFixKey = VK_MENU; mn_SingleModifierFixState |= (RIGHT_ALT_PRESSED); break; case VK_SHIFT: mn_SingleModifierFixKey = VK_MENU; mn_SingleModifierFixState |= RIGHT_ALT_PRESSED; break; } } } else if (ModCount > 1) { // Больше не нужно mb_LastSingleModifier = FALSE; mn_LastSingleModifier = mn_SingleModifierFixKey = mn_SingleModifierFixState = 0; } } } return false; } ConEmuChord VkState = ChordFromVk(vk); if (bKeyDown) m_SkippedMsg = 0; const ConEmuHotKey* pHotKey = ProcessHotKey(VkState, bKeyDown, pszChars, pRCon); // Для "одиночных" if (pHotKey && mn_LastSingleModifier) { if (pHotKey != ConEmuSkipHotKey) { mb_LastSingleModifier = TRUE; } } else if (!pHotKey && !(VkState.Mod & (cvk_Ctrl|cvk_Alt|cvk_Shift))) { if (bKeyDown) { // Раз мы попали сюда - значит сам Apps у нас не хоткей, но может быть модификатором? if ((vk == VK_APPS) && gpSet->isModifierExist(vk)) { m_SkippedMsg = messg; m_SkippedMsgWParam = wParam; m_SkippedMsgLParam = lParam; // Откладываем либо до // *) нажатия другой кнопки, не перехватываемой нами (например Apps+U) // *) отпускания самого Apps return ConEmuSkipHotKey; } } else if ((vk == VK_APPS) && m_SkippedMsg && pRCon) { // Отпускается Apps. Сначала нужно "дослать" в консоль ее нажатие pRCon->ProcessKeyboard(m_SkippedMsg, m_SkippedMsgWParam, m_SkippedMsgLParam, NULL); } } if (((VkState.Mod & cvk_ALLMASK) == cvk_Win) && (vk == VK_DOWN || vk == VK_LEFT || vk == VK_RIGHT)) { //120821 - в режиме HideCaption почему-то не выходит из Maximized по Win+Down if (gpSet->isCaptionHidden()) { if (vk == VK_DOWN) { if (::IsZoomed(ghWnd)/*тут нужен реальный Zoomed*/) { gpConEmu->SetWindowMode(wmNormal); } } } } return (pHotKey != NULL); }
LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam ) { HWND hwnd, hwndActive; MSG msg; BOOL Esc = FALSE; INT Count = 0; WCHAR Text[1024]; // Already in the loop. if (switchdialog) return 0; hwndActive = GetActiveWindow(); // Nothing is active so exit. if (!hwndActive) return 0; // Capture current active window. SetCapture( hwndActive ); switch (lParam) { case VK_TAB: if( !CreateSwitcherWindow(User32Instance) ) goto Exit; if( !GetDialogFont() ) goto Exit; ProcessHotKey(); break; case VK_ESCAPE: windowCount = 0; Count = 0; EnumWindowsZOrder(EnumerateCallback, 0); if (windowCount < 2) goto Exit; if (wParam == SC_NEXTWINDOW) Count = 1; else { if (windowCount == 2) Count = 0; else Count = windowCount - 1; } TRACE("DoAppSwitch VK_ESCAPE 1 Count %d windowCount %d\n",Count,windowCount); hwnd = windowList[Count]; GetWindowTextW(hwnd, Text, 1023); TRACE("[ATbot] Switching to 0x%08x (%ls)\n", hwnd, Text); MakeWindowActive(hwnd); Esc = TRUE; break; default: goto Exit; } // Main message loop: while (1) { for (;;) { if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE )) { if (!CallMsgFilterW( &msg, MSGF_NEXTWINDOW )) break; /* remove the message from the queue */ PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); } else WaitMessage(); } switch (msg.message) { case WM_KEYUP: { PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); if (msg.wParam == VK_MENU) { CompleteSwitch(TRUE); } else if (msg.wParam == VK_RETURN) { CompleteSwitch(TRUE); } else if (msg.wParam == VK_ESCAPE) { TRACE("DoAppSwitch VK_ESCAPE 2\n"); CompleteSwitch(FALSE); } goto Exit; //break; } case WM_SYSKEYDOWN: { PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); if (HIWORD(msg.lParam) & KF_ALTDOWN) { INT Shift; if ( msg.wParam == VK_TAB ) { if (Esc) break; Shift = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW; if (Shift == SC_NEXTWINDOW) { selectedWindow = (selectedWindow + 1)%windowCount; } else { selectedWindow = selectedWindow - 1; if (selectedWindow < 0) selectedWindow = windowCount - 1; } InvalidateRect(switchdialog, NULL, TRUE); } else if ( msg.wParam == VK_ESCAPE ) { if (!Esc) break; if (windowCount < 2) goto Exit; if (wParam == SC_NEXTWINDOW) { Count = (Count + 1)%windowCount; } else { Count--; if (Count < 0) Count = windowCount - 1; } hwnd = windowList[Count]; GetWindowTextW(hwnd, Text, 1023); MakeWindowActive(hwnd); } } break; } case WM_LBUTTONUP: PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); ProcessMouseMessage(msg.message, msg.lParam); goto Exit; default: if (PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE )) { TranslateMessage(&msg); DispatchMessageW(&msg); } break; } } Exit: ReleaseCapture(); if (switchdialog) DestroyWindow(switchdialog); switchdialog = NULL; selectedWindow = 0; windowCount = 0; return 0; }
LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam ) { HWND hwndActive; MSG msg; // FIXME: Is loading timing OK? LoadCoolSwitchSettings(); if (!CoolSwitch) return 0; // Already in the loop. if (switchdialog || Esc) return 0; hwndActive = GetActiveWindow(); // Nothing is active so exit. if (!hwndActive) return 0; if (lParam == VK_ESCAPE) { Esc = TRUE; windowCount = 0; EnumWindowsZOrder(EnumerateCallback, 0); if (windowCount < 2) return 0; RotateTasks(GetAsyncKeyState(VK_SHIFT) < 0); hwndActive = GetActiveWindow(); if (hwndActive == NULL) { Esc = FALSE; return 0; } } // Capture current active window. SetCapture( hwndActive ); switch (lParam) { case VK_TAB: if( !CreateSwitcherWindow(User32Instance) ) goto Exit; if( !GetDialogFont() ) goto Exit; if( !ProcessHotKey() ) goto Exit; break; case VK_ESCAPE: break; default: goto Exit; } // Main message loop: while (1) { for (;;) { if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE )) { if (!CallMsgFilterW( &msg, MSGF_NEXTWINDOW )) break; /* remove the message from the queue */ PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); } else WaitMessage(); } switch (msg.message) { case WM_KEYUP: { PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); if (msg.wParam == VK_MENU) { CompleteSwitch(TRUE); } else if (msg.wParam == VK_RETURN) { CompleteSwitch(TRUE); } else if (msg.wParam == VK_ESCAPE) { TRACE("DoAppSwitch VK_ESCAPE 2\n"); CompleteSwitch(FALSE); } goto Exit; //break; } case WM_SYSKEYDOWN: { PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); if (HIWORD(msg.lParam) & KF_ALTDOWN) { if ( msg.wParam == VK_TAB ) { if (Esc) break; if (GetKeyState(VK_SHIFT) < 0) { MoveLeft(); } else { MoveRight(); } } else if ( msg.wParam == VK_ESCAPE ) { if (!Esc) break; RotateTasks(GetKeyState(VK_SHIFT) < 0); } else if ( msg.wParam == VK_LEFT ) { MoveLeft(); } else if ( msg.wParam == VK_RIGHT ) { MoveRight(); } else if ( msg.wParam == VK_UP ) { MoveUp(); } else if ( msg.wParam == VK_DOWN ) { MoveDown(); } } break; } case WM_LBUTTONUP: PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); ProcessMouseMessage(msg.message, msg.lParam); goto Exit; default: if (PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE )) { TranslateMessage(&msg); DispatchMessageW(&msg); } break; } } Exit: ReleaseCapture(); if (switchdialog) DestroyWindow(switchdialog); if (Esc) DestroyAppWindows(); switchdialog = NULL; selectedWindow = 0; windowCount = 0; Esc = FALSE; return 0; }