DirectX Input 键盘实现 收藏
view plaincopy to clipboardprint?
// DInputKeyboard.h: interface for the CDInputKeyboard class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#define DIRECTINPUT_VERSION 0x800
#include <afxtempl.h>
#include <dinput.h>
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "DXguid.Lib")
class CDInputKeyboard
{
#define BUFFERCOUNT 256
LPDIRECTINPUT lpDirectInput;
LPDIRECTINPUTDEVICE lpdiKeyboard;
BOOL KeyboardAcquired;
BOOL KeyboardFound;
CTypedPtrArray <CPtrArray, LPDIDEVICEINSTANCE> m_KeyboInstance_Array;
protected:
virtual BOOL ProcessInputKey(TCHAR tChar)
{
return false;
}
static BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi,
LPVOID pvRef)
{
if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD
|| ((lpddi->dwDevType & DIDEVTYPE_HID) && GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DEVICE ) )
{
LPDIDEVICEINSTANCE pNewdid = (LPDIDEVICEINSTANCE) new DIDEVICEINSTANCE;
memcpy(pNewdid, lpddi, sizeof(DIDEVICEINSTANCE));
((CDInputKeyboard *)pvRef)->m_KeyboInstance_Array.Add(pNewdid);
}
return DIENUM_CONTINUE;
} // DIEnumDevicesProc
void RemoveGUID()
{
KeyboardFound = 0;
while(m_KeyboInstance_Array.GetSize() > 0)
{
delete m_KeyboInstance_Array.GetAt(0);
m_KeyboInstance_Array.RemoveAt(0);
}
}
public:
HWND hMainWindow; // app window handle
virtual BOOL InitInput(HWND hWnd)
{
ASSERT(lpDirectInput == NULL);
ASSERT(hWnd);
hMainWindow = hWnd;
HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hMainWindow, GWL_HINSTANCE); // program instance
// try to create DirectInput object
if(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&lpDirectInput, NULL) != DI_OK)
{
lpDirectInput = NULL;
OutputDebugString( _T("Failed to create DirectInput object.\n") );
return FALSE;
}
return TRUE;
}
INT_PTR EnumKeyboard()
{
RemoveGUID();
if(lpDirectInput)
{
// enumerate devices so we can get the GUIDs
if (lpDirectInput->EnumDevices(0,
DIEnumDevicesProc,
this,
DIEDFL_ALLDEVICES) != DI_OK)
{
OutputDebugString( _T("Could not enumerate devices.\n") );
}
}
return m_KeyboInstance_Array.GetSize();
}
BOOL Unacquire()
{
if(lpdiKeyboard)
{
lpdiKeyboard->Unacquire();
lpdiKeyboard->Release();
lpdiKeyboard = NULL;
}
KeyboardAcquired = false;
return TRUE;
}
BOOL Acquire(INT_PTR nPos = -1)
{
Unacquire();
if(lpDirectInput == NULL)
{
OutputDebugString( _T("lpDirectInput is NULL.\n") );
return FALSE;
}
GUID KeyboardGUID = GUID_SysKeyboard;
if(nPos >=0 && nPos < m_KeyboInstance_Array.GetSize())
{
KeyboardGUID = m_KeyboInstance_Array.GetAt(nPos)->guidInstance;
}
// try to create keyboard device
if(lpDirectInput->CreateDevice(KeyboardGUID, &lpdiKeyboard, NULL) != DI_OK ) //GUID_SysKeyboard
{
OutputDebugString( _T("Failed to create keyboard device.\n") );
Unacquire();
return FALSE;
}
// set kbd cooperative level
if (lpdiKeyboard->SetCooperativeLevel(hMainWindow, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
{
OutputDebugString( _T("Failed to set keyboard cooperative level.\n") );
Unacquire();
return FALSE;
}
// set kbd data format
if (lpdiKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
{
OutputDebugString( _T("Failed to set keyboard data format.\n") );
Unacquire();
return FALSE;
}
// set kbd buffer size
DIPROPDWORD dipdw = {0};
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = BUFFERCOUNT; // * sizeof(DIDEVICEOBJECTDATA);
if (lpdiKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK)
{
OutputDebugString( _T("Failed to set keyboard buffer size.\n") );
Unacquire();
return FALSE;
}
// try to acquire the keyboard
if (lpdiKeyboard->Acquire() != DI_OK)
{
OutputDebugString( _T("Failed to acquire the keyboard.\n") );
Unacquire();
return FALSE;
}
KeyboardAcquired = TRUE;
return TRUE;
}
BOOL ReacquireInput(void)
{
//the keyboard
if(lpdiKeyboard != NULL)
{
lpdiKeyboard->Acquire();
}
else
{
// keyboard device has not been created.
return FALSE;
}
// if we get here, we are acquired again
KeyboardAcquired = TRUE;
return TRUE;
} // ReacquireInputDevices()
BOOL PollKeyboard(void) //Reads the keyboard state
{
if(lpdiKeyboard && KeyboardAcquired)
{
BYTE diKeys[257] = {0};
if (lpdiKeyboard->GetDeviceState(256, &diKeys) == DI_OK)
{
if(diKeys[DIK_LWIN] & 0x80) /* Left Windows key */
{
}
if(diKeys[DIK_RWIN] & 0x80) /* Right Windows key */
{
}
return TRUE; // success
}
}
return FALSE;
} // PollKeyboard()
HRESULT ReadKeyboardInput(void)
{
HRESULT hRes = DI_OK;
if(KeyboardAcquired)
{
DIDEVICEOBJECTDATA KbdBuffer[BUFFERCOUNT] = {0};
DWORD dwItems = BUFFERCOUNT;
hRes = lpdiKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),
KbdBuffer, &dwItems, 0);
if(hRes == DI_OK || hRes == DI_BUFFEROVERFLOW)
{
for (DWORD k = 0; k < dwItems; k++)
{
LPDIDEVICEOBJECTDATA lpdidod = &KbdBuffer[k];
TCHAR VKey = MapVirtualKey(lpdidod->dwOfs, 3); //映射到虚拟键
ProcessInputKey(VKey); //处理输入
CString dbgStr, tmpStr;
dbgStr.Format(_T("%d"), lpdidod->dwSequence);
tmpStr.Format(_T(". Scan code 0x%04X"), lpdidod->dwOfs);
dbgStr += tmpStr;
dbgStr += (lpdidod->dwData & 0x80)? _T(" pressed ") : _T(" released ");
tmpStr.Format(_T(". Age: %d ms"), GetTickCount() - lpdidod->dwTimeStamp);
dbgStr += tmpStr;
dbgStr += _T("\n");
OutputDebugString(dbgStr);
}
}
else if(hRes == DIERR_INPUTLOST)
{
ReacquireInput();
hRes = S_FALSE;
}
}
return hRes;
}
////////////////////////////////////////////////
CDInputKeyboard()
{
hMainWindow = NULL;
lpDirectInput = NULL;
lpdiKeyboard = NULL;
KeyboardAcquired = 0;
KeyboardFound = 0;
m_KeyboInstance_Array.RemoveAll();
}
virtual ~CDInputKeyboard()
{
if(lpdiKeyboard)
{
lpdiKeyboard->Unacquire();
lpdiKeyboard->Release();
lpdiKeyboard = NULL;
}
if(lpDirectInput)
{
lpDirectInput->Release();
lpDirectInput = NULL;
}
RemoveGUID();
}
};
// DInputKeyboard.h: interface for the CDInputKeyboard class.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#define DIRECTINPUT_VERSION 0x800
#include <afxtempl.h>
#include <dinput.h>
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "DXguid.Lib")
class CDInputKeyboard
{
#define BUFFERCOUNT 256
LPDIRECTINPUT lpDirectInput;
LPDIRECTINPUTDEVICE lpdiKeyboard;
BOOL KeyboardAcquired;
BOOL KeyboardFound;
CTypedPtrArray <CPtrArray, LPDIDEVICEINSTANCE> m_KeyboInstance_Array;
protected:
virtual BOOL ProcessInputKey(TCHAR tChar)
{
return false;
}
static BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi,
LPVOID pvRef)
{
if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD
|| ((lpddi->dwDevType & DIDEVTYPE_HID) && GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DEVICE ) )
{
LPDIDEVICEINSTANCE pNewdid = (LPDIDEVICEINSTANCE) new DIDEVICEINSTANCE;
memcpy(pNewdid, lpddi, sizeof(DIDEVICEINSTANCE));
((CDInputKeyboard *)pvRef)->m_KeyboInstance_Array.Add(pNewdid);
}
return DIENUM_CONTINUE;
} // DIEnumDevicesProc
void RemoveGUID()
{
KeyboardFound = 0;
while(m_KeyboInstance_Array.GetSize() > 0)
{
delete m_KeyboInstance_Array.GetAt(0);
m_KeyboInstance_Array.RemoveAt(0);
}
}
public:
HWND hMainWindow; // app window handle
virtual BOOL InitInput(HWND hWnd)
{
ASSERT(lpDirectInput == NULL);
ASSERT(hWnd);
hMainWindow = hWnd;
HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hMainWindow, GWL_HINSTANCE); // program instance
// try to create DirectInput object
if(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&lpDirectInput, NULL) != DI_OK)
{
lpDirectInput = NULL;
OutputDebugString( _T("Failed to create DirectInput object.\n") );
return FALSE;
}
return TRUE;
}
INT_PTR EnumKeyboard()
{
RemoveGUID();
if(lpDirectInput)
{
// enumerate devices so we can get the GUIDs
if (lpDirectInput->EnumDevices(0,
DIEnumDevicesProc,
this,
DIEDFL_ALLDEVICES) != DI_OK)
{
OutputDebugString( _T("Could not enumerate devices.\n") );
}
}
return m_KeyboInstance_Array.GetSize();
}
BOOL Unacquire()
{
if(lpdiKeyboard)
{
lpdiKeyboard->Unacquire();
lpdiKeyboard->Release();
lpdiKeyboard = NULL;
}
KeyboardAcquired = false;
return TRUE;
}
BOOL Acquire(INT_PTR nPos = -1)
{
Unacquire();
if(lpDirectInput == NULL)
{
OutputDebugString( _T("lpDirectInput is NULL.\n") );
return FALSE;
}
GUID KeyboardGUID = GUID_SysKeyboard;
if(nPos >=0 && nPos < m_KeyboInstance_Array.GetSize())
{
KeyboardGUID = m_KeyboInstance_Array.GetAt(nPos)->guidInstance;
}
// try to create keyboard device
if(lpDirectInput->CreateDevice(KeyboardGUID, &lpdiKeyboard, NULL) != DI_OK ) //GUID_SysKeyboard
{
OutputDebugString( _T("Failed to create keyboard device.\n") );
Unacquire();
return FALSE;
}
// set kbd cooperative level
if (lpdiKeyboard->SetCooperativeLevel(hMainWindow, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
{
OutputDebugString( _T("Failed to set keyboard cooperative level.\n") );
Unacquire();
return FALSE;
}
// set kbd data format
if (lpdiKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
{
OutputDebugString( _T("Failed to set keyboard data format.\n") );
Unacquire();
return FALSE;
}
// set kbd buffer size
DIPROPDWORD dipdw = {0};
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = BUFFERCOUNT; // * sizeof(DIDEVICEOBJECTDATA);
if (lpdiKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK)
{
OutputDebugString( _T("Failed to set keyboard buffer size.\n") );
Unacquire();
return FALSE;
}
// try to acquire the keyboard
if (lpdiKeyboard->Acquire() != DI_OK)
{
OutputDebugString( _T("Failed to acquire the keyboard.\n") );
Unacquire();
return FALSE;
}
KeyboardAcquired = TRUE;
return TRUE;
}
BOOL ReacquireInput(void)
{
//the keyboard
if(lpdiKeyboard != NULL)
{
lpdiKeyboard->Acquire();
}
else
{
// keyboard device has not been created.
return FALSE;
}
// if we get here, we are acquired again
KeyboardAcquired = TRUE;
return TRUE;
} // ReacquireInputDevices()
BOOL PollKeyboard(void) //Reads the keyboard state
{
if(lpdiKeyboard && KeyboardAcquired)
{
BYTE diKeys[257] = {0};
if (lpdiKeyboard->GetDeviceState(256, &diKeys) == DI_OK)
{
if(diKeys[DIK_LWIN] & 0x80) /* Left Windows key */
{
}
if(diKeys[DIK_RWIN] & 0x80) /* Right Windows key */
{
}
return TRUE; // success
}
}
return FALSE;
} // PollKeyboard()
HRESULT ReadKeyboardInput(void)
{
HRESULT hRes = DI_OK;
if(KeyboardAcquired)
{
DIDEVICEOBJECTDATA KbdBuffer[BUFFERCOUNT] = {0};
DWORD dwItems = BUFFERCOUNT;
hRes = lpdiKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),
KbdBuffer, &dwItems, 0);
if(hRes == DI_OK || hRes == DI_BUFFEROVERFLOW)
{
for (DWORD k = 0; k < dwItems; k++)
{
LPDIDEVICEOBJECTDATA lpdidod = &KbdBuffer[k];
TCHAR VKey = MapVirtualKey(lpdidod->dwOfs, 3); //映射到虚拟键
ProcessInputKey(VKey); //处理输入
CString dbgStr, tmpStr;
dbgStr.Format(_T("%d"), lpdidod->dwSequence);
tmpStr.Format(_T(". Scan code 0x%04X"), lpdidod->dwOfs);
dbgStr += tmpStr;
dbgStr += (lpdidod->dwData & 0x80)? _T(" pressed ") : _T(" released ");
tmpStr.Format(_T(". Age: %d ms"), GetTickCount() - lpdidod->dwTimeStamp);
dbgStr += tmpStr;
dbgStr += _T("\n");
OutputDebugString(dbgStr);
}
}
else if(hRes == DIERR_INPUTLOST)
{
ReacquireInput();
hRes = S_FALSE;
}
}
return hRes;
}
////////////////////////////////////////////////
CDInputKeyboard()
{
hMainWindow = NULL;
lpDirectInput = NULL;
lpdiKeyboard = NULL;
KeyboardAcquired = 0;
KeyboardFound = 0;
m_KeyboInstance_Array.RemoveAll();
}
virtual ~CDInputKeyboard()
{
if(lpdiKeyboard)
{
lpdiKeyboard->Unacquire();
lpdiKeyboard->Release();
lpdiKeyboard = NULL;
}
if(lpDirectInput)
{
lpDirectInput->Release();
lpDirectInput = NULL;
}
RemoveGUID();
}
};
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zgl7903/archive/2010/02/01/5277822.aspx