⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dijoystick.cpp

📁 手柄驱动DEMO程序源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	// 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 + -