The problem that I'm getting stumped at is in EnumAxesCB function. *pDIDeviceInfo is NULL so my application crashes. Here's what my code looks like for there:
Code: Select all
/*---------------------------------------------------------------------------*/
BOOL CALLBACK EnumAxesCB( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext )
/*
Callback function for enumerating the axes on a UsbHidDevice
-----------------------------------------------------------------------------*/
{
HWND hDlg = (HWND)pContext;
DIDeviceInfo *pDIDeviceInfo = (DIDeviceInfo *)GetWindowLongPtr( hDlg, GWLP_HINSTANCE );
#if 0 // this has no effect
// Set the range for the axis
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
diprg.lMin = -512; // +/- 512 matches the hardware 1:1
diprg.lMax = 511;
if( FAILED( pDIDeviceInfo->pUsbHidDevice->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
return DIENUM_STOP;
#endif
/*
* Recent 3Dx USB device descriptors indicate that the device axes return relative data
* even though the device is really an absolute device.
* HID ignores this, but apparently DI uses it.
* Changing the axis handling to return RELATIVE values gives us back what we want (displacement
* values rather than accumulated values). If older USB devices were to be supported, this handling
* would have to be changed to DIPROPAXISMODE_ABS.
*
* In this mode, DI sets the notification event even though the values haven't changed.
*/
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.diph.dwObj = 0; // set for whole device not an axis (really only needs to be done once)
dipdw.dwData = DIPROPAXISMODE_REL;
if( FAILED( pDIDeviceInfo->pUsbHidDevice->SetProperty( DIPROP_AXISMODE, &dipdw.diph ) ) )
return DIENUM_STOP;
return DIENUM_CONTINUE;
}
Code: Select all
BOOL CALLBACK EnumDevicesCB( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext )
/*
Called once for each enumerated UsbHidDevice. If we find one, create a
device interface on it so we can play with it.
-----------------------------------------------------------------------------*/
{
int newIndex;
HRESULT hr;
GUID guid = pdidInstance->guidProduct;
# define LOGITECH_3DX_VID 0x046d // Vendor ID for Logitech/3Dx
/* Check to see if this is a 3Dx device. Look at the VendorID before stopping the enumeration. */
if ( (guid.Data1 & 0x0000ffff) != LOGITECH_3DX_VID)
return DIENUM_CONTINUE;
/* Filter out LOGI mice and such */
else if (pdidInstance->wUsagePage != 0x0001 || pdidInstance->wUsage != 0x0008)
return DIENUM_CONTINUE;
/* Make sure haven't found too many 3Dx devices for our array */
if (g_nDevices >= MAX_DEVICES)
return DIENUM_CONTINUE;
newIndex = g_nDevices;
g_pDevices[g_nDevices++] = (DIDeviceInfo*)malloc( sizeof(DIDeviceInfo) );
/* Set state variables to known values */
ZeroMemory( &g_pDevices[newIndex]->lastJoyState, sizeof(DIJOYSTATE) );
g_pDevices[newIndex]->lastVectorType = BothZeroVectors;
/*
* Save the DIDEVICEINSTANCE struct for later display.
* This isn't necessary. The demo just does it to display the info in the dlg box.
*/
g_pDevices[newIndex]->DIDevInstance = *pdidInstance;
/* Obtain an interface to the enumerated device. */
hr = g_pDI->CreateDevice( pdidInstance->guidInstance, &g_pDevices[newIndex]->pUsbHidDevice, NULL );
/*
* If it failed, then we can't use this UsbHidDevice. (Maybe the user unplugged
* it while we were in the middle of enumerating it.)
*/
if( FAILED(hr) )
{
free (g_pDevices[newIndex]);
g_nDevices--;
return DIENUM_CONTINUE;
}
/* Create a info dialog box for this device */
//g_pDevices[newIndex]->hDlg = CreateDialogParam( hInst, MAKEINTRESOURCE(_APS_NEXT_RESOURCE_VALUE), NULL, DlgProc,
// (LPARAM)g_pDevices[newIndex] );
g_pDevices[newIndex]->hDlg = GetForegroundWindow();
return DIENUM_CONTINUE;
}
Any help on this issue is appreciated. Thank you.