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 - 如何获取鼠标滚轮数据的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用鼠标的滚轮?

如何禁用鼠标滚轮?

vb如何监视鼠标滚轮事件

js中如何禁用鼠标滚轮事件?急,在线等!

LabVIEW操作鼠标滚轮放大/缩小图像

LabVIEW操作鼠标滚轮放大/缩小图像