Platform SDK: DirectX

Step 2: Create the DirectInput Force-Feedback Device

[Visual Basic]

The information in this topic pertains only to applications written in C++. See DirectInput Visual Basic Tutorials.

[C++]

In order to have DirectInput enumerate devices, you must create a callback function of the same type as DIEnumDevicesCallback. In Step 1 you passed the address of this function to the IDirectInput7::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 chief interest in the example is guidInstance, the unique identifier for the particular piece of hardware on the user's system. You will need to pass this GUID to the IDirectInput7::CreateDeviceEx method.

Here's the first part of the callback, which extracts the GUID and creates the device object:

BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi, 
                                LPVOID pvRef)
  {
  HRESULT hr;
  GUID DeviceGuid = lpddi->guidInstance;
 
  // Create game device.
 
  hr = lpdi->CreateDeviceEx(DeviceGuid, IID_IDirectInputDevice7,
          (void**)&g_lpdid7, NULL); 
 
  if (FAILED(hr))
    {
    OutputDebugString("Failed to create device.\n");
    return DIENUM_STOP;
    } 
 

The next steps, still within 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. You also need to set the data format.

  // Set cooperative level.
  if (FAILED(g_lpdid7->SetCooperativeLevel(hMainWindow,
         DISCL_EXCLUSIVE | DISCL_FOREGROUND)))
    {
    OutputDebugString(
      "Failed to set cooperative level.\n");
    g_lpdid7->Release();
    g_lpdid7 = NULL;
    return DIENUM_STOP;
    }
 
  // set game data format
  if (FAILED(g_lpdid7->SetDataFormat(&c_dfDIJoystick)))
    {
    OutputDebugString("Failed to set game device data format.\n");
    g_lpdid7->Release();
    g_lpdid7 = NULL;
    return DIENUM_STOP;
    }
 

Finally. you may 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's a good idea to turn it off so that it doesn't 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 = 0;
 
  if (FAILED(lpdid7->SetProperty(DIPROP_AUTOCENTER, 
          &DIPropAutoCenter.diph)))
    {
    OutputDebugString("Failed to change device property.\n");
    }
 
  return DIENUM_STOP;   // One is enough.
  } // end DIEnumDevicesProc
 

Before using the device, you must acquire it. See Step 5: Gain Access to the Joystick in the previous tutorial for an example of how to handle acquisition.

Next: Step 3: Enumerate Supported Effects