Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 302
George Netu Avatar asked Jun 25 '15 13:06

George Netu


2 Answers

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.

like image 59
VAndrei Avatar answered Oct 17 '22 03:10

VAndrei


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.

like image 24
Mihai Avatar answered Oct 17 '22 02:10

Mihai