CBitmapButton上へ文字列表示 – プログラミング – Home

CBitmapButton上へ文字列表...
 
通知
すべてクリア

[解決済] CBitmapButton上へ文字列表示


ebimayo
 ebimayo
(@ebimayo)
ゲスト
結合: 19年前
投稿: 40
Topic starter  

初めまして
タイトルに書いたCBitmapButton上に文字列表示する方法について
質問させて頂きます。

<<やろうとしている事>>
1.CBimapButtonの機能を用いて通常状態、押された状態、無効状態、
  フォーカスを得た状態のビットマップを設定する。
2.1で用意したビットマップボタンに任意の文字列を書く。
(1は問題なく出来ていて2の実現方法で悩んでいます)

<<実現のために試した方法と結果>>
 CBitmapButtonを派生させたクラスを自作して、そのクラス内で
 OnPaintのイベントをキャッチして文字列を描画する。
実際の処理例を以下に記述しました。

// CBitmapButtonを基本クラスとして派生したCButtonTestクラスを自作し
class CButtonTest : public CBitmapButton

// CButtonTestクラスでOnPaintをキャッチするようにして
// 以下の文字列描画処理を書きました。
void CButtonTest::OnPaint()
{
if (IsIconic()){
}else{
CBitmapButton::OnPaint();

CDC *hDC;
PAINTSTRUCT lpPaint;
RECT tRect;

GetClientRect(&tRect);
InvalidateRect( NULL, FALSE );
hDC = BeginPaint(&lpPaint);
hDC->SetBkMode(TRANSPARENT);
hDC->DrawText( _T(表示したい文字),-1, &tRect,
DT_SINGLELINE|DT_CENTER );
EndPaint(&lpPaint);
}
}

上記のように書くとビットマップボタン上に文字列が表示されるのですが、
エクスプローラや別のアプリケーションなどのウィンドウで
ビットマップボタンに重なるように動かすと、ビットマップボタンの
ビットマップが灰色表示になってしまいます。(文字列は正常に表示し続けます)

<<知りたいこと>>
1.ビットマップボタンを用いてビットマップをボタンの背景のように使用し、
  その上に文字列を表示することは可能か?可能ならその実現方法
2.1の実現が不可能な場合の代わりになりそうな方法

何か少しでもわかることがあったら教えていただけたらと思い質問しました。

開発環境
Microsoft WindowsXP(SP2)
Microsoft Visual C++ 2005
  ダイアログベースアプリケーション(MFC)


引用未解決
トピックタグ
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

DrawItemをオーバーライドするとできるのではないでしょうか。


返信引用
ebimayo
 ebimayo
(@ebimayo)
ゲスト
結合: 19年前
投稿: 40
Topic starter  

回答ありがとうございます。

教えていただいたDrawItemを使用して以下のようにしました。
(OnPaintでは処理しないように削除しました。)

// 以下のようにオーバーライドするようにしました
public:
virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );

// DrawItemの処理を以下のようにしました
void CButtonTest::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
CDC *hDC;
CFont *pcFont;
PAINTSTRUCT lpPaint;
RECT tRect;
WORD wID;
HANDLE hBmp;
BITMAP tBmp;
HDC hBufdc;
HGDIOBJ hDef;

wID = 0;
if( (lpDrawItemStruct->itemState & ODS_DISABLED) != 0 ){
wID = m_nBMPDisabled;
}else
if( (lpDrawItemStruct->itemState & ODS_SELECTED) != 0 ){
wID = m_nBMPSel;
}else
if( (lpDrawItemStruct->itemState & ODS_FOCUS) != 0 ){
wID = m_nBMPFocus;
}
if(wID == 0){
wID = m_nBMP;
}
hDC = CDC::FromHandle(lpDrawItemStruct->hDC);
hBmp = LoadImage( AfxGetInstanceHandle(), MAKEINTRESOURCE(wID),
IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR );
GetObject(hBmp, sizeof(BITMAP), &tBmp);
hBufdc = CreateCompatibleDC(hDC->m_hDC);
hDef = SelectObject(hBufdc, hBmp);
BitBlt( hDC->m_hDC, 0, 0, tBmp.bmWidth, tBmp.bmHeight,
hBufdc, 0, 0, SRCCOPY);
DeleteObject(hBmp);
GetClientRect(&tRect);
hDC->SetBkMode(TRANSPARENT);
hDC->DrawText( _T(表示したい文字),-1, &tRect,
DT_SINGLELINE|DT_CENTER );
if( hDef != NULL ){ SelectObject(hBufdc, hDef); }
if( hBufdc != NULL ){ DeleteDC(hBufdc); }
}

上記で使っているm_nBMPDisabled、m_nBMPSel、m_nBMPFocus、m_nBMPは
元々このクラスはCBitmapButtonの派生クラスでLoadBitmapsに渡すために
派生クラスのコンストラクタで渡すようにしている各ボタン状態に応じた
ビットマップリソースIDです。

知りたかったことの1に書いたことが上記の方法で実現できました。
ありがとうございます。

ただ、これに関してひとつ疑問があるのですが、私のやり方だとCBitmapButtonを
派生して作っている意味がなく、CButtonの派生クラスで実現可能なのでは?
自分でCButtonから派生したCBitmapButtonのクラスの拡張(文字が書けるだけですが)
バージョンを作っているんじゃないかと思えてきたことです。

教えていただいたことを参考に出来たので解決チェック付けておきます。
これ以外にもいい方法があって私のやり方が回りくどいやり方だとしたら
教えてもらえたら幸いです。
#自分のやり方が最適だと思えなかったので・・・


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

動作確認してないんですけどこんな感じでどうでしょうか?

void CButtonTest::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CBitmapButton::DrawItem(lpDrawItemStruct);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
pDC->SetBkMode(TRANSPARENT);
pDC->DrawText( _T(表示したい文字),-1, &lpDrawItemStruct->rcItem,
DT_SINGLELINE|DT_CENTER );
}


返信引用
ebimayo
 ebimayo
(@ebimayo)
ゲスト
結合: 19年前
投稿: 40
Topic starter  

返信遅くなってすいません
subaruさんありがとうございます。

subaruさんの提示してくれたやり方で実現できました。
まだ理屈が理解できてませんが、CBitmapButton::DrawItemで
基本クラスが担当してくれる描画を行わせてからその上に自分の
描画したい文字列を書くってイメージでしょうか

OnPaintでやったときにCBitmapButton::OnPaint();を呼び出して
うまく描画出来なかったのでDrawItemでは基本クラスを呼ぶことを最初から
試していませんでした。

MSDNの対象クラスとそのメンバ関数のヘルプは良く見ますが
イベントの発生条件等詳しく理解出来ていませんでした。
OnPaintとDrawItemの違いがいまいち良くわかってないですが、
もっと理解出来るようにしたいと思います。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました