2

Win32 Raw Input API を使用して生のマウス データをより高い精度で収集しようとしていますが、ドキュメントとサンプルをまったく理解できないようですGetRawInputBuffer

ウィンドウの上にマウスを置いている間、何も起こらないようです。ウィンドウのタイトルバーをクリックまたは離したときにのみバッファリングされたデータを取得しているように見えますが、それでもほとんどの移動値は取得されず、マウスボタンの変更はまったく受信されません。サンプルをできる限り詳しく追跡しましたが、オンラインで検索することはほとんどありませんでした。

以下は、問題を抱えた非常に単純化された例のウィンドウ プロシージャとメインです。

LRESULT CALLBACK MessageHandler(HWND WindowHandle, UINT Message, WPARAM wParameter, LPARAM lParameter)
{
    switch(Message)
    {
    case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;
        }
        break;
    case WM_CLOSE:
        {
            DestroyWindow(WindowHandle);
            return 0;
        }
        break;
    case WM_INPUT: 
        {
            UINT RawInputSize;
            UINT Result;

            Result = GetRawInputBuffer(NULL, &(RawInputSize), sizeof(RAWINPUTHEADER));
            if(Result == -1)
            {
                DWORD ErrorCode = GetLastError();
                std::cout << "GetRawInputBuffer returned error code" << ErrorCode << std::endl;
            }
            else if(Result == 0 && RawInputSize != 0)
            {
                UINT AllocatedBufferByteCount = RawInputSize * 16;
                RAWINPUT* RawInputBuffer = reinterpret_cast<RAWINPUT*>(malloc(AllocatedBufferByteCount));

                UINT AllocatedBufferByteCountTwo = AllocatedBufferByteCount;
                Result = GetRawInputBuffer(RawInputBuffer, &(AllocatedBufferByteCountTwo), sizeof(RAWINPUTHEADER));
                if(Result == -1)
                {
                    DWORD ErrorCode = GetLastError();
                    std::cout << "GetRawInputBuffer returned error code" << ErrorCode << std::endl;
                }
                else if(Result != 0)
                {
                    UINT RawInputCount = Result;

                    DWORD MouseDeltaX = 0;
                    DWORD MouseDeltaY = 0;

                    bool ButtonsPressed[2] = {false, false};

                    RAWINPUT* RawInput = RawInputBuffer;
                    for(unsigned int i = 0; i < RawInputCount; ++i)
                    {
                        switch(RawInput->header.dwType) 
                        {
                        // Raw mouse movement data for high-resolution mice. 
                        case RIM_TYPEMOUSE:
                            {
                                MouseDeltaX += RawInput->data.mouse.lLastX;
                                MouseDeltaY += RawInput->data.mouse.lLastY;

                                ButtonsPressed[0] = ((RawInput->data.mouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) == RI_MOUSE_LEFT_BUTTON_DOWN);
                                ButtonsPressed[1] = ((RawInput->data.mouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) == RI_MOUSE_RIGHT_BUTTON_DOWN);
                            }
                            break;
                        }

                        RawInput = NEXTRAWINPUTBLOCK(RawInput);
                    }
                    DefRawInputProc(&(RawInputBuffer), RawInputCount, sizeof(RAWINPUTHEADER));
                    std::cout << "Mouse moved (" << MouseDeltaX << ", " << MouseDeltaY << ")." << std::endl;

                    if(ButtonsPressed[0])
                    {
                        std::cout << "LMB pressed." << std::endl;
                    }
                    if(ButtonsPressed[1])
                    {
                        std::cout << "RMB pressed." << std::endl;
                    }
                }

                free(RawInputBuffer);
            }
            return 0;
        }
        break;
    default:
        {
            return DefWindowProc(WindowHandle, Message, wParameter, lParameter);
        }
        break;
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    // Initialize window strings.
    wchar_t WindowClassName[] = L"DominionWindowClass";
    wchar_t WindowCaption[] = L"Test Window";

    // Create the window class.
    WNDCLASSEX WindowClass;
    WindowClass.cbSize = sizeof(WindowClass);
    WindowClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    WindowClass.lpfnWndProc = &(MessageHandler);
    WindowClass.cbClsExtra = 0;
    WindowClass.cbWndExtra = 0;
    WindowClass.hInstance = hInstance;
    WindowClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
    WindowClass.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
    WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WindowClass.hbrBackground = NULL;
    WindowClass.lpszMenuName = NULL; 
    WindowClass.lpszClassName = WindowClassName;

    // Register window class.
    RegisterClassEx(&WindowClass);

    // Setup window style flags.
    DWORD WindowStyles = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
    DWORD ExWindowStyles = WS_EX_APPWINDOW;

    // Setup window rectangle area.
    RECT WindowArea;
    WindowArea.left = 0;
    WindowArea.top = 0;
    WindowArea.right = 1024;
    WindowArea.bottom = 768;

    AdjustWindowRectEx(&(WindowArea), WindowStyles, false, ExWindowStyles);

    // Window creation.
    HWND WindowHandle = CreateWindowEx(ExWindowStyles, WindowClass.lpszClassName, WindowCaption, WindowStyles, CW_USEDEFAULT, CW_USEDEFAULT, (WindowArea.right - WindowArea.left), (WindowArea.bottom - WindowArea.top), NULL, NULL, hInstance, NULL);

    // Display the window.
    ShowWindow(WindowHandle, SW_SHOWDEFAULT);
    UpdateWindow(WindowHandle);

    // Register devices for raw input.
    const unsigned int RawInputDeviceCount = 1;
    RAWINPUTDEVICE RawInputDevices[RawInputDeviceCount];

    memset(RawInputDevices, 0, RawInputDeviceCount * sizeof(RAWINPUTDEVICE));

    RAWINPUTDEVICE* MouseRawInputDevice;

    MouseRawInputDevice = RawInputDevices;
    MouseRawInputDevice->usUsagePage = 1;
    MouseRawInputDevice->usUsage = 2;
    MouseRawInputDevice->hwndTarget = WindowHandle;

    BOOL SuccessfullyRegisteredInput = RegisterRawInputDevices(RawInputDevices, RawInputDeviceCount, sizeof(RAWINPUTDEVICE));

    // Core loop.
    MSG Message;
    for(;;)
    {
        while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&Message);
            DispatchMessage(&Message);
            if(Message.message == WM_QUIT)
            {
                break;
            }
        }

        if(Message.message == WM_QUIT)
        {
            break;
        }
    }

    // Unregister devices for raw input.
    memset(RawInputDevices, 0, RawInputDeviceCount * sizeof(RAWINPUTDEVICE));
    MouseRawInputDevice = RawInputDevices;
    MouseRawInputDevice->usUsagePage = 1;
    MouseRawInputDevice->usUsage = 2;
    MouseRawInputDevice->dwFlags = RIDEV_REMOVE;
    MouseRawInputDevice->hwndTarget = NULL;

    BOOL SuccessfullyUnregisteredInput = RegisterRawInputDevices(RawInputDevices, RawInputDeviceCount, sizeof(RAWINPUTDEVICE));

    return Message.wParam;
}

Raw Input API を試すための、これ以上簡単な方法は思いつきません。考え?

4

2 に答える 2

0

GetRawInputBuffer() を使用すると、HID データのみを読み取ることができると思います。つまり、RAWINPUT 構造体のデータ部分にある hid 構造体だけが入力データで埋められます。RAWHID の bRawData メンバーを使用してキーボードから入力を読み取ることができましたが、その値はキーボードごとに異なるため、役に立たないと思います。そこで、GetRawInputData に切り替えました....

于 2012-06-20T16:38:10.553 に答える