Direct3D轮回:构建基于DirectInput机制的键盘输入设备
2011-06-22 22:20 独孤残云 阅读(2011) 评论(2) 编辑 收藏 举报有了鼠标输入设备,这一篇简单讨论基于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个字符
};
代码清单: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个字符
};
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()
{
代码清单: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);
}
m_pIDirectInputDevice->Unacquire();
ReleaseCOM(m_pIDirectInputDevice);
ReleaseCOM(m_pIDirectInput);
}
通过如上代码不难发现,键盘输入设备的构建流程其实与鼠标设备很类似~
区别在于,这次我们将输入设备的相关信息记录到了
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);
}
}
{
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);
如下效果图: