Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Can';t处理WM_键控消息_C++_Windows_Winapi - Fatal编程技术网

C++ Can';t处理WM_键控消息

C++ Can';t处理WM_键控消息,c++,windows,winapi,C++,Windows,Winapi,我试图使用以下wndproc和winmain处理WM_KEYDOWN消息,但当我按下一个键(即ascii值为24、25、26、27的箭头键)时,它不会处理 WndProc LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ /*TO CHECK uMsg message*/ char buff[256]; _itoa_s(uMsg, buff, 10); Set

我试图使用以下wndproc和winmain处理WM_KEYDOWN消息,但当我按下一个键(即ascii值为24、25、26、27的箭头键)时,它不会处理

WndProc

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
    /*TO CHECK uMsg message*/
    char buff[256];
    _itoa_s(uMsg, buff, 10);
    SetWindowText(hEdit, buff);
    /**********************/
    switch (uMsg)
        case WM_CREATE:
            hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "Edit", "", WS_CHILD | WS_VISIBLE |ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL, 735, 5, 150, 100, hWnd, NULL, hInst, NULL);
            HButton1 = CreateWindowEx(NULL, "BUTTON", "START", WS_CHILD | WS_VISIBLE | SS_CENTER, 2, 2, 80, 20, hWnd, (HMENU)IDC_BUTTON1, hInst, NULL);
            HButton2 = CreateWindowEx(NULL, "BUTTON", "B", WS_CHILD | WS_VISIBLE | SS_CENTER, 82, 2, 80, 20, hWnd, (HMENU)IDC_BUTTON2, hInst, NULL);
            HButton3 = CreateWindowEx(NULL, "BUTTON", "STOP", WS_CHILD | WS_VISIBLE | SS_CENTER, 162, 2, 80, 20, hWnd, (HMENU)IDC_BUTTON3, hInst, NULL);
            Hmainbmp = CreateWindowEx(NULL, "STATIC", "", WS_CHILD | WS_VISIBLE | SS_BITMAP | WS_THICKFRAME, 1, 23, 600, 500, hWnd, NULL, hInst, NULL);
            break;
        case WM_KEYDOWN:
            PRESSED_KEY = wParam;
            break;
        case WM_COMMAND:
                    break;
            case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return(DefWindowProc(hWnd, uMsg, wParam, lParam));
    return(0L);
}
WinMain

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){
    MSG      msg;
    WNDCLASSEX wc;
    HMENU MainMenu, FileMenu;
    MainMenu = CreateMenu();
    FileMenu = CreatePopupMenu();
    AppendMenu(FileMenu, MF_STRING, IDC_OPEN, "Open");
    AppendMenu(MainMenu, MF_POPUP, (UINT_PTR)FileMenu, "FILE");

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    wc.lpszMenuName = lpszAppName;
    wc.lpszClassName = lpszAppName;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hIconSm = (HICON)LoadImage(hInstance, lpszAppName, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

    if (!RegisterClassEx(&wc)) return(FALSE);

    hInst = hInstance;
    hWnd = CreateWindowEx(0, lpszAppName, lpszTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 900, 600, NULL, MainMenu, hInstance, NULL);


    if (!hWnd) return(FALSE);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}
为什么下面的案例不起作用?我如何处理WM_键关闭

case WM_KEYDOWN:
    PRESSED_KEY = wParam;
    break;
更新

当我再次最小化和最大化窗口时,
WM_KEYDOWN
已处理,但如果我单击任何按钮,它将不起作用。

根据文档:

当按下非系统键时,以键盘焦点发布到窗口。非系统键是在未按下ALT键时按下的键

但是,窗口中还有其他按钮和编辑框。因此,当您按下其他按钮或单击编辑框时,焦点将集中在该窗口上。这将导致
WndProc
功能无法处理
WM_KEYDOWN
消息

您可以使用该功能设置键盘焦点窗口。然后您可以通过主窗口获取
WM_KEYDOWN
消息,并通过编辑控件显示值

如以下代码所示:

case WM_KEYDOWN:
    PRESSED_KEY = wParam;
    _itoa_s(wParam, buff, 10);
    SetWindowTextA(hEdit, buff);
    break;
当然,如果您不想关注某个特定的窗口来获取键盘信息,我建议您使用该函数来获取全局键盘消息,而不要关注某个特定的窗口

编辑:

如果要处理所有
WM_KEYDOWN
消息,可以使用
SetWindowsHookEx
功能

您只需要修改代码的几个部分:

1.添加处理键盘的功能:

LRESULT __stdcall KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    char buff[256] = "";
    PKBDLLHOOKSTRUCT key = (PKBDLLHOOKSTRUCT)lParam;
    //a key was pressed
    if (wParam == WM_KEYDOWN && nCode == HC_ACTION)
    {
        _itoa_s(key->vkCode, buff, 10);
        SetWindowTextA(hEdit, buff);
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}
2.在主功能中将钩子进程设置为键盘:

HHOOK _k_hook;
int WINAPI WinMain(_In_  HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_  LPSTR szCmdLine, _In_  int nCmdShow)
{
    MSG      msg;
    WNDCLASSEX wc;
    HMENU MainMenu, FileMenu;
    _k_hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
    ...
}
3.最后,不要忘记在程序结束后删除钩子进程:

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    HWND HButton1, HButton2, HButton3, Hmainbmp;
    switch (uMsg)
    {
        ...
    case WM_DESTROY:
        if (_k_hook)
            UnhookWindowsHookEx(_k_hook);
        PostQuitMessage(0);
        break;
        ...
    }
}

这样,您就不需要在
WndProc
中处理
WM_KEYDOWN
的消息。按键信息在
KeyboardProc
功能中处理,并且键的值显示在编辑控件中。

可能是因为WM_KEYDOWN消息将发送到您创建的编辑控件。如果您想截获发送到编辑控件的键盘消息,必须使用一种称为的技术。另外请注意,箭头键的处理是特殊的,因为它们是操作系统为导航而保留的默认情况下,它们不会生成
WM\u KEY…
消息。您必须通过处理返回
DLGC\u WANTARROWS
标志的消息来显式地请求它。@john实际上,我想在按下键时更改全局变量(按下键)的值。键盘上的信息只会在有焦点的窗口中传递。用户可以通过单击窗口来更改具有焦点的窗口。因此,如果你真的想跟踪所有键盘使用情况,那么windows消息并不是最好的方法。也许你应该看看,尽管我没有这方面的经验。我希望
WndProc
处理所有
WM\u KEYDOWN
消息。你能分享你建议的例子吗?@不,我已经更新了我的答案,你可以参考。