メモリデバイスコンテキストとBMPイメージデータ部を関連付けるには? – プログラミング – Home

メモリデバイスコンテキストとBMPイメ...
 
通知
すべてクリア

[解決済] メモリデバイスコンテキストとBMPイメージデータ部を関連付けるには?


ぺこ
 ぺこ
(@ぺこ)
ゲスト
結合: 18年前
投稿: 23
Topic starter  

HDC hdc;
HBITMAP hBitmap;
HDC hMemDC;
CDC* pDc;

pDc = mPictureCtrl.GetDC(); //DC取得
hdc = pDC->GetSafeHdc(); //ハンドル取得
hMemDC = CreateCompatibleDC(hdc); //メモリDCを作成
hBitmap = CreateCompatibleBitmap(hdc, 800, 600);//DCに関連付けられた互換性のあ
るBMPを作成
SelectObject(hMemDC, hBitmap); //ビットマップを選択
//描画
SelectObject(hMemDC,GetStockObject(GRAY_BRUSH));
Rectangle(hMemDC,25,25,50,50);

DeleteObject(hBitmap); //不用になったBMPを削除
BitBlt(hdc, 0, 0, 800, 600, hMemDC, 0, 0, SRCCOPY);//ビットマップ描画

PictureControlにビットマップを描画したく、上記のようなプログラムを
作りました。DC関連の知識が浅く、ここまで作成したのはよいのですが
以下をどのように実現するのかわかりません。ご教授お願い致します。

1.hdc=GetDC(hWnd);
  このようにハンドルを取得した場合、ReleaseDC(hWnd,hdc);
  と、解放することとありますが、上記のようにpDC->GetSafeHdc();と
  した場合、解放は不要なのでしょうか?

2.描画している部分ですが、本来はhMemDCに対してビットマップを描画したいので
す。
  ただ、ビットマップは、BITMAPINFOHEADERと、イメージデータ部(BYTE配列)にな
っています。
  これを高速に描画させる場合の手段がわかりません。


引用未解決
トピックタグ
ぺこ
 ぺこ
(@ぺこ)
ゲスト
結合: 18年前
投稿: 23
Topic starter  

すみません、環境を書き忘れました。
環境はXP、VC2005、MFCです。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

1. 「GetSafeHdc()」は、単にHWNDがNULLでない時にCDCを取得するだけです。
  「GetSafeHdc()」を使っても開放はしなければなりません。
 
  


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

補足、
「GetSafeHdc()」を使えばすべて安全というわけではないので、
 心配のところは、「HWND ==NULL」のところで処理しないようにしたほうがいい
と思います。


返信引用
ぺこ
 ぺこ
(@ぺこ)
ゲスト
結合: 18年前
投稿: 23
Topic starter  

ITOさん
そうですか、わかりました。
mPictureCtrl.GetDC()->ReleaseOutputDC();
として解放するようにしました。
ありがとうございます。

あとはビットマップ・・・


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

>1. 「GetSafeHdc()」は、単にHWNDがNULLでない時にCDCを取得するだけです。
すみません、CDCでなくHDCです。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

すいません、間違っていたら申し訳ないのですけれど。

CDC::GetSafeHdcは、単純にCDC自身が存在していたらメンバー変数のm_hDCを返却するだけ
の実装だと思うのですけれど、この場合もReleaseDCの必要はあるんでしょうか?
内部的に::GetDCを読んでいるとかならわかるんですけれど、メンバー変数を返すだけの
実装の場合、逆にReleaseDCしてしまうと拙いケースもあるような気がするのですが。
例えば、CDCからGetSafeHdcしたものをReleaseDCしてしまった後、CDCのメンバー関数を
呼ぶと拙いのではないかなぁと言う気がします。
CDCのGetSafeHdcの場合はm_hDCの後始末はCDCのデストラクタに委ねた方が良いのでは
と言う気がします。

ちなみにGetSafeHdcで取得したHDCに関しては、NULLチェックは必要ですね。
NULLが返ってきているときは目的の物は取れていない事になりますから。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

>mPictureCtrl.GetDC()->ReleaseOutputDC();
>として解放するようにしました。
これでは解放したことにならんでしょう。
mPictureCtrl.GetDC()としてるのだからmPictureCtrl.ReleaseDC()で開放すべきです。

>2.描画している部分ですが、本来はhMemDCに対してビットマップを描画したいので
>す。
>  ただ、ビットマップは、BITMAPINFOHEADERと、イメージデータ部(BYTE配列)にな
>っています。
>  これを高速に描画させる場合の手段がわかりません。
hMemDCへの描画はSetDIBitsToDeviceでできるでしょう。
毎回呼ぶと効率が悪いので普通DIBSectionに変換します。
よくわからなければCImageクラスを使ってください。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

すみません、PATIOさんのご意見通りだと思います。

CDC::GetSafeHdcの説明に
「出力デバイス コンテキストの m_hDC を取得します。」てありました。

HDCは「pDc = mPictureCtrl.GetDC();」で作成したのを使っていますから、

最後に、mPictureCtrl.ReleaseDC(pDc);
の処理がしてあればいいはずですよね。


返信引用
+
 +
(@ )
ゲスト
結合: 17年前
投稿: 50
 

ビットマップはDDBなので、そのままでは描画できません。

DrawDib***関数郡を使って変換すると楽かな?


返信引用
rin
 rin
(@rin)
ゲスト
結合: 18年前
投稿: 112
 

MFCなんだから、HDCまで掘り下げる必要もないような気がするが・・・

>ただ、ビットマップは、BITMAPINFOHEADERと、イメージデータ部(BYTE配列)にな
>っています。
CBitmap、CImageあたりが楽です。

開放といえば、
>SelectObject(hMemDC, hBitmap); //ビットマップを選択
こっちの返り値を残してないのがちょっと気になる。


返信引用
菟ー
 菟ー
(@菟ー)
ゲスト
結合: 17年前
投稿: 21
 

1に対するアドバイス。
は、不要か。回答でてるね。

2に対するアドバイス。
も不要か。

じゃ蛇足。
DC操作の基本知識ありきの関数ですが、
選択とか解放とか面倒なことは、SaveDC()、
RestorDC()ですべて解消できます。
使い方覚えると便利だけと誤ると・・・。
両刃の刃ですねw


返信引用
ぺこ
 ぺこ
(@ぺこ)
ゲスト
結合: 18年前
投稿: 23
Topic starter  

大変遅くなってしましました。
やらなければならないことが沢山あって、そちらの方に時間を費やして
しまいました。ついでに解決できました。

subaruさん
>mPictureCtrl.GetDC()としてるのだからmPictureCtrl.ReleaseDC()で開放すべきです。
なるほど、言われてみればそうですね。mPictureCtrlからDCを取得わけですからね。
ありがとうございました。

+さん
CreateDIBitmapを使うことで解決しました。
を使い、メモリ上のイメージデータ+α(ヘッダ等)でビットマップを作成し、
ここで得たハンドルをメモリデバイスコンテキストに
SelectObjectすることで描画できました。ありがとうございました。

rinさん
SelectObjectの戻り値ですが、最後に元に戻すように変更してあります。
ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました