マーク、
WM_INPUT
Windows イベントが処理するよりも速くマウスを動かした場合に問題が発生する可能性があります。たとえば、マウスが 1 フレームで 2 ピクセル移動したとします。処理される1 つのイベントに対して 2ピクセルWM_INPUT
移動するため、1/5700 インチの損失が発生します (この場合) 。
これを修正するには、WM_INPUT メッセージがプログラムに送信されるたびにマウスが移動するピクセル数を確認する必要があります。あなたがしなければならないことは、RAWINPUTDEVICE
変数を作成し、マウスに関する情報を持つように構造体を設定することです。
次のコードは、RAWINPUTDEVICE
で使用できるように を登録しWM_INPUT
ます。
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;
RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]);
次のコードは、Rid
変数 two を実際に使用して、前回WM_INPUT
開始されてからマウスが移動したピクセル数を決定します。
case WM_INPUT:
{
UINT dwSize = 40;
static BYTE lpb[40];
GetRawInputData((HRAWINPUT)lParam, RID_INPUT,
lpb, &dwSize, sizeof(RAWINPUTHEADER));
RAWINPUT* raw = (RAWINPUT*)lpb;
if (raw->header.dwType == RIM_TYPEMOUSE)
{
int xPosRelative = raw->data.mouse.lLastX; // Could be 1, or could be more than 1
int yPosRelative = raw->data.mouse.lLastY; // Could be 1, or could be more than 1!
}
break;
}
このコードは、まさにこのトピックに関する msdn で提示されたコードと同じであることに注意してください (以下のリンク)。
マウスの x 位置と y 位置 (ピクセル単位) を持つある種のグローバル変数を使用できるようになりました。次に、これらの変数を DPI で除算するだけで、グローバル変数を 0 に設定するたびにオフセットされるインチの量が得られます。
より簡単な方法は、WM_MOUSEMOVE
代わりにイベントを処理することです。これにより、マウスの正確な位置 (もちろんピクセル単位) を簡単に取得できます。これを使用して、開始位置のピクセル値からこれを減算できます。
例:
DPI = 5700。
初期位置 = (100px, 300px)。
3 秒後の位置 = (500px, 400px)。
この 3 秒間に移動したインチ数 = ((500px - 100px)/5700 インチ、(400px - 300px)/5700 インチ)
一般的な規則: S 秒後に移動したインチ数 = (inital_pixels_x - final_pixels_x)/DPI インチ
水平方向、(initial_pixels_y - final_pixels_y)/DPI インチ垂直方向
ここで、final_pixels_x は s 秒後のマウスの x 位置であり、final_pixels y は s 秒後の y 位置です。
何を間違えたかを要約すると、各WM_INPUT
イベントはマウスが 1 ピクセル移動したことを意味すると誤って想定していました。
何らかの理由で質問を誤解していて、すでに正しい量のピクセルが移動されていることがわかっている場合は、コメントを残してください。回答を修正するために最善を尽くします. ただし、マウス専用であり、一番下のリンクで読むことができる「ポインターアクセラレーション」を適用するため、WM_MOUSEMOVE
代わりに使用することをお勧めします.WM_INPUT
tcs08 さん、ご質問ありがとうございます。
WM_INPUT を使用したマウス入力の msdn コードと説明
WM_MOUSEMOVE を使用したマウス入力の msdn コードと説明