dポイントプレゼントキャンペーン実施中!

MFCでJPEG画像を表示するプログラムを OnPaint() の中に書いていたのですが・・・

 :
bool m_bImageMemDCInit;
CImage m_Image;
CBitmap *m_pImageBitmap;
CDC m_ImageMemDC;
 :
 :

void CChildView::OnPaint()
{
 CPaintDC dc(this);

 if(!m_bImageMemDCInit){
  m_bImageMemDCInit = true;
  // イメージをロード
  m_Image.Load("test.jpg");
  m_pImageBitmap = CBitmap::FromHandle(m_Image);
  m_ImageMemDC.CreateCompatibleDC(&dc);
  m_ImageMemDC.SelectObject(m_pImageBitmap);
 }
 // 描画
 dc.BitBlt(0, 0, 256, 256, &m_ImageMemDC, 0, 0, SRCCOPY);
}


このように、Load や CreateCompatibleDC などの初期化にあたる処理を、起動時に1度しか処理しないように書いています。
しかし、このプログラムではあまりに汚い。どうにかして PreCreateWindow などの初期化関数内に書きたいのですが、CreateCompatibleDC 関数で CPaintDC* を渡す必要があるので、OnPaint 関数内に書かざるを得ないのです。
(Loadだけなら初期化関数内に移せるのですが・・・)

いっそ CreateCompatibleDC を再描画のたびに呼んでもいいのでは? と思い、やってみると異常終了してしまいました。

また、CPaintDC dc(this); を PreCreateWindow 関数内に書いても異常終了しました。


どなたかスマートな方法をご存知でしたら、ご指導願います m(_ _)m

A 回答 (1件)

PreCreateWindowで CPaintDC(this)としてもエラーになるのは当然です


CPaintDCはウィンドウハンドルを必要とします
しかし PreCreateWindowではまだウィンドウハンドルは作成されていません
# ウィンドウ作成の前処理なので当然ですが ・・・

WM_CREATEメッセージに対するイベントハンドラOnCreateかCreateで処理します

OnCreateでやるなら
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CView::OnCreate(lpCreateStruct) == -1)
    return -1;

  // TODO: ここに特定な作成コードを追加してください。

  return 0;
}
といったスケルトンを VC++が作成してくれるので TODOコメントの部分で DCの初期化処理を行いましょう
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CView::OnCreate(lpCreateStruct) == -1)
    return -1;

  // TODO: ここに特定な作成コードを追加してください。
  m_Image.Load("test.jpg");
  m_pImageBitmap = CBitmap::FromHandle( m_Image );
  CClientDC dc(this);
  m_ImageMemDC.CrateCompatibleDC( &dc );
  m_ImageMemDC.SelectObject( m_pImageBitmap );

  return 0;
}
といった具合です

本来は m_ImageMemDC.SelectObject( m_pImageBitmap ) の戻り値も記憶しておいて m_ImageMemDCを破棄する際に選択を元に戻すのがセオリーです
    • good
    • 0
この回答へのお礼

うまくいきました、ありがとうございます!

お礼日時:2008/05/09 12:44

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