简体   繁体   English

在 windows 控制台获取按键

[英]Get key press in windows console

I foundthis piece of code online:我在网上找到了这段代码

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;
}

Using it like:像这样使用它:

while(1) {
    TCHAR key = getch();
}

I am able to get numeric, alphabetic even return key presses.我能够获得数字、字母甚至回车键。 But am not able to get escape or other functional keys like control, alt.但我无法获得转义键或其他功能键,如 control、alt。 Is it possible to modify it to detect also these keys?是否可以修改它以检测这些键?

If stuff like control and alt keys, these are virtual key strokes, they are supplements to characters. 如果诸如控制键和alt键之类的东西是虚拟按键,则它们是字符的补充。 You will need to use ReadConsoleInput . 您将需要使用ReadConsoleInput But you will get it all, the mouse also. 但是您将获得全部,鼠标也一样。 So you really need to filter and return a structure from the call so you know if it is the likes of ctrl-A Alt-A. 因此,您确实需要从调用中过滤并返回一个结构,以便知道它是否类似于ctrl-A Alt-A。 Filter repeats if you don't want them. 如果您不想重复过滤器。

This may need work, don't know what you are after... 这可能需要工作,不知道您要干什么...

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 ReadConsoleInput函数

INPUT_RECORD structure INPUT_RECORD结构

KEY_EVENT_RECORD structure KEY_EVENT_RECORD结构

Virtual-Key Codes 虚拟键码

The following code captures any key press.以下代码捕获任何按键。 It is used to return from a function.它用于从 function 返回。

Documentation:文档:

https://learn.microsoft.com/en-us/windows/console/readconsoleinput?redirectedfrom=MSDN https://learn.microsoft.com/en-us/windows/console/readconsoleinput?redirectedfrom=MSDN

https://learn.microsoft.com/en-us/windows/console/input-record-str?redirectedfrom=MSDN https://learn.microsoft.com/en-us/windows/console/input-record-str?redirectedfrom=MSDN

https://learn.microsoft.com/en-us/windows/console/key-event-record-str?redirectedfrom=MSDN https://learn.microsoft.com/en-us/windows/console/key-event-record-str?redirectedfrom=MSDN

Purpose The function does some calculations, the progress of which are shown to the user on the console.目的 function 进行一些计算,其进度在控制台上显示给用户。 When all is done the user wishes to return from the function. She does that by pressing any key.完成所有操作后,用户希望从 function 返回。她通过按任意键来实现。 In all my other applications the user can return with the Esc key, so it is nice to have that work also here.在我所有的其他应用程序中,用户可以使用 Esc 键返回,所以很高兴在这里也有这项工作。

It works by allocating the console and setting handles for output from and input to the console.它的工作原理是从控制台分配控制台并设置 output 的句柄并输入到控制台。 Flags OKflg_out and OKflg_in are set to verify the operations at the end.设置标志 OKflg_out 和 OKflg_in 以验证最后的操作。 The for (; ;)-loop after the message "Press any key."消息“按任意键”后的 for (; ;) 循环。 to the user ends when the user presses a key.当用户按下一个键时,到用户结束。

The numerical code for the pressed key is (((irec.Event).KeyEvent).uChar).AsciiChar, but it is not used here.按下的键的数字代码是 (((irec.Event).KeyEvent).uChar).AsciiChar,但这里没有使用。 It could of course be used as a return code to determine the following actions in the calling function.它当然可以用作返回码,以确定调用 function 中的以下操作。

#include <windows.h>
// Various other includes.
void wrintf0(HANDLE stdOut, unsigned char *message)
{
    DWORD written=0;
    WriteConsoleA(stdOut, message, strleni(message), &written, NULL);
}
#define wrintf(message) wrintf0(stdOut,message)
// Various code lines.
void Myfunction(void)
{
    unsigned char OKflg_in=0,OKflg_out=0;
    HANDLE stdIn,stdOut;
    // Various code lines.
    AllocConsole();
    stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (stdOut != NULL && stdOut != INVALID_HANDLE_VALUE)
    {
        OKflg_out = 1;
        stdIn = GetStdHandle(STD_INPUT_HANDLE);
        if (stdIn != NULL && stdIn != INVALID_HANDLE_VALUE) OKflg_in = 1;
    }
    // Various code lines.
    if (OKflg_out)
    {
        if (OKflg_in)
        {
          DWORD cc;
          INPUT_RECORD irec;
          wrintf("Press any key.");
          for(; ;) {
              ReadConsoleInput(stdIn, &irec, 1, &cc );
              if (irec.EventType == KEY_EVENT && ((irec.Event).KeyEvent).bKeyDown) break;
          }
          CloseHandle(stdIn);
        }
        CloseHandle(stdOut);
    }
    FreeConsole();
    return;
}

you have a lot of ways to get the keyboard inputs 您有很多方法来获取键盘输入

you can use GetAsyncKeyState https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms646293(v=vs.85).aspx or GetKeyState https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms646301.aspx 您可以使用GetAsyncKeyState https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms646293(v=vs.85).aspx或GetKeyState https://msdn.microsoft.com/fr-fr/库/窗/桌面/ ms646301.aspx

which are far better than getch 比起getch要好得多

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM