ut 来对另个非常重要输入设备----鼠标编程问题
鼠标编程同键盘编程过程是非常相似有了上次基础你很快就能看出两者在形式上其实完全是大同
小异.
1、DIRECTINPUT 化
同前面讲键盘编程过程样我们还是先从 DIRECTINPUT 化开始吧:
# <dinput.h>
# DINPUT_BUFFERSIZE 16
LPDIRECTINPUT lpDirectInput; // DirectInput object
LPDIRECTINPUTDEVICE lpMouse; // DirectInput device
BOOL InitDInput(HWND hWnd)
{
HRESULT hr;
// 创建个 DIRECTINPUT 对象
hr = DirectInputCreate(hInstanceCopy, DIRECTINPUT_VERSION, &lpDirectInput, NULL);
FAILED(hr)
{
// 失败
FALSE;
}
// 创建个 DIRECTINPUTDEVICE 界面
hr = lpDirectInput->CreateDevice(GUID_SysMouse, &lpMouse, NULL);
FAILED(hr)
{
// 失败
FALSE;
}
// 设定查询鼠标状态返回数据格式
hr = lpMouse->SetDataFormat(&c_dfDIMouse);
FAILED(hr)
{
// 失败
FALSE;
}
// 设定协作模式
hr = lpMouse->SetCooperativeLevel(hWnd,
DISCL_EXCLUSIVE | DISCL_FOREGROUND);
FAILED(hr)
{
// 失败
FALSE;
}
// 设定缓冲区大小
// 如果不设定缓冲区大小默认值为 0就只能按立即模式工作
// 如果要用缓冲模式工作必须使缓冲区大小超过 0
DIPROPDWORD property;
property.diph.dwSize = (DIPROPDWORD);
property.diph.dwHeaderSize = (DIPROPHEADER);
property.diph.dwObj = 0;
property.diph.dwHow = DIPH_DEVICE;
property.dwData = DINPUT_BUFFERSIZE;
hr = lpMouse->SetProperty(DIPROP_BUFFERSIZE, &property.diph);
FAILED(hr)
{
// 失败
FALSE;
}
hr = lpMouse->Acquire;
FAILED(hr)
{
// 失败
FALSE;
}
TRUE;
}
除了少数几处改动以外这段代码同前面讲键盘编程代码基本上完全样
注意 CreateDevice 来建立个 DIRECTINPUTDEVICE 界面时我们用参数是 GUID_SysMouse 而不是 G
UID_SysKeyboard我们以此来指明了建立是鼠标对象相应在用 SetDataFormat 来设定返回数据格式时
我们用参数是 &c_dfDIMouse 而不是 &c_dfDIKeyboard
还有要特别注意是前面讲到键盘在设置协作方式时是只能按非独占方式工作而鼠标即可以按非
独占方式工作也可以按独占方式工作
2、DIRECTINPUT 数据查询
在作 DIRECTINPUT 鼠标数据查询时 我般都是使用缓冲模式而不是立即模式原因很简单鼠标
移动事件频率很高 按立即模式去处理就很难保证不丢失数据至于 DIRECTX SDK 里例程使用立即模式读取
数据则是它们用了个多媒体计时器来保证以每秒 3十次频率处理接受鼠标数据
明白这点后 下面我们就来看看相应代码由于 DIRECTX SDK 里例程有立即模式代码我就偷点懒
下面只给出了段缓冲模式下代码:
HRESULT UpdateInputState(void)
{
DWORD i;
(lpMouse != NULL)
{
DIDEVICEOBJECTDATA didod; // Receives buffered data
DWORD dwElements;
HRESULT hr;
while(TRUE)
{
dwElements = 1; // 每次从缓冲区中读个数据
hr = lpMouse->GetDeviceData((DIDEVICEOBJECTDATA),&didod,&dwElements,0);
FAILED(hr)
{
// 发生了个
(hr DIERR_INPUTLOST)
{
hr = lpMouse->Acquire; // 试图重新取回设备
FAILED(hr)
{
S_FALSE; // 失败
}
}
}
(elements 1)
{
switch(didod.dwOfs)
{
DIMOFS_X: // X 轴偏移量
// didod.dwData 里是具体偏移相对值单位为像素
;
DIMOFS_Y: // Y 轴偏移量
// didod.dwData 里是具体偏移相对值单位为像素
;
DIMOFS_BUTTON0: // 0 号键(左键)状态
// didod.dwData 里是具体状态值
// 低字节最高位为 1 则表示按下
// 低字节最高位为 0 表示未按下
;
DIMOFS_BUTTON1: // 1 号键(右键)状态
// 同上
;
DIMOFS_BUTTON2: // 2 号键(中键)状态
// 同上
;
DIMOFS_BUTTON3: // 3 号键状态
// 同上
;
}
}
(elements 0) ; // 缓冲区读空
}
}
S_OK;
}
这段代码注释得非常详细相信你很快就能看懂
3、DIRECTINPUT 结束处理
还记得当结束时必须要进行释放处理吧其代码如下:
void ReleaseDInput(void)
{
(lpDirectInput)
{
(lpMouse)
{
// Always unacquire the device before calling Release.
lpMouse->Unacquire;
lpMouse->Release;
lpMouse = NULL;
}
lpDirectInput->Release;
lpDirectInput = NULL;
}
}
最新评论