ヒットテスト


マウスメッセージの基盤

これまでいくつかのマウスメッセージを紹介しましたが
これらは、DefWindowProc() がマウスの位置から生成したメッセージなのです

全てのマウスメッセージの最初に WM_NCHITTEST が発生します
通常はこのメッセージが最初に DefWindowProc() に渡されます

この WM_NCHITTEST メッセージを処理することで
あらゆるマウスメッセージを無効化させることもできてしまいます

WM_NCHITTEST メッセージは 第四引数 LPARAM にマウス座標を含みます
戻り値は、どの部分が押されたのかを表すヒットテストを返す必要があります

この戻り値によって、各種のマウスメッセージが生成されます
つまり、今までは DefWindowProc() がマウスの情報から位置を算出し
適切な戻り値を返して Windows に各種のマウスメッセージを要求していたのです
#include <windows.h>

LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
	HDC hdc;
	PAINTSTRUCT ps;
	static TCHAR strLocation[128];
	static unsigned short int x = 0 , y = 0;
	RECT rect;

	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_NCHITTEST:
		x = LOWORD(lp);
		y = HIWORD(lp);
		wsprintf(strLocation , "x座標 = %d\ny座標 = %d" , x , y);
		InvalidateRect(hwnd , NULL , TRUE);
		return HTNOWHERE;
	case WM_PAINT:
		hdc = BeginPaint(hwnd , &ps);

		GetClientRect(hwnd , &rect);
		DrawText(hdc , strLocation , -1 , &rect , DT_LEFT);

		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;
}
このプログラムを実行すると、ウィンドウの全ての位置で
マウスの移動がキャッチされ WM_NCHITTEST メッセージが送られてきます

WM_NCHITTEST は常に HTNOWHERE を返します
そのため、ここから他のマウスメッセージが生成されることはありません
逆に HTCAPTION を返せば、ウィンドウ全体がタイトルバーと同じ効果を持ち
どの場所でもドラッグでウィンドウを移動させることができるようになります



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