• 締切済み

丸いボタンの表示でCPU100%

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); } 以上、よろしくお願いします。

みんなの回答

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.4

> OnPaint()でなぜ生のHDCを取得? このようにしないと表示がされなかったのです。 うーん、そんなばかな・・・ CWnd::GetDC()で問題ないはずです。 MFC内では、生のHDCを使う必要はよっぽどのことがないとありません。HBITMAPなどのハンドルを使うのもです。 CreateCompatibleDC()、SelectObject()、BitBlt()に関しても、CWndやCDCのメンバ関数を使ってください。 いきなりボタンを丸くするのではなく、まず正しくMFCのソースを書くところからはじめたほうがいいと思います。 あと、エラーチェックを適時入れ、関数の成否をチェックしたほうがいいですよ。 どこまで処理がうまく行っているのかもわかりますし。 非矩形ウィンドウを作成するのはそれからで遅くありません。

  • cherry3
  • ベストアンサー率39% (18/46)
回答No.3

MFCについては、あまり詳しくないので分かりませんが、 SDKの場合、GetDCを行うとWM_PAINTメッセージが発生する らしいので(ちょっと記憶があいまいですが)、WM_PAINTメ ッセージ内でGetDCを行うとある意味無限ループみたいな形 になってしまうので、その関係でCPU使用率があがっている のではないかと思います。 参考までに、SDKではWM_PAINTメッセージが来たときは BeginPaint関数、EndPaint関数でデバイスコンテキストの ハンドルを取得します。

yuyama
質問者

お礼

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

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

>OnPaint()でなぜ生のHDCを取得? > >疑問2 >BitBlt()でダイアログ全体に転送しているのはボタンのビットマップでは? > >疑問3 すみません。この部分は無視してください。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.1

CRgnって、メンバ変数にしておかなくても平気でしたっけ? ヘルプより SetWindowRgn 関数が成功すると、システムは、パラメータ hRgn で指定したリージョンを所有します。システムは、このリージョンのコピーを作成しません。したがって、これ以降はこのリージョンハンドルに対して関数を呼び出すべきではありません。特に、このリージョンハンドルを削除しないでください。必要がなくなると、システムはこのリージョンハンドルを自動的に削除します。 あと、なぜ生のHBITMAPやHDCを使用しているのですか? OnPaint()でなぜ生のHDCを取得? 疑問2 BitBlt()でダイアログ全体に転送しているのはボタンのビットマップでは? 疑問3

参考URL:
http://www.microsoft.com/JAPAN/developer/library/jpgdipf/_win32_setwindowrgn.htm
yuyama
質問者

お礼

ありがとうございます。 > OnPaint()でなぜ生のHDCを取得? このようにしないと表示がされなかったのです。 リージョンについてはご指摘の通りですね。

関連するQ&A