Using DirectInput to receive signal after plugging in joystick
Asked Answered
C

2

7

I have a C++ program that enumerates all the input devices (using direct input) at the start of the program. If the program is started, and then I plug in another controller, this controller won't be recognized until the program is restarted. Anyone know of an event I can use that will cause my program to enumerate all of the devices after a new one is plugged in?

Chartres answered 13/5, 2013 at 17:54 Comment(0)
R
5

This article discusses how to detect game pad changes. First of all, you can handle the WM_DEVICECHANGE message and check wParam for DBT_DEVICEARRIVAL or DBT_DEVICEREMOVECOMPLETE. It seems that in order to receive these as WPARAMs, though, you need to call RegisterDeviceNotification first.

The article's example of how to do this is as follows:

DEV_BROADCAST_DEVICEINTERFACE notificationFilter;
ZeroMemory(&notificationFilter, sizeof(notificationFilter));
 
notificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
notificationFilter.dbcc_size = sizeof(notificationFilter);
 
HDEVNOTIFY hDevNotify;
hDevNotify = RegisterDeviceNotification(m_hWnd, &notificationFilter,
   DEVICE_NOTIFY_WINDOW_HANDLE |
   DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
 
if(hDevNotify == NULL) {
   // do some error handling
}

The only other thing to watch out for is that the minimum supported OS for this is XP, so you need to put in the appropriate #define for that before including the Windows headers.

Depending on what you want to do, you might not even have to call this function first. Instead, you can just check DBT_DEVNODES_CHANGED to not differentiate between a device being plugged or unplugged. That could save some code if you don't care.

Reconciliatory answered 13/5, 2013 at 18:14 Comment(0)
R
1

Got it working. When any device is removed or added just dispose all 'IDirectInputDevice8' and re-create them. This avoids bugs and keeps things simple.

Hook WinProc method to watch for add/remove events

bool refreshInputDevices = false;
LRESULT SubWndProc(int code, WPARAM wParam, LPARAM lParam)
{
    // invalid code skip
    if (code < 0) return CallNextHookEx(NULL, code, wParam, lParam);

    // check if device was added/removed
    PCWPSTRUCT pMsg = PCWPSTRUCT(lParam);
    if (pMsg->message == WM_DEVICECHANGE)
    {
        switch (pMsg->wParam)
        {
        case DBT_DEVNODES_CHANGED:
            refreshInputDevices = true;
            break;

        case DBT_DEVICEARRIVAL:
            refreshInputDevices = true;
            break;

        case DBT_DEVICEREMOVECOMPLETE:
            refreshInputDevices = true;
            break;
        }
    }

        // continue as normal
        return CallNextHookEx(NULL, code, wParam, lParam);
    }

Here is how you can hook on the input thread

// hook WinProc to watch for device changes
HMODULE module = GetModuleHandleW(NULL);
DWORD threadID = GetCurrentThreadId();
HHOOK hook = SetWindowsHookExW(WH_CALLWNDPROC, (HOOKPROC)&SubWndProc, module, threadID);
Ricks answered 2/7, 2021 at 9:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.