• ベストアンサー

ダイアログの表示と同時に、ピクチャーボックスを塗る方法

あるサイトの過去ログで以下を見つけました。 エラーは出ませんが、何も起こりません。 このコードは何をしようとしているのでしょうか? ************************* ダイアログ上にピクチャーボックスを配置して、ダイアログの表示と同時に、ピクチャーボックスを塗る方法。 まず、ピクチャコントロールをClassWizardのメンバ変数タブによりm_pictureとして実態を作成します。 その後、 class CPictureDlg { private: CBitmap m_bitmap; // ... }; BOOL CPictureDlg::OnInitDialog() { CDialog::OnInitDialog(); // ... CDC desktopDC; desktopDC.Attach ( ::GetDC ( NULL ) ); CDC memDC; memDC.CreateCompatibleDC ( &desktopDC ); m_bitmap.CreateCompatibleBitmap ( &desktopDC, 100, 100 ); CBitmap *pOldBitmap = memDC.SelectObject ( &m_bitmap ); CRect rcPicture ( 0, 0, 100, 100 ); CBrush brush; brush.CreateStockObject ( WHITE_BRUSH ); memDC.FillRect ( &rcPicture, &brush ); memDC.SelectObject ( pOldBitmap ); m_picture.SetBitmap ( ( HBITMAP ) m_bitmap.GetSafeHandle () ); ReleaseDC ( &desktopDC ); memDC.DeleteDC (); }

質問者が選んだベストアンサー

  • ベストアンサー
noname#5537
noname#5537
回答No.2

ピクチャボックスのタイプが「ビットマップ」になってますか? ダイアログエディタで,ピクチャボックスの「プロパティ」を見てください。 # ウィンドウスタイルで言えば SS_BITMAP です。 そのコードは直接ピクチャボックスを塗っているわけではありません。 まずビットマップを作成し, 作成したビットマップをピクチャボックスにセットする(m_picture.SetBitmap のところ)コードです。 ピクチャボックスのタイプが「ビットマップ」になっていれば, セットしたビットマップを表示してくれます。 タイプが「ビットマップ」でなければ何もおこりません。

参考URL:
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclib/html/_mfc_cstatic.3a3a.setbitma
VitaminBB
質問者

お礼

回答ありがとうございます。 プロパティをビットマップにすることで、ちゃんと白色でピクチャーボックスが塗りつぶされました。 今一つこのコードがなにをしているのか分かりません。 (結果は分かりましたが。) 申し訳ありませんが、各行が何をしているのが、ざっくりの殴り書きで良いので教えていただけないでしょうか?

その他の回答 (4)

noname#5537
noname#5537
回答No.5

#4 の訂正です。最後のほうが意味不明になってますね。 > CDC のデストラクタでは DeleteObject が呼ばれるようになっているので, > 結局,GetDC(NULL) で取得した DC に対して,DeleteObject を呼ぶことになってしまいます。 DeleteObject ではなくて,DeleteDC の間違いでした。

noname#5537
noname#5537
回答No.4

まず #3 で書いたコードについてですが, CreateCompatibleBitmap にメモリ DC を渡したのがいけなかったようです。 # MSDN によると,メモリ DC を渡した場合,モノクロのビットマップが作成されます。 冒頭部分を以下のように変更してください。 CClientDC dc(this); CDC memDC; memDC.CreateCompatibleDC(&dc); m_bitmap.CreateCompatibleBitmap(&dc, 100, 100); > Attachは何をしているのでしょうか? CDC::Attach はデバイスコンテキストのハンドル(HDC 型)を, CDC のオブジェクトに結び付けます。 ::GetDC(NULL) で画面全体を表す DC を取得していますが,戻り値はハンドル(HDC 型)です。 しかしながら,CreateCompatibleDC や CreateCompatibleBitmap には CDC* を渡さなければならないので, desktopDC.Attach で,desktopDC(CDC 型)にハンドル(HDC 型)を結び付けているのでしょう。 ただ,元のコードには少し問題があります。 CDC のデストラクタでは DeleteObject が呼ばれるようになっているので, 結局,GetDC(NULL) で取得した DC に対して,DeleteObject を呼ぶことになってしまいます。 # 実際には DeleteDC が失敗するだけなので実害はないようですが。

VitaminBB
質問者

お礼

いろいろ親切にありがとうございました。 PGはコードの変更にて問題無く動きました。 Attachについては相変わらず良く分かりません。 yoppiiさんはオブジェクトに結びつけると説明されています。 その他本で調べても、Attach関数でアタッチする。と書いてあり結局Attachそのものの意味は分かりませんでした。 前後のコードなどから分かるべきなのでしょうが、今回はまだ実力不足ということで諦めます。

noname#5537
noname#5537
回答No.3

元のコードと若干変えてあります。 // メモリ DC (デバイスコンテキスト)を作成する CDC memDC; memDC.CreateCompatibleDC(NULL); // ビットマップを作成する m_bitmap.CreateCompatibleBitmap(&memDC, 100, 100); // 作成したビットマップをメモリ DC で選択 // 以後 memDC に描画した結果が m_bitmap に反映されるようになる CBitmap *pOldBitmap = memDC.SelectObject(&m_bitmap); // ここで,memDC のメンバ関数を用いて描画する。例えば, memDC.FillSolidRect(0, 0, 100, 100, RGB(255,255,0)); // 黄色一色に塗る // ビットマップの選択を元に戻す(m_bitmap は選択から外れる) memDC.SelectObject(pOldBitmap); // 作成したビットマップをピクチャボックスにセットする m_picture.SetBitmap((HBITMAP)m_bitmap.GetSafeHandle());

VitaminBB
質問者

お礼

回答ありがとうございます。 yoppiiさんの若干変えられたコードでは、エラーは出ませんが、何も描かれませんでした。 また、自分でも色々調べているのですが、一番分からないコードが desktopDC.Attach ( ::GetDC ( NULL ) ); です。 Attachは何をしているのでしょうか? 何度も済みませんが、お分かりでしたらお教えください。

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

Windowsのメッセージについて勉強しなおしましょう。 WM_CREATEや、WM_INITDIALOGのタイミングでは、ウィンドウはまだ表示されていません。 この状態で描画を行っても表示されていないので意味がありません。 Windowsから、描画を行うタイミングで送られるメッセージがWM_PAINTです。 もちろん、ウィンドウが表示されようとしているときにも送られてくるので描画処理はここで問題ありません。 OnDrawやOnPaintがWM_PAINTに対応するメッセージハンドラになります。 描画した絵がちらつくとかいう話であれば、別ですが。

VitaminBB
質問者

お礼

回答ありがとうございます。 OnPaintでもやってみましたが、何も起こりませんでした。

関連するQ&A