To have DirectInput enumerate devices, create a callback function of the same type as DIEnumDevicesCallback. In Step 1 you passed the address of this function to the IDirectInput8::EnumDevices method.
DirectInput passes into the callback, as the first parameter, a pointer to a DIDEVICEINSTANCE structure that tells you what you need to know about the device. The structure member of most interest in the example is guidInstance, the unique identifier for the particular piece of hardware on the user's system. You must pass this globally unique identifier (GUID) to the IDirectInput8::CreateDevice method.
The following code fragment is the first part of the callback, which extracts the globally unique identifier (GUID) and creates the device object.
BOOL CALLBACK DIEnumDevicesProc( LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef ) { HRESULT hr; GUID DeviceGuid = lpddi->guidInstance; // Create game device. hr = g_lpDI->CreateDevice(DeviceGuid, &g_lpDIDevice, NULL); if (FAILED(hr)) // Continue enumerating until successful or finished return DIENUM_CONTINUE;
The next steps of the callback function are similar to those for setting up any input device. Note that you need the exclusive cooperative level for any force-feedback device.
// Set cooperative level. hr = g_lpDIDevice->SetCooperativeLevel(g_hwndMain, DISCL_EXCLUSIVE | DISCL_FOREGROUND); if (FAILED(hr)) return hr; // set game data format hr = g_lpDIDevice->SetDataFormat(&c_dfDIJoystick); if (FAILED(hr)) return hr;
Finally, you might want to turn off the device's autocenter feature. Autocenter is essentially a condition effect that uses the motors to simulate the springs in a standard joystick. It is a good idea to turn it off so that it does not interfere with other effects.
DIPROPDWORD DIPropAutoCenter; DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter); DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER); DIPropAutoCenter.diph.dwObj = 0; DIPropAutoCenter.diph.dwHow = DIPH_DEVICE; DIPropAutoCenter.dwData = DIPROPAUTOCENTER_OFF; hr = g_lpDIDevice->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph); if (FAILED(hr)) { // Handle the failure as appropriate } return DIENUM_STOP; // One is enough. } // end DIEnumDevicesProc
Before using the device, you must acquire it. See Step 5: Gaining Access to the Joystick in Tutorial 3: Using the Joystick for an example of how to handle acquisition. Note that unlike other property changes, force-feedback effects can be downloaded to a device when it is in an acquired state.
After you have created the DirectInput force-feedback device, go to Step 3: Enumerating Supported Effects.