Direct3D轮回:构建基于DirectInput机制的键盘输入设备

有了鼠标输入设备,这一篇简单讨论基于DirectInput机制的键盘输入设备的构建。
继续上一篇,我们再原有基础上丰富DirectInput.h和DirectInput.cpp的内容:
/*------------------------------------- 代码清单:D3DInput.h 来自:http://www.cnblogs.com/kenkao -------------------------------------*/ ………… ………… class CKeyboardInput { public: CKeyboardInput(); ~CKeyboardInput(); HRESULT Initialize(HINSTANCE hInst,HWND hWnd); //初始化输入设备 void GetState(); //获取设备状态 BOOL IsKeyDown(int KeyCode); //键位是否按下 BOOL IsKeyUp(int KeyCode); //键位是否弹起 void Release(); //释放输入设备 private: HWND m_hWnd; //设备所属的窗口句柄 LPDIRECTINPUT8 m_pIDirectInput; //IDirectInput接口对象 LPDIRECTINPUTDEVICE8 m_pIDirectInputDevice; //IDirectInput设备对象 char keyBuffer[256]; //键盘缓冲区,对应全盘256个字符 };
Direct3D轮回:构建基于DirectInput机制的键盘输入设备Direct3D轮回:构建基于DirectInput机制的键盘输入设备D3DInput.cpp /*------------------------------------- 代码清单:D3DInput.cpp 来自:http://www.cnblogs.com/kenkao -------------------------------------*/ ………… ………… CKeyboardInput::CKeyboardInput() : m_pIDirectInput(NULL), m_pIDirectInputDevice(NULL) { } CKeyboardInput::~CKeyboardInput() { } HRESULT CKeyboardInput::Initialize(HINSTANCE hInst,HWND hWnd) { m_hWnd=hWnd; HRESULT hr; //创建IDirectInput接口对象 hr=DirectInput8Create(hInst,DIRECTINPUT_VERSION, IID_IDirectInput8,(void**)&m_pIDirectInput,NULL); if(FAILED(hr)){ return hr; } //初始化键盘输入设备 hr=m_pIDirectInput->CreateDevice(GUID_SysKeyboard,&m_pIDirectInputDevice,NULL);//GUID_SysKeyboard代表初始化设备为键盘设备 if(FAILED(hr)){ ReleaseCOM(m_pIDirectInput); return hr; } //设置键盘设备的数据格式 hr=m_pIDirectInputDevice->SetDataFormat(&c_dfDIKeyboard); if(FAILED(hr)){ ReleaseCOM(m_pIDirectInputDevice); ReleaseCOM(m_pIDirectInput); return hr; } //设置键盘设备的协调级别 hr=m_pIDirectInputDevice->SetCooperativeLevel(hWnd,DISCL_FOREGROUND|DISCL_EXCLUSIVE); if(FAILED(hr)){ ReleaseCOM(m_pIDirectInputDevice); ReleaseCOM(m_pIDirectInput); return hr; } //获取键盘设备访问权限 hr=m_pIDirectInputDevice->Acquire(); //键盘缓冲区清零 ZeroMemory(keyBuffer,sizeof(char)*256); return S_OK; } void CKeyboardInput::GetState() { HRESULT hr; //键盘缓冲区清零 ZeroMemory(keyBuffer,sizeof(char)*256); //立即模式下获取设备状态 hr = m_pIDirectInputDevice->GetDeviceState(sizeof(keyBuffer),(LPVOID)keyBuffer); if(FAILED(hr)) { //如果失败,则重新获取键盘设备的访问权限 hr=m_pIDirectInputDevice->Acquire(); } } BOOL CKeyboardInput::IsKeyDown(int KeyCode) { return keyBuffer[KeyCode] & 0x80; } BOOL CKeyboardInput::IsKeyUp(int KeyCode) { return !IsKeyDown(KeyCode); } void CKeyboardInput::Release() {
// 释放键盘设备的访问权 m_pIDirectInputDevice->Unacquire(); ReleaseCOM(m_pIDirectInputDevice); ReleaseCOM(m_pIDirectInput); }
通过如上代码不难发现,键盘输入设备的构建流程其实与鼠标设备很类似~
区别在于,我们使用了与缓冲模式相对的立即模式。该模式比较适用于构建键盘或者游戏杆类型的输入设备。
需要注意两个地方:
1>因为立即模式为DirectInput默认模式,所以无需再设置设备属性,即省去了SetProperty这一步;
2>与立即模式相对的状态获取函数为GetDeviceState,而不再是缓冲模式下的GetDeviceData。
GetDeviceData传入的参数为我们事先定义好的
char keyBuffer[256];
长度256代表键盘上的256个键位(我没有仔细统计,感兴趣的朋友可以详细的数一下~囧~),换言之,键盘设备通过GetDeviceState记录下了键盘当前256个键位的所有状态。
理解清楚这些内容,我们可以在原有工程基础上新增一个键盘输入设备检测函数:
void TestKeyboardInput() { TCHAR tmpText[50]; // 获得键盘输入设备状态 g_pKeyboardInput->GetState(); // 单键检测 if(g_pKeyboardInput->IsKeyDown(DIK_D)) { sprintf(tmpText,"D键被按下"); MessageBox(NULL,tmpText,"提示",MB_OK|MB_ICONINFORMATION); } // 组合键检测 else if(g_pKeyboardInput->IsKeyDown(DIK_A)&g_pKeyboardInput->IsKeyDown(DIK_S)) { sprintf(tmpText,"A&S组合键被按下"); MessageBox(NULL,tmpText,"提示",MB_OK|MB_ICONINFORMATION); } }
大家不难看出,组合键检测的实现其实相当容易~
当然,最后不要忘记释放我们构建的键盘设备~
ReleaseCOM(g_pKeyboardInput);
如下效果图:
Tags: 

延伸阅读

最新评论

发表评论