如何在 Window Procedure 方法中检测击键?

How to detect a keystroke in the Window Procedure method?

我对 c++ 有点陌生,我正在尝试创建一个 gui 应用程序来告诉我我的大写锁定是否处于活动状态。我已经设置了基本 UI 并按计划启动(通过颜色向我显示我的锁定状态)但我无法在运行时更改 window 颜色。

这是我的代码:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
bool state = false;
switch (uMsg) {
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);

        // All painting occurs here, between BeginPaint and EndPaint.
        if ((GetKeyState(VK_CAPITAL) & 0x0001) != 0) {
            FillRect(hdc, &ps.rcPaint, CreateSolidBrush(RGB(0, 255, 0)));
        }
        else {
            FillRect(hdc, &ps.rcPaint, CreateSolidBrush(RGB(255, 0, 0)));
        }

        EndPaint(hwnd, &ps);
    }
    case WM_KEYUP:
    {

        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        // All painting occurs here, between BeginPaint and EndPaint.
        if ((GetKeyState(VK_CAPITAL) & 0x0001) != 0) {
            FillRect(hdc, &ps.rcPaint, CreateSolidBrush(RGB(0, 255, 0)));
        }
        else {
            FillRect(hdc, &ps.rcPaint, CreateSolidBrush(RGB(255, 0, 0)));
        }

        EndPaint(hwnd, &ps);
    }
    return 0;
}

return DefWindowProc(hwnd, uMsg, wParam, lParam);

}

提前致谢。

捕获 WM_KEYDOWN 消息。如果我是 Caps Lock 键按下(检查参数),请通过调用 InvalidateRect.

让您的 window 重绘自身

不要在 WM_KEYUP 处理程序中调用 (Begin/End)Paint(),也不要在 WM_PAINT 处理程序中调用 GetKeyState()。让 WM_KEY(DOWN|UP) 将所需的颜色保存到变量中,然后在该变量更改值时调用 InvalidateRect() 以触发 window 的重绘。让 WM_PAINT 根据需要使用该变量的当前值绘制 window。

此外,您的 case 块缺少 break 语句。你正在泄露 CreateSolidBrush().

返回的 HBRUSH

试试像这样的东西:

COLORREF color;

void UpdateColorForCapsLock()
{
    if (GetKeyState(VK_CAPITAL) & 0x0001) {
        color = RGB(0, 255, 0);
    }
    else {
        color = RGB(255, 0, 0);
    }
}

RESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg) {
        case WM_CREATE:
        {
            UpdateColorForCapsLock();
            break;
        }

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            HBRUSH hBrush = CreateSolidBrush(color);
            FillRect(hdc, &ps.rcPaint, hBrush);
            DeleteObject(hBrush);
            EndPaint(hwnd, &ps);
            return 0;
        }

        case WM_KEYDOWN:
        case WM_KEYUP:
        {
            if (wParam == VK_CAPITAL)
            {
                UpdateColorForCapsLock();
                InvalidateRect(hwnd, NULL, TRUE);
            }
            break;
        }
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}