VOID NTAPI ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg) { static BYTE KeyState[256] = { 0 }; /* MSDN mentions that you should use the last virtual key code received * when putting a virtual key identity to a WM_CHAR message since multiple * or translated keys may be involved. */ static UINT LastVirtualKey = 0; DWORD ShiftState; WCHAR UnicodeChar; UINT VirtualKeyCode; UINT VirtualScanCode; BOOL Down = FALSE; BOOLEAN Fake; // Synthesized, not a real event BOOLEAN NotChar; // Message should not be used to return a character INPUT_RECORD er; if (Console == NULL) { DPRINT1("No Active Console!\n"); return; } VirtualScanCode = HIWORD(msg->lParam) & 0xFF; Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; GetKeyboardState(KeyState); ShiftState = ConioGetShiftState(KeyState, msg->lParam); if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) { VirtualKeyCode = LastVirtualKey; UnicodeChar = msg->wParam; } else { WCHAR Chars[2]; INT RetChars = 0; VirtualKeyCode = msg->wParam; RetChars = ToUnicodeEx(VirtualKeyCode, VirtualScanCode, KeyState, Chars, 2, 0, NULL); UnicodeChar = (RetChars == 1 ? Chars[0] : 0); } Fake = UnicodeChar && (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); if (NotChar) LastVirtualKey = msg->wParam; DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n", Down ? "down" : "up ", (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? "char" : "key ", Fake ? "fake" : "real", NotChar ? "notc" : "char", VirtualScanCode, VirtualKeyCode, (UnicodeChar >= L' ') ? UnicodeChar : L'.', ShiftState); if (Fake) return; /* Process Ctrl-C and Ctrl-Break */ if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT && Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') && (ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80) ) { DPRINT1("Console_Api Ctrl-C\n"); ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT); if (Console->LineBuffer && !Console->LineComplete) { /* Line input is in progress; end it */ Console->LinePos = Console->LineSize = 0; Console->LineComplete = TRUE; } return; } if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 && (VirtualKeyCode == VK_UP || VirtualKeyCode == VK_DOWN) ) { if (!Down) return; /* Scroll up or down */ if (VirtualKeyCode == VK_UP) { /* Only scroll up if there is room to scroll up into */ if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1) { Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + Console->ActiveBuffer->ScreenBufferSize.Y - 1) % Console->ActiveBuffer->ScreenBufferSize.Y; Console->ActiveBuffer->CursorPosition.Y++; } } else { /* Only scroll down if there is room to scroll down into */ if (Console->ActiveBuffer->CursorPosition.Y != 0) { Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % Console->ActiveBuffer->ScreenBufferSize.Y; Console->ActiveBuffer->CursorPosition.Y--; } } ConioDrawConsole(Console); return; } /* Send the key press to the console driver */ er.EventType = KEY_EVENT; er.Event.KeyEvent.bKeyDown = Down; er.Event.KeyEvent.wRepeatCount = 1; er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; er.Event.KeyEvent.dwControlKeyState = ShiftState; ConioProcessInputEvent(Console, &er); }
VOID WINAPI ConioProcessKey(PCONSOLE Console, MSG* msg) { static BYTE KeyState[256] = { 0 }; /* MSDN mentions that you should use the last virtual key code received * when putting a virtual key identity to a WM_CHAR message since multiple * or translated keys may be involved. */ static UINT LastVirtualKey = 0; DWORD ShiftState; WCHAR UnicodeChar; UINT VirtualKeyCode; UINT VirtualScanCode; BOOL Down = FALSE; BOOLEAN Fake; // synthesized, not a real event BOOLEAN NotChar; // message should not be used to return a character if (NULL == Console) { DPRINT1("No Active Console!\n"); return; } VirtualScanCode = HIWORD(msg->lParam) & 0xFF; Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; GetKeyboardState(KeyState); ShiftState = ConioGetShiftState(KeyState, msg->lParam); if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) { VirtualKeyCode = LastVirtualKey; UnicodeChar = msg->wParam; } else { WCHAR Chars[2]; INT RetChars = 0; VirtualKeyCode = msg->wParam; RetChars = ToUnicodeEx(VirtualKeyCode, VirtualScanCode, KeyState, Chars, 2, 0, NULL); UnicodeChar = (1 == RetChars ? Chars[0] : 0); } if (ConioProcessKeyCallback(Console, msg, KeyState[VK_MENU], ShiftState, VirtualKeyCode, Down)) { return; } Fake = UnicodeChar && (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); if (NotChar) LastVirtualKey = msg->wParam; DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n", Down ? "down" : "up ", (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? "char" : "key ", Fake ? "fake" : "real", NotChar ? "notc" : "char", VirtualScanCode, VirtualKeyCode, (UnicodeChar >= L' ') ? UnicodeChar : L'.', ShiftState); if (Fake) return; /* Send the key press to the console driver */ ConDrvProcessKey(Console, Down, VirtualKeyCode, VirtualScanCode, UnicodeChar, ShiftState, KeyState[VK_CONTROL]); }