マウスメッセージ


マウスクリックイベント

さて、今回はマウスイベントの処理方法について説明します
キーボード同様に、メッセージによって処理できることは想像に安いでしょう

注意してほしいことがあります
マウスの存在は、時代によって異なっていて
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 - 分割するダブルワードの値

戻り値 - 指定されたダブルワードの上位ワード



前のページへ戻る次のページへ