2012-06-02 2 views
0

Win32 Raw Input API를 사용하여 원시 마우스 데이터를보다 정확하게 수집하려고 시도하고 있지만 을 전혀 이해할 수 없습니다. GetRawInputBuffer.GetRawInputBuffer를 올바르게 사용하십시오.

내 마우스가 창 위에 떠있는 동안 아무 것도 일어나지 않는 것 같습니다. 나는 단지 윈도우의 제목 표시 줄을 클릭하거나 놓을 때 버퍼링 된 데이터를 얻는 것으로 보이고 심지어는 대부분 0의 움직임 값을 얻습니다. 결코 마우스 버튼 변경 사항을 수신합니다. 나는 샘플을 가능한 한 가깝게 따라 왔으며 온라인에서 검색하는 행운이별로 없었다.

다음은이 문제가있는 매우 단순화 된 예제의 Window Procedure와 Main입니다.

LRESULT CALLBACK MessageHandler(HWND WindowHandle, UINT Message, WPARAM wParameter, LPARAM lParameter) 
{ 
    switch(Message) 
    { 
    case WM_DESTROY: 
     { 
      PostQuitMessage(0); 
      return 0; 
     } 
     break; 
    case WM_CLOSE: 
     { 
      DestroyWindow(WindowHandle); 
      return 0; 
     } 
     break; 
    case WM_INPUT: 
     { 
      UINT RawInputSize; 
      UINT Result; 

      Result = GetRawInputBuffer(NULL, &(RawInputSize), sizeof(RAWINPUTHEADER)); 
      if(Result == -1) 
      { 
       DWORD ErrorCode = GetLastError(); 
       std::cout << "GetRawInputBuffer returned error code" << ErrorCode << std::endl; 
      } 
      else if(Result == 0 && RawInputSize != 0) 
      { 
       UINT AllocatedBufferByteCount = RawInputSize * 16; 
       RAWINPUT* RawInputBuffer = reinterpret_cast<RAWINPUT*>(malloc(AllocatedBufferByteCount)); 

       UINT AllocatedBufferByteCountTwo = AllocatedBufferByteCount; 
       Result = GetRawInputBuffer(RawInputBuffer, &(AllocatedBufferByteCountTwo), sizeof(RAWINPUTHEADER)); 
       if(Result == -1) 
       { 
        DWORD ErrorCode = GetLastError(); 
        std::cout << "GetRawInputBuffer returned error code" << ErrorCode << std::endl; 
       } 
       else if(Result != 0) 
       { 
        UINT RawInputCount = Result; 

        DWORD MouseDeltaX = 0; 
        DWORD MouseDeltaY = 0; 

        bool ButtonsPressed[2] = {false, false}; 

        RAWINPUT* RawInput = RawInputBuffer; 
        for(unsigned int i = 0; i < RawInputCount; ++i) 
        { 
         switch(RawInput->header.dwType) 
         { 
         // Raw mouse movement data for high-resolution mice. 
         case RIM_TYPEMOUSE: 
          { 
           MouseDeltaX += RawInput->data.mouse.lLastX; 
           MouseDeltaY += RawInput->data.mouse.lLastY; 

           ButtonsPressed[0] = ((RawInput->data.mouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) == RI_MOUSE_LEFT_BUTTON_DOWN); 
           ButtonsPressed[1] = ((RawInput->data.mouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) == RI_MOUSE_RIGHT_BUTTON_DOWN); 
          } 
          break; 
         } 

         RawInput = NEXTRAWINPUTBLOCK(RawInput); 
        } 
        DefRawInputProc(&(RawInputBuffer), RawInputCount, sizeof(RAWINPUTHEADER)); 
        std::cout << "Mouse moved (" << MouseDeltaX << ", " << MouseDeltaY << ")." << std::endl; 

        if(ButtonsPressed[0]) 
        { 
         std::cout << "LMB pressed." << std::endl; 
        } 
        if(ButtonsPressed[1]) 
        { 
         std::cout << "RMB pressed." << std::endl; 
        } 
       } 

       free(RawInputBuffer); 
      } 
      return 0; 
     } 
     break; 
    default: 
     { 
      return DefWindowProc(WindowHandle, Message, wParameter, lParameter); 
     } 
     break; 
    } 
} 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) 
{ 
    // Initialize window strings. 
    wchar_t WindowClassName[] = L"DominionWindowClass"; 
    wchar_t WindowCaption[] = L"Test Window"; 

    // Create the window class. 
    WNDCLASSEX WindowClass; 
    WindowClass.cbSize = sizeof(WindowClass); 
    WindowClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; 
    WindowClass.lpfnWndProc = &(MessageHandler); 
    WindowClass.cbClsExtra = 0; 
    WindowClass.cbWndExtra = 0; 
    WindowClass.hInstance = hInstance; 
    WindowClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION); 
    WindowClass.hIconSm = LoadIcon(hInstance, IDI_APPLICATION); 
    WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW); 
    WindowClass.hbrBackground = NULL; 
    WindowClass.lpszMenuName = NULL; 
    WindowClass.lpszClassName = WindowClassName; 

    // Register window class. 
    RegisterClassEx(&WindowClass); 

    // Setup window style flags. 
    DWORD WindowStyles = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; 
    DWORD ExWindowStyles = WS_EX_APPWINDOW; 

    // Setup window rectangle area. 
    RECT WindowArea; 
    WindowArea.left = 0; 
    WindowArea.top = 0; 
    WindowArea.right = 1024; 
    WindowArea.bottom = 768; 

    AdjustWindowRectEx(&(WindowArea), WindowStyles, false, ExWindowStyles); 

    // Window creation. 
    HWND WindowHandle = CreateWindowEx(ExWindowStyles, WindowClass.lpszClassName, WindowCaption, WindowStyles, CW_USEDEFAULT, CW_USEDEFAULT, (WindowArea.right - WindowArea.left), (WindowArea.bottom - WindowArea.top), NULL, NULL, hInstance, NULL); 

    // Display the window. 
    ShowWindow(WindowHandle, SW_SHOWDEFAULT); 
    UpdateWindow(WindowHandle); 

    // Register devices for raw input. 
    const unsigned int RawInputDeviceCount = 1; 
    RAWINPUTDEVICE RawInputDevices[RawInputDeviceCount]; 

    memset(RawInputDevices, 0, RawInputDeviceCount * sizeof(RAWINPUTDEVICE)); 

    RAWINPUTDEVICE* MouseRawInputDevice; 

    MouseRawInputDevice = RawInputDevices; 
    MouseRawInputDevice->usUsagePage = 1; 
    MouseRawInputDevice->usUsage = 2; 
    MouseRawInputDevice->hwndTarget = WindowHandle; 

    BOOL SuccessfullyRegisteredInput = RegisterRawInputDevices(RawInputDevices, RawInputDeviceCount, sizeof(RAWINPUTDEVICE)); 

    // Core loop. 
    MSG Message; 
    for(;;) 
    { 
     while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) 
     { 
      TranslateMessage(&Message); 
      DispatchMessage(&Message); 
      if(Message.message == WM_QUIT) 
      { 
       break; 
      } 
     } 

     if(Message.message == WM_QUIT) 
     { 
      break; 
     } 
    } 

    // Unregister devices for raw input. 
    memset(RawInputDevices, 0, RawInputDeviceCount * sizeof(RAWINPUTDEVICE)); 
    MouseRawInputDevice = RawInputDevices; 
    MouseRawInputDevice->usUsagePage = 1; 
    MouseRawInputDevice->usUsage = 2; 
    MouseRawInputDevice->dwFlags = RIDEV_REMOVE; 
    MouseRawInputDevice->hwndTarget = NULL; 

    BOOL SuccessfullyUnregisteredInput = RegisterRawInputDevices(RawInputDevices, RawInputDeviceCount, sizeof(RAWINPUTDEVICE)); 

    return Message.wParam; 
} 

원시 입력 API를 실험하는 간단한 방법을 생각할 수 없습니다. 생각?

답변

0

메시지 처리 루프 외부에서 폴링을 위해 오래 늦게 대답했지만, GetRawInputBuffer이 사용 된 것 같습니다. GetRawInputDataWM_INPUT 처리 내에 사용하거나 GetRawInputBuffer을 메시지 처리 루프 외부에서 사용하십시오.

0

GetRawInputBuffer()를 사용하면 HID 데이터 만 읽을 수 있습니다. 즉, RAWINPUT 구조의 데이터 부분에있는 hid 구조 만 입력 데이터로 채워진다는 의미입니다. RAWHID의 bRawData 멤버를 사용하여 키보드에서 입력을 읽을 수 있었지만 값이 키보드에서 키보드까지 다양하기 때문에 쓸모가 없다고 생각합니다. 그래서 다시 GetRawInputData ....로 바꿨습니다.

관련 문제