Windows Theme API

DrawThemeTextExで描画

WTLのソースを見ながら必要な部分だけ自分のプログラムに組み込んでみました。

テキストの周りのglowがいいですねぇ。
背景が黒くても文字が読めますね。


さて、以下ソースです。

1.uxtheme.dllをロードしてtheme APIがサポートされているかチェック
2.OpenThemeData()でウィンドウのテーマを取得
3.BeginBufferedPaint()でペイントバッファとメモリデバイスコンテキストを取得
4.テキストの背景を塗りつぶし
5.DrawThemeTextEx()でテキスト描画
6.EndBufferedPaint()でペイントバッファ破棄
7.CloseThemeData()でテーマを破棄

uxtheme.dllをロードしてTheme APIがサポートされているかチェック

XP以前のOSで利用する場合はチェックが必要です。

int theme_supported = -1;

bool IsThemeSupported()
{
    if( theme_supported == -1 )
    {
        HMODULE dll = ::LoadLibrary( "uxtheme.dll" );
        theme_supported = ( dll != 0 ) ? 1 : 0;
        if( dll != NULL )::FreeLibrary( dll );
    }

    return theme_supported == 1;
}

テーマの取得と破棄

Theme APIが利用可能であれば、ウィンドウやボタンなど各コントロールのパーツに対応するテーマを取得します。とりあえず今回はウィンドウのテーマ。

HTHEME theme = ::OpenThemeData( hwnd, VSCLASS_WINDOW );
if( theme != 0 )
{
    //ペイントバッファを取得しテキストの描画
    /*...*/

    ::CloseThemeData( theme );
}

ペイントバッファ(メモリデバイスコンテキスト、バックバッファ)に描画

テキストの描画領域に対応したペイントバッファを作成し、DrawThemeTextEx()で描画します。

RECT r = { 0, 0, 200, 50 };	//テキストの描画領域
BP_PAINTPARAMS m_PaintParams = { sizeof(BP_PAINTPARAMS) };
HDC mem_dc = NULL;
HPAINTBUFFER paint_buffer = ::BeginBufferedPaint(hdc, &r, BPBF_TOPDOWNDIB, &m_PaintParams, &mem_dc );
if( paint_buffer != 0 )
{
    DTTOPTS option = { sizeof(DTTOPTS) };
    option.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE;
    option.iGlowSize = 8; //glowサイズ
    ::DrawThemeTextEx( theme, mem_dc, TEXT_BODYTITLE, 0, str, -1, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX, &r, &option );

    ::EndBufferedPaint( paint_buffer, TRUE );
}


次はWTL風にテンプレート化しましょうか。