OrangeMaker_logo
memo アイコン SDK-MFC 備忘録

Windows SDKやMFCに関するメモです。
(記載内容について正しいことを保証するものではありません。MSDN等で確認してください)

エアロで透けないチェックボックス

2009/11/15 作成
2009/11/21 サンプル画像追加

先に通常のボタンで文字が透けない方法を考えましたが、この方法ではチェックボックスなどはうまくないです。通常のボタンではボタンの周りは透けないですがチェックボックスを文字描画部分を狙い撃ちすると透けないですがエアログラスの色によっては見ずらい状態になります。

チェックボックスの文字を自力でThemeAPIを使用してグロー効果付きで描画する方法を考えます。
今回はちょっと長いです。

OnPaint()ハンドラ:
 HDC targetDC = this->GetDC()->m_hDC;
 HDC bufferedDC = NULL;
 RECT rect;
 GetClientRect(&rect);
 HPAINTBUFFER pb = BeginBufferedPaint(targetDC, &rect, 
     BPBF_TOPDOWNDIB, 0, &bufferedDC);
 HRESULT hr = S_OK;
 if (0 == pb){
     //Error
 }
 else{
     //先に標準コンポーネントに書いてもらう
     SendMessage(WM_PRINTCLIENT, 
         reinterpret_cast<WPARAM>(bufferedDC), PRF_CLIENT);
     //チェックBOXのテキストを取得
     CString t;
     this->GetWindowText(t);
     CStringW text;
     text = t;
     int len = text.GetLength();
     if(len > 0){//テキストが設定されてないならなにもしない 
         //チェックBOXサイズ(あとでシステムから取得するように変更)
         CSize szCheckBox(13,13);//ひとまず固定値で
         CRect rText(0,0,0,0); 
         //テキスト描画矩形
         //テーマを開く
         HTHEME hTheme = OpenThemeData(this->m_hWnd, L"Button");
         int a = TMT_CAPTIONFONT;
         CSize szText(0,0);
         //親ダイアログからフォントを取得する
         CFont* pFont = this->GetParent()->GetFont();
         LOGFONT lf;
         pFont->GetLogFont(&lf);
         HFONT hFont = CreateFontIndirect(&lf);
         ::SelectObject(bufferedDC, hFont);
         //フォントのポイント数を求める
         int fh = - lf.lfHeight;
         int point = CFontUtl::HeightToPointfh);
         //テキストの描画サイズを取得
         GetTextExtentPoint32W(bufferedDC, text, len, &szText);
         //テキスト描画矩形を計算する
         //縦位置は中央(の1px 下)
         rText.top = ((rect.bottom - szText.cy) / 2) + 1;
         rText.bottom = rText.top + szText.cy;
         //横位置は左寄せ決め打ちで
         rText.left = rect.left + szCheckBox.cx + 3;
         rText.right = rText.left + szText.cx;
	
         int nPartID = TEXT_BODYTITLE;
         int nStateID = 0;
         DTTOPTS option = { sizeof(DTTOPTS) };
         option.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE;
         option.iGlowSize = point; //glowサイズ->フォントのポイント数にする
         DrawThemeTextEx(hTheme, bufferedDC, nPartID, nStateID, text, len,
             DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX,
             &rText,&option);
		
         //テーマを閉じる
         ::CloseThemeData(hTheme);
     }
     hr = EndBufferedPaint(pb, TRUE);
     if (hr != S_OK){
         //error
     }
 }
		

チェックボックスのボックス部分のサイズは13px固定で処理しています。(気になる場合はシステムリソースからチェックBOXイメージを取得してサイズを割り出す必要があります)

フォントは、親ウィンドウ(通常はダイアログ)から取得していますが自身のDCから取得すればいいのかもしれません。

ボックス部分の描画には関与していないのでradioボタンも共用できると思います。

Aeroで透けないチェックBox (グロー効果で背景が黒くても見えます)

チェックボックスの描画方法は、こちらのサイトを参考にさせてもらいました。
http://pg-torch-ic.jugem.jp/?eid=26