【问题标题】:RAWINPUT - How to get Mouse Wheel dataRAWINPUT - 如何获取鼠标滚轮数据
【发布时间】: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;
    }
}

【问题讨论】:

    标签: c++ winapi directx raw-input


    【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-07
      • 2012-01-01
      • 1970-01-01
      相关资源
      最近更新 更多