Convert events from a USB human interface device using C++

1.5k views Asked by At

I have a USB HID touchpad that collects input. By default, when I press on the touchpad it generates carriage return (Enter) and when I try to use it as a mouse it actually enters a dragging state.

What I want to do is to convert the carriage return into a mouse click event and the dragging state into a cursor move without the initial clicking part.

I found the raw input alternative. However, I don't know how to convert it into mouse click and cursor move.

Here is the code responsible with the mouse 'reading':

LRESULT CALLBACK mouseProc (int nCode, WPARAM wParam, LPARAM lParam)
{
    MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
    if (pMouseStruct != NULL)
    {
        if(wParam == WM_LBUTTONDOWN)
        {
            cout<<"clicked"<<endl;
        }
        printf("Mouse position X = %d  Mouse Position Y = %d\n", pMouseStruct->pt.x,pMouseStruct->pt.y);

        stringstream sx, sy;
        sx << (int) pMouseStruct->pt.x << endl;
        sy << (int) pMouseStruct->pt.y << endl;
    }
    return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}

then the keyboard part:

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < 0)
        return CallNextHookEx(NULL, nCode, wParam, lParam);

    tagKBDLLHOOKSTRUCT *str = (tagKBDLLHOOKSTRUCT *)lParam;

    cout<<str->vkCode<<endl;

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

then the logging part:

DWORD WINAPI MyLogger(LPVOID lpParm)
{

    HINSTANCE hInstance = GetModuleHandle(NULL);
    hMouseHook = SetWindowsHookEx( WH_MOUSE_LL, mouseProc, hInstance, NULL );
    hKeyHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, NULL );

    MSG message;
    while (GetMessage(&message,NULL,0,0))
    {
        TranslateMessage( &message );
        DispatchMessage( &message );
    }

    UnhookWindowsHookEx(hMouseHook);
    return 0;
}

Note: I don't know if this is relevant, but I want to use the HID to play in a Chromium instance on a windows system.

3

There are 3 answers

0
VAndrei On BEST ANSWER

When you register the hook with WH_MOUSE_LL, the possible values of wparam are: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_RBUTTONDOWN, or WM_RBUTTONUP.

I'm expecting that once the WM_LBUTTONDOWN is issued, a corresponding WM_LBUTTONUP has to be issued to prevent the cursor from entering dragging state.

I don't have the device to test this but I would try the call below to prevent entering dragging state.

CallNextHookEx(hMouseHook, nCode, WM_LBUTTONUP, lParam);

or use mouse_event with MOUSEEVENTF_LEFTUP to inject the release of the left button.

I don't think that the raw input alternative is a good idea. I see it as a measure of last resort.

0
ahmedsafan86 On

For mouse click and mouse move - when you handle the input from the HID use the SendInput method.

The click is easy, for the mouse move try to get the scaled drag coordinates and convert them to the current screen scale coordinates and also use the SendInput method.

Also you can track the displacement in x, y and make appropriate calibration to translate them to screen x, y

0
Mihai On

The touchpad is just a mouse like any other. It generates standard mouse events. Use a global WH_MOUSE hook via SetWindowsHookEx() to capture mouse events globally. To replay them, use mouse_event(). Alternatively, use WH_JOURNALRECORD and WH_JOURNALPLAYBACK hooks instead for capture and playback, respectively.