描画領域のサイズ


クライアントエリアのサイズを得る

より柔軟な文字列表現をしたい場合、TextOut()関数では不十分な面があります
この関数は、たとえクライアントエリアの幅が文字列より小さくなっても
文字列は改行されることなく、クライアントエリアから途切れてしまいます
//ウィンドウの外に描画されることはありません

そこで、クライアントエリアのサイズを知る必要があります
現在のクライアントエリアのサイズを得るには GetClientRect() 関数を使います

BOOL GetClientRect(HWND hWnd , LPRECT lpRect);

hWnd は、ウィンドウのハンドルを指定し
lpRect は、サイズを格納する RECT 構造体へのポインタです
左上の座標 top と left は必ず0になります

これと、フォントメトリックスを計算し
ウィンドウサイズによって動的な改行を表現することができます

しかし、TextOut() 関数でそれを実装したりはしません
一般的にこのような処理は DrawText() 関数がサポートしています
int DrawText(
  HDC hdc ,
  LPTSTR lpchText ,
  int cchText ,
  LPRECT lprc ,
  UINT dwDTFormat ,
);
hdc は、デバイスコンテキストのハンドルを
lpchText は、表示する文字列を指定します

cchText には、文字列の文字数を指定します
lpchText で指定した文字列が NULL で終わっている場合は -1 を指定することで
文字数の計算を自動的に行うことができます

lprc は、表示する長方形の座標を表す RECT 構造体へのポインタを指定します
関数での文字表現は、この長方形を元に描画されます

dwDTFormat には、テキストのフォーマット方法を示す定数を指定します
用意された DT をプレフィックスにする各種定数を組み合わせることができます
指定した長方形の中央に揃える DT_CENTER
文字列を表示できない場合に改行する DT_WORDBREAK などがあります
#include<windows.h>
#include<stdio.h>

LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
	HDC hdc;
	PAINTSTRUCT ps;
	static RECT rect;
	static PCTSTR ctStr = 
		TEXT("Government of the people , by the people , for the people");

	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hwnd , &ps);
		GetClientRect(hwnd , &rect);
		DrawText(hdc , ctStr , -1 , &rect ,
			 DT_CENTER | DT_WORDBREAK );
		EndPaint(hwnd , &ps);
		return 0;
	}
	return DefWindowProc(hwnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
		 PSTR pCmdLine , int nCmdShow ) {
	HWND hwnd;
	WNDCLASS winc;
	MSG msg;

	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 0;

	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 0;

	while (GetMessage(&msg , NULL , 0 , 0)) DispatchMessage(&msg);
	return msg.wParam;
}




上の画像のように、幅に余裕があれば文字列を中央によせ
指定した長方形が文字列を表現するのに不十分であれば、自動的に改行します
長方形は WM_PAINT が呼び出されるたびに更新しています
常に、現在のクライアントエリアのサイズを DrawText() 関数に渡しています

文字列の開始位置なども、長方形の top や left を操作します


GetClientRect()

BOOL GetClientRect(HWND hWnd , LPRECT lpRect);

ウィンドウのクライアントエリアの座標を得ます
左上の座標は常に (0 , 0) の値になり
右下は、左上からの相対的座標になります

hWnd - 座標を取得するウィンドウのハンドルを指定します
lpRect - RECT 構造体へのポインタを指定します。この構造体に座標が格納されます

戻り値 - 関数が成功すると0以外、失敗すると0が返ります

DrawText()

int DrawText(
  HDC hdc ,
  LPTSTR lpchText ,
  int cchText ,
  LPRECT lprc ,
  UINT uFormat ,
);
指定された長方形に、指定された形式でフォーマットした文字列を表示します

hdc - デバイスコンテキストのハンドルを指定します
lpchText - 表示する文字列を渡します。cchTextが -1 の場合 NULL で終わる文字列を指定します
cchText - 文字数を指定します。NULL で終わる文字列の場合 -1 を指定すると自動で計算します
lprc - 表示する長方形の座標が入った RECT 構造体へのポインタを指定します
uFormat - フォーマット方法を指定します

戻り値 - 描画したテキストの高さが返ります

定数解説
フォーマット指定
DT_BOTTOM 長方形の下辺にテキストを揃えます
DT_SINGLELINE と同時に指定しなければなりません
DT_CALCRECT RECT 構造体で指定した長方形の幅と高さを
実際にテキストを表示するために必要な大きさに変更します
テキストは描画しません
DT_CENTER テキストを水平方向に中央揃えで表示します
DT_EDITCONTROL 複数行エディットコントロールがもつ特性と同じ特性で描画します
部分的に見えている最後の行は表示しません
DT_END_ELLIPSIS 指定した長方形に収まるよう
必要に応じてテキストの最後を省略符号 (...) に置き換えます
DT_PATH_ELLIPSIS 指定した長方形に収まるよう
必要に応じてテキストの途中を省略符号 (...) に置き換えます
パス名の描画に適しています
DT_EXPANDTABS タブ文字を展開します
デフォルトのタブ間隔は 8 文字です
DT_EXTERNALLEADING 行の高さに、外部レディングの高さ
(テキストの行間として適切な高さ) を加算します
通常、外部レディングはテキスト行の高さに加えられません
DT_LEFT テキストを左揃えにします
DT_MODIFYSTRING lpString パラメータが指すバッファに
表示された文字列を格納します
DT_END_ELLIPSIS または DT_PATH_ELLIPSIS フラグを
指定したときにしか意味をもちません
DT_NOCLIP クリッピングをしません。描画が多少速くなります
DT_NOPREFIX プリフィックス文字の処理を行わないようにします
通常、ニーモニックプレフィクス「 & 」は
その次にくる文字にアンダースコア (_) を付けて
表示する命令であると解釈されます
また、「 && 」を 1 つの「 & 」として表示します
DT_NOPREFIX を指定すると、この処理が行われなくなります
DT_RIGHT テキストを右揃えにします
DT_RTLREADING 右から左への読み取り順序で表示します
ヘブライ語やアラビア語を表示するときに有効です
DT_SINGLELINE テキストを単一行で表示します
テキストがキャリッジリターンやラインフィードを含んでいても、改行されません
DT_TABSTOP タブ間隔を設定します
この値を指定したときは、uFormat パラメータの
15 ビットから 8 ビット (下位ワードの上位バイト) で
タブ間隔の文字数を指定します
デフォルトのタブ間隔は 8 文字です
DT_TOP 長方形の上辺にテキストを揃えます (単一行のときのみ)
DT_VCENTER テキストを垂直方向に中央揃えで表示します (単一行のときのみ)
DT_WORDBREAK テキストを複数行で表示します
折り返しは自動的に行われます
キャリッジリターンとラインフィードの組み合わせによっても折り返されます

DT_TABSTOP に対して、以下の各値と組み合わせることはできません

DT_CALCRECT
DT_EXTERNALLEADING
DT_INTERNAL
DT_NOCLIP
DT_NOPREFIX



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