当有2个键盘的时候,怎么区别不同键盘的按键命令 用C#的钩子类,可以获取键盘事件,但是现在我有2个USB键盘的,更要命的,是需要区分这2个键盘的输入,google好几个小时了,还是没有结果,不知道有没有作过相关的东西,指点小菜我一下。。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 API截取键盘命令的时候,能再区分这个命令的来源吗? 看看能不能区分是来自哪个USB口的。 难道从都USB设备获取开始?而且键盘数据还拿不到的,USB键盘的数据不能通过报文共享的方式获取 那成驱动级别了,那还有什么不能实现的,那就不是都键盘事件了,是获取USB的原始数据了。。我现在没有搞明白怎么通过API方式获取USB键盘的报文,WINIO也不行,已经被处理成键盘事件的命令了,我还要设备做什么,就是因为键盘命令中不带设备区分 用WMI取出硬件媒体对象遍历,取其编号属性试试 C++比较初级的方法也就是调用API,建立连接后去BULK管道读取数据,调用IRP_MJ_READ和IRP_MJ_WRITE,最后不还是调用readfile来处理的。。如果只是建立连接C++才能写的话,HID是自动识别建立的,问题是这个数据怎么拿? 同前面讲键盘编程的过程一样,我们还是先从 DIRECTINPUT 的初始化开始吧: #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。 还有要特别注意的是,前面讲到的键盘,在设置协作方式时,是只能按非独占方式工作的,而鼠标即可以按非独占方式工作,也可以按独占方式工作。2、DIRECTINPUT 的数据查询 在作 DIRECTINPUT 的鼠标数据查询时, 我一般都是使用的缓冲模式而不是立即模式。原因很简单,因为鼠标移动事件的频率很高, 按立即模式去处理就很难保证不丢失数据。至于 DIRECTX SDK 里的例程使用立即模式读取数据则是因为它们用了一个多媒体计时器来保证以每秒三十次的频率处理接受鼠标数据。 明白这一点后, 下面我们就来看看相应的代码。由于 DIRECTX SDK 里的例程有立即模式的代码,我就偷点懒,下面只给出了一段缓冲模式下的代码: 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; } 这段代码注释得非常详细,相信你很快就能看懂。3、DIRECTINPUT 的结束处理 还记得当程序结束时必须要进行的释放处理吧,其代码如下: void ReleaseDInput(void) { if (lpDirectInput) { if(lpMouse) { // Always unacquire the device before calling Release(). lpMouse->Unacquire(); lpMouse->Release(); lpMouse = NULL; } lpDirectInput->Release(); lpDirectInput = NULL; } } 以上是C++的一种获取方式,我对C++不了解,有没有了解的人,给我通俗的解释下 DirectInput 说是也可以获取USB数据的,但我不知道怎么用 vs2008 c#代码编辑的问题 服务器的信息转发问题 新手程序 数据库连接方面 如何把 '% 替换成 "% ? 请问:在web叶面上面如何弹出一个文件保存的对话框呀 请教dataGrid问题?? 如何实现一条输入框内输入"(4+5)*3+1"点击确认后输出答案 海康4004HC关于网络开发问题。 关于随机数问题,送分100!!! C#发送SOAP消息调用WebService丢失参数的问题 200分求教:webRequest 如何获取和保持cookies!
而且键盘数据还拿不到的,USB键盘的数据不能通过报文共享的方式获取
我现在没有搞明白怎么通过API方式获取USB键盘的报文,WINIO也不行,
已经被处理成键盘事件的命令了,我还要设备做什么,就是因为键盘命令中不带设备区分
#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 而不是 G
UID_SysKeyboard,我们以此来指明了建立的是鼠标对象。相应的,在用 SetDataFormat 来设定返回数据的格式时
,我们用的参数是 &c_dfDIMouse 而不是 &c_dfDIKeyboard。
还有要特别注意的是,前面讲到的键盘,在设置协作方式时,是只能按非独占方式工作的,而鼠标即可以按非
独占方式工作,也可以按独占方式工作。2、DIRECTINPUT 的数据查询
在作 DIRECTINPUT 的鼠标数据查询时, 我一般都是使用的缓冲模式而不是立即模式。原因很简单,因为鼠标
移动事件的频率很高, 按立即模式去处理就很难保证不丢失数据。至于 DIRECTX SDK 里的例程使用立即模式读取
数据则是因为它们用了一个多媒体计时器来保证以每秒三十次的频率处理接受鼠标数据。
明白这一点后, 下面我们就来看看相应的代码。由于 DIRECTX SDK 里的例程有立即模式的代码,我就偷点懒
,下面只给出了一段缓冲模式下的代码:
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;
}
这段代码注释得非常详细,相信你很快就能看懂。3、DIRECTINPUT 的结束处理
还记得当程序结束时必须要进行的释放处理吧,其代码如下:
void ReleaseDInput(void)
{
if (lpDirectInput)
{
if(lpMouse)
{
// Always unacquire the device before calling Release().
lpMouse->Unacquire();
lpMouse->Release();
lpMouse = NULL;
}
lpDirectInput->Release();
lpDirectInput = NULL;
}
}
以上是C++的一种获取方式,我对C++不了解,有没有了解的人,给我通俗的解释下