Device Object Enumeration

It might be necessary for your application to determine what buttons or axes are available on a given device. To do this, you enumerate the device objects in much the same way as you enumerate devices.

Note    Because of limitations imposed by device drivers, enumeration of keyboard keys and indicator lights is not reliable. Objects might falsely be reported as present. You can get basic information about available keys from the device subtype, but there is no way to determine whether extra objects such as the menu key are available, other than asking the user for input.

To some extent, IDirectInputDevice8::EnumObjects overlaps the functionality of IDirectInputDevice8::GetCapabilities. Either method can be used to determine how many buttons or axes are available. However, IDirectInputDevice8::EnumObjects is intended for cataloging all the available objects rather than checking for a particular one.

Like IDirectInput8::EnumDevices, the IDirectInputDevice8::EnumObjects method has a callback function that enables you to do other processing on each object-for example, adding it to a list or creating a corresponding element on a user interface.

The following sample callback extracts the name of each object so that it can be added to a string list or array. This standard callback is documented under the placeholder name DIEnumDeviceObjectsCallback, but you can give it any name you like. Remember, this function is called once for each object enumerated.

char  szName[MAX_PATH];

BOOL CALLBACK DIEnumDeviceObjectsCallback( 
                      LPCDIDEVICEOBJECTINSTANCE lpddoi,
                      LPVOID pvRef) 
{ 
  HRESULT hr = StringCchCopy(szName, MAX_PATH, lpddoi->tszName);
  if(SUCCEEDED(hr))
  {
  // Now add szName to a list or array. 
  . 
  . 
  . 
  }
  else
  // Handle errors.

  return DIENUM_CONTINUE; 

}

The first parameter points to a structure containing information about the object. This structure is created for you by DirectInput.

The second parameter is an application-defined pointer to data, equivalent to the second parameter to IDirectInputDevice8::EnumObjects. In the example, this parameter is not used.

The return value in this case indicates that enumeration is to continue as long as there are objects to be enumerated.

Now here's the call to the IDirectInputDevice8::EnumObjects method, which puts the callback function to work.

lpdiMouse->EnumObjects(DIEnumDeviceObjectsCallback, 
                             NULL, DIDFT_ALL); 

The first parameter is the address of the callback function. The second parameter can be a pointer to any data you want to use or modify in the callback. The example does not use this parameter and so passes NULL. The third parameter is a flag to indicate which type or types of objects are to be included in the enumeration. In the example, all objects are to be enumerated. To restrict the enumeration, you can use one or more of the other DIDFT_* flags listed at IDirectInputDevice8::EnumObjects.

Note    Some of the DIDFT_* flags are combinations of others; for example, DIDFT_AXIS is equivalent to DIDFT_ABSAXIS | DIDFT_RELAXIS.

When an application has exclusive access to the keyboard, DirectInput suppresses all keyboard messages except CTRL+ALT+DEL and, on Microsoft Windows 95 and Windows 98, ALT+TAB. Under Microsoft Windows 2000, no application launched subsequently to the exclusive-mode DirectInput application can get keyboard data.