简体   繁体   English

Win32消息循环中的键盘输入

[英]Keyboard Input in Win32 Message Loop

Is there a way of detecting keyboard input within the message loop. 有没有一种方法可以检测消息循环内的键盘输入。 Here is something I've tried below: 这是我在下面尝试过的方法:

LRESULT D3DApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch( msg )
    {     
    // WM_DESTROY is sent when the window is being destroyed.
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_KEYDOWN:
        BYTE keyboardState[256];

        if (keyboardState[DIK_W]) {
            OutputDebugStringW(L"W Button Pressed\n");
        }  

        if (keyboardState[DIK_A]) {
            OutputDebugStringW(L"A Button Pressed\n");
        } 

        if (keyboardState[DIK_S]) {
            OutputDebugStringW(L"S Button Pressed\n");
        } 

        if (keyboardState[DIK_D]) {
            OutputDebugStringW(L"D Button Pressed\n");
        }
        return 0;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

The problem is the it seems to return all of the keyboard states: Output is as follows... 问题是它似乎返回了所有键盘状态:输出如下...

W Button Pressed
A Button Pressed
S Button Pressed
D Button Pressed

How can I implement this so it just detects the key input pressed. 我该如何实现它,使其仅检测按下的按键输入。 I'm new so this might be a stupid implementation :) 我是新手,所以这可能是一个愚蠢的实现:)

You never set the elements when a key is pressed. 按下键时,您永远不会设置元素。

You are also using the keyboardState array as a local variable. 您还将keyboardState数组用作局部变量。 You must make it global or static, because each time the MsgProc function is called the keyboardState is allocated on the stack, and there is no guarantee of its contents, which may have been modified by previous function calls using the same memory space. 您必须使其成为全局或静态的,因为每次调用MsgProc函数时, MsgProc在堆栈上分配keyboardState ,并且不能保证其内容,该内容可能已被以前的函数调用使用相同的内存空间进行了修改。

In your code basically each element of keyboardState has 255/256 chance of being non-zero, and you are detecting that instead of real key presses. 在您的代码中, keyboardState每个元素基本上都有255/256的可能性为非零,并且您正在检测到的不是真正的按键。

If you are not accessing keyboard states from outside, don't bother with the array - just use the wParam argument of the MsgProc function: 如果您不是从外部访问键盘状态,请不要理会该数组-只需使用MsgProc函数的wParam参数MsgProc

 case WM_KEYDOWN:

    if (wParam == DIK_W) {
        OutputDebugStringW(L"W Button Pressed\n");
    }  

    if (wParam == DIK_A) {
        OutputDebugStringW(L"A Button Pressed\n");
    } 

    if (wParam == DIK_S) {
        OutputDebugStringW(L"S Button Pressed\n");
    } 

    if (wParam == DIK_D) {
        OutputDebugStringW(L"D Button Pressed\n");
    }
    return 0;

(Assuming your DIK_ key values are the same as WinAPI's VK_ key codes) (假设您的DIK_密钥值与WinAPI的VK_密钥代码相同)

You are not initializing keyboardState before using it: 您没有在使用它之前初始化keyboardState

case WM_KEYDOWN:
{
    BYTE keyboardState[256];
    ::GetKeyboardState(keyboardState); // <-- ADD THIS!
    ...
    return 0;
}

Alternatively, use Get(Async)KeyState() instead: 或者,改用Get(Async)KeyState()

case WM_KEYDOWN:
{
    if (GetKeyState('W') & 0x8000) {
        OutputDebugStringW(L"W Button is Down\n");
    }  

    if (GetKeyState('A') & 0x8000) {
        OutputDebugStringW(L"A Button is Down\n");
    } 

    if (GetKeyState('S') & 0x8000) {
        OutputDebugStringW(L"S Button is Down\n");
    } 

    if (GetKeyState('D') & 0x8000) {
        OutputDebugStringW(L"D Button is Down\n");
    }

    return 0;
}

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

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