RAWINPUT - 如何获取鼠标滚轮数据
Posted
技术标签:
【中文标题】RAWINPUT - 如何获取鼠标滚轮数据【英文标题】:RAWINPUT - How to get Mouse Wheel data 【发布时间】:2012-02-12 00:24:34 【问题描述】:我正在将 rawinput 与 directx 一起使用...当使用鼠标滚轮时,我正在尝试使用相机进行缩放...当我使用以下代码运行程序时,我从 rawinput 获得的 usbuttondata 数据会消失当我向前推动鼠标滚轮时到 120...然后它失控...高达 65000...我认为数据应该是 1 或 -1 或 0...rawinput 作为鼠标发送什么车轮数据?
代码:
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg,
WPARAM wParam, LPARAM lParam)
switch(Msg)
case WM_CREATE:
RAWINPUTDEVICE Rid[2];
// Keyboard
Rid[0].usUsagePage = 1;
Rid[0].usUsage = 6;
Rid[0].dwFlags = 0;
Rid[0].hwndTarget=Inst.Wnd.hWnd;
// Mouse
Rid[1].usUsagePage = 1;
Rid[1].usUsage = 2;
Rid[1].dwFlags = 0;
Rid[1].hwndTarget=Inst.Wnd.hWnd;
if (!RegisterRawInputDevices(Rid,2,sizeof(RAWINPUTDEVICE)))
MessageBox(NULL, L"Failed to Register Input Devices!", L"ALERT", MB_OK);
exit(1);
return 0;
case WM_INPUT:
// Determine how big the buffer should be
UINT iBuffer;
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &iBuffer,
sizeof(RAWINPUTHEADER));
LPBYTE lpb = new BYTE[iBuffer];
if (lpb == NULL)
return 0;
UINT readSize = GetRawInputData( (HRAWINPUT)lParam, RID_INPUT, lpb, &iBuffer, sizeof(RAWINPUTHEADER) ) ;
if( readSize != iBuffer )
puts( "ERROR: GetRawInputData didn't return correct size!" ) ;
RAWINPUT *raw = (RAWINPUT*) lpb;
if (raw->header.dwType== RIM_TYPEMOUSE)
riProcessMouseMessage(&raw->data.mouse);
if (raw->header.dwType== RIM_TYPEKEYBOARD)
//riProcessKeyboardMessage(&raw->data.keyboard);
return 0;
case WM_COMMAND:
switch(LOWORD(wParam))
case IDM_FILE_NEW:
// Create the game object
pGame = new CGame(dxMgr.getD3DDevice());
// Initialize the game object
if (!pGame->init(Inst.Wnd.hWnd))
return 0;
break;
case IDM_FILE_OPEN:
pGame->m_animCollection->LoadXFile("oxana.x", 0);
//objects.CreateNewObject(1, L"oxana.x", NULL);
break;
case IDM_FILE_SAVE:
break;
case IDM_FILE_SAVEAS:
break;
case IDM_FILE_EXIT:
PostQuitMessage(WM_QUIT);
break;
return 0;
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
return 0;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
return TRUE;
void riProcessMouseMessage( const RAWMOUSE* rmouse )
if(pGame != NULL)
//MessageBox(NULL, L"Game Found", L"SUCCESS", MB_OK);
if ( MOUSE_MOVE_RELATIVE == rmouse->usFlags )
riMgr.mxr = &rmouse->lLastX;
riMgr.myr = &rmouse->lLastY;
riMgr.mzr = (RI_MOUSE_WHEEL & rmouse->usButtonFlags) ? &rmouse->usButtonData : 0;
【问题讨论】:
【参考方案1】:我怀疑它和 WM_MOUSEWHEEL 一样:
高位词表示车轮转动的距离,以WHEEL_DELTA的倍数或除数表示,即120。正值表示车轮向前转动,远离用户;负值表示***向后旋转,朝向用户。 低位字表示各种虚拟键是否down。
因此你需要提取高位词。您需要注意正确处理负值。取而代之的是,您可能不会这样做。
如果您愿意,可以使用以下宏:GET_WHEEL_DELTA_WPARAM(wParam)
【讨论】:
哦,但是你应该把它转换为短(有符号)来处理负值。 谢谢,但这不起作用...鼠标滚轮数据来自一个结构:RAWMOUSE。该数据的类型是 USHORT 而不是 WPARAM...结构的实现如下: RAWMOUSE *raw; USHORT mouseZ = raw->usButtonData;此外,没有负数......当我向前滚动鼠标滚轮(远离用户)时,值为 120 并缓慢上升......当我向后滚动鼠标(朝向用户)时,值为 65,416 并缓慢下降......这似乎不合逻辑,一定是由于在某处不正确地投射数据而引起的? 是的,如果你这样做 ((short)(unsigned short)65416),结果是否定的 (-120)。这是你需要做的。更有意义? 太棒了!如果这回答了您的问题 - 您需要我编辑我的原始答案以供您接受吗? 类似于 OP - 我得到 +120 或 -120 的结果 - 但这个宏将它们转换为 ... 0。+/-120 在方向上是正确的,但缺乏幅度。我缺少这个宏是否有一些额外的微妙之处?【参考方案2】:在switch语句中添加以下内容
case WM_MOUSEWHEEL:
int delta = GET_WHEEL_DELTA_WPARAM(wparam);
if(delta > 0)
//Mouse Wheel Up
else
//Mouse Wheel Down
return 0;
【讨论】:
以上是关于RAWINPUT - 如何获取鼠标滚轮数据的主要内容,如果未能解决你的问题,请参考以下文章