文字サイズの情報
フォントを変更すると、文字のサイズも変更されます。
環境によって使用されるフォントは異なるため、開発環境でのサイズ情報を数値で決め打ちすると別の環境でズレが生じる可能性があります。
ここでは文字サイズ取得の方法を説明します。
DrawText関数
DrawText関数の第五引数の書式設定にDT_CALCRECT
フラグを指定することで、描画に必要な領域を計算して取得することができます。
#include <windows.h>
#include <strsafe.h>
//ウィンドウの生成等は省略
#define BUFFERSIZE 128
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rtClient;
RECT rt;
static WCHAR* txt = L"あいうえお\n1234567890";
static WCHAR* format =
L"LEFT:\t\t%d\n"
L"TOP:\t\t%d\n"
L"RIGHT:\t\t%d\n"
L"BOTTOM:\t%d\n";
WCHAR buf[BUFFERSIZE];
switch (message)
{
case WM_PAINT:
GetClientRect(hWnd, &rtClient);
hdc = BeginPaint(hWnd, &ps);
//クライアント領域サイズをコピー
rt = rtClient;
//テキスト領域サイズを計算して取得
DrawText(hdc, txt, -1, &rt, DT_WORDBREAK | DT_CALCRECT);
//テキスト出力
DrawText(hdc, txt, -1, &rt, DT_WORDBREAK);
//サイズ情報の出力
rtClient.top += rt.bottom + 20;
StringCchPrintf(buf, BUFFERSIZE, format,
rt.left, rt.top, rt.right, rt.bottom);
DrawText(hdc, buf, -1, &rtClient, DT_WORDBREAK | DT_EXPANDTABS);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //ウィンドウの破棄
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
実行結果です。
この処理はRECT構造体のright
メンバとbottom
メンバのみが書き換えられます。
left
メンバとtop
メンバにはあらかじめ0をセットしておく必要があります。
DT_WORDBREAK
フラグを指定して複数行のサイズを取得する場合、あらかじめ描画領域の幅をRECT構造体に設定しておく必要があります。
複数行文字列は、指定された幅に合わせて適宜改行をするためで、実際に何行になるかはこの幅を元に計算されるためです。
(right
メンバが0のままだとサイズ取得に失敗します)
文字列の幅が領域の幅に満たない場合は、幅の情報は適切なサイズに縮小されます。
行間の高さを含める場合はDT_EXTERNALLEADING
フラグを同時に指定します。
なお、このフラグを指定した場合は実際に文字列の描画は行われません。
GetTextMetrics関数
GetTextMetrics
関数はフォントの情報を取得します。
- BOOL GetTextMetrics(
HDC hdc,
LPTEXTMETRIC lptm
); - デバイスコンテキストhdcに設定されているフォントの情報を取得しlptmに格納する。
成功した場合は0以外を、失敗した場合は0を返す。
TEXTMETRIC
は構造体で、フォントの情報を格納します。
(頭の「LP」はポインタの意味です)
- typedef struct tagTEXTMETRICW {
LONG tmHeight;
LONG tmAscent;
LONG tmDescent;
LONG tmInternalLeading;
LONG tmExternalLeading;
LONG tmAveCharWidth;
LONG tmMaxCharWidth;
LONG tmWeight;
LONG tmOverhang;
LONG tmDigitizedAspectX;
LONG tmDigitizedAspectY;
WCHAR tmFirstChar;
WCHAR tmLastChar;
WCHAR tmDefaultChar;
WCHAR tmBreakChar;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmPitchAndFamily;
BYTE tmCharSet;
} TEXTMETRICW, *PTEXTMETRICW, *NPTEXTMETRICW, *LPTEXTMETRICW; - フォントの基本情報を格納する構造体。
メンバが多いので簡単に説明します。
メンバ | 説明 |
---|---|
tmHeight | フォントの高さ (アセント+ディセント) |
tmAscent | アセント (基準線より上の高さ) |
tmDescent | ディセント (基準線より下の高さ) |
tmInternalLeading | 内部レディング 文字の上のアクセント記号等が表示される領域の高さ (tmHeightに含まれる) |
tmExternalLeading | 外部レディング 文字の外側の領域(行間)の高さ 文字の描画による影響を受けない (tmHeightに含まれない) |
tmAveCharWidth | フォントの平均幅 (斜体や太字は考慮されない) |
tmMaxCharWidth | フォントの最大幅 |
tmWeight | フォントの太さ |
tmOverhang | 合成フォント(太字や斜体など)で使用される追加の幅 通常のフォントより広い領域が必要になるフォントで、元のフォントから広げられる量 |
tmDigitizedAspectX | そのデバイスでの水平アスペクト |
tmDigitizedAspectY | そのデバイスでの垂直アスペクト |
tmFirstChar | フォントで定義されている最初の文字 |
tmLastChar | フォントで定義されている最後の文字 |
tmDefaultChar | デフォルトの文字 フォントに存在しない文字を使用したときの置き換えに使用される |
tmBreakChar | 単語と単語の間を表す文字 |
tmItalic | 0以外の値ならフォントはイタリック体 |
tmUnderlined | 0以外の値ならフォントは下線を持つ |
tmStruckOut | 0以外の値ならフォントは打消し線を持つ |
tmPitchAndFamily | フォントのピッチとファミリ |
tmCharSet | フォントの文字セット (→CreateFont関数#iCharSet) |
フォントのいくつかの設定はプログラマが設定した上で使用しますが、実際に描画される大きさは各フォントによって異なるのでこの関数で取得する必要があります。
フォントの縦幅は以下の図のように複数のパートから成り立っています。