AboutDialogBoxの背景色 – プログラミング – Home

通知
すべてクリア

[解決済] AboutDialogBoxの背景色

固定ページ 1 / 2

Beginner
 Beginner
(@Beginner)
ゲスト
結合: 23年前
投稿: 63
Topic starter  

何時もお世話になります。
ブロック崩しの色付けにAboutDialogBoxの背景色をセットしようとして、以下のコードを
CAboutDlgにOnEraseBkgndメッセージハンドラを付け加えて、以下のコードを書きました。

BOOL CAboutDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォル
トの処理を呼び出してください
CBrush backBrush(RGB(200,20,200));
CBrush *oldBrush = pDC->SelectObject(&backBrush);
CRect rect;
pDC->GetClipBox(&rect);
pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
PATCOPY);
pDC->SelectObject(oldBrush);
return CDialog::OnEraseBkgnd(pDC);
}

しかし、背景色はdefaultのままで変化ありません。ちなみにreturn文の前にAfxMessageBox()
を置けば背景色は思いどおりに変わりますが、無限ループに入ります。

どなたかご教示下さい。


引用未解決
トピックタグ
Beginner
 Beginner
(@Beginner)
ゲスト
結合: 23年前
投稿: 63
Topic starter  

書き忘れました。申し訳ありません。
Win2K, VC++6.0, MFCです。


返信引用
小悪魔恭子
 小悪魔恭子
(@小悪魔恭子)
ゲスト
結合: 22年前
投稿: 25
 

> return CDialog::OnEraseBkgnd(pDC);
return TRUE;
でよいのでは?


返信引用
123
 123
(@123)
ゲスト
結合: 22年前
投稿: 9
 

HBRUSH BOOL CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
COLOREF backColor=RGB(200,20,200);
CBrush backBrush(backColor);

if (nCtlColor == CTLCOLOR_DLG || nCtlColor == CTLCOLOR_STATIC)
{
pDC->SetBkColor(backColor);
return (HBRUSH) backBrush.GetSafeHandle();
}

return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
}


返信引用
Beginner
 Beginner
(@Beginner)
ゲスト
結合: 23年前
投稿: 63
Topic starter  

小悪魔恭子様、

ありがとうございます。仰る通りreturn TRUE;に変更するとうまくいきました。ただ、Dialog
の中のstatic_textについては背景色は変わりません。

123様、
ご教授ありがとうございます。
試みましたが、WM_CTLCOLORのメッセージがAboutDlgに送られないのか、ダイアロクもテキス
トも背景色は変化しませんでした。どのようにすればWM_CTLCOLORのメッセージがAboutDlgを
開いた時に送られるようになるでしょうか?


返信引用
Beginner
 Beginner
(@Beginner)
ゲスト
結合: 23年前
投稿: 63
Topic starter  

小悪魔恭子様、

今、発見しました。

要するにdefaultでメッセージハンドラの最後に付け加えられる
return CDialog::OnEraseBkgnd(pDC);
を実行させずに
return FALSE;でも
return TRUE;でも
何でも良いから戻せば良いようです。
結果は同じになります。

何だか良く分かりません。
要するに
return CDialog::OnEraseBkgnd(pDC);
を返せば、折角その前に行った背景描画処理が無駄になって、派生元クラスのdefaultの関数が
実行されてしまうからでしょうか?


返信引用
sugar
 sugar
(@sugar)
ゲスト
結合: 24年前
投稿: 448
 

CDialog::OnEraseBkgnd(pDC);
これを実行していることが、デフォルトの処理を実施させていることになります。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> CBrush backBrush(backColor);
>
> if (nCtlColor == CTLCOLOR_DLG || nCtlColor == CTLCOLOR_STATIC)
> {
> pDC->SetBkColor(backColor);
> return (HBRUSH) backBrush.GetSafeHandle();
> }

これでは、関数から出た時にブラシが削除されてしまいます。
backBrushを関数より寿命の長いスコープに置いてみてください。
(メンバ変数、クラス変数、グローバル変数など)


返信引用
Beginner
 Beginner
(@Beginner)
ゲスト
結合: 23年前
投稿: 63
Topic starter  

dairygoods様、

ご指導のようにbackBrushをAboutDlgのメンバー変数に持っていきましたが、ビルドすると

BlockHitGame.obj : error LNK2001: 外部シンボル "protected: int __thiscall
CAboutDlg::OnEraseBkgnd(class CDC *) (?
OnEraseBkgnd@CAboutDlg@@IAEHPAVCDC@@@Z) は未解決です

のようなエラーがでてしまいます。
何のことだかさっぱり分かりません。
また、123様のコードでもreturnでbackBrushへのハンドルを返すことになるので、backBrush
が関数を出たときに削除されるとは思えないのですが。
ご指導宜しくお願いします。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> のようなエラーがでてしまいます。

CBrushの件とは関係ないと思います。
OnEraseBkgnd()関数を削除したが、MESSAGE_MAPが
そのままとかではないですか。

> 関数を出たときに削除されるとは思えないのですが。

イメージだけで捉えずに、疑問に思った点は
テストプログラムを作って確かめてみると良いでしょう。

HBRUSH GetHandle() {
CBrush brush(RGB(0,0,0));
return (HBRUSH)brush.GetSafeHandle();
}

...

HBRUSH hbr = GetHandle();
LOGBRUSH lb;
int ret = ::GetObject(hbr, sizeof(lb), &lb);
if (ret == 0) {
// hbrは削除されている
} else {
// hbrは削除されていない
}


返信引用
Beginner
 Beginner
(@Beginner)
ゲスト
結合: 23年前
投稿: 63
Topic starter  

dairygoods様、

仰る通り、小生が勝手にハンドラをコメントアウトして、MESSAGE_MAPに残ったままだからでし
た。そこの部分もコメントアウトするとOKでした。
しかし、未だ問題があります。
やはりAbouDlgの背景色は変化しません。残念ながらSPY++などの使い方も分からないのです
が、きっとWM_CTLCOLORメッセージがAboutDlgに届いていないのだと思います。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> 残念ながらSPY++などの使い方も分からないのです
> が、きっとWM_CTLCOLORメッセージがAboutDlgに届いていないのだと思います。

SPY++など使えなくても簡単に調べられます。
OnCtlColor()関数の中にブレークポイントを設置して
デバッガで実行するだけです。

で、本当に呼ばれていない場合ですが、
MESSAGE_MAPにON_WM_CTLCOLOR()はありますか?


返信引用
Beginner
 Beginner
(@Beginner)
ゲスト
結合: 23年前
投稿: 63
Topic starter  

dairygoods様、

そうですね。馬鹿でした。ブレークポイントを

BRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: この位置で DC のアトリビュートを変更してください

// TODO: デフォルトのブラシが望みのものでない場合には、違うブラシを返してく
ださい
if (nCtlColor==CTLCOLOR_DLG||nCtlColor==CTLCOLOR_STATIC) {

pDC->SetBkColor(backColor);
return (HBRUSH) backBrush.GetSafeHandle();
}
return hbr;
}

の中のifの頭に設定しましたところ、ちゃんとAboutDlgを表示しようとするとそのブレークポ
イントで停止しました。ということはちゃんとこのハンドラが呼ばれているということですね。
では、どうして思いどおりに行かないのでしょうか?


返信引用
akey
 akey
(@akey)
ゲスト
結合: 22年前
投稿: 53
 

backBrushは、作っていますか?
(CBrush::CreateSolidBrushを呼んでいますか?)


返信引用
Beginner
 Beginner
(@Beginner)
ゲスト
結合: 23年前
投稿: 63
Topic starter  

akey様、

ご指摘ありがとうございます。
CBrushのコンストラクタを調べたのですが、

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
backColor = RGB(200,100,100);
CBrush backBrush(backColor);
}

でCreateSolidBrushが呼ばれているように思います。
ですから、backBrushはちゃんと作成されていると思いますが......


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

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