You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用RegisterRawInputDevices后窗口无响应问题求助

问题分析与解决方案

核心问题原因

你设置的RIDEV_NOLEGACY标志会让系统停止向窗口发送传统鼠标消息(如WM_MOUSEMOVE、WM_LBUTTONDOWN等),但你的程序没有处理原始输入对应的WM_INPUT消息,导致窗口无法响应任何鼠标交互——系统把传统消息截住了,新的原始消息又没被处理,所以看起来窗口“无法交互”但实际程序没崩溃。

解决方案

有两种可行的处理方式,根据你的需求选择:

方式一:保留传统鼠标消息,同时接收原始输入

如果不需要屏蔽传统鼠标消息,直接移除RIDEV_NOLEGACY标志即可。修改后的注册函数如下:

bool N_RegisterMouseRawInput()
{
    RAWINPUTDEVICE rid;

    rid.usUsagePage = 0x01;          // HID_USAGE_PAGE_GENERIC
    rid.usUsage = 0x02;              // HID_USAGE_GENERIC_MOUSE
    rid.dwFlags = 0;                 // 移除RIDEV_NOLEGACY,同时接收原始输入和传统消息
    rid.hwndTarget = nullptr;

    if (RegisterRawInputDevices(&rid, 1, sizeof(rid)) == FALSE)
    {
        CYC_WIN32_LASTERROR_NOBREAK(false, "Raw Input RegisterRawInputDevices failed")
        return false;
    }
    return true;
}

这样窗口既可以正常接收传统鼠标消息维持交互,同时也能收到WM_INPUT消息处理原始输入数据。

方式二:保留RIDEV_NOLEGACY,处理WM_INPUT消息

如果必须屏蔽传统鼠标消息,就需要在窗口过程(WindowProc)中添加WM_INPUT的处理逻辑,解析原始鼠标输入数据并实现交互逻辑:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_INPUT:
        {
            UINT dataSize = 0;
            // 先获取原始输入数据的大小
            if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, nullptr, &dataSize, sizeof(RAWINPUTHEADER)) == -1)
            {
                // 处理错误
                return DefWindowProc(hwnd, uMsg, wParam, lParam);
            }

            // 分配内存存储原始输入数据
            std::vector<BYTE> buffer(dataSize);
            if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer.data(), &dataSize, sizeof(RAWINPUTHEADER)) != dataSize)
            {
                // 处理错误
                return DefWindowProc(hwnd, uMsg, wParam, lParam);
            }

            // 解析鼠标原始输入数据
            RAWINPUT* rawInput = reinterpret_cast<RAWINPUT*>(buffer.data());
            if (rawInput->header.dwType == RIM_TYPEMOUSE)
            {
                const RAWMOUSE& mouseData = rawInput->data.mouse;
                // 在这里处理鼠标输入,比如判断按键状态、移动偏移等
                // 示例:检查左键是否按下
                if (mouseData.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
                {
                    // 执行左键按下的逻辑
                }
                // 处理鼠标移动
                if (mouseData.usFlags & MOUSE_MOVE_RELATIVE)
                {
                    int deltaX = mouseData.lLastX;
                    int deltaY = mouseData.lLastY;
                    // 执行移动逻辑
                }
            }
            break;
        }
        // 其他消息处理逻辑...
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

注意:使用RIDEV_NOLEGACY时,所有鼠标交互逻辑都需要通过WM_INPUT实现,传统的鼠标消息会被系统拦截,无法再通过WM_MOUSEMOVE等消息处理交互。

内容的提问来源于stack exchange,提问作者Cool_Cornflakes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:41:38