📄 dijoystick.cpp
字号:
// Resest the Force Feedback Flag
m_FFAvailable = FALSE;
// Try and initialise the Joystick!
if ( !InitJoystick() ) return FALSE;
// In case you were wondering, this is not a good time to acquire the
// device. For one thing, we can't acquire in foreground mode here
// because the options dialog may be open. We'll acquire it when the
// main window is activated.
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
//
// Either Acquire or Unacquire the Device!
//
////////////////////////////////////////////////////////////////////////////////
bool CDIJoystick::Acquire(bool state)
{
HRESULT hr;
if(!m_lpDIDevice)
{
OutputDebugString("Error in CDIJoystick::Acquire(bool state)\nDevice Has Not Been Created.\n");
return false;
}
if ( !state ) // Unacquire.
{
hr = m_lpDIDevice->Unacquire();
}
else // Acquire.
{
// This could take a while with FF.
::SetCursor( m_hCursorWait );
hr = m_lpDIDevice->Acquire();
if ( SUCCEEDED( hr ) )
{
// Initialize effects; ignore failure and just
// pretend FF not there.
if ( m_FFAvailable ) // First set when device initialized.
{
//m_FFAvailable = InitFFEffects();
}
}
}
if(FAILED(hr))
{
OutputDebugString("Failed in CDIJoystick::Acquire(bool state)\n");
OutputDebugString(GetDIError(hr));
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////
//
// Set the HWND that will be used when Acquiring Devices!
//
//////////////////////////////////////////////////////////////////////
void CDIJoystick::SetHWND(HWND hwnd)
{
//Shutdown();
m_hwnd=hwnd;
//m_EnumerationStarted=false;
m_hInstance=GetModuleHandle(NULL);
// Initialise Direct Input
//Initialise();
// Start Enumeration of Attached Joysticks.
//Enumerate_Joysticks();
}
//////////////////////////////////////////////////////////////////////
//
// Set the preferred GUID for the joystick device
//
//////////////////////////////////////////////////////////////////////
void CDIJoystick::SetPreferredDevice(GUID *pguid)
{
memcpy(&m_JoystickGUID,pguid,sizeof(GUID));
}
//////////////////////////////////////////////////////////////////////
//
// Re-Initialise this object, used when changing HWND or Device
// Not yet implemented.
//
//////////////////////////////////////////////////////////////////////
bool CDIJoystick::ReInitialise()
{
// m_EnumerationStarted=false;
// m_hInstance=GetModuleHandle(NULL);
// Enumerate_Joysticks();
return true;
}
//////////////////////////////////////////////////////////////////////
//
// Return Error Text From HRESULT
//
//////////////////////////////////////////////////////////////////////
TCHAR* CDIJoystick::GetDIError(HRESULT error)
{
switch(error)
{
case E_PENDING : return _T("E_PENDING : Data Not Available.\n");
break;
case E_HANDLE : return _T("E_HANDLE : The HWND parameter is not a valid top-level window that belongs to the process.\n");
break;
case DIERR_UNSUPPORTED : return _T("DIERR_UNSUPPORTED : The function called is not supported at this time. This value is equal to the E_NOTIMPL standard COM return value.\n");
break;
case DIERR_UNPLUGGED : return _T("DIERR_UNPLUGGED : The operation could not be completed because the device is not plugged in.\n");
break;
case DIERR_REPORTFULL : return _T("DIERR_REPORTFULL : More information was requested to be sent than can be sent to the device.\n");
break;
case DIERR_READONLY : return _T("DIERR_READONLY : The specified property cannot be changed. This value is equal to the E_ACCESSDENIED standard COM return value.\n");
break;
case DIERR_OUTOFMEMORY : return _T("DIERR_OUTOFMEMORY : The DirectInput subsystem could not allocate sufficient memory to complete the call. This value is equal to the E_OUTOFMEMORY standard COM return value.\n");
break;
// case DIERR_OTHERAPPHASPRIO : return _T("DIERR_OTHERAPPHASPRIO : Another application has a higher priority level, preventing this call from succeeding. This value is equal to the E_ACCESSDENIED standard COM return value. This error can be returned when an application has only foreground access to a device but is attempting to acquire the device while in the background. ");
// break;
case DIERR_OLDDIRECTINPUTVERSION : return _T("DIERR_OLDDIRECTINPUTVERSION : The application requires a newer version of DirectInput.\n");
break;
case DIERR_OBJECTNOTFOUND : return _T("DIERR_OBJECTNOTFOUND : The requested object does not exist.\n");
break;
case DIERR_NOTINITIALIZED : return _T("DIERR_NOTINITIALIZED : This object has not been initialized.\n");
break;
// case DIERR_NOTFOUND : return _T("DIERR_NOTFOUND : The requested object does not exist.\n");
// break;
case DIERR_NOTEXCLUSIVEACQUIRED : return _T("DIERR_NOTEXCLUSIVEACQUIRED : The operation cannot be performed unless the device is acquired in DISCL_EXCLUSIVE mode.\n");
break;
case DIERR_NOTDOWNLOADED : return _T("DIERR_NOTDOWNLOADED : The effect is not downloaded.\n");
break;
case DIERR_NOTBUFFERED : return _T("DIERR_NOTBUFFERED : The device is not buffered. Set the DIPROP_BUFFERSIZE property to enable buffering.\n");
break;
case DIERR_NOTACQUIRED : return _T("DIERR_NOTACQUIRED : The operation cannot be performed unless the device is acquired.\n");
break;
case DIERR_NOINTERFACE : return _T("DIERR_NOINTERFACE : The specified interface is not supported by the object. This value is equal to the E_NOINTERFACE standard COM return value.\n");
break;
case DIERR_NOAGGREGATION : return _T("DIERR_NOAGGREGATION : This object does not support aggregation.\n");
break;
case DIERR_MOREDATA : return _T("DIERR_MOREDATA : Not all the requested information fit into the buffer.\n");
break;
case DIERR_INVALIDPARAM : return _T("DIERR_INVALIDPARAM : An invalid parameter was passed to the returning function, or the object was not in a state that permitted the function to be called. This value is equal to the E_INVALIDARG standard COM return value.\n");
break;
case DIERR_INPUTLOST : return _T("DIERR_INPUTLOST : Access to the input device has been lost. It must be reacquired.\n");
break;
case DIERR_INCOMPLETEEFFECT : return _T("DIERR_INCOMPLETEEFFECT : The effect could not be downloaded because essential information is missing. For example, no axes have been associated with the effect, or no type-specific information has been supplied.\n");
break;
// case DIERR_HANDLEEXISTS : return _T("DIERR_HANDLEEXISTS : The device already has an event notification associated with it. This value is equal to the E_ACCESSDENIED standard COM return value.\n");
// break;
case DIERR_GENERIC : return _T("DIERR_GENERIC : An undetermined error occurred inside the DirectInput subsystem. This value is equal to the E_FAIL standard COM return value.\n");
break;
case DIERR_HASEFFECTS : return _T("DIERR_HASEFFECTS : The device cannot be reinitialized because there are still effects attached to it.\n");
break;
case DIERR_EFFECTPLAYING : return _T("DIERR_EFFECTPLAYING : The parameters were updated in memory but were not downloaded to the device because the device does not support updating an effect while it is still playing.\n");
break;
case DIERR_DEVICENOTREG : return _T("DIERR_DEVICENOTREG : The device or device instance is not registered with DirectInput. This value is equal to the REGDB_E_CLASSNOTREG standard COM return value.\n");
break;
case DIERR_DEVICEFULL : return _T("DIERR_DEVICEFULL : The device is full.\n");
break;
case DIERR_BETADIRECTINPUTVERSION : return _T("DIERR_BETADIRECTINPUTVERSION : The application was written for an unsupported prerelease version of DirectInput.\n");
break;
case DIERR_BADDRIVERVER : return _T("DIERR_BADDRIVERVER : The object could not be created due to an incompatible driver version or mismatched or incomplete driver components.\n");
break;
case DIERR_ALREADYINITIALIZED : return _T("DIERR_ALREADYINITIALIZED : This object is already initialized\n");
break;
case DIERR_ACQUIRED : return _T("DIERR_ACQUIRED : The operation cannot be performed while the device is acquired.\n");
break;
case DI_TRUNCATEDANDRESTARTED : return _T("DI_TRUNCATEDANDRESTARTED : Equal to DI_EFFECTRESTARTED | DI_TRUNCATED\n");
break;
case DI_TRUNCATED : return _T("DI_TRUNCATED : The parameters of the effect were successfully updated, but some of them were beyond the capabilities of the device and were truncated to the nearest supported value.\n");
break;
case DI_PROPNOEFFECT : return _T("DI_PROPNOEFFECT : The change in device properties had no effect. This value is equal to the S_FALSE standard COM return value.\n");
break;
case DI_POLLEDDEVICE : return _T("DI_POLLEDDEVICE : The device is a polled device. As a result, device buffering does not collect any data and event notifications is not signaled until the IDirectInputDevice7::Poll method is called.\n");
break;
case DI_OK : return _T("DI_OK : The operation completed successfully. This value is equal to the S_OK standard COM return value.\n");
break;
// case DI_NOTATTACHED : return _T("DI_NOTATTACHED : The device exists but is not currently attached. This value is equal to the S_FALSE standard COM return value.\n");
// break;
// case DI_NOEFFECT : return _T("DI_NOEFFECT : The operation had no effect. This value is equal to the S_FALSE standard COM return value.\n");
// break;
case DI_EFFECTRESTARTED : return _T("DI_EFFECTRESTARTED : The effect was stopped, the parameters were updated, and the effect was restarted.\n");
break;
case DI_DOWNLOADSKIPPED : return _T("The parameters of the effect were successfully updated, but the effect could not be downloaded because the associated device was not acquired in exclusive mode.\n");
break;
// case DI_BUFFEROVERFLOW : return _T("DI_BUFFEROVERFLOW : The device buffer overflowed and some input was lost. This value is equal to the S_FALSE standard COM return value.\n");
// break;
default: return _T("Unknown Error Code.\n");
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// Update member variables to reflect the state of the device
//
//////////////////////////////////////////////////////////////////////////////////////////
bool CDIJoystick::PollDevice()
{
static loopcount=0;
HRESULT hr;
//DIDEVICEOBJECTDATA rgdod[BUFFERSIZE];
//DWORD dwItems;
ZeroMemory(&m_dijs,sizeof(m_dijs));
// Has device been initialised ?
if (!m_lpDIDevice)
{
// Try and initialise device
if(!InitDevice())
OutputDebugString("Failed To Initialise and Poll Joystick in CDIJoystick::PollDevice()\n");
return false;
}
hr=m_lpDIDevice->Poll(); // May be unnecessary but never hurts.
if(FAILED(hr))
{
OutputDebugString("Failed To Poll Joystick in CDIJoystick::PollDevice()\n");
OutputDebugString(GetDIError(hr));
}
getImmediateData:
if(loopcount>20) return false; // Infinite Loop Protection
hr = m_lpDIDevice->GetDeviceState( sizeof( DIJOYSTATE2 ), &m_dijs );
// The data stream was interrupted. Reacquire the device and try again.
if ( hr == DIERR_INPUTLOST )
{
OutputDebugString("Failed To Obtain Immediate Device State in CDIJoystick::PollDevice()\n");
OutputDebugString(GetDIError(hr));
// Increment Infinite Loop Protection Counter and try again.
loopcount++;
// Try and acquire device and start again.
if ( Acquire( true ) )
goto getImmediateData;
}
// We can't get the device because it has not been acquired so try and acquire it.
if ( hr == DIERR_NOTACQUIRED )
{
// Increment Infinite Loop Protection Counter.
loopcount++;
OutputDebugString("Device Not Acquired Trying Again immediate CDIJoystick::PollDevice()\n");
if(!Acquire(true))
{
OutputDebugString("Unable to acquire Immediate Device in CDIJoystick::PollDevice() Quitting\n");
return false;
}
// Try and get buffered data if device is buffered!
goto getImmediateData;
}
if ( FAILED(hr))
{
OutputDebugString("Unable to obtain Immediate Data from Device in CDIJoystick::PollDevice() Quitting\n");
return false;
}
// First set immediate direction if your only interested in basic movement
if ( m_dijs.lX < 0 ) m_JoyLeft=true; else m_JoyLeft=false;
if ( m_dijs.lX > 0 ) m_JoyRight=true; else m_JoyRight=false;
if ( m_dijs.lY < 0 ) m_JoyUp=true; else m_JoyUp=false;
if ( m_dijs.lY > 0 ) m_JoyDown=true; else m_JoyDown=false;
m_JoyFire1=false;
#ifdef _DEBUG
int firecount=0;
#endif
for(int i=0;i<sizeof(m_dijs.rgbButtons);i++)
{
if(m_dijs.rgbButtons[i]&0x80)
{
#ifdef _DEBUG
firecount++;
#endif
m_JoyFire[i]=true;
m_JoyFire1=true;
}
else m_JoyFire[i]=false;
}
#ifdef _DEBUG
if(firecount>0)
{
OutputDebugString("Many Buttons Pressed\n");
}
#endif
return true;
}
//////////////////////////////////////////////////////////////////////
//
// Run the joystick Control Panel!
//
//////////////////////////////////////////////////////////////////////
void CDIJoystick::RunControlPanel()
{
if(!m_lpDI) return;
m_lpDI->RunControlPanel(m_hwnd,NULL);
}
HRESULT CDIJoystick::EnumJoystick( void )
{
return m_lpDI->EnumDevices(DI8DEVCLASS_GAMECTRL ,EnumDevicesProc,this,DIEDFL_ATTACHEDONLY);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -