概要

ウィンドウに長方形を描画するサンプルです。
ブラシにはハッチを使用しています。

テスト環境

コンパイラ

Visual C++ 2008 Standard 32/64bit
Visual C++ 2013 Express 32/64bit

実行環境

Windows 8.1 Enterprise 64bit
Windows 7 EnterPrise Service Pack 1 64bit
Windows Vista Ultimate Service Pack 2 32bit
Windows XP Professional Service Pack 3 32bit

プログラムソースの概要

_tWinMain関数

WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)ウィンドウプロシージャー

RegisterClass APIにより登録することによりWindowsから呼び出されます。
第2引数にメッセージの種類が格納されていますので、switchステートメントによりメッセージごとの処理を振り分けます。
自分で処理しないメッセージはDefWindowProc APIに渡せばWindowsが標準的な処理を行ってくれます。 Windowsから最初に_tWinMain関数が呼び出されます。 ウィンドウを作成する場合は、RegisterClass APIによりウィンドウクラスを定義してからCreateWindow APIを呼び出しウィンドウを作成します。 Windowsは入力等のイベントが発生するとアプリケーションにメッセージを送付します。 メッセージはキューに保管されます。アプリケーションはメッセージを取り出し、該当ウィンドウにメッセージを配信します。 メッセージの取り出しから配信までループで処理を行いウィンドウから終了メッセージが届くと、ループを抜けるように記述します。 これらの一連の処理は、通常にCreateWindow APIの後に記述しこれをメッセージループと呼んでいます。 詳細は以下を参照してください。
メッセージループ

case WM_CREATE:

ウィンドウの初期化時に呼び出されます。
今回のプログラムでは、DefWindowProc APIにそのままメッセージを渡して処理しています。

case WM_SIZE:

ウィンドウのサイズが変更されたときに呼び出されます。
今回のプログラムでは、DefWindowProc APIにそのままメッセージを渡して処理しています。

case WM_DESTROY:

ウィンドウが閉じるときに呼び出されます。
PostQuitMessage APIにより終了コードを指定して、ウィンドウプロシージャーを終了させます。

case WM_PAINT:

ウィンドウを再描画する必要があるときに呼び出されます。
他のウィンドウに隠れ再びフォアグラウンドになった場合などウィンドウの再描画はWindowsが面倒を見ないのでプログラマの仕事となっています。
BeginPaint APIを呼び出して、描画に必要なデバイスコンテキストのハンドルを取得します。
BeginPaint APIの第2引数のポインタにはPAINTSTRUCT構造体のポインタを渡します。
BeginPaint API終了後、PAINTSTRUCT構造体には再描画が必要な領域の座標等の値が格納されています。
線を使用して描画するには、ペンの取得または作成し選択しなければなりません。
ペンの作成方法の詳細は以下を参照してください。
GDIのペンの作成方法
ペンを作成したらそのペンで描画させるためにSelectObject APIによりペンを選択します。戻り値は、前回のペンのハンドルですので保存しておき、デバイスコンテキストの解放前にペンの設定をもとに戻すときに使用します。
次にブラシの作成を行います。
ブラシの作成方法の詳細は以下を参照してください。
GDIのブラシの作成方法
ここではハッチをブラシにしています。
Rectangle APIで長方形を描画します。
SelectObject APIでペンを元に戻します。
再描画が終了したことをWindowsに知らせるためにEndPaint APIを使用してます。このAPIを呼び出さないと何度もWM_PAINTメッセージが発生し暴走します。

プログラムソース

rect.cpp

//	長方形の描画
//	Visual C++ 2008/2013	32/64bit

#include <windows.h>
#include <tchar.h>
#include <math.h>

//	ウィンドウプロシージャー
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

TCHAR szClassNme[] = TEXT("rect");

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInst,TCHAR* lpszCmdLine, int nCmdShow){
	HWND hWnd;
	MSG lpMsg;
	WNDCLASS myProg;

	if (!hPreInst) {
		myProg.style =CS_HREDRAW | CS_VREDRAW;
		myProg.lpfnWndProc =WndProc;
		myProg.cbClsExtra =0;
		myProg.cbWndExtra =0;
		myProg.hInstance =hInstance;
		myProg.hIcon =NULL;
		myProg.hCursor =LoadCursor(NULL, IDC_ARROW);
		myProg.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);
		myProg.lpszMenuName =NULL;
		myProg.lpszClassName =szClassNme;
		if (!RegisterClass(&myProg))
			return FALSE;
	}
	hWnd = CreateWindow(szClassNme,
	szClassNme,
	WS_OVERLAPPEDWINDOW,
	CW_USEDEFAULT,
	CW_USEDEFAULT,
	200,
	200,
	NULL,
	NULL,
	hInstance,
	NULL);
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
	while (GetMessage(&lpMsg, NULL, 0, 0)) {
		TranslateMessage(&lpMsg);
		DispatchMessage(&lpMsg);
	}
	return int(lpMsg.wParam);
}

//	ウィンドウプロシージャー
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
	HDC hdc;
	PAINTSTRUCT ps;

	switch (msg) {
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		case WM_PAINT:{
			hdc = BeginPaint(hWnd, &ps);
			HPEN hPen, hOldPen;
			HBRUSH hBrush, hOldBrush;

			hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
			hOldPen = (HPEN)SelectObject(hdc, hPen);
			hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
			hOldBrush =(HBRUSH) SelectObject(hdc, hBrush);

			Rectangle(hdc, 10, 10, 100, 100);

			DeleteObject(hPen);
			DeleteObject(hBrush);
			EndPaint(hWnd, &ps);
			break;}
		default:
			return(DefWindowProc(hWnd, msg, wParam, lParam));
	}
	return (0L);
}

ソースファイルと実行ファイルのダウンロード

ダウンロード rect.zip(37.0kByte)

ZIPファイルに含まれるファイル
rect.cpp
rect.exe