1

I'm looking for a way to determine if a computer running my game has a trackpad and a mouse connected to it. A typical example would be a laptop with an external mouse connected to it.

Is there a Windows API that will return the number of mice/pointing devices connected to the system?

I need to support Windows 7+.

EDIT

I'm keeping the accepted answer because it works and answers my question but I decided not to use it after discovering ManyMouse. It does what I want and allows me to use the same API on Mac, Windows and (hopefully, still need to test) Linux.

NoobsArePeople2
  • 1,986
  • 14
  • 21
  • I'm sure there's a way but why do this? I don't see any practical reason for it. – TerraOrbis Apr 10 '14 at 18:09
  • @TerraOrbis Because I want to handle different input setups (e.g., keyboard + mouse, just keyboard, gamepad) when the user starts up the game without requiring any config on the user's part. I can use [SYSTEM_POWER_STATUS](http://stackoverflow.com/a/4849574/608884) to make an informed guess if the user is on a laptop (and has a trackpad). Detecting if the user also has a second mouse would let me further guess that they have a kb+mouse setup. A lot of guessing but I think it would work out in most cases, if not then fallback to some default and offer manual config. – NoobsArePeople2 Apr 10 '14 at 18:15

1 Answers1

2

I happened to have a bit of code lying around that enumerates the mice attached to the system. If there's more than one, it's likely that one is a trackpad and the other one an external mouse, although I guess it might be a trackpad and one of those little sticks. It should be possible to use the same API to get enough information about each nominal mouse to make an intelligent guess; for example, the built-in mouse devices usually seem to be connected via PS/2 whereas external mice are almost always USB.

Anyway, hopefully this will help:

#include <windows.h>

#include <Hidsdi.h>
#include <SetupAPI.h>
#include <devguid.h>

#include <stdio.h>

#pragma comment(lib, "hid.lib")
#pragma comment(lib, "setupapi.lib")

int main(int argc, char ** argv)
{
    GUID hid_guid;
    GUID mouse_guid = GUID_DEVCLASS_MOUSE;
    HDEVINFO hdevinfo;
    SP_DEVICE_INTERFACE_DATA devinterface;
    SP_DEVINFO_DATA devinfo;
    BYTE devdetailbuffer[4096];
    PSP_DEVICE_INTERFACE_DETAIL_DATA devdetail;
    DWORD n;

    HidD_GetHidGuid(&hid_guid);

    hdevinfo = SetupDiGetClassDevs(&hid_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

    if (hdevinfo == INVALID_HANDLE_VALUE)
    {
        printf("SetupDiGetClassDevs: %u\n", GetLastError());
        return 1;
    }

    for (n = 0;; n++)
    {
        devinterface.cbSize = sizeof(devinterface);
        if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, &hid_guid, n, &devinterface))
        {
            printf("SetupDiEnumDeviceInterfaces: %u\n", GetLastError());
            break;
        }
        devdetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)devdetailbuffer;
        devdetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        devinfo.cbSize = sizeof(devinfo);
        if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &devinterface, devdetail, sizeof(devdetailbuffer), NULL, &devinfo))
        {
            printf("SetupDiGetDeviceInterfaceDetail: %u\n", GetLastError());
            break;
        }
        if (IsEqualGUID(&devinfo.ClassGuid, &mouse_guid))
        {
            // This is a mouse
            printf("DevicePath: %ws\n", devdetail->DevicePath);
        }
    }
    return 0;
}
Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • Just wanted to say that you RULE! Had to make a few changes to get this to build under MinGW but in general it's working great. Thinking about my original question more I'm not so concerned about discerning trackpad vs. mouse as I am about laptop (implicitly with trackpad) but no mouse vs. laptop (again, with trackpad) but also external mouse. Your code snippet plus [this](http://stackoverflow.com/a/4849574/608884) should let me make an informed guess that will cover most cases quite well. Thanks again! – NoobsArePeople2 Apr 11 '14 at 05:33
  • @Harry Johnston I believe that invoking GetSystemMetrics(SM_MousePresent) is the preferred way to check if mouse is connected – Artur Dec 16 '15 at 08:42
  • @Artur: I don't think that will tell you the number of mice, just whether there's at least one. Also the documentation says that it is often inaccurate. – Harry Johnston Dec 16 '15 at 22:01