アプリを作るときにほぼ確実に使うのは文字列ですよね。
そして、たまに文字列の大きさが必要になる時があります。

そんな時のために文字列の幅をちゃんと取ってくれる関数を作りました。

文字列のサイズを測る

引数にHDCが入るかどうかで二つに分けています。

■ 引数にHDCが有る場合

/**
 * @brief テキストのサイズを測る
 * @param hWnd ウィンドウハンドル
 * @param hdc デバイスコンテキストハンドル
 * @param pText サイズを測るテキスト
 * @param hFont テキストを表示するのに使用するフォント
 * @return テキストのサイズ
 * @detail 既にフォントが設定されているなら、hFont は NULL でもOK
 **/
SIZE GetTextSize( HWND hWnd, HDC hdc, TCHAR *pText, HFONT hFont )
{
	SIZE sizeText;

	auto hOldFont = (HFONT)SendMessage( hWnd, WM_GETFONT, NULL, NULL );

	if( hFont )
	{
		SendMessage( hWnd, WM_SETFONT, (WPARAM)hFont, FALSE );
	}

	GetTextExtentPoint32( hdc, pText, wcslen( pText ), &sizeText );

	SendMessage( hWnd, WM_SETFONT, (WPARAM)hOldFont, FALSE );

	return sizeText;
}

■ 引数にHDCが無い場合

/**
 * @brief テキストのサイズを測る
 * @param hWnd ウィンドウハンドル
 * @param pText サイズを測るテキスト
 * @param hFont テキストを表示するのに使用するフォント
 * @return テキストのサイズ
 * @detail 既にフォントが設定されているなら、hFont は NULL でもOK
 **/
SIZE GetTextSize( HWND hWnd, TCHAR *pText, HFONT hFont )
{
	SIZE sizeText;

	auto hdc = GetDC( hWnd );
	auto hOldFont = (HFONT)SendMessage( hWnd, WM_GETFONT, NULL, NULL );

	if( hFont )
	{
		SendMessage( hWnd, WM_SETFONT, (WPARAM)hFont, FALSE );
	}

	GetTextExtentPoint32( hdc, pText, wcslen( pText ), &sizeText );

	SendMessage( hWnd, WM_SETFONT, (WPARAM)hOldFont, FALSE );

	ReleaseDC( hWnd, hdc );

	return sizeText;
}

デバイスコンテキストハンドル(HDC)が引数で簡単に渡せる時と渡せない時があるので2つ用意しています。

WM_PAINTの処理中ならHDCが引数で渡せる上のパターンを使うと便利です。
それ以外の場合は、自動でHDCを取ってくれるHDC引数無しの方が使いやすいです。

大事なポイントは、WM_SETFONTでフォントを指定していることです。これが無いと現在設定されているフォントを使って大きさを測るので正しい大きさが測れません。