2016-05-06 16 views
0

thisQAbstractNativeEventFilterクラスで作業した後、クラスIは最終的にHID(マウスとキーボードの両方)からネイティブイベントを得ました。Qtでの生のマウス移動を取得

私は多くの同様の質問を読んだが、誰も私の問題を解決しなかった。私はdpiに基づいてマウスの動きを取得しようとします。 Qt 5.5で私のプロジェクト全体がビルドされています。

RIM_TYPEMOUSEフラグが設定されていても、マウスの移動イベントを他のHIDイベント(マウスとキーボード)から分離することはできません。ここで

は私の実装からいくつかのコードです:ここにも

bool MouseRawMovement::nativeEventFilter(const QByteArray &eventType, void *message, long *result) 
{ 
    if(eventType == "windows_generic_MSG") 
    { 
     MSG *msg = reinterpret_cast<MSG*>(message); 
     qDebug()<<msg->message; // It prints numbers such as 6,26,28,141 on each event 
     if(msg->message == WM_INPUT) //it never gets in 
     { 
     UINT dwSize = 40; 
     static BYTE lpb[40]; 
     GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT, 
         lpb, &dwSize, sizeof(RAWINPUTHEADER)); 

     RAWINPUT* raw = (RAWINPUT*)lpb; 
     if (raw->header.dwType == RIM_TYPEMOUSE) 
     { 
      int xPosRelative = raw->data.mouse.lLastX; 
      int yPosRelative = raw->data.mouse.lLastY; 

      qDebug()<<xPosRelative<<yPosRelative ; 
     } 
     } 
    } 
    return false; 
} 

は私のコンストラクタ

MouseRawMovement::MouseRawMovement() 
    { 
     Rid[0].usUsagePage = 0x01; 
     Rid[0].usUsage = 0x02; 
     Rid[0].dwFlags = RIDEV_INPUTSINK; 
     Rid[0].hwndTarget = 0; 
     if(!RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]))) 
      qDebug()<<QString::number(GetLastError()); //I see error msg 6 - Ref. ERROR_INVALID_HANDLE 
    } 

出力がゼロ(0)のすべての時間を私に示してあります。

hWndで何が起こっているのですか?私はこれを与えることを試みた:

HWND hWnd =::GetConsoleWindow();

が、私は同じ結果を持っていました。 main.cppには

私は日のために試してみて、私は解決策を見つけることができませんでした

MainWindow w; 
a.installNativeEventFilter(&w.mm); 

ネイティブフィルターをインストールします。 HRAWINPUT
RAWINPUT構造へのハンドル:誰もがそこにある...(???)GetRawInputData MSDNのページ状態として

+0

から一部ですが、あなたの問題は何ですか? 「分離できない」とはどういう意味ですか? –

+0

私はRIM_TYPEMOUSEのどちらかをチェックしていません。マウスやキーボードのキーを押すと、出力があります...次に、ゼロだけが表示されます。 – thanasispap

答えて

0

@nnatarrあなたの助けは充実していました!ありがとうございました!!!

私は最終的に解決策を見つける。

私は、main.cppにRegisterRawInputDevicesと電話をかけていました。ここで

はmain.cppに

#include "mainwindow.h" 
#include <QApplication> 
#include <windows.h> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    a.installNativeEventFilter(&w.mm); 
    w.show(); 

    UINT nDevices; 
    PRAWINPUTDEVICELIST pRawInputDeviceList; 

    if (!GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST))) 
    { 
     qDebug() << "ERROR -- GetRawInputDeviceList ..."; 
     return 1; 
    } 

    if (!(pRawInputDeviceList = (PRAWINPUTDEVICELIST)malloc(sizeof(RAWINPUTDEVICELIST) * nDevices))) 
    { 
     qDebug() << "Initialization failed..."; 
     return 1; 
    } 

    RAWINPUTDEVICE Rid[1]; 
    Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC; 
    Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE; 
    Rid[0].dwFlags = RIDEV_INPUTSINK; 
    Rid[0].hwndTarget = (HWND)w.effectiveWinId(); 
    if(!RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]))) 
     qDebug()<<"Huston Problem."; 
    qDebug()<<QString::number(GetLastError()); 

    return a.exec(); 
} 

されており、ここではマウスHandligクラス

bool MouseRawMovement::nativeEventFilter(const QByteArray &eventType, void *message, long *result) 
{ 
    if(eventType == "windows_generic_MSG") 
    { 
     MSG *msg = reinterpret_cast<MSG*>(message); 

     if(msg->message == WM_INPUT) 
     { 
      UINT dwSize = 40; 
      static BYTE lpb[40]; 
      if(!GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT,lpb, &dwSize, sizeof(RAWINPUTHEADER))) 
       qDebug()<<"Error GetRawInputData"; 
      else 
      { 
       RAWINPUT* raw = (RAWINPUT*)lpb; 
       if (raw->header.dwType == RIM_TYPEMOUSE) 
       { 
        int xPosRelative = raw->data.mouse.lLastX; 
        int yPosRelative = raw->data.mouse.lLastY; 
        //qDebug()<<xPosRelative<<yPosRelative; 
       } 
      } 

     } 
    } 
    return false; 
} 
0

、この関数の最初のパラメータは

hRawInput
タイプ[中]です。これは、WM_INPUTのlParamに由来します。

あなたが処理しているメッセージがWM_INPUTメッセージ(msg->message == WM_INPUT)であり、唯一の後、生の入力データを抽出しようとするのであれば、あなたは最初にチェックする必要があります。 次に、WM_INPUTメッセージのlParam

lParamに
デバイスから生の入力が含まRAWINPUT構造へのハンドルです。

WM_INPUT MSDNページです。 GetRawInputData関数でこのハンドルを使用する必要があります。今、不正なデータハンドルを使用しているため、GetRawInputDataは有効な情報を返さない(処理するデータの場所を知りません)。

記事MSDN: Using Raw Inputを読む必要があります。そこには、keybaordとマウスの生の入力処理のサンプルコードがあります。

便利なリンク:

もう1つ。等価演算子を使用してQByteArrayインスタンスを文字列と比較することができます。この場合は、if (eventType == "windows_generic_MSG") {...}のようになります。

bool QByteArray::operator==(const QString & str) const 

このページでそれについて読むことができます:QByteArray::operator== QByteArrayが過負荷に等価演算子を持っているためです。

UPDATE

MSDN: RAWINPUTDEVICEページが設定されている場合

RIDEV_INPUTSINK 0x00000100
が、これは、発信者がフォアグラウンドでない場合でも に入力を受信し、発信者を可能にすることを指摘しています。 hwndTargetを指定する必要があることに注意してください。

あなたのウィンドウのhWndを指定する必要があるので、あなたはINVALID_HANDLE_ERRORエラーが発生しています。 MainWindowクラスとは何ですか?あなたはQMainWindowまたはQWidgetから継承していますか? QtのすべてのウィジェットにはwinIdプロパティ(WId QWidget::winId() const)があります。これはあなたが探している非常にhWndです。だから、このようRid構造に、あなたの窓のwinId()を取るHWNDにキャストして記述する必要があります。それは助けにはなりません場合は

Rid[0].hwndTarget = (HWND)w->winId(); 

は、その後、あなたはさらなる調査のためMinimal, Complete, and Verifiable exampleを提供する必要があります。

+0

あなたの答えをありがとう! lParamをthis(HRAWINPUT)msg-> lParamに設定しました。 WM_INPUTとのアプリケーションの関連付けは、コンストラクタで実装されています。私は私の質問にそれを置くでしょう。 WM_INPUTのifステートメントのコメントを外すと、それは入ってこない。 私の質問をより詳しい情報で編集する...私はこの問題のために私の研究ですでに渡してきたので、あなたの答えで強調しているリンクをチェックした。 お返事ありがとうございました – thanasispap

+0

@thanasispapが答えを更新しました。 –

関連する問題