土曜の昼、学校帰りの昼メシの思い出

はじめまして、質問させてください。

VC++ 2005 MFC で開発しております。

Picture Control(DDX CStasic型)に
イメージ(外部ファイル JPG)を静的に描画させたいのですが
方法がわかりません。

お詳しい方がおられましたら、ご教授お願いいたします。

ちなみに
CImageを使用して描画はできるのですが
その場合、OnPaintをオーバーライドして
描画更新処理を書かないと一度だけ描画されて終わって
しまうと思います。

CStaic変数にロードしたら
再度ロードされるまで
ずっと描画させていたいです。

以上になります。
宜しくお願いいたします。

A 回答 (7件)

SelectObjectで選択するとその時まで選択されていたデバイスハンドルを返してきます


そのハンドルを一時変数に保存しておいて描画後に戻してやるのです

CBitmap* pOld = m_dcMem.SelectObject( &m_bmpMem );
といった具合で記憶して描画処理を行います
使用後に
m_dcMem.SelectObject( pOld );
といった具合にして m_bmpMemをDCからはずします
この後
m_ctlImage.SetBitmap( m_bmpMem );
といった具合に選択してやればできると思います

CStaticのTypeはビットマップで無いとSetBitmapでイメージを表示しません
    • good
    • 0
この回答へのお礼

redfox63 様

ご教授ありがとうございました。
おかげさまで実装できました。

お礼日時:2008/01/17 09:59

出力先のDCを指定せずに描画するのは不可能でしょう



CImage::StretchBltではどのタイプも 第一引数でHDCを必要とします

SetBitmapではビットマップハンドルを指定するだけですから
その描画は windows任せです
Windowsはビットマップハンドルにしたがって取得できるBitmap構造体の情報で描画するのですから 拡大縮小はできないと思います

メモリー上にDCなどを作成して StretchBltを使う方向で考えたほうがよさそうですよ

GetDC()でコントロールなどから取得して
CreateCompatibleDC()でコンパチDCを作成
これに描画範囲をカバーできるBITMAP(CBitmap)をSelectObjectで選択しておいて
StretchBltで描画
SelectObjectでコンパチDCからビットマップを外して
ビットマップハンドルをコントロールのSetBitmapで設定
といった具合でしょう

または CImageの内部で使われている GDI+のGraphicsオブジェクト経由でやるとか ・・・
    • good
    • 0
この回答へのお礼

redfox63 様

何度もご回答ありがとうございます。

教えていただいた方法で実装してみましたが
うまくいきませんでした。

以下実装内容
--------
メンバ
CDC m_dcMem;
CBitmap m_bmpMem;
CImage m_imgThumbnail;
CStatic m_pictThumbnail;
--------
CDC *pDC = m_pictThumbnail.GetDC();

m_dcMem.DeleteDC();
m_dcMem.CreateCompatibleDC( pDC );

m_bmpMem.DeleteObject();
m_bmpMem.CreateCompatibleBitmap( pDC, 100, 100 );//m_sizeImage.cx, m_sizeImage.cy );
m_dcMem.SelectObject( &m_bmpMem );

m_imgThumbnail.Load( _T("jpgフルパス") );
m_dcMem.SetStretchBltMode( COLORONCOLOR );
m_imgThumbnail.StretchBlt( m_dcMem.GetSafeHdc(), 0, 0,
100, 100, 0, 0, m_imgThumbnail.GetWidth(), m_imgThumbnail.GetHeight(), SRCCOPY );

//m_pictThumbnail.SetBitmap( &m_bmpMem );
ReleaseDC( pDC );
--------

>SelectObjectでコンパチDCからビットマップを外して
という箇所がよくわかりません。

この方法の場合、
CStaticのプロパティタイプは「フレーム」でもよろしいのでしょうか?

お手数おかけいたしますが、
宜しくお願いいたします。

お礼日時:2008/01/16 10:18

まさかとは思いますが コントロールのタイプが『フレーム』のままではないですよね


Typeプロパティを『ビットマップ』に変更してますよね ・・・
    • good
    • 0
この回答へのお礼

redfox63 様

恥ずかしながら『フレーム』のままでした。
描画できました。
ありがとうございます。

最後にもうひとつ教えていただきたいのですが、
CImageのStretchBltを使用して縮尺描画できると思うのですが、
OnPaint()等、CDC(デバイスコンテキスト)を取得して
コピー先のDCを指定せずにSetBitmap()で縮尺or拡大は可能でしょうか?

検討違いでしたら申し訳ありませんが、
宜しくお願いいたします。

お礼日時:2008/01/15 19:58

どうも 頭がぼけているようです … (いまだに正月ボケ)



リファレンスで確認したところ
以前のイメージの破棄はDestroyで良いようです ・・・ 内部で ::DeleteObjectを呼んでいました

当方の環境では

m_ImageTemp.Destroy();
m_ImageTemp.Load("ファイルパス");
m_ctlImage.SetBitmap( m_ImageTemp ); // ...(1)
といった具合でうまく表示されます

(1)にブレークポインタを設定して ステップ実行した際に
CImageの operator HBITMAPで m_hBitmapを返され
初回ならCStaticの SetBitmapで NULLハンドルが返されます
2回目以降は 前回のイメージハンドルが返されます

Loadで失敗するなら 例外がスローされるだろうし ・・・
    • good
    • 0

すみません DeleteObjectはCBitmapなどの CGDIObjectからの継承時です



CImageの場合 Detachでハンドルを開放です
// ハンドルが有効なら
if ( m_Imagetemp.m_hBitmap )
  m_ImageTemp.Detach();
m_ImageTemp.Load("ファイルパス");

m_ctlImage.SetBitmap( m_ImageTemp );
といった具合です

スタティックコントロールのIDは IDC_STATIC以外のものですよね
IDC_STATICではコントロールの判別不能になると思います
    • good
    • 0
この回答へのお礼

redfox63 様

m_hBitmapはprivateメンバだと思うのですが...

Detach()してもしなくても描画されません。

スタティックコントロールIDは IDC_STATICではありません。
DDX変数自体作れませんから。

教えていただいたサンプルソースで実際にイメージを
描画できているのでしょうか?

以上になります。
宜しくお願いいたします。

お礼日時:2008/01/15 17:30

> m_ImageTemp.Destroy();


Destroyで破壊してしまってはいけません

m_ImageTemp.DeleteObject();
で 以前読み込んだイメージを破棄するだけです
その後
m_ImageTemp.Loadでファイルから読み込みます

これをスタティックコントロールの コントロール変数を介して SetBitmapメソッドを使って イメージハンドルを設定します
    • good
    • 0
この回答へのお礼

redfox63 様

ご回答ありがとうございます。

DeleteObjectはCImageのメソッドではないですよね?

CImageをメンバで保持し、
CStaticコントロールのDDX変数もメンバで保持して
実装しています。

その上で描画されませんでした。

ちなみに
現在読み込んでいるイメージは破棄せずに(初回1イメージのみ)
でも描画できませんでした。

以上になります。
宜しくお願いいたします。

お礼日時:2008/01/15 16:38

CImageクラスの変数をその描画したいクラスに用意して CStaticのコントロールのSetBitmapを実行すれば良いでしょう



クラスに
CImage m_ImageTemp;
といった具合に宣言しておきます

画像を指示する関数で
// 以前読み込んだイメージを除去
m_ImageTemp.deleteObject();
m_ImageTemp.Load( ファイルパス );

m_ctlStatic.SetBitmap( m_ImageTemp );
といった具合です

イメージを保持する変数をローカルにしてしまうと再描画の情報などが失われてしまうので気おつけましょう
    • good
    • 0
この回答へのお礼

redfox63 様

ご回答ありがとうございます。

教えていただいたとおり実装してみましたが
描画できませんでした。

ちなみに
m_ImageTemp.deleteObject();
m_ImageTemp.Destroy();
ですよね?

お礼日時:2008/01/15 15:35

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

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報

このQ&Aを見た人がよく見るQ&A