Issues using DInput

Post questions, comments and feedback to our 3Dconnexion Windows Development Team.

Moderator: Moderators

Issues using DInput

Postby simplyRubbish » Fri Oct 02, 2009 7:39 am

I have already posted this topic in the general "Developer's Forum for Windows" but figured to post here as well. If I shouldn't have I apologize.

First off, I am using the SpaceExplorer and attempting to get this device to work with our software using DirectInput: http://www.3dconnexion.com/3dmouse/spaceexplorer.php

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;
}


The reason I'm using GLWP_HINSTANCE instead of GWLP_USERDATA is due to the fact I'm not actually creating the window the HWND is attached to in EnumDevicesCB function. Here's my code for EnumDevicesCB to show what I mean:

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;
}


As you can see, the original "CreateDialogParam" is removed due to the fact this console application was already created so the code to handle that is done. I guess the question I'm trying to get at is, how can I handle the EnumAxesCB() function properly while getting the correct pDIDeviceInfo if I didn't do the creation of the window in EnumDevicesCB?

Any help on this issue is appreciated. Thank you.
simplyRubbish
 
Posts: 13
Joined: Fri Oct 02, 2009 7:25 am
Location: Daytona Beach, FL

Postby simplyRubbish » Fri Oct 02, 2009 7:54 am

Double thread, please ignore this one.
simplyRubbish
 
Posts: 13
Joined: Fri Oct 02, 2009 7:25 am
Location: Daytona Beach, FL


Return to Developer's Forum for Windows

Who is online

Users browsing this forum: Heritrix [Crawler] and 0 guests