0

I am trying to connect a USB controller to my computer and be able to read what buttons are pressed. After looking at Microsoft documentation, I tried making a raw input system. However, I can't seem to understand the documentation and can't find any other good documentation. Below is my best effort. What am I doing wrong?

#include<iostream>
#include<string>
#include<Windows.h>

LRESULT WINAPI WindProc(HWND hwnd, UINT msg, WPARAM wpar, LPARAM lpar)
{
    switch (msg)
    {
    case WM_CREATE:
    {
        RAWINPUTDEVICE rid;
        rid.usUsagePage = 0x0001;
        rid.usUsage = 0x0004;
        rid.dwFlags = 0;
        rid.hwndTarget = hwnd;
        if (RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == false)
        {
            std::cout << "Failed to register raw input device\n";
            exit(-1);
        }
    
        break;
    }
    case WM_INPUT:
    {
        UINT Size = 0;
        if (GetRawInputData((HRAWINPUT)lpar, RID_INPUT, NULL, &Size, sizeof(RAWINPUTHEADER)) != 0)
        {
            std::cout << "error in getting raw input data\n";
            exit(-1);
        }
        LPBYTE lpb = new BYTE[Size];
        if (lpb == nullptr)
        {
            std::cout << "error creating lpb\n";
            exit(-1);
        }

        if (GetRawInputData((HRAWINPUT)lpar, RID_INPUT, &lpb, &Size, sizeof(RAWINPUTHEADER)) != Size)
        {
            std::cout << "Does not return correct size\n";
            exit(-1);
        }

        RAWINPUT* raw = (RAWINPUT*)lpb;
        if (raw->header.dwType == RIM_TYPEHID)
        {
            std::cout << raw->data.hid.bRawData << std::endl;
        }
        delete[] lpb;
        break;
    }
    }
    return DefWindowProc(hwnd, msg, wpar, lpar);
} 

int main() {
    const wchar_t* name = L"MY_WND";
    WNDCLASS wc = { };
    wc.lpfnWndProc = WindProc;
    wc.lpszClassName = name;
    if (!RegisterClass(&wc))
    {
        terminate();
    }

    HWND hwnd = CreateWindow(name, name, WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, 0, 0, 0);
    ShowWindow(hwnd, SW_SHOW);
    SetFocus(hwnd);

    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
Grady
  • 45
  • 6
  • What's the problem? Have you tried debugging it? Checking return values from calls? Maybe printing some possible errors using a MessageBox? – rturrado Apr 16 '21 at 19:07
  • Right now I get a read access violation for reading the raw header type – Grady Apr 16 '21 at 19:12
  • Recommendation: [Read this documentation link](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdata), particularly the section on the return value. Few programmers will waste time returning a diagnostic value if it's not important. – user4581301 Apr 16 '21 at 19:19
  • @Grady I would start with debugging the `case WM_INPUT`: check that the first call to `GetRawInputData` doesn't return a `Size` equals 0, and that `raw` is not a null pointer. – rturrado Apr 16 '21 at 19:19
  • Unrelated: rather than `LPBYTE lpb = new BYTE[Size];`, consider using `std::vector lpb(Size);` `vector` will automatically clean up any messes in any non-fatal circumstances, and in the fatal circumstances, a memory leak's the least of your worries. – user4581301 Apr 16 '21 at 19:24
  • It looks like the second call to GetRawInputData does not return the right size. But I can't see why it wouldn't. – Grady Apr 16 '21 at 19:31
  • @Grady you are not validating that the 1st call to `GetRawInputData()` is successful before making the 2nd call. And you are not validating the 2nd call is successful before using the contents of `lpb` – Remy Lebeau Apr 16 '21 at 19:45
  • I have now applied proper error checking and the second call to GetRawInputData() is causing an error. – Grady Apr 16 '21 at 19:57
  • I can't find any documentation saying why it would return the wrong size though. – Grady Apr 16 '21 at 20:15
  • have you seen [this question](https://stackoverflow.com/questions/49572093/getrawinputdata-within-a-simple-main) and [this documentation](https://learn.microsoft.com/en-us/windows/win32/inputdev/raw-input?redirectedfrom=MSDN) from the answer to that question – ma1169 Apr 16 '21 at 20:23
  • If the second call results in an error, you cannot trust the size. The call failed. Call [`GetLastError`](https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) for more diagnostics. If I'm misreading you and what you meant to say is "I don't get the results I expect." I have to bow out because my familiarity with the API is low and I have no idea why it would say all is well and return the wrong result or if it returns the right result and your expectations are wrong. – user4581301 Apr 16 '21 at 21:04
  • Which line are you have problems with ? And try `rid.usUsagePage = HID_USAGE_PAGE_GAME;` (hidusage.h). – YangXiaoPo-MSFT Apr 19 '21 at 08:57

0 Answers0