在 Windows 控制台中获取按键

Posted

技术标签:

【中文标题】在 Windows 控制台中获取按键【英文标题】:Get key press in windows console 【发布时间】:2016-12-18 20:40:03 【问题描述】:

我在网上找到了this piece of code:

CHAR getch() 
    DWORD mode, cc;
    HANDLE h = GetStdHandle( STD_INPUT_HANDLE );

    if (h == NULL) 
        return 0; // console not found
    

    GetConsoleMode( h, &mode );
    SetConsoleMode( h, mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT) );
    TCHAR c = 0;
    ReadConsole( h, &c, 1, &cc, NULL );
    SetConsoleMode( h, mode );
    return c;

像这样使用它:

while(1) 
    TCHAR key = getch();

我能够获得数字、字母甚至返回按键。但我无法获得转义或其他功能键,如控制、alt。是否可以对其进行修改以检测这些键?

【问题讨论】:

【参考方案1】:

如果像控制和 alt 键这样的东西,这些是虚拟键击,它们是字符的补充。您将需要使用ReadConsoleInput。但你会得到一切,鼠标也一样。所以你真的需要从调用中过滤并返回一个结构,这样你就知道它是否是 ctrl-A Alt-A 之类的。如果您不想要它们,过滤重复。

这可能需要工作,不知道你在追求什么......

bool getconchar( KEY_EVENT_RECORD& krec )

    DWORD cc;
    INPUT_RECORD irec;
    HANDLE h = GetStdHandle( STD_INPUT_HANDLE );

    if (h == NULL)
    
        return false; // console not found
    

    for( ; ; )
    
        ReadConsoleInput( h, &irec, 1, &cc );
        if( irec.EventType == KEY_EVENT
            &&  ((KEY_EVENT_RECORD&)irec.Event).bKeyDown
            )//&& ! ((KEY_EVENT_RECORD&)irec.Event).wRepeatCount )
        
            krec= (KEY_EVENT_RECORD&)irec.Event;
            return true;
        
    
    return false; //future ????


int main( )

    KEY_EVENT_RECORD key;
    for( ; ; )
    
        getconchar( key );
        std::cout << "key: " << key.uChar.AsciiChar
            << " code:  " << key.wVirtualKeyCode << std::endl;
    

ReadConsoleInput function

INPUT_RECORD structure

KEY_EVENT_RECORD structure

Virtual-Key Codes

【讨论】:

【参考方案2】:

你有很多方法来获取键盘输入

您可以使用 GetAsyncKeyState https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms646293(v=vs.85).aspx 或 GetKeyState https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms646301.aspx

比getch好很多

【讨论】:

这些适用于 GUI 应用程序,而不适用于控制台应用程序。您将获得的结果不会与控制台输入缓冲区的状态同步。 你会得到字符,你不会让它们与控制台输入函数同步,Win32 标准输入和 CRT 标准输入(和 GetAsyncKeyState 你甚至不会让它们同步与线程的输入队列)。这有微妙的含义,所以除非你完全理解它们,否则你应该避免这些东西。

以上是关于在 Windows 控制台中获取按键的主要内容,如果未能解决你的问题,请参考以下文章

控制台检查按下的键,就像在 monogame 中一样

python如何用按键控制程序开始?

在 .NET 控制台应用程序中监听按键

如何检查是不是已在 Ruby 和 Windows 控制台中按下箭头键

获取在C#中输入控制台输入所需的时间

inputsimulator - Windows Input Simulator