在 WM_KEYDOW 消息中捕获 VK_UP 不起作用

问题描述

窗口过程中的这段代码不起作用:

    case WM_KEYDOWN:
        switch(wParam)
        {
             case VK_UP:
                MessageBox(NULL,L"key up",L"",MB_OK);
             break;

            default: 
                break;
        }

我按下了向上箭头键,但没有调用 MessageBox。我错过了什么?

完整代码

#pragma comment(lib,"user32.lib")
#pragma comment(lib,"Comctl32.lib")
#pragma comment(lib,"Gdi32.lib")

#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE

#ifdef UNICODE
#define STRSPLIT wcsrchr
#else
#define STRSPLIT strrchr
#endif

#define __FILENAME__ (STRSPLIT(TEXT(__FILE__),'/') ? STRSPLIT(TEXT(__FILE__),'/') + 1 : TEXT(__FILE__))
#define NAMEOF(s) TEXT(#s)
#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))

#include <windows.h>
#include <strsafe.h>
#include <CommCtrl.h>

LRESULT CALLBACK WndProc(HWND,UINT,WParaM,LParaM);
void setUpScrollBar(HWND hwnd);
void ErrorExit(LPWSTR lpszFunction,int line,LPWSTR filename);
DWORD ShowLastError(LPWSTR lpszFunction,LPWSTR filename);
void InsertTabItem(HWND tabHwnd,UINT id,LPWSTR text);
void CreateTab(HWND hwnd);

HWND hTab;

int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PWSTR lpCmdLine,int nCmdshow) {

    MSG  msg;
    WNDCLASSW wc = {0};
    wc.lpszClassName = L"main window";
    wc.hInstance     = hInstance;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc   = WndProc;
    wc.hCursor       = LoadCursor(0,IDC_ARROW);

  
    RegisterClassW(&wc);
    HWND hWnd =
    CreateWindowW(wc.lpszClassName,L"foo",WS_OVERLAPPEDWINDOW | WS_VISIBLE,100,330,180,hInstance,0);

    while (GetMessage(&msg,NULL,0))
    {
        if (!IsDialogMessage(hWnd,&msg))
        {
            TranslateMessage(&msg);
            dispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WParaM wParam,LParaM lParam)
{
    static int g_scrollY;

    switch(msg)
    {
        case WM_CREATE:
            CreateWindowW(L"Static",L"This is label 1...",WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER,50,10,130,25,hwnd,(HMENU) 18,NULL);
            CreateWindowW(L"Static",L"This is label 2...",40,(HMENU) 19,L"This is label 3...",70,L"This is label 4...",L"This is label 5...",L"This is label 6...",160,L"This is label 7...",190,NULL);

            setUpScrollBar(hwnd);
            break;

          case WM_VSCROLL:
            int action = LOWORD(wParam);
            //HWND hScroll = (HWND)lParam;
            int pos = -1;
            if (action == SB_THUMBPOSITION || action == SB_THUMBTRACK) {
                pos = HIWORD(wParam);
            } else if (action == SB_LINEDOWN) {
                pos = g_scrollY + 30;
            } else if (action == SB_LINEUP) {
                pos = g_scrollY - 30;
            } 
            if (pos == -1)
                break;
            
            SCROLLINFO si = { 0 };
            si.cbSize = sizeof(SCROLLINFO);
            si.fMask = SIF_POS;
            si.nPos = pos;
            si.nTrackPos = 0;
            SetScrollInfo(hwnd,SB_VERT,&si,TRUE);
            GetScrollInfo(hwnd,&si);
            pos = si.nPos;
            POINT pt;
            pt.x = 0;
            pt.y = pos - g_scrollY;
            HDC hdc = GetDC(hwnd);
            LPtoDP(hdc,&pt,1);
            ReleaseDC(hwnd,hdc);
            ScrollWindow(hwnd,-pt.y,NULL);
            g_scrollY = pos;
            return 0;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        
        case WM_KEYDOWN:
            switch(wParam)
            {
                 case VK_UP:
                    MessageBox(NULL,MB_OK);
                 break;

                default: 
                    break;
            }
        break;
    }

    return DefWindowProcW(hwnd,msg,wParam,lParam);
}

void setUpScrollBar(HWND hwnd)
{
    RECT rc = { 0 };
    GetClientRect(hwnd,&rc);
    SCROLLINFO si = { 0 };
    si.cbSize = sizeof(SCROLLINFO);
    si.fMask = SIF_ALL;
    
    si.nMin = 0;
    si.nMax = 220;
    si.nPage = (rc.bottom - rc.top);
    si.nPos = 0;
    si.nTrackPos = 0;

    SetScrollInfo(hwnd,TRUE);
}

void ErrorExit(LPWSTR lpszFunction,LPWSTR filename)
{
    DWORD dw = ShowLastError(lpszFunction,line,filename);
    ExitProcess(dw);
}

DWORD ShowLastError(LPWSTR lpszFunction,LPWSTR filename)
{
    #define MAX_DIGITS 16

    DWORD dw = GetLastError();
    LPVOID lpMsgBuf;
    LPVOID lpdisplayBuf;
    
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYstem |
        FORMAT_MESSAGE_IGnorE_INSERTS,dw,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,NULL
    );

    lpdisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT,(lstrlen((LPCTSTR)lpMsgBuf) +
            lstrlen((LPCTSTR)lpszFunction) + 40 +
            (line > 0 ? MAX_DIGITS : 0) +
            (filename != NULL ? lstrlen(filename) : 0)) *
            sizeof(TCHAR)
    );
    StringCchPrintf((LPTSTR)lpdisplayBuf,LocalSize(lpdisplayBuf) / sizeof(TCHAR),TEXT("%s Failed with %d: %s"),lpszFunction,lpMsgBuf
    );
    MessageBox(NULL,(LPCTSTR)lpdisplayBuf,TEXT("Error"),MB_OK);
    LocalFree(lpMsgBuf);
    LocalFree(lpdisplayBuf);
    return dw;
}

解决方法

您的消息泵未正确形成。您正在为无模式对话框(通过 CreateDialog 创建的窗口)做一些事情,但您的应用程序中没有这样的窗口类型。因此,您的一些消息被 IsDialogMessage 函数吞没了。

所以不是这样:

while (GetMessage(&msg,NULL,0))
{
    if (!IsDialogMessage(hWnd,&msg))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

这个:

while (GetMessage(&msg,0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

当我将您的代码更改为该代码时,消息框会出现。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...