Jump to content
  • Advertisement
Sign in to follow this  
Giallanon

How to detect only attached device using win32 GetRawInputDeviceList?

This topic is 2145 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using GetRawInputDeviceList() to obtain a list of input devices, and it's working fine, but it returns something like 3 o 4 keyboards and 2 or 3 mouses even if I only have 1 keyboard and 1 mouse attached.

I guess that what the function is returning is a list of all devices ever seen by the OS.

I can't find a way to know if a device is actually attached (and working) or it's a ghost.

I remember that with direct input there was a flag to set in order to retreive only attached devices, so I'm guessing that there should be something similar to use with RawInput family of functions, but so far I've found any.

Any idea?

 

Share this post


Link to post
Share on other sites
Advertisement

I was aware of this answer on stackoverflow, but it's not very useful because it doesn't clarify anything and doesn't even help the OP to understand which one of the 3 keyboards is the one attached, which it's the same problem I'm facing

Share this post


Link to post
Share on other sites

Really, because it's pretty clear to me, but I'll try to explain anyway:

 

You have to use GetRawInputDeviceInfo for each of the devices returned by GetRawInputDeviceList to get more info about the devices, but you're already doing this, since you mentioned you're only looking at the keyboard devices.

 

Next, from what I understand of that stackoverflow response:

1) The first keyboard device returned by GetRawInputDeviceList (in the order in which GetRawInputDeviceList returns them), is a sort of virtual keyboard created by the system, which handles keyboard events from all physical attached keyboards.

2) The second keyboard device is a physical keyboard - if there's only one keyobard attached, then this is it.

3) The third keyboard device is also physical

4) So on...

 

If that is true, then IMO, you should either use the first device (the virtual one) if your game requires only one keyboard, the second one if you want the "main" keyboard", or offer a choice between all of them. Unfortunately, I cannot find this info anywhere on MSDN, to verify if it's correct, but like I said, I tend to trust stackoverflow most of the time.

 

As for why you're seeing three (or four?) keyboards when you say you only have one: could the extra ones (after the first two) be Bluetooth devices? You can verify in Device Manager.

 


...clarify anything and doesn't even help the OP...

Aren;t you the OP? :)

Share this post


Link to post
Share on other sites

Well the answer on stackoverflow seems based on guesses and not on official documentation. If the program I'm working on was for personal use, I could make a guess and live with it, but who can assure me that the same assumptions will hold on every pc with every possible combinations of mouse keyboard and whatever else?

There should be an api to use to understand if a device is alive or not...

Share this post


Link to post
Share on other sites

From a MVP page (don't ask me which one) I took this to weed out those "virtual" combined devices like this:

 

  UINT        numDevices = 0;
  if ( GetRawInputDeviceList( NULL, &numDevices, sizeof( RAWINPUTDEVICELIST ) ) != 0 )
  {
    // Error?
    return false;
  }
  RAWINPUTDEVICELIST*   pDeviceData = new RAWINPUTDEVICELIST[numDevices];
  if ( GetRawInputDeviceList( pDeviceData, &numDevices, sizeof( RAWINPUTDEVICELIST ) ) == -1 )
  {
    // Error
    delete[] pDeviceData;
    return false;
  }
  int numTotalControls    = 0;
  int numTotalVirtualKeys = 0;
  int currentHIDJoystickOrGamepad = 0;
  for ( UINT i = 0; i < numDevices; ++i )
  {
    wchar_t             pathBuffer[260 + 4];
    UINT                bufferSize = UINT( sizeof( pathBuffer ) / sizeof( pathBuffer[0] ) );
    std::wstring        name;
 
    bufferSize = GetRawInputDeviceInfoW( pDeviceData[i].hDevice, RIDI_DEVICENAME, pathBuffer, &bufferSize );
    if ( sizeof pathBuffer / sizeof pathBuffer[0] < bufferSize )
    {
      // Negative UINTs werden sehr groß positiv
      dh::Log( "invalid HID (%d, %x): could not retrieve its path", i, pDeviceData[i].hDevice );
      continue;
    }
    std::wstring    originalName = pathBuffer;
    pathBuffer[1] = L'\\';
    HANDLE              ntHandle = CreateFileW( pathBuffer,
                                                0u,
                                                FILE_SHARE_READ | FILE_SHARE_WRITE, // wir können anderen Prozessen nicht verbieten, das HID zu benutzen
                                                NULL,
                                                OPEN_EXISTING,
                                                0u,
                                                NULL );
    if ( INVALID_HANDLE_VALUE == ntHandle )
    {
      dh::Log( "%d: invalid HID: could not open its handle", i );
      continue;
    }
    if ( GR::Strings::ToUpper( pathBuffer ).find( L"ROOT" ) != std::string::npos )
    {
      // skip combined devices, we only want real devices
      //dh::Log( "skip combined device %d (%x)", i, pDeviceData[i].hDevice );
      continue;
    }
    // snip ... from here one gather additional data from devices

Share this post


Link to post
Share on other sites

That will work to get rid of the virtual devices, but it won't get rid of disconnected devices.

 

Is CreateFile supposed to return INVALID_HANDLE_VALUE for disconnected devices? Because it's not working that way for me. For a Bluetooth keyboard (it's actually a keyboard app on my phone). When I shutdown the app, the phone's bluetooth goes off, but the keyboard still shows in Device Manager. It only goes away after a few minutes, but I assume in this case, my application will receive a WM_INPUT_DEVICE_CHANGE message if I register for them.

 

Also, PS/2 does not have plug and play capability, so if you remove a PS/2 mouse or keyboard, it will probably not be detected by Windows. But if you do this, then do not plug the keyboard or mouse back in while the computer is still running - you might ruin the PS/2 controller; you have to shutdown the computer, then plug in the keyboard /mouse.

Edited by tonemgub

Share this post


Link to post
Share on other sites

CreateFile!!! How I didn't thought of it before...it seems pretty obvious now.

Thank you Endurion, I think this will work for me.

As for disconnected devices, it's not a problem for me now, because I can assume that any devices I found at startup will last for the entire duration of the program.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!