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 ); }