Win32APIでマウスのイベントをチェックしたり座標を取得したりする
Win32APIでマウスイベントの管理をしたい場合は、WindowProc(ウィンドウプロシージャ関数)内で行う。
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
}
左クリックやダブルクリック等のマウスイベントが発生した時には、第2引数のUINTには「どの種類のマウスイベントなのか」の情報が格納されて、第3引数にはマウスイベントの種類が入り、第4引数のLPARAMには「上位ビットにy座標の情報、下位ビットにx座標の情報」が格納される。
マウスイベントによって処理を分ける
マウスイベントによって処理を分けたい場合は、WM_PAINTとかWM_CREATEと同じようにマウスイベントを指定してあげればよい。
Point pt;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_CREATE:
return 0;
case WM_LBUTTONDOWN:
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
上記の例では、WM_LBUTTONDOWN
と指定してあげることで、左クリックが押された時に処理が実行される。
他にも、指定できるマウスイベントは多くあるので、公式ページを確認しよう。
参考:Mouse Input Notifications - Windows applications | Microsoft Docs
マウスの座標を取得する
マウス座標を獲得する方法はいくつかあり、多くの解説サイトで紹介されているのが、LOWORD(lParam)
とHIWORD(lParam)
の2つの関数を使う事だ。
Point pt;
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
一行目のPOINT pt
の部分はPOINT構造体を定義している。POINT構造体の中身はシンプルで、double型のx変数とy変数を格納しているだけの構造体だ。(なので、絶対に使わないといけない、と言うわけではない)
参考:Point(Double, Double) Constructor (System.Windows) | Microsoft Docs
先ほども解説したように、マウスイベント時にはWindowProc関数の第4引数LPAMRA
引数に座標の情報が格納されており、LOWORD(lParam)
とすることでx座標を取得し、HIWORD(lParam)
とすることでy座標を取得する。
ちなみに、LOWORDはLow Wordの意味、HIWORDはHigh Wordの意味。
マウス座標を取得する時には、GET_X_LPARAMを使うべき
多くの解説サイトではマウス座標の取得にはLOWORDとHIWORDを使っているのが、公式ページには「LOWORDとHIWORDではなくて、GET_X_LPARAMとGET_Y_LPARAMを使うべき」と書かれている。
Do not use the LOWORD or HIWORD macros to extract the x- and y- coordinates of the cursor position because these macros return incorrect results on systems with multiple monitors. Systems with multiple monitors can have negative x- and y- coordinates, and LOWORD and HIWORD treat the coordinates as unsigned quantities. WM_MBUTTONDOWN message - Windows applications | Microsoft Docs
簡単に言うと、複数のモニターを使っているパソコンの場合は、LOWORDやHIWORDだと座標を上手く取得できないから使わないでね、と書かれている。
#include <windowsx.h>
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
こちらの関数の方が何がしたいのか分かりやすくて良い。1つ注意なのが、windowsx.h
をincludeするのを忘れないようにすること。