アプリ版:「スタンプのみでお礼する」機能のリリースについて

VC6.0でMFCアプリケーションを作成しています。
・ダイアログベース
・背景はビットマップ(スタイルにWS_CLIPCHILDRENを追加)
・ボタンはビットマップ&非矩形(丸)

これを作成し、実行するとCPU使用率が100%になってしまいます。
OnPaint()での描画をしなければ、ボタンが丸く表示されません。
ご存知の方は教えてください。

以下、ソース抜粋です。
メンバ
CButton m_cbImage;
CBitmap m_cBmpBack;
CBitmap m_cBmpButton;
HBITMAP m_hBmpBack;
BITMAP m_bmp;
HDC m_hDc;

OnInitDialog(){
//背景ビットマップ
m_cBmpBack.LoadBitmap(IDB_BITMAP_BACK);
//ボタンビットマップ
m_cBmpButton.LoadBitmap(IDB_BITMAP_BUTTON);

HBITMAP hBmpButton = HBITMAP(m_cBmpButton);
m_cbImage.SetBitmap(hBmpButton);

// ウィンドウに関する情報を取得
// BMPサイズ取得
m_hBmpBack = HBITMAP(m_cBmpBack);
GetObject(m_hBmpBack, sizeof(BITMAP), &m_bmp);
// BMPデバイスコンテキスト作成
m_hDc = CreateCompatibleDC(NULL);
// オブジェクトを選択する
SelectObject(m_hDc, m_hBmpBack);

// ボタン変形
CRect cRectButton;
m_cbImage.GetClientRect(cRectButton);
CRgn rgnButton;
rgnButton.CreateEllipticRgn(cRectButton.Width() * 1 / 8, cRectButton.Height() * 1 / 8, cRectButton.Width() * 7 / 8, cRectButton.Height() * 7 / 8);
m_cbImage.SetWindowRgn((HRGN)rgnButton, TRUE);
}

OnPaint(){
HDC hdc = ::GetDC(m_hWnd);
BitBlt(hdc, 0, 0, (int)m_bmp.bmWidth, (int)m_bmp.bmHeight, m_hDc, 0, 0, SRCCOPY);
::ReleaseDC(m_hWnd, hdc);
}

以上、よろしくお願いします。

A 回答 (4件)

MFCについては、あまり詳しくないので分かりませんが、


SDKの場合、GetDCを行うとWM_PAINTメッセージが発生する
らしいので(ちょっと記憶があいまいですが)、WM_PAINTメ
ッセージ内でGetDCを行うとある意味無限ループみたいな形
になってしまうので、その関係でCPU使用率があがっている
のではないかと思います。

参考までに、SDKではWM_PAINTメッセージが来たときは
BeginPaint関数、EndPaint関数でデバイスコンテキストの
ハンドルを取得します。
    • good
    • 0
この回答へのお礼

ありがとうございます。

描画あたりの理解が低いもので、そのような仕組みになっていたんですね。

ちなみに、丸いボタンのサンプルプログラムがあり、
それを使ってみようと思います。
見ただけではとても理解できるものではありませんでしたが。

お礼日時:2002/07/03 17:53

> OnPaint()でなぜ生のHDCを取得?


このようにしないと表示がされなかったのです。

うーん、そんなばかな・・・
CWnd::GetDC()で問題ないはずです。

MFC内では、生のHDCを使う必要はよっぽどのことがないとありません。HBITMAPなどのハンドルを使うのもです。
CreateCompatibleDC()、SelectObject()、BitBlt()に関しても、CWndやCDCのメンバ関数を使ってください。


いきなりボタンを丸くするのではなく、まず正しくMFCのソースを書くところからはじめたほうがいいと思います。

あと、エラーチェックを適時入れ、関数の成否をチェックしたほうがいいですよ。
どこまで処理がうまく行っているのかもわかりますし。

非矩形ウィンドウを作成するのはそれからで遅くありません。
    • good
    • 0

>OnPaint()でなぜ生のHDCを取得?


>
>疑問2
>BitBlt()でダイアログ全体に転送しているのはボタンのビットマップでは?
>
>疑問3

すみません。この部分は無視してください。
    • good
    • 0

CRgnって、メンバ変数にしておかなくても平気でしたっけ?




ヘルプより
SetWindowRgn 関数が成功すると、システムは、パラメータ hRgn で指定したリージョンを所有します。システムは、このリージョンのコピーを作成しません。したがって、これ以降はこのリージョンハンドルに対して関数を呼び出すべきではありません。特に、このリージョンハンドルを削除しないでください。必要がなくなると、システムはこのリージョンハンドルを自動的に削除します。


あと、なぜ生のHBITMAPやHDCを使用しているのですか?




OnPaint()でなぜ生のHDCを取得?

疑問2
BitBlt()でダイアログ全体に転送しているのはボタンのビットマップでは?

疑問3

参考URL:http://www.microsoft.com/JAPAN/developer/library …
    • good
    • 0
この回答へのお礼

ありがとうございます。

> OnPaint()でなぜ生のHDCを取得?
このようにしないと表示がされなかったのです。

リージョンについてはご指摘の通りですね。

お礼日時:2002/07/03 17:50

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!