Raw Input report rate is so low

나느 41 Reputation points
2025-07-27T06:13:49.77+00:00

Hello.

I'm trying to scan some keyboard input, and it works but the polling rate is so low. The hidclass.sys driver seemed to aggregate some input packets while I don't want to do that. Is there a way to make the HID driver have high polling rate (at least about 1000 Hz)? It might be a Windows settings I guess

Here's the code and result:

#include <windows.h>
#include <iostream>
#include <thread>
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void RawInputThread() {
    // Register window class
    const wchar_t CLASS_NAME[] = L"RawInputWindowClass";
    WNDCLASS wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = GetModuleHandle(nullptr);
    wc.lpszClassName = CLASS_NAME;
    RegisterClass(&wc);
    // Create a message-only window
    HWND hwnd = CreateWindowEx(
        0, CLASS_NAME, L"RawInputHiddenWindow",
        0, 0, 0, 0, 0,
        HWND_MESSAGE, nullptr, GetModuleHandle(nullptr), nullptr);
    if (!hwnd) {
        std::cerr << "Failed to create window\n";
        return;
    }
    // Register for raw input from the mouse
    RAWINPUTDEVICE rid;
    rid.usUsagePage = 0x01; // Generic Desktop Controls
    rid.usUsage = 0x02;     // Mouse
    rid.dwFlags = RIDEV_INPUTSINK; // Receive input even when not in focus
    rid.hwndTarget = hwnd;
    if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) {
        std::cerr << "Failed to register raw input\n";
        return;
    }
    // Message loop
    MSG msg = {};
    while (GetMessage(&msg, nullptr, WM_INPUT, WM_INPUT) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
UINT64 then = 0;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    if (msg == WM_INPUT) {
        UINT dwSize = 0;
        GetRawInputData((HRAWINPUT)lParam, RID_INPUT, nullptr, &dwSize, sizeof(RAWINPUTHEADER));
        BYTE* lpb = new BYTE[dwSize];
        if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) == dwSize) {
            RAWINPUT* raw = (RAWINPUT*)lpb;
            if (raw->header.dwType == RIM_TYPEMOUSE) {
                LONG x = raw->data.mouse.lLastX;
                LONG y = raw->data.mouse.lLastY;
                std::cout << "Mouse move: X=" << x << " Y=" << y << " " << _Query_perf_counter() - then << "\n";
                then = _Query_perf_counter();
            }
        }
        delete[] lpb;
        return 0;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
int main() {
    std::thread t(RawInputThread);
    t.detach();
    std::cout << "Mouse raw input thread running. Press Enter to exit.\n";
    std::cin.get();
    return 0;
}

asdfasdfasdfasdf

(The value after X and Y is QueryPerformanceCounter() Ticks with 10 MHz frequency, and it indicates about 7-8 ms)

Right before asking I changed the code to bypass Windows message loop and use GetRawInputBuffer()function, still not resolving the problem

Developer technologies | C++
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.