<meta content="MSHTML 6.00.2900.3199" name="GENERATOR">
<style></style>2007年10月12日 01:49:00
作者:樊一鹏
前回同大家简单介绍了如何用
DirectInput 来进行键盘编程,本回所要讲述的就该是关于如何使用
DirectInput 来对另一个非常重要的输入设备----鼠标的编程问题。
鼠标的编程同键盘编程的过程是非常相似的,有了上次的基础,你很快就能看出两者在形式上其实完全是大同小异的。
DIRECTINPUT 的初始化
同前面讲键盘编程的过程一样,我们还是先从 DIRECTINPUT 的初始化开始吧:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->#include >dinput.h
#define 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);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 创建一个 DIRECTINPUTDEVICE 界面
hr = lpDirectInput-CreateDevice(GUID_SysMouse, &lpMouse, NULL);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 设定查询鼠标状态的返回数据格式
hr = lpMouse-SetDataFormat(&c_dfDIMouse);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 设定协作模式
hr = lpMouse-SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 设定缓冲区大小
// 如果不设定,缓冲区大小默认值为 0,程序就只能按立即模式工作
// 如果要用缓冲模式工作,必须使缓冲区大小超过 0
DIPROPDWORD property;
property.diph.dwSize = sizeof(DIPROPDWORD);
property.diph.dwHeaderSize = sizeof(DIPROPHEADER);
property.diph.dwObj = 0;
property.diph.dwHow = DIPH_DEVICE;
property.dwData = DINPUT_BUFFERSIZE;
hr = lpMouse-SetProperty(DIPROP_BUFFERSIZE, &property.diph);
if FAILED(hr)
{
// 失败
return FALSE;
}
hr = lpMouse-Acquire();
if FAILED(hr)
{
// 失败
return FALSE;
}
return TRUE;
}
除了少数几处改动以外,这段代码同前面讲的键盘编程的代码基本上完全一样。
注意调用 CreateDevice 来建立一个 DIRECTINPUTDEVICE 界面时,我们用的参数是 GUID_SysMouse 而不是 GUID_SysKeyboard,我们以此来指明了建立的是鼠标对象。相应的,在用 SetDataFormat 来设定返回数据的格式时,我们用的参数是 &c_dfDIMouse 而不是 &c_dfDIKeyboard。
还有要特别注意的是,前面讲到的键盘,在设置协作方式时,是只能按非独占方式工作的,而鼠标即可以按非独占方式工作,也可以按独占方式工作。
DIRECTINPUT 的数据查询
在作 DIRECTINPUT 的鼠标数据查询时,我一般都是使用的缓冲模式而不是立即模式。原因很简单,因为鼠标移动事件的频率很高,按立即模式去处理就很难保证不丢失数据。至于 DIRECTX SDK 里的例程使用立即模式读取数据则是因为它们用了一个多媒体计时器来保证以每秒三十次的频率处理接受鼠标数据。
明白这一点后,下面我们就来看看相应的代码。由于 DIRECTX SDK 里的例程有立即模式的代码,我就偷点懒,下面只给出了一段缓冲模式下的代码:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->HRESULT UpdateInputState(void)
{
DWORD i;
if(lpMouse != NULL)
{
DIDEVICEOBJECTDATA didod; // Receives buffered data
DWORD dwElements;
HRESULT hr;
while(TRUE)
{
dwElements = 1; // 每次从缓冲区中读一个数据
hr = lpMouse-GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &didod, &dwElements, 0);
if FAILED(hr)
{
// 发生了一个错误
if(hr == DIERR_INPUTLOST)
{
hr = lpMouse-Acquire(); // 试图重新取回设备
if FAILED(hr)
{
return S_FALSE; // 失败
}
}
}
else
if(elements == 1)
{
switch(didod.dwOfs)
{
case DIMOFS_X: // X 轴偏移量
// didod.dwData 里是具体偏移相对值,单位为像素
break;
case DIMOFS_Y: // Y 轴偏移量
// didod.dwData 里是具体偏移相对值,单位为像素
break;
case DIMOFS_BUTTON0: // 0 号键(左键)状态
// didod.dwData 里是具体状态值
// 低字节最高位为 1 则表示按下
// 低字节最高位为 0 表示未按下
break;
case DIMOFS_BUTTON1: // 1 号键(右键)状态
// 同上
break;
case DIMOFS_BUTTON2: // 2 号键(中键)状态
// 同上
break;
case DIMOFS_BUTTON3: // 3 号键状态
// 同上
break;
}
}
else if (elements == 0) break; // 缓冲区读空
}
}
return S_OK;
}
这段代码注释得非常详细,相信你很快就能看懂。
DIRECTINPUT 的结束处理
还记得当程序结束时必须要进行的释放处理吧,其代码如下:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->void ReleaseDInput(void)
{
if (lpDirectInput)
{
if(lpMouse)
{
// Always unacquire the device before calling Release().
lpMouse-Unacquire();
lpMouse-Release();
lpMouse = NULL;
}
lpDirectInput-Release();
lpDirectInput = NULL;
}
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1821040
相关推荐
Linux 下编程的三个重要工具(ZT).rar
斑马打印机 ZT411 ZT421中文手册
ZT213LEEA,国外找到的数据手册。
jsp Servlet基础入门学习教程(ZT).txt
ZT410打印机IP地址设置网络打印机ZT410打印机IP地址设置网络打印机ZT410打印机IP地址设置网络打印机ZT410打印机IP地址设置网络打印机ZT410打印机IP地址设置网络打印机
斑马打印机ZT210用户指南
赠送jar包:zt-exec-1.9.jar; 赠送原API文档:zt-exec-1.9-javadoc.jar; 赠送源代码:zt-exec-1.9-sources.jar; 赠送Maven依赖信息文件:zt-exec-1.9.pom; 包含翻译后的API文档:zt-exec-1.9-javadoc-API文档-...
斑马zt410驱动是由斑马官方推出的打印机驱动程序,如果你的打印机与电脑的连接出现了异常而导致打印机无法正常的使用,下载此驱动能帮你很好的解决这个问题,欢迎购买了此型号打印机的朋友下载使用!斑马zt410打印机...
赠送jar包:zt-exec-1.9.jar; 赠送原API文档:zt-exec-1.9-javadoc.jar; 赠送源代码:zt-exec-1.9-sources.jar; 赠送Maven依赖信息文件:zt-exec-1.9.pom; 包含翻译后的API文档:zt-exec-1.9-javadoc-API文档-...
这款RS485通信芯片zt13085e用的不多,网上很少这款的原理图库和PCB库,自己画了一个。
ZT213/ZT213LEEA USB多通道收发/驱动芯片规格书V2.10及手册,内含ZT213规格参数说明,选型参考表以及应用原理图。更多USB相关应用及方案可查看作者文章了解....
斑马zt410中文库
霍尼维尔 ZT930 点火变压器PDF,霍尼维尔 ZT930 点火变压器
【ASP.NET编程知识】在ASP.NET中支持断点续传下载大文件(ZT)源码.docx
斑马ZT510打印机驱动文件
单片机多级菜单编程实现(ZT) 建立一个树状的菜单结构,用链表实现
ZT2835W0M1贴片发光二极管规格书pdf,ZT2835W0M1贴片发光二极管规格书
ZT短信平台接口开发文档
根据冀中能源峰峰集团新屯矿实际情况,研制了ZT19600/25/50端头液压支架。该端头支架的应用,降低了劳动强度,加快了推采进度,提高了生产效率和煤炭回收率,实现了巷道超前支护的机械化。