Step 2: Creating the DirectInput Joystick Device
After creating the DirectInput object, the application must retrieve a pointer to an IDirectInputDevice interface, which will be used to perform most joystick-related tasks. In the Space Donuts sample, this is done in the callback function InitJoystickInput, which is called each time a joystick is enumerated.
Here is the first part of the callback function:
BOOL FAR PASCAL InitJoystickInput(LPCDIDEVICEINSTANCE pdinst,
LPVOID pvRef)
{
LPDIRECTINPUT pdi = pvRef;
LPDIRECTINPUTDEVICE pdev;
// create the DirectInput joystick device
if (pdi->lpVtbl->CreateDevice(pdi, &pdinst->guidInstance,
&pdev, NULL) != DI_OK)
{
OutputDebugString("IDirectInput::CreateDevice FAILED\n");
return DIENUM_CONTINUE;
}
The parameters to the callback function InitJoystickInput are:
·A pointer to the device instance, supplied by the DirectInput system when the device is enumerated.
·A pointer to the DirectInput interface, which you supplied as an parameter to IDirectInput::EnumDevices. This parameter could have been any 32-bit value but in this case you want the DirectInput interface so that you can call the IDirectInput::CreateDevice method.
The InitJoystickInput sample function declares a local pointer to the DirectInput object, pdi, and assigns it the value passed into the callback. It also declares a local pointer to a DirectInput device, pdev, which is initialized when the device is created. This device starts life as an instance of the IDirectInputDevice interface, but when it is added to the application's list of input devices it is converted to an IDirectInputDevice2 object so that it can use the IDirectInputDevice2::Poll method.
The first task of the callback function, then, is to create the device. The IDirectInput::CreateDevice method accepts four parameters.
The first, unnecessary in C++, is a this pointer to the calling DirectInput interface.
The second parameter is a reference to the globally unique identifier (GUID) for the instance of the device. In this case, the GUID is taken from the DIDEVICEINSTANCE structure supplied by DirectInput when it enumerated the device.
The third parameter is the address of the variable that will be initialized with a valid IDirectInputDevice interface pointer if the call succeeds.
The fourth parameter specifies the address of the controlling object's IUnknown interface for use in COM aggregation. Space Donuts doesn't use aggregation, so the parameter is NULL.
Note that if for some reason the device interface cannot be created, DIENUM_CONTINUE is returned from the callback function. This flag instructs DirectInput to keep enumerating as long as there are devices to be enumerated.