マウスメッセージ
マウスクリックイベント
さて、今回はマウスイベントの処理方法について説明します
キーボード同様に、メッセージによって処理できることは想像に安いでしょう
注意してほしいことがあります
マウスの存在は、時代によって異なっていて
Windows 発表当時から2つボタンのマウスが標準だったわけではありません
当時は、マウスがなくても操作できるように設計されており
事実、Windowsが標準でサポートしているアプリケーションはキーボードだけでも操作できる
さらに、当時はマウスの2つ、3つ目のボタンをプログラムで使用することは避けられていた
これは、1つボタンのマウスユーザーへの配慮だったのです
このような背景があることをよく覚えておいてください
もし、マウスやボタンの数に依存するプログラムを作る場合
必ず GetSystemMetrics() 関数でチェックすることを推奨します
さて、マウスには 「押す」「離す」 の基本動作があります
メッセージは、これらの動作を左、右、中央のボタンに分けて処理できます
ボタン | 押した | 離した
|
---|
左 | WM_LBUTTONDOWN | WM_LBUTTONUP
|
中央 | WM_MBUTTONDOWN | WM_MBUTTONUP
|
右 | WM_RBUTTONDOWN | WM_RBUTTONUP
|
処理した時、戻り値は全て 0 を返します
これらのメッセージは、ウィンドウプロシージャの第三引数 WPARAM に
マウスボタンと Shift と Ctrl キーの状態を格納している
定数 | 解説
|
---|
MK_LBUTTON | 左ボタンが押されている
|
MK_MBUTTON | 中央ボタンが押されている
|
MK_RBUTTON | 右ボタンが押されている
|
MK_SHIFT | Shift キーが押されている
|
MK_CONTROL | Ctrl キーが押されている
|
GetKeyState() 関数を使うことも一つの方法ですが
基本的に、マウス処理の場合はこのパラメータを使ったほうが便利です
ウィンドウプロシージャ第四引数 LPARAM にはマウスの座標が入ります
クライアントエリアの左上を原点とした座標で、上位16ビットに y 座標
下位16ビットに x 座標がそれぞれ格納されています
これらのパラメータは、シフトやキャストで取り除いても問題ありませんが
一般には LOWORD() マクロと HIWORD マクロを使います
WORD LOWORD(DWORD dwValue);
dwValue には分解するダブルワードの値を指定します
指定した値の下位16ビットを返します
WORD HIWORD(DWORD dwValue);
dwValue には分割するダブルワードの値を指定します
指定した値の上位16ビットを返します
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
HDC hdc;
PAINTSTRUCT ps;
static LPCTSTR pctKitty = TEXT("Kitty on your lap");
static unsigned short int x = 0 , y = 0;
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN:
x = LOWORD(lp);
y = HIWORD(lp);
InvalidateRect(hwnd , NULL , TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd , &ps);
TextOut(hdc , x , y , pctKitty , lstrlen(pctKitty));
EndPaint(hwnd , &ps);
return 0;
}
return DefWindowProc(hwnd , msg , wp , lp);
}
int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
PSTR lpCmdLine , int nCmdShow ) {
HWND hwnd;
MSG msg;
WNDCLASS winc;
winc.style = CS_HREDRAW | CS_VREDRAW;
winc.lpfnWndProc = WndProc;
winc.cbClsExtra = winc.cbWndExtra = 0;
winc.hInstance = hInstance;
winc.hIcon = LoadIcon(NULL , IDI_APPLICATION);
winc.hCursor = LoadCursor(NULL , IDC_ARROW);
winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winc.lpszMenuName = NULL;
winc.lpszClassName = TEXT("KITTY");
if (!RegisterClass(&winc)) return -1;
hwnd = CreateWindow(
TEXT("KITTY") , TEXT("Kitty on your lap") ,
WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
CW_USEDEFAULT , CW_USEDEFAULT ,
CW_USEDEFAULT , CW_USEDEFAULT ,
NULL , NULL , hInstance , NULL
);
if (hwnd == NULL) return -1;
while(GetMessage(&msg , NULL , 0 , 0)) DispatchMessage(&msg);
return msg.wParam;
}
マウスの左ボタンを押すと、その位置に文字が移動します
LOWORD()
WORD LOWORD(DWORD dwValue);
指定されたダブルワードの下位ワードを返します
dwValue - 分割するダブルワードの値
戻り値 - 指定されたダブルワードの下位ワード
HIWORD()
WORD HIWORD(DWORD dwValue);
指定されたダブルワードの上位ワードを返します
dwValue - 分割するダブルワードの値
戻り値 - 指定されたダブルワードの上位ワード