IPCamera监控软件如何支持joystick遥控手柄控制云台

IPCamera监控软件如何支持joystick遥控手柄控制云台_第1张图片


ipc提供的windows监控软件SDK比较多,但是都不支持遥控手柄基于onvif协议支持云台控制,需要加入directshow里的两个库dxinput.lib和dxguid.lib,增加游戏手柄控制的类

1. CDIJoystick类用来控制遥控手柄

头文件:

// DIJoystick.h: interface for the CDIJoystick class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_DIJOYSTICK_H__D1950720_938F_4491_A3E3_583B1FB98E2C__INCLUDED_)
#define AFX_DIJOYSTICK_H__D1950720_938F_4491_A3E3_583B1FB98E2C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#pragma comment (lib, "dxguid.lib")
#pragma comment (lib, "dinput.lib")

#define MAXJOYBUTTONS 256
class CDIJoystick  
{
public:
	CDIJoystick();
	virtual ~CDIJoystick();

	bool PollDevice();				// Update the device state.
	void SetPreferredDevice(GUID* pguid);  // Set the current GUID for joystick device.
	void SetHWND(HWND hwnd);		// The the HWND to which the joystick will be attached.
	bool InitDevice(void);			// Initialise the Device Pointer
	bool InitJoystick(void);		// Initialise the Joystick
	int HowManyButtons(void);		// Find out how many buttons the attached device has
	bool CreateDevice(GUID *guid);	// Create A Device Pointer for a GUID

	LPCDIDEVICEINSTANCE GetFirstJoystickID(void);	// Get First Joystick Device Data For Enumerated Devices (Must be called before GetNextJoystickID()
	LPCDIDEVICEINSTANCE GetNextJoystickID();		// Get Next Joystick Device Data For Enumerated Devices
	TCHAR* GetFirstButtonName(void);// Get First Joystick Button Friendly Name For Enumerated Device (Must be called before GetNextJoystickID()
	TCHAR* GetNextButtonName();		// Get First Joystick Button Friendly Name For Enumerated Device

	bool IsJoystickLeft(void) {return m_JoyLeft;};	// Is Joystick Being Moved Left?
	bool IsJoystickRight(void) {return m_JoyRight;};// Is Joystick Being Moved Right?
	bool IsJoystickUp(void) {return m_JoyUp;};		// Is Joystick Being Moved Up?
	bool IsJoystickDown(void) { return m_JoyDown;};	// Is Joystick Being Moved Down?
	bool IsJoystickFire(void) { return m_JoyFire1;};// Has Any Fire Button Been Pressed?
	bool IsJoystickFire(int button) { return m_JoyFire[button%MAXJOYBUTTONS];};// Has a specific button been pressed?

	DIJOYSTATE2* GetJoystickStateInfo(void) {return &m_dijs;};
	void RunControlPanel(void);		// Run the Control Panel

protected:
	bool Initialise(void);			// Initialise Direct Input 7
	void Shutdown(void);			// Close down and de-allocate any memory assigned to this object.
	bool Enumerate_Joysticks(void);	// Start Enumeration of Attached Joystick Devices

	TCHAR* GetDIError(HRESULT error);// Return Friendly Text to DI7 Error HR
	bool ReInitialise(void);		// ReInitialise DI7 (Not Implemented)

	void ClearFriendlyButtonNames(void);	// Clear Down Allocated Memory for Friendly Button Names
	bool AddDeviceInfo(LPCDIDEVICEINSTANCE lpddi); // Add DI7 Device Info for Enumerated Device
	static BOOL CALLBACK EnumDevicesProc( LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); // Callback procedure for Enumerating Attached Joystick Devices
	bool Acquire(bool state);		// Acquire/UnAcquire the Joystick

private:
	POSITION m_DevicePOS;			// Used in CPtrList to keep track of next item.
	POSITION m_ButtonPOS;			// Used in CPtrList to keep track of next item.

	bool m_EnumerationStarted;		// Has enumeration started and joystick been found?

	DIJOYSTATE2   m_dijs;				// Holds Joystick State Information
	
	GUID m_JoystickGUID;			// Current Joystick GUID
	
	CPtrList	m_DIJoystickList;	// Contains a pointer list to Attached Joystick Devices
	CPtrList	m_DIButtonNames;	// Contains a pointer list to Button Names for selected Joystick

	bool m_JoyLeft;					// Generic Direction, Is Joystick Moving Left
	bool m_JoyUp;					// Generic Direction, Is Joystick Moving Up
	bool m_JoyDown;					// Generic Direction, Is Joystick Moving Down
	bool m_JoyRight;				// Generic Direction, Is Joystick Moving Right
	bool m_JoyFire[MAXJOYBUTTONS];	// Which Fire Button Has Been Pressed?
	bool m_JoyFire1;				// Has any fire button been pressed?
	
	
	HCURSOR m_hCursorWait;			// Wait Cursor Handle when Enumerating Feedback Effects
	HWND m_hwnd;					// HWND to which Direct Input will be attached to.
	
	bool m_Initialised;				// Has Direct Input Been Initialised?
	char m_buffer[256];				// A Generic buffer

	HINSTANCE m_hInstance;				// This modules Instance
	LPDIRECTINPUT7  m_lpDI;				// Pointer to Direct Input 7
	LPDIRECTINPUTDEVICE7  m_lpDIDevice;	// Pointer to Direct Input 7 Device

	//////////////////////////////////////////////////////////////////////
	// Used for Force Feed Back, Not Yet Implemented
	//////////////////////////////////////////////////////////////////////
	LPDIRECTINPUTEFFECT  m_lpTriggerEffect;	// For Force Feedback Effects
	LPDIRECTINPUTEFFECT  m_lpStickyEffect;	// For Force Feedback Effects
	LPDIRECTINPUTEFFECT  m_lpResistEffect;	// For Force Feedback Effects
	bool m_TriggerOK;
	BOOL m_FFAvailable;				// Is device Force Feedback Compatible?
	GUID m_TriggerGuid;				// GUID For Force Feed Back Device?
};
#endif // !defined(AFX_DIJOYSTICK_H__D1950720_938F_4491_A3E3_583B1FB98E2C__INCLUDED_)
CPP文件:
<pre name="code" class="cpp">// DIJoystick.cpp: implementation of the CDIJoystick class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
//#include "JoystickDemo.h"
#include "DIJoystick.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif



#include "stdafx.h"
#include "DIJoystick.h"

#define BUFFERSIZE 16

// Set the maxmimum range to which we'll gauge the swing
#define JOYMAX 10000
#define JOYMIN -10000

/*				Y
				
				^
				|
				|
X	-10,000 <---*---> +10,000
				|
				|
				\/
*/
// Dead zone is the amount of sway the joystick can have before we start registering movement
// In this case 20%

#define JOYDEAD 2000

// The Saturation Point Is Where the Joystick is deemed to be at Full Swing, in this case 95%
#define JOYSAT  9500

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDIJoystick::CDIJoystick()
{
	// Initialise Member Variables
	m_EnumerationStarted=false;
	m_Initialised=false;
	m_hInstance=GetModuleHandle(NULL);

	// Initialise Direct Input
	Initialise();

	// Start Enumeration of Attached Joysticks.
	Enumerate_Joysticks();
}

//////////////////////////////////////////////////////////////////////
//
// Destroy The Direct Input Joystick Control and tidy up.
//
//////////////////////////////////////////////////////////////////////
CDIJoystick::~CDIJoystick()
{
	Shutdown();
}

//////////////////////////////////////////////////////////////////////
//
// Initialise Direct Input
//
//////////////////////////////////////////////////////////////////////
bool CDIJoystick::Initialise()
{
	HRESULT         hr; 

	hr = DirectInputCreateEx(m_hInstance, DIRECTINPUT_VERSION, 
			IID_IDirectInput7, (void**)&m_lpDI, NULL); 
	if FAILED(hr) 
	{ 
	    // DirectInput not available; 
	    // take appropriate action
		OutputDebugString("Failed To Initialise Direct Input 7 in CDIJoystick::Initialise\n");
		OutputDebugString(GetDIError(hr));
		return false;
	}

	m_hwnd=NULL;

	if FAILED(hr)
	{ 
		OutputDebugString(GetDIError(hr));
		Shutdown(); 
		return false; 
	}

	m_Initialised=true;
	return true;	// Successfully Created Direct Input 7 Object
}

//////////////////////////////////////////////////////////////////////
//
// Shutdown the Direct input object and release it.
//
// Basically clean up any memory allocated to this object
//
//////////////////////////////////////////////////////////////////////
void CDIJoystick::Shutdown()
{
	ClearFriendlyButtonNames();

	// Remove Joystick Information
	if(!m_DIJoystickList.IsEmpty())
	{
		POSITION pos=m_DIJoystickList.GetHeadPosition();
		LPVOID del=NULL;

		while(pos)
		{
			del=static_cast<LPVOID>(m_DIJoystickList.GetNext(pos));
			if(del)
			{
				delete del;
			}
		}
		m_DIJoystickList.RemoveAll();
	}

	// Shutdown Direct Input!
	if (m_lpDI) 
	{ 
		if (m_lpDIDevice) 
		{ 
				// Always unacquire device before calling Release().
			try
			{
				Acquire(false);
				m_lpDIDevice->Release();
				m_lpDIDevice = NULL; 
			}
			catch(...)
			{
				OutputDebugString("Failed to Release Pointer in CDIJoystick::Shutdown\n");
			}
		} 
		try
		{
			m_lpDI->Release();
			m_lpDI = NULL; 
		}
		catch(...)
		{
			OutputDebugString("Failed to Release DI7 Pointer in CDIJoystick::Shutdown\n");
		}
	} 
	m_Initialised=false;
}

//////////////////////////////////////////////////////////////////////
//
// Start the Enumeration Of Attached Joystick Devices.
//
//////////////////////////////////////////////////////////////////////
bool CDIJoystick::Enumerate_Joysticks()
{
	HRESULT hr=NULL;

	if(!m_Initialised) Initialise();

	if(!m_lpDI) // Has a Direct Input Interface Already Been Initialised?
	{
		hr = DirectInputCreateEx(m_hInstance, DIRECTINPUT_VERSION, 
							   IID_IDirectInput7, (void**)&m_lpDI, NULL);

		if FAILED(hr) 
		{
			OutputDebugString("Error in CDIJoystick::Enumerate_Joysticks()\n");
			OutputDebugString(GetDIError(hr));
			return false; 
		}
	}
	
	if(m_lpDI) hr=m_lpDI->EnumDevices(DIDEVTYPE_JOYSTICK ,EnumDevicesProc,this,DIEDFL_ATTACHEDONLY);
    if FAILED(hr) 
	{
		OutputDebugString("Error in CDIJoystick::Enumerate_Joysticks()\n");
		OutputDebugString(GetDIError(hr));
		return false; 
	}

	OutputDebugString("Enumerating Joystick Devices\n");
	return true;
}

//////////////////////////////////////////////////////////////////////
//
// Add Enumerated Devices To A Link List Object
// Continue Enumeration Of The Device
//
//////////////////////////////////////////////////////////////////////
BOOL CDIJoystick::EnumDevicesProc(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
{
	CDIJoystick *obj=(CDIJoystick*)(pvRef);
	obj->AddDeviceInfo(lpddi);

	return DIENUM_CONTINUE;   
}

//////////////////////////////////////////////////////////////////////
//
// Add Device Info To The List Of Pointers Held in m_DIJoystickList
//
// return  true = Successfully Added 
//        false = Failed To Add
//
//////////////////////////////////////////////////////////////////////
bool CDIJoystick::AddDeviceInfo(LPCDIDEVICEINSTANCE lpddi)
{
	m_EnumerationStarted=true;

	LPCDIDEVICEINSTANCE lpdi2=new DIDEVICEINSTANCE;
	if(lpdi2)
	{
		memcpy((void*)lpdi2,lpddi,sizeof(DIDEVICEINSTANCE));

		if(m_DIJoystickList.AddHead((void*)lpdi2))return true;
		OutputDebugString("Failed To Add Device Info in CDIJoystick::AddDeviceInfo(LPCDIDEVICEINSTANCE lpddi)\n");
	}
	return false;
}

//////////////////////////////////////////////////////////////////////
//
// Return First Joystick Device Data If Possible
//
// return  NULL if Failed or No Joysticks Available
//
//////////////////////////////////////////////////////////////////////
LPCDIDEVICEINSTANCE CDIJoystick::GetFirstJoystickID()
{
	if(!m_EnumerationStarted) 
	{
		OutputDebugString("Joystick Have Not Yet Been Enumerated Returning NULL from CDIJoystick::GetFirstJoystickID()\n");
		return NULL;
	}

	if(m_DIJoystickList.IsEmpty()) 
	{
		OutputDebugString("Joysticks Have Been Enumerated However None Were Found Attached To This System\n"
						  "Therefore I am Returning NULL from CDIJoystick::GetFirstJoystickID()\n");
		return NULL;
	}

	m_DevicePOS=m_DIJoystickList.GetHeadPosition();

	return GetNextJoystickID();

	LPCDIDEVICEINSTANCE info=static_cast<LPCDIDEVICEINSTANCE>(m_DIJoystickList.GetNext(m_DevicePOS));

	return info;
}

//////////////////////////////////////////////////////////////////////
//
// Return Next Joystick Device Data If Possible
//
// return  NULL if Failed or No Joysticks Available
//
//////////////////////////////////////////////////////////////////////
LPCDIDEVICEINSTANCE CDIJoystick::GetNextJoystickID()
{
	if(!m_DevicePOS) return NULL;

	return static_cast<LPCDIDEVICEINSTANCE>(m_DIJoystickList.GetNext(m_DevicePOS));
}

//////////////////////////////////////////////////////////////////////
//
// Return First Joystick Button Name Data If Possible
//
// return  NULL if Failed or No Joysticks Available
//
//////////////////////////////////////////////////////////////////////
TCHAR* CDIJoystick::GetFirstButtonName()
{
	if(!m_EnumerationStarted) 
	{
		OutputDebugString("Joystick Have Not Yet Been Enumerated\nor None attached to this systemReturning NULL from CDIJoystick::GetFirstJoystickID()\n");
		return NULL;
	}

	if(m_DIButtonNames.IsEmpty()) 
	{
		OutputDebugString("Joysticks Have Been Enumerated However None Were Found Attached To This System\n"
						  "Therefore I am Returning NULL from CDIJoystick::GetFirstButtonName()\n");
		return NULL;
	}

	m_ButtonPOS=m_DIButtonNames.GetHeadPosition();

	TCHAR* info=static_cast<TCHAR*>(m_DIButtonNames.GetNext(m_ButtonPOS));
	return info;	
}

//////////////////////////////////////////////////////////////////////
//
// Return First Joystick Button Name Data If Possible
//
// return  NULL if Failed or No Joysticks Available
//
//////////////////////////////////////////////////////////////////////
TCHAR* CDIJoystick::GetNextButtonName()
{
	if(!m_ButtonPOS) return NULL;

	return static_cast<TCHAR*>(m_DIButtonNames.GetNext(m_ButtonPOS));
}


//////////////////////////////////////////////////////////////////////
//
//  Create the Joystick Device Using GUID Passed
//
//////////////////////////////////////////////////////////////////////
bool CDIJoystick::CreateDevice(GUID *guid)
{
	HRESULT hr=NULL;

	// If a device already exists and is created, Release it.
	if (m_lpDIDevice) 
    { 
		// Always unacquire device before calling Release().
		try
		{
			hr=m_lpDIDevice->Unacquire(); 
		}
		catch(...)
		{
		}
		try
		{
			hr=m_lpDIDevice->Release();
			if(FAILED(hr))
			{
				OutputDebugString(GetDIError(hr));
			}
			else m_lpDIDevice = NULL; 
		}
		catch(...)
		{
			OutputDebugString("Failed to Release Pointer in CDIJoystick::CreateDevice(GUID *guid)\n");
		}
    }
	
	// Check to see that Direct Input has been created and initialised.
	if(!m_lpDI) 
	{
		OutputDebugString("Failed to Create DI 7 interface to device in CDIJoystick::CreateDevice(GUID *guid) m_lpDI not initialised.\n");
		return false;
	}

	// Attempt to create the device based on the GUID passed to this routine
	hr=m_lpDI->CreateDeviceEx(*guid,IID_IDirectInputDevice7,(void**)&m_lpDIDevice,NULL);
	if(FAILED(hr))
	{
		OutputDebugString("Failed to Create DI 7 interface to device in CDIJoystick::CreateDevice(GUID *guid)\n");
		return false;
	}

	// We must have been successful at this point.
	// Therefore copy the GUID to this members instance for future reference.
	memcpy(&m_JoystickGUID,guid,sizeof(GUID));

	return true;
}

//////////////////////////////////////////////////////////////////////
//
// Return How Many Buttons The Attached Device Has Installed
// When giving the player an option of which joystick to use
// You may wish to evaluate the buttons available per attached device.
// Returns the number of buttons for the currently selected device.
//
//////////////////////////////////////////////////////////////////////
int CDIJoystick::HowManyButtons()
{
    DIDEVICEOBJECTINSTANCE didoi;
    DWORD x;
    DWORD dwOfs;
	int count=0;
	HRESULT hr=NULL;
	
	ClearFriendlyButtonNames();

	//if(m_lpDIDevice)
	if(InitDevice())
	{
		ZeroMemory(&didoi,sizeof(DIDEVICEOBJECTINSTANCE));
		didoi.dwSize = sizeof( didoi );

		for ( x = 0; x < 32; x++ )
		{
			dwOfs = DIJOFS_BUTTON( x ); 

			hr=m_lpDIDevice->GetObjectInfo( &didoi, dwOfs, DIPH_BYOFFSET );
            
			if ( SUCCEEDED( hr ) )
			{
				count++;
				TCHAR* name=new char[sizeof(didoi.tszName)];

				// Should include UNICODE support here.
				strcpy(name,didoi.tszName);

				// Add the button name to the Pointer List for future reference.
				m_DIButtonNames.AddTail(name);
			}
			else
			{
				OutputDebugString(GetDIError(hr));
			}
		}
	}
	return count;	// How many buttons did we find?
}

////////////////////////////////////////////////////////////////////////
//
// Shutdown the the link list of Friendly Button Names
//
////////////////////////////////////////////////////////////////////////
void CDIJoystick::ClearFriendlyButtonNames()
{
	try
	{
		if(!m_DIButtonNames.IsEmpty())
		{
			POSITION pos=m_DIButtonNames.GetHeadPosition();
			LPVOID del=NULL;

			while(pos)
			{
				del=static_cast<LPVOID>(m_DIButtonNames.GetNext(pos));
				if(del)
				{
					delete del;
				}
			}
		}
		m_DIButtonNames.RemoveAll();
	}
	catch(...)
	{
		OutputDebugString("Some unforseen error occurred in CDIJoystick::ClearFriendlyButtonNames()\n");
	}
}

//////////////////////////////////////////////////////////////////////
//
// Initialise The Joystick!
//
//////////////////////////////////////////////////////////////////////
bool CDIJoystick::InitJoystick()
{
    // Set range. 
    // Note: range, deadzone, and saturation are being set for the
    // entire device. This could have unwanted effects on
    // sliders, dials, etc.

    DIPROPRANGE diprg; 
 
    diprg.diph.dwSize       = sizeof( diprg ); 
    diprg.diph.dwHeaderSize = sizeof( diprg.diph ); 
    diprg.diph.dwObj        = 0; 
    diprg.diph.dwHow        = DIPH_DEVICE; 
    diprg.lMin              = JOYMIN; 
    diprg.lMax              = JOYMAX; 
 
    if ( FAILED( m_lpDIDevice->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
        return FALSE; 

    // Set deadzone.
    DIPROPDWORD dipdw;

    dipdw.diph.dwSize       = sizeof( dipdw ); 
    dipdw.diph.dwHeaderSize = sizeof( dipdw.diph ); 
    dipdw.diph.dwObj        = 0;
    dipdw.diph.dwHow        = DIPH_DEVICE;
    dipdw.dwData            = JOYDEAD;

    if ( FAILED( m_lpDIDevice->SetProperty( DIPROP_DEADZONE, &dipdw.diph ) ) )
        return FALSE;

    // Set saturation.
    dipdw.dwData            = JOYSAT;
    if ( FAILED( m_lpDIDevice->SetProperty( DIPROP_SATURATION, &dipdw.diph ) ) )
        return FALSE;

    // Find out if force feedback available.
    DIDEVCAPS didc;
    didc.dwSize = sizeof( DIDEVCAPS );
    if ( FAILED( m_lpDIDevice->GetCapabilities( &didc ) ) ) 
        return FALSE;
    m_FFAvailable = ( didc.dwFlags & DIDC_FORCEFEEDBACK );

    // If it's a force feedback stick, turn off autocenter so it doesn't
    // get in the way of our effects.
    if ( m_FFAvailable )
    {
        DIPROPDWORD DIPropAutoCenter;
        DIPropAutoCenter.diph.dwSize = sizeof( DIPropAutoCenter );
        DIPropAutoCenter.diph.dwHeaderSize = sizeof( DIPROPHEADER );
        DIPropAutoCenter.diph.dwObj = 0;
        DIPropAutoCenter.diph.dwHow = DIPH_DEVICE;
        DIPropAutoCenter.dwData = 0;

        m_lpDIDevice->SetProperty( DIPROP_AUTOCENTER, 
                               &DIPropAutoCenter.diph );
    } 
    return TRUE;
}

//////////////////////////////////////////////////////////////////////
//
// Initialise The Joystick Device
//
//////////////////////////////////////////////////////////////////////
bool CDIJoystick::InitDevice()
{
    HRESULT hr;
    DIDEVICEINSTANCE    diDeviceInstance;

	// Just a precaution when Enumerating Devices and button Names if you create
	// An options Dialog before creating your main gaming window.
	// Then simply use the desktop window, temporarily!
	if(!m_hwnd)m_hwnd=::GetDesktopWindow();

    // Release device if it already exists.
    if ( m_lpDIDevice ) 
    {
        //if ( m_FFAvailable ) ReleaseEffects(); 
        
		Acquire( false);

        hr=m_lpDIDevice->Release();
		if(FAILED(hr))
		{
			OutputDebugString("Error Releasing Interface in CDIJoystick::InitDevice()\n");
			OutputDebugString(GetDIError(hr));
		} 
		else m_lpDIDevice=NULL;
    }

    // Create game device and set IDirectInputDevice7 interface in m_lpDIDevice.
    if(!CreateDevice( &m_JoystickGUID ))
	{
		OutputDebugString("Failed to create device in CDIJoystick::InitDevice()\n");
		return false;
	}

    // Find out what type it is and set data format accordingly.

    diDeviceInstance.dwSize = sizeof( DIDEVICEINSTANCE );

    hr=m_lpDIDevice->GetDeviceInfo( &diDeviceInstance );
	if ( FAILED( hr ) ) 
	{
		OutputDebugString("Failed to obtain device info in CDIJoystick::InitDevice()\n");
		OutputDebugString(GetDIError(hr));
		return false;
	}

	// Set the data format to be a Joystick
	hr = m_lpDIDevice->SetDataFormat( &c_dfDIJoystick2 );
	if ( FAILED( hr ) ) 
	{
		OutputDebugString("Failed to create device in CDIJoystick::InitDevice()\n");
		OutputDebugString(GetDIError(hr));
		return false;
	}

    // Set cooperative level. 
    DWORD cl, cl1;
	cl = DISCL_EXCLUSIVE;

	// Set foreground level for release version, but use background level
	// for debugging so we don't keep losing the device when switching to 
	// a debug window. 

    //cl1 = DISCL_FOREGROUND;
	cl1 = DISCL_BACKGROUND;
#ifdef _DEBUG
    cl1 = DISCL_BACKGROUND;
#endif

	// now set the co-operation level.
	hr=m_lpDIDevice->SetCooperativeLevel( m_hwnd, cl | cl1 );
    if ( FAILED( hr ))
    {
        OutputDebugString( "Failed to set game device cooperative level.\n" );
		OutputDebugString(GetDIError(hr));
        return false;
    }

    // Set up the data buffer.
    DIPROPDWORD dipdw =
    {
        // The header.
        {
            sizeof( DIPROPDWORD ),      // diph.dwSize
            sizeof( DIPROPHEADER ),     // diph.dwHeaderSize
            0,                          // diph.dwObj
            DIPH_DEVICE,                // diph.dwHow
        },
        // Number of elements in data buffer.
        BUFFERSIZE              // dwData
    };

    hr=m_lpDIDevice->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
	if(FAILED(hr))
    {
        OutputDebugString( "Failed to set up Data Buffer property.\n" );
		OutputDebugString(GetDIError(hr));
        return false;
    }

	// 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		int 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);
}


 2. 打开遥控手柄:

<span style="white-space:pre">	</span>CWnd *jb = (CNetSDKDemoDlg *)theApp.m_pMainWnd;
	myJoystick1.SetHWND(jb->m_hWnd);

	LPCDIDEVICEINSTANCE lpddi=NULL;

	m_ctlButtonNames.ResetContent();

	int x=m_ctlJoystickName.GetCurSel();

	lpddi=(LPCDIDEVICEINSTANCE)m_ctlJoystickName.GetItemDataPtr(x);

	GUID myguid;

	if(lpddi && ((int)lpddi!=-1))
	{

		memcpy(&myguid,&(lpddi->guidInstance),sizeof(GUID));

		//bool flag=myJoystick1.CreateDevice(&myguid);
		myJoystick1.SetPreferredDevice(&myguid);

		m_Buttons=myJoystick1.HowManyButtons();

		TCHAR* name=NULL;
		name=myJoystick1.GetFirstButtonName();

		while(name)
		{
			m_ctlButtonNames.AddString(name);
			name=myJoystick1.GetNextButtonName();
		}
	}

	m_ctlButtonNames.SetCurSel(0);	
3.  设置500毫秒定时器读取游戏手柄事件

void CDevCtrlDlg::OnTimer(UINT_PTR nIDEvent)
{
	
	myJoystick1.PollDevice();

	if(myJoystick1.IsJoystickLeft()) m_Left=true; else m_Left=false;
	if(myJoystick1.IsJoystickRight()) m_Right=true; else m_Right=false;
	if(myJoystick1.IsJoystickUp()) m_Up=true; else m_Up=false;
	if(myJoystick1.IsJoystickDown()) m_Down=true; else m_Down=false;
	if(myJoystick1.IsJoystickFire()) m_Fire=true; else m_Fire=false;
	

	LPDIJOYSTATE2 joy=myJoystick1.GetJoystickStateInfo();

	m_XAxis.Format("%d",joy->lX);
	m_YAxis.Format("%d",joy->lY);
	m_ZAxis.Format("%d",joy->lZ);

	m_RXAxis.Format("%d",joy->lRx);
	m_RYAxis.Format("%d",joy->lRy);
	m_RZAxis.Format("%d",joy->lRz);


	m_FireText.Empty();

	for(int i=0;i<m_Buttons;i++)
	{
		if(myJoystick1.IsJoystickFire(i))
		{
			CString temp;
			temp.Format("Fire Button : %d\r\n",i);
			m_FireText+=temp;
			if(i==0){
				m_btn1Press = true;
			}
			if(i==1){
				m_btn2Press = true;
			}
			if(i==2){
				m_btn3Press = true;
			}
		}else{
			if(i==0){
				m_btn1Press=false;
			}
			if(i==1){
				m_btn2Press = false;
			}
			if(i==2){
				m_btn3Press = false;
			}

		}
	}

	UpdateJoystickEvent();

	CDialog::OnTimer(nIDEvent);
}
4. 遥控手柄事件映射成摄像头云台onvif标准事件
<pre name="code" class="cpp">void CDevCtrlDlg::UpdateJoystickEvent(void)
{
	CNetSDKDemoDlg *pNetSDKDemoDlg = (CNetSDKDemoDlg *)theApp.m_pMainWnd;//(CNetSDKDemoDlg *)GetParent();
	int iP = m_ctlPanSpeed.GetCurSel() + 1; //水平
	int iT = m_ctlTiltSpeed.GetCurSel() + 1;//垂直

	if(m_Left){
		m_text.SetWindowText("left=true");
		m_lastDir =1;
		pNetSDKDemoDlg->PTZCtrl(PAN_LEFT, iP, iT);
	}
	if(m_Right){
		m_text.SetWindowText("right=true");
		m_lastDir = 2;
		pNetSDKDemoDlg->PTZCtrl(PAN_RIGHT, iP, iT);
	}
	if(m_Up) {
		m_text.SetWindowText("up=true");
		m_lastDir =3;
		pNetSDKDemoDlg->PTZCtrl(TILT_UP, iP, iT);
	}
	if(m_Down) {
		m_text.SetWindowText("down=true");
		m_lastDir = 4;
		pNetSDKDemoDlg->PTZCtrl(TILT_DOWN, iP, iT);
	}
	if(m_btn1Press){
		if(m_lastDir != 5){
		m_text.SetWindowText("btn1=true,cmd=ZOOM_IN");
		pNetSDKDemoDlg->PTZCtrl(ZOOM_IN_VALUE, iP, iT);
		}

		m_lastDir=5;
		//pNetSDKDemoDlg->PTZCtrl(ZOOM_IN, iP, iT);
	}
	if(m_btn2Press){
	
		if(m_lastDir != 6){
		m_text.SetWindowText("btn2=true,cmd=ZOOM_OUT");
		pNetSDKDemoDlg->PTZCtrl(ZOOM_OUT_VALUE, iP, iT);
		}
			m_lastDir=6;
		//pNetSDKDemoDlg->PTZCtrl(ZOOM_OUT, iP, iT);
	}
	if(m_btn3Press){
		if(m_lastDir != 7){
		m_text.SetWindowText("btn3=true,cmd=PAN_AUTO");
		
		pNetSDKDemoDlg->PTZCtrl(PAN_AUTO, iP, iT);
		}
		m_lastDir=7;
	}
	switch(m_lastDir){
		case 1:
			if(!m_Left){
				m_text.SetWindowText("left=false");
				pNetSDKDemoDlg->PTZCtrl(STOPACTION, 0, 0);
				m_lastDir =0;
			}
			break;
		case 2:
			if(!m_Right){
				m_text.SetWindowText("right=false");
				pNetSDKDemoDlg->PTZCtrl(STOPACTION, 0, 0);
				m_lastDir =0;
			}
			break;
		case 3:
			if(!m_Up){
				m_text.SetWindowText("up=false");
				pNetSDKDemoDlg->PTZCtrl(STOPACTION, 0, 0);
				m_lastDir =0;
			}
			break;
		case 4:
			if(!m_Down){
				m_text.SetWindowText("down=false");
				pNetSDKDemoDlg->PTZCtrl(STOPACTION, 0, 0);
				m_lastDir =0;
			}
			break;
		case 5:

			if(!m_btn1Press){
				m_text.SetWindowText("btn1=false");
				pNetSDKDemoDlg->PTZCtrl(STOPACTION, 0, 0);
				m_lastDir =0;
			}

			break;
		case 6:
			if(!m_btn2Press){
				m_text.SetWindowText("btn2=false");
				pNetSDKDemoDlg->PTZCtrl(STOPACTION, 0, 0);
				m_lastDir =0;
			}
			break;
		case 7:
			if(!m_btn3Press){
				m_text.SetWindowText("btn3=false");
				pNetSDKDemoDlg->PTZCtrl(STOPACTION, 0, 0);
				m_lastDir =0;
			}
			break;
		default:
			break;
	}
}











你可能感兴趣的:(摄像头,Joystick,遥控手柄)