EternalWindows
リージョン / リージョンの描画

リージョンは、ブラシやペン、ビットマップと同じように、GDIオブジェクトの1つです。 リージョンは図形を定義し、定義している図形を描画したり、 図形の範囲だけ描画を許可したりする目的に使用できます。 次に示すCreateRectRgnは、長方形のリージョンを作成します。

HRGN CreateRectRgn(
  int nLeftRect,
  int nTopRect,
  int nRightRect,
  int nBottomRect
);

nLeftRectは、長方形の左上隅のx座標を指定します。 nTopRectは、長方形の左上隅のy座標を指定します。 nRightRectは、長方形の右下隅のx座標を指定します。 nBottomRectは、長方形の右下隅のx座標を指定します。 戻り値は、作成されたリージョンを表すハンドルが返ります。 リージョンは、HRGN型で識別されます。

リージョンを描画するには、FillRgnを呼び出します。

BOOL FillRgn(
  HDC hdc,
  HRGN hrgn,
  HBRUSH hbr
);

hdcは、デバイスコンテキストのハンドルを指定します。 hrgnは、描画したいリージョンを指定します。 hbrは、リージョンの塗りつぶしに使用するブラシを指定します。

描画したリージョンがマウスで押下されたかを特定したい場合は、 PtInRegionを呼び出すことができます。

BOOL PtInRegion(
  HRGN hrgn,
  int X,
  int Y
);

hrgnは、リージョンを指定します。 Xは、x座標を指定します。 Yは、y座標を指定します。 戻り値がTRUEの場合は、指定した座標がリージョン内に位置することを意味します。

今回のプログラムは、リージョンを描画します。 また、リージョンがマウスで押下されたかを確認します。

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
	TCHAR      szAppName[] = TEXT("sample");
	HWND       hwnd;
	MSG        msg;
	WNDCLASSEX wc;

	wc.cbSize        = sizeof(WNDCLASSEX);
	wc.style         = 0;
	wc.lpfnWndProc   = WindowProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hinst;
	wc.hIcon         = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
	wc.hCursor       = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = szAppName;
	wc.hIconSm       = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
	
	if (RegisterClassEx(&wc) == 0)
		return 0;

	hwnd = CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hinst, NULL);
	if (hwnd == NULL)
		return 0;

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	
	while (GetMessage(&msg, NULL, 0, 0) > 0) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HRGN hrgn = NULL;

	switch (uMsg) {

	case WM_CREATE:
		hrgn = CreateRectRgn(50, 50, 200, 100);
		return hrgn != NULL ? 0 : -1;

	case WM_LBUTTONDOWN: {
		int x, y;

		x = LOWORD(lParam);
		y = HIWORD(lParam);

		if (PtInRegion(hrgn, x, y))
			MessageBox(hwnd, TEXT("リージョンを選択しました。"), TEXT("OK"), MB_OK);;

		return 0;
	}

	case WM_PAINT: {
		HDC         hdc;
		PAINTSTRUCT ps;

		hdc = BeginPaint(hwnd, &ps);

		FillRgn(hdc, hrgn, (HBRUSH)GetStockObject(GRAY_BRUSH));

		EndPaint(hwnd, &ps);

		return 0;
	}

	case WM_DESTROY:
		if (hrgn != NULL)
			DeleteObject(hrgn);
		PostQuitMessage(0);
		return 0;

	default:
		break;

	}

	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

WM_CREATEでは、CreateRectRgnを呼び出して長方形のリージョンを作成しています。 マウスの左ボタンが押された場合は、押された位置を基にPtInRegionを呼び出し、 リージョンを押下したかどうかを確認します。 WM_PAINTでは、FillRgnを呼び出してリージョンをデバイスコンテキストに描画します。 塗りつぶしに使用するブラシはCreateSolidBrushなどで作成することもできますが、 今回はGetStockObjectで既存の灰色ブラシを使用しています。 リージョンはGDIオブジェクトであるため、DeleteObjectで削除することになります。


戻る