//======================================================================
/**
* @file Input.cpp
*
* 项目描述: DirectInput输入系统
*
* 文件描述: 输入系统类CInputSystem
* 其中,类CKeyboard、CMouse和CJoystick分别用来处理键盘、鼠标
* 和游戏手柄,CInputSystem是输入设备的管理类。
* 适用平台: Windows98/2000/NT/XP
*
* 作者: WWBOSS
* 电子邮件: wwboss123@gmail.com
* 创建日期: 2007-07-24
* 修改日期: 2007-07-24
*/
//======================================================================
#include "Input.h"
//************** 键盘类CKeyboard的实现 **************************/
/** 构造函数 */
CKeyboard::CKeyboard(LPDIRECTINPUT8 pDI, HWND hwnd)
{
/** 创建设备对象 */
if (FAILED(pDI->CreateDevice(GUID_SysKeyboard, &m_pDIDev, NULL)))
{
MessageBox(NULL,"创建键盘设备对象失败!","错误",MB_OK);
}
/** 设置数据格式 */
if (FAILED(m_pDIDev->SetDataFormat(&c_dfDIKeyboard)))
{
MessageBox(NULL,"设置键盘数据格式失败!","错误",MB_OK);
}
/** 设置协作层次 */
if (FAILED(m_pDIDev->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
{
MessageBox(NULL,"设置键盘协作层次失败!","错误",MB_OK);
}
/** 捕获设置 */
if (FAILED(m_pDIDev->Acquire()))
{
MessageBox(NULL,"捕获键盘设备失败!","错误",MB_OK);
}
/** 键盘数据清零 */
Clear();
}
/** 析构函数 */
CKeyboard::~CKeyboard()
{
if (m_pDIDev)
{
m_pDIDev->Unacquire();
m_pDIDev->Release();
}
}
/** 更新键盘数据 */
bool CKeyboard::Update()
{
if (FAILED(m_pDIDev->GetDeviceState(sizeof(m_keys), (LPVOID)m_keys)))
{
if (FAILED(m_pDIDev->Acquire()))
return false;
if (FAILED(m_pDIDev->GetDeviceState(sizeof(m_keys),(LPVOID)m_keys)))
return false;
}
return TRUE;
}
//************** 鼠标类CMouse的实现 **************************/
/** 构造函数 */
CMouse::CMouse(LPDIRECTINPUT8 pDI, HWND hwnd, bool isExclusive)
{
/** 得到当前窗口的大小 */
RECT r;
GetClientRect(hwnd , &r);
m_iWidth = r.right - r.left;
m_iHeight = r.bottom - r.top;
m_iMousePos.x = m_iWidth/2;
m_iMousePos.y = m_iHeight/2;
/** 创建设备对象 */
if (FAILED(pDI->CreateDevice(GUID_SysMouse, &m_pDIDev, NULL)))
{
MessageBox(NULL,"创建鼠标设备对象失败!","错误",MB_OK);
}
/** 设置数据格式 */
if (FAILED(m_pDIDev->SetDataFormat(&c_dfDIMouse)))
{
MessageBox(NULL,"设置鼠标数据格式失败!","错误",MB_OK);
}
DWORD flags;
if (isExclusive)
flags = DISCL_FOREGROUND|DISCL_EXCLUSIVE|DISCL_NOWINKEY;
else
flags = DISCL_FOREGROUND|DISCL_NONEXCLUSIVE;
/** 设置协作层次 */
if (FAILED(m_pDIDev->SetCooperativeLevel(hwnd, flags)))
{
MessageBox(NULL,"设置鼠标协作层次失败!","错误",MB_OK);
}
/** 设置鼠标属性 */
DIPROPDWORD dipROPWORD;
dipROPWORD.diph.dwSize = sizeof(DIPROPDWORD);
dipROPWORD.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipROPWORD.diph.dwObj = 0;
dipROPWORD.diph.dwHow = DIPH_DEVICE;
dipROPWORD.dwData = DINPUT_BUFFERSIZE;
if(FAILED(m_pDIDev->SetProperty(DIPROP_BUFFERSIZE,&dipROPWORD.diph)))
{
MessageBox(NULL,"设置鼠标设备属性失败!","错误",MB_OK);
}
/** 捕获设备 */
if (FAILED(m_pDIDev->Acquire()))
{
MessageBox(NULL,"捕获鼠标设备失败!","错误",MB_OK);
}
}
/** 判断鼠标左键是否按下 */
bool CMouse::IsLButtonPressed()
{
for(int i=0;i<DINPUT_BUFFERSIZE; i++)
{
if((m_diData[i].dwOfs == DIMOFS_BUTTON0) &&
(m_diData[i].dwData & 0x80))
return true;
}
return false;
}
/** 判断鼠标右键是否按下 */
bool CMouse::IsRButtonPressed()
{
for(int i=0;i<DINPUT_BUFFERSIZE; i++)
{
if((m_diData[i].dwOfs == DIMOFS_BUTTON1) &&
(m_diData[i].dwData & 0x80))
return true;
}
return false;
}
/** 判断鼠标中键是否按下 */
bool CMouse::IsMButtonPressed()
{
for(int i=0;i<DINPUT_BUFFERSIZE; i++)
{
if((m_diData[i].dwOfs == DIMOFS_BUTTON2) &&
(m_diData[i].dwData & 0x80))
return true;
}
return false;
}
/** 析构函数 */
CMouse::~CMouse()
{
if (m_pDIDev)
{
m_pDIDev->Unacquire();
m_pDIDev->Release();
}
}
/** 更新鼠标参数 */
bool CMouse::Update()
{
HRESULT hr;
DWORD dwReadNum = 1;
int i;
/** 清零鼠标缓冲区 */
ZeroMemory(m_diData,sizeof(DIDEVICEOBJECTDATA) * DINPUT_BUFFERSIZE);
/**循环读取鼠标数据 */
for(i=0; i<DINPUT_BUFFERSIZE;i++)
{
hr = m_pDIDev->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),
&m_diData[i],&dwReadNum,0);
if(hr == DIERR_INPUTLOST)
{
m_pDIDev->Acquire();
hr = m_pDIDev->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),
&m_diData[i],&dwReadNum,0);
if(FAILED(hr))
{
MessageBox(NULL,"取得鼠标缓冲区数据失败!","错误",MB_OK);
return false;
}
}
/** 更新鼠标位置 */
if(m_diData[i].dwOfs == DIMOFS_X)
m_iMousePos.x += m_diData[i].dwData;
if(m_diData[i].dwOfs == DIMOFS_Y)
m_iMousePos.y += m_diData[i].dwData;
/** 限制鼠标在窗口范围 */
if(m_iMousePos.x < 0)
m_iMousePos.x = 0;
if(m_iMousePos.x> m_iWidth)
m_iMousePos.x = m_iWidth;
if(m_iMousePos.y < 0)
m_iMousePos.y = 0;
if(m_iMousePos.y > m_iHeight)
m_iMousePos.y = m_iHeight;
}
return true;
}
//************** 游戏手柄CJoystick的实现 *******************************/
CJoystick::CJoystick(LPDIRECTINPUT8 pDI,HWND hwnd,HINSTANCE appInstance)
:m_iMin(-100),m_iMax(100),m_iDeadZone(20)
{
HRESULT hr;
m_pDI = pDI;
/** 枚举已安装的所有游戏杆 */
/**hr = m_pDI->EnumDevices(DI8DEVCLASS_GAMECTRL,(LPDIENUMDEVICESCALLBACKA)EnumJSCallback,&m_pDIDev,DIEDFL_ATTACHEDONLY);
if(FAILED(hr))
{
MessageBox(NULL,"枚举游戏杆失败!","错误",MB_OK);
exit(-1);
}*/
if(m_pDIDev == NULL)
{
MessageBox(NULL,"没有安装游戏杆!","错误",MB_OK);
exit(-1);
}
/** 设置游戏杆的数据格式 */
hr = m_pDIDev->SetDataFormat(&c_dfDIJoystick2);
if(FAILED(hr))
MessageBox(NULL,"设置游戏杆数据格式失败!","错误",MB_OK);
/** 设置游戏杆的协作层级 */
hr = m_pDIDev->SetCooperativeLevel(hwnd,DISCL_BACKGROUND|DISCL_NONEXCLUSIVE);
if(FAILED(hr))
MessageBox(NULL,"设置游戏杆协作层级失败!","错误",MB_OK);
/** 设置游戏杆的轴范围 */
DIPROPRANGE dipROPRANGE;
dipROPRANGE.diph.dwSize = sizeof(DIPROPRANGE);
dipROPRANGE.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipROPRANGE.diph.dwObj = 0;
dipROPRANGE.diph.dwHow = DIPH_DEVICE;
dipROPRANGE.lMin = m_iMin;
dipROPRANGE.lMax = m_iMax;
hr = m_pDIDev->SetProperty(DIPROP_RANGE,&dipROPRANGE.diph);
if(FAILED(hr))
MessageBox(NULL,"设置游戏杆轴范围失败!","错误",MB_OK);
/** 设置游戏杆的死区范围 */
DIPROPDWORD dipROPDWORD;
dipROPDWORD.diph.dwSize = sizeof(DIPROPDWORD);
dipROPDWORD.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipROPDWORD.diph.dwObj = 0;
dipROPDWORD.diph.dwHow = DIPH_DEVICE;
dipROPDWORD.dwData = 100 * m_iDeadZone;
hr = m_pDIDev->SetProperty(DIPROP_DEADZONE,&dipROPDWORD.diph);
if(FAILED(hr))
MessageBox(NULL,"设置游戏杆死区范围失败!","错误",MB_OK);
/** 初始化数据区 */
ZeroMemory(&m_diJoyState2,sizeof(DIJOYSTATE2));
}
/** 回调函数 */
bool CALLBACK CJoystick::EnumJSCallback(LPCDIDEVICEINSTANCE pDIDeviceInstance, LPVOID pvRef)
{
HRESULT hr;
LPDIRECTINPUTDEVICE8* ppDID = (LPDIRECTINPUTDEVICE8* )pvRef;
hr = m_pDI->CreateDevice(pDIDeviceInstance->guidInstance,ppDID,NULL);
if(FAILED(hr))
return DIENUM_CONTINUE;
else
return DIENUM_STOP;
}
/** 更新,获取输入 */
bool CJoystick::Update()
{
/** 获取游戏杆的访问权 */
HRESULT hr;
hr = m_pDIDev->Acquire();
if(FAILED(hr))
{
MessageBox(NULL,"获得游戏杆访问权失败!","错误",MB_OK);
return false;
}
/** 检测游戏杆 */
hr = m_pDIDev->Poll();
if(FAILED(hr))
{
MessageBox(NULL,"检测游戏杆失败!","错误",MB_OK);
return false;
}
/** 读取游戏杆的输入 */
hr = m_pDIDev->GetDeviceState(sizeof(DIJOYSTATE2),&m_diJoyState2);
/** 设备丢失 */
if(hr == DIERR_INPUTLOST)
{
m_pDIDev->Acquire(); /**< 重新获得设备使用权 */
m_pDIDev-
licl19870605
- 粉丝: 59
- 资源: 69
最新资源
- Azure OpenAI:生成式人工智能的创新与实践
- ParseError12.md
- 内存分配失败异常解决办法.md
- java.静态关键字(解决方案).md
- content_1736261633667.zip
- MATLAB 实现基于AOA(算术优化算法)进行时间序列预测模型的项目详细实例(含完整的程序,GUI设计和代码详解)
- MATLAB 实现基于AFSA(人工鱼鹰算法)进行时间序列预测模型的项目详细实例(含完整的程序,GUI设计和代码详解)
- CCleaner注册表修复工具
- MATLAB 实现基于NGO(北方苍鹰优化算法)进行时间序列预测模型的项目详细实例(含完整的程序,GUI设计和代码详解)
- MATLAB 实现基于SLWCHOA(简化的Levy加权黑猩猩优化算法)进行时间序列预测模型的项目详细实例(含完整的程序,GUI设计和代码详解)
- 基于python+Django+Mysql的校园二手交易市场源码+数据库脚本+文档说明
- 基于C++的绘图软件直线、圆、曲线、矩形、二次均匀B样条曲线、多边形等等-2025期末大作业
- 索尼CMOS图像传感器全球快门功能与工业应用:IMX264和IMX265的小型高分辨率像素设计
- MATLAB 实现基于HKELM(混合核极限学习机)进行时间序列预测模型的项目详细实例(含完整的程序,GUI设计和代码详解)
- MATLAB 实现基于EBWO(改进的白鲸优化算法)进行时间序列预测模型的项目详细实例(含完整的程序,GUI设计和代码详解)
- linux常用命令大全.txt
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0