Direct2Dで文字列の幅と高さを取得するには、IDWriteTextLayoutインターフェイスのGetMetrics()メソッドを使います。 取得できるDWRITE_TEXT_METRICS構造体の、left, top, width, heightに矩形が入ります。
#include <stdio.h>
#include <tchar.h>
#include <locale.h>
#include <iostream>
#include <windows.h>
#include <wingdi.h>
#include <d2d1.h>
#include <dwrite.h>
// lib
#pragma comment( lib, "d2d1.lib" )
#pragma comment( lib, "dwrite.lib" )
/*
メインウインドウイベント処理
*/
LRESULT CALLBACK eMainWindowProc(
HWND hwnd // handle to window
, UINT uMsg // message identifier
, WPARAM wParam // first message parameter
, LPARAM lParam // second message parameter
);
// グローバル変数
ID2D1Factory* pD2d1Factory = NULL;
IDWriteFactory* pDWFactory = NULL;
ID2D1HwndRenderTarget* pRenderTarget = NULL;
/*
Direct2Dで文字列の幅と高さを取得
*/
int _tmain
(
int argc
, _TCHAR* argv[]
)
{
// 標準出力にユニコードを表示できるようにする
setlocale( LC_ALL, "Japanese" );
WNDCLASSEX tWndClass;
HINSTANCE hInstance;
TCHAR* cpClassName;
TCHAR* cpWindowName;
TCHAR* cpMenu;
HWND hWnd;
MSG tMsg;
// アプリケーションインスタンス
hInstance = ::GetModuleHandle( NULL );
// クラス名称
cpClassName = _T("MainWindowClass");
// メニュー
cpMenu = MAKEINTRESOURCE( NULL );
// ウインドウ名称
cpWindowName = _T("Direct2Dで文字列の幅と高さを取得");
// ウインドウクラスパラメータセット
tWndClass.cbSize = sizeof( WNDCLASSEX );
tWndClass.style = CS_HREDRAW | CS_VREDRAW;
tWndClass.lpfnWndProc = eMainWindowProc;
tWndClass.cbClsExtra = 0; // ::GetClassLong で取得可能なメモリ
tWndClass.cbWndExtra = 0; // ::GetWindowLong で取得可能なメモリ
tWndClass.hInstance = hInstance;
tWndClass.hIcon = ::LoadIcon( NULL, IDI_APPLICATION );
tWndClass.hCursor = ::LoadCursor( NULL, IDC_ARROW );
tWndClass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
tWndClass.lpszMenuName = cpMenu;
tWndClass.lpszClassName = cpClassName;
tWndClass.hIconSm = NULL;
// ウインドウクラス生成
if ( 0 == ::RegisterClassEx( &tWndClass ) ) {
/* 失敗 */
return( -1 );
}
// ウインドウを生成する
hWnd = ::CreateWindowEx (
0 // extended window style
, tWndClass.lpszClassName // pointer to registered class name
, cpWindowName // pointer to window name
, WS_OVERLAPPEDWINDOW // window style
, CW_USEDEFAULT // horizontal position of window
, CW_USEDEFAULT // vertical position of window
, 640 // window width
, 480 // window height
, NULL // handle to parent or owner window
, NULL // handle to menu, or child-window identifier
, hInstance // handle to application instance
, (VOID*)0x12345678 // pointer to window-creation data
);
/*
メッセージループ
*/
while( 0 != ::GetMessage( &tMsg, NULL, 0, 0 ) ) {
::TranslateMessage ( &tMsg );
::DispatchMessage ( &tMsg );
}
// WM_QUITの終了コードを返却する
return( tMsg.wParam );
}
/*
メインウインドウイベント処理
*/
LRESULT CALLBACK eMainWindowProc
(
HWND hWnd // handle to window
, UINT uMsg // message identifier
, WPARAM wParam // first message parameter
, LPARAM lParam // second message parameter
)
{
switch( uMsg ) {
case WM_CREATE:
//--------------------------------------------
// WM_CREATE
//--------------------------------------------
{
CREATESTRUCT* tpCreateSt = (CREATESTRUCT*)lParam;
/* パラメータ表示 */
wprintf(
L"CREATESTRUCT¥n"
L"¥tlpCreateParams = 0x%08x¥n"
L"¥thInstance = 0x%08x¥n"
L"¥thMenu = 0x%08x¥n"
L"¥thwndParent = 0x%08x¥n"
L"¥tcy = %d¥n"
L"¥tcx = %d¥n"
L"¥ty = %d¥n"
L"¥tx = %d¥n"
L"¥tstyle = 0x%08x¥n"
L"¥tlpszName = ¥"%s¥"¥n"
L"¥tlpszClass = ¥"%s¥"¥n"
L"¥tdwExStyle = 0x%08x¥n"
, tpCreateSt->lpCreateParams
, tpCreateSt->hInstance
, tpCreateSt->hMenu
, tpCreateSt->hwndParent
, tpCreateSt->cy
, tpCreateSt->cx
, tpCreateSt->y
, tpCreateSt->x
, tpCreateSt->style
, tpCreateSt->lpszName
, tpCreateSt->lpszClass
, tpCreateSt->dwExStyle
);
HRESULT hResult = S_OK;
/*
ID2D1Factoryの生成
*/
hResult = ::D2D1CreateFactory( D2D1_FACTORY_TYPE_MULTI_THREADED, &pD2d1Factory );
if ( FAILED( hResult ) ) {
// エラー
std::wcout << L"D2D1CreateFactory失敗" << std::endl;
break;
}
/*
IDWriteFactoryの生成
*/
hResult = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>( &pDWFactory ) );
if ( FAILED( hResult ) ) {
// エラー
std::wcout << L"D2D1CreateFactory失敗" << std::endl;
break;
}
/*
ID2D1HwndRenderTargetの生成
*/
{
D2D1_SIZE_U oPixelSize = {
tpCreateSt->cx
, tpCreateSt->cy
};
D2D1_RENDER_TARGET_PROPERTIES oRenderTargetProperties = D2D1::RenderTargetProperties();
D2D1_HWND_RENDER_TARGET_PROPERTIES oHwndRenderTargetProperties = D2D1::HwndRenderTargetProperties( hWnd, oPixelSize );
/*
ID2D1HwndRenderTargetの生成
*/
hResult = pD2d1Factory->CreateHwndRenderTarget(
oRenderTargetProperties
, oHwndRenderTargetProperties
, &pRenderTarget
);
if ( FAILED( hResult ) ) {
// エラー
std::wcout << L"CreateHwndRenderTarget失敗" << std::endl;
break;
}
}
// ウインドウを表示する
::ShowWindow( hWnd, SW_SHOW );
}
break;
case WM_DESTROY:
//--------------------------------------------
// WM_DESTROY
//--------------------------------------------
{
// ID2D1HwndRenderTargetの破棄
if ( NULL != pRenderTarget ) {
pRenderTarget->Release();
}
// IDWriteFactoryの破棄
if ( NULL != pDWFactory ) {
pDWFactory->Release();
}
// ID2D1Factoryの破棄
if ( NULL != pD2d1Factory ) {
pD2d1Factory->Release();
}
// 終了する( 引数はそのまま終了コードとなります )
::PostQuitMessage( 0 );
}
break;
case WM_SIZE:
//--------------------------------------------
// WM_SIZE
//--------------------------------------------
{
D2D1_SIZE_U oPixelSize = { LOWORD( lParam ), HIWORD( lParam ) };
// ターゲットリサイズ
pRenderTarget->Resize( &oPixelSize );
}
break;
case WM_ERASEBKGND:
//--------------------------------------------
// WM_ERASEBKGND
//--------------------------------------------
{
;
}
return( TRUE );
case WM_PAINT:
//--------------------------------------------
// WM_PAINT
//--------------------------------------------
{
HRESULT hResult = S_OK;
// ターゲットサイズの取得
D2D1_SIZE_F oTargetSize = pRenderTarget->GetSize();
// 描画開始
PAINTSTRUCT tPaintStruct;
::BeginPaint( hWnd, &tPaintStruct );
// 描画開始(Direct2D)
pRenderTarget->BeginDraw();
// 背景のクリア
D2D1_COLOR_F oBKColor = { 1.0f, 1.0f, 1.0f, 1.0f };
pRenderTarget->Clear( oBKColor );
/*
テキストの描画
*/
{
/*
ブラシの生成(黒)
*/
ID2D1SolidColorBrush* pBrush = NULL;
{
pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF( D2D1::ColorF::Black )
, &pBrush
);
}
/*
ブラシの生成(赤)
*/
ID2D1SolidColorBrush* pBrushR = NULL;
{
pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF( D2D1::ColorF::Red )
, &pBrushR
);
}
/*
テキストフォーマットの生成
*/
IDWriteTextFormat* pTextFormat = NULL;
{
pDWFactory->CreateTextFormat(
L"Meiryo"
, NULL
, DWRITE_FONT_WEIGHT_NORMAL
, DWRITE_FONT_STYLE_NORMAL
, DWRITE_FONT_STRETCH_NORMAL
, 128
, L""
,&pTextFormat
);
}
std::wstring strText = L"Hello World!!";
D2D1_RECT_F tTextRectF;
{
IDWriteTextLayout* pTextLayout = NULL;
// IDWriteTextLayoutの取得
hResult = pDWFactory->CreateTextLayout(
strText.c_str() // 文字列
, strText.size() // 文字列の幅
, pTextFormat // DWriteTextFormat
, oTargetSize.width // 枠の幅
, oTargetSize.height // 枠の高さ
, &pTextLayout
);
if ( SUCCEEDED( hResult ) ) {
DWRITE_TEXT_METRICS tTextMetrics;
// Metricsの取得
pTextLayout->GetMetrics( &tTextMetrics );
/*
文字列矩形の取得
*/
tTextRectF = D2D1::RectF(
tTextMetrics.left // left
, tTextMetrics.top // top
, tTextMetrics.left + tTextMetrics.width // right
, tTextMetrics.top + tTextMetrics.height // bottom
);
// 四角形の描画
pRenderTarget->DrawRectangle( &tTextRectF, pBrushR, 1.0f );
// IDWriteTextLayoutの破棄
pTextLayout->Release();
}
}
/*
テキストの描画
*/
if ( NULL != pBrush && NULL != pTextFormat ) {
// テキストの描画
pRenderTarget->DrawText(
strText.c_str() // 文字列
, strText.size() // 文字数
, pTextFormat
, &D2D1::RectF( 0, 0, oTargetSize.width, oTargetSize.height )
, pBrush
, D2D1_DRAW_TEXT_OPTIONS_NONE
);
}
// テキストフォーマットの破棄
if ( NULL != pTextFormat ) {
pTextFormat->Release();
}
// ブラシの破棄(赤)
if ( NULL != pBrushR ) {
pBrushR->Release();
}
// ブラシの破棄(黒)
if ( NULL != pBrush ) {
pBrush->Release();
}
}
// 描画終了(Direct2D)
pRenderTarget->EndDraw();
// 描画終了
::EndPaint( hWnd, &tPaintStruct );
}
return( FALSE );
}
// デフォルト処理呼び出し
return ::DefWindowProc( hWnd, uMsg, wParam, lParam );
}
