

お世話になります。
Borland C++ 5.5.1 for Win32で簡易な画像ビュアーを開発しています。
基本的な動作は完成したのですが、ある条件下で発生する問題を回避するために、メモリデバイスコンテキストを用いようと考えています。
ところが、後述のように変更したところ、画像がまったく表示されなくなりました。(ウィンドウ背景色で塗りつぶされたままです。一瞬たりとも表示されません。)
Windowsプログラムに慣れていないため解決に難儀しています。
どなたか原因と対策をご教示くださいますようよろしくお願いします。
//////////////////////////
//変更前 画像表示される//
//////////////////////////
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
/* ~省略(画像処理)~ */
StretchDIBits(hdc,~,SRCCOPY);//処理した画像をウィンドウへ
EndPaint(hWnd, &ps);
break;
////////////////////////////
//変更後 画像表示されない//
////////////////////////////
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hmemdc = CreateCompatibleDC(hdc);
/* ~省略(画像処理)~ */
StretchDIBits(hdc,~,SRCCOPY);//処理した画像をMemoryDCへ
BitBlt(hdc, 0, 0, rc.right, rc.bottom, hmemdc, 0, 0, SRCCOPY);//MemoryDCからウィンドウへ(rcはクライアント領域)
DeleteDC(hmemdc);
EndPaint(hWnd, &ps);
break;
No.4ベストアンサー
- 回答日時:
StretchDIBitsは、hdcへ出力しているぞ
hmemdcへは何も出力していないみたいだぞ
その後、BitBltでhmemdcをhdcへ出力しているから
何にも表示されないのだ
メモリデバイスコンテキストでやりたいなら、
1.CreateCompatibleBitmapで空のHBITMAPを作成する
2.SelectObject(hmemdc, hBitmap)とかで、hmemdcに
空のHBITMAPをくっつける
(これで、hmemdcへの描画処理がhBitmapのメモリに
描かれることになる)
3.StretchDIBitsでhmemdcに出力する
(画像データ -> hBitmap)
4.BitBltでhmemdcをhdcへ出力する
(hBitmap -> ディスプレイ)
※hBitmapとhmemdcの解放を忘れないでちょーだい!
解放する順番によってメモリリークがおきちゃうぞ
後に作成したものを先に解放するのだー
おちまい
動きました!表示できました!
SelectObject意味や役割の理解が一歩進みました。
目からウロコだのなんだの色々落ちまくりです。
回答ありがとうございました。
No.3
- 回答日時:
>とりあず付け焼刃の知識でSelectObjectを使ってみたのですが、やはり表示されません。
言葉で説明するのは難しいですね。
おそらく、StretchDIBitsでの画像の拡縮に時間がかかるから、画像の読み込み時に拡縮をやって、あとはBitBltでできるだけ高速に描画させるという方針だと思います。
だとすると、CreateCompatibleBitmapでビットマップを作成するのがいいです。CompatibleBitmapはVRAMに空きがあればそこに置かれるようなので、BitBltが桁違いに速いです。
1.画像の読み込み
HBITMAP imageBm = 画像の読み込み();
HDC dispDC = GetDC(NULL);
HDC memDC = CreateCompatibleDC(dispDC);
HBITMAP memBm = CreateCompatibleBitmap(dispDC, IMAGE_WIDTH, IMAGE_HEIGHT);
HGDIOBJ prevMemBm = SelectObject(memDC, (HGDIOBJ)memBm);
StretchDIBits(memDC, ...);// memDCを通してmemBmにimageBmを書き込む
DeleteDC(dispDC);
DeleteObject((HGDIOBJ)imageBm);
2.WM_PAINT
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
BitBlt(hdc, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, memDC, 0, 0, SRCCOPY);
EndPaint(hwnd, &ps);
3.画像の開放
SelectObject(memDC, prevMemBm);
DeleteDC(memDC);
DeleteObject((HGDIOBJ)memBm);
回答ありがとうございます。
すいません、お礼がすっかり遅くなってしまいました。(^^;
すばらしい!
必要な関数や変数が一目瞭然で、非常に参考になります。
残念ながら勉強不足で、まだ応用できるレベルに達していないのですが、勉強を終えて応用が利くようになったらぜひ試してみます。
回答本当にありがとうございました。
No.2
- 回答日時:
省略されている部分にあるのかもしれませんが、
メモリDCの書き込み対象は、そのメモリDCにSelectObjectされたビットマップになります。
CreateDIBSectionなどで作成することが多いです。
SelectObjectで戻ってきたビットマップを再度SelectObjectしないと、DeleteDCは失敗します。
アドバイスありがとうございます。
SelectObjectですか。今は使っていないです。
これが原因でしょうか。
とりあず付け焼刃の知識でSelectObjectを使ってみたのですが、やはり表示されません。というか、修正量が多くてもはやどこまで正常なのかさえ分からなくなってしまってるんですけど。
もっと簡単なものかと思っていたのですが、やはり何事も基本を抑えないとだめですね。。。
今回はいったん質問を締め切り、改めて勉強しなおして出直します。
そのときはまたよろしくお願いします。
No.1
- 回答日時:
ふつうはWM_PAINTなんかでそんなことしないんですけどね。
描画にコストがかかるからこそメモリデバイスコンテキストを使うんですから。WM_PAINTの中ではBitBltのみ。
CreateCompatibleDCで元にするHDCはBeginPaintではなくGetDCとかですかね。
http://www13.plala.or.jp/kymats/explain/gameprog …
参考URL:http://www13.plala.or.jp/kymats/explain/gameprog …
アドバイスありがとうございます。
>ふつうはWM_PAINTなんかでそんなことしないんですけどね。描画にコストがかかるからこそメモリデバイスコンテキストを使うんですから。
勉強不足による設計思想のまずさから、今となっては現在の設計を変更するのが困難な造りになってしまっています。(実は今日も挑戦してみたのですが、連鎖的に問題が増える一方です。根本的解決には設計からやり直した方がよさそうなので、今のところは見送ろうと思います。)
>WM_PAINTの中ではBitBltのみ。
>CreateCompatibleDCで元にするHDCはBeginPaintではなくGetDCとかですかね。
おお!!
前者は(前述の理由で)後に回すとして、とりあえず
hMemDC = CreateCompatibleDC(GetDC(hWnd));
としてみました・・・・が、まだ同じ状況です。
うーん、作り直したほうが早いかなぁ。。。
アドバイスおよび細部にまでわたるチェックありがとうございます。
これから参考サイトでじっくり腰を据えて勉強します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
画面がチカチカする
-
画像処理 ビットマップ ダブ...
-
デバイスコンテキストに関して2...
-
エクセルで作った新しいウイン...
-
コンボボックス内の文字サイズ変更
-
「アイテムは収集されました」...
-
グラフの交点の求め方(Excel)
-
コントロールの書式設定で、“コ...
-
ダイアログのスクロールバー
-
他のウィンドウのボタンを自動...
-
エクセルのコントロールツール...
-
勝手にウィンドウが開いて止ま...
-
フォームでPDFを表示させた...
-
MSNのフォントサイズを設定する...
-
[VB.net] DataGridViewの列ヘッ...
-
検索の画面がでなくなってしま...
-
ウインドウサイズを変更しても...
-
VB6,リストボックスの特定行の...
-
Exelを開く時に困っています
-
皆さん、おはようございます♪ ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンテキスト依存とは?
-
メモリデバイスコンテキストを...
-
画面がチカチカする
-
Windowsプログラミング 画面描...
-
Rectangleで、リソースが解放さ...
-
ダイアログにビットマップを貼...
-
VBでデスクトップアクセサリを...
-
ちらつきについて
-
画像処理 ビットマップ ダブ...
-
C 多角形を半透明に塗る方法
-
VC++でopenGLを利用したい...。
-
ハードコピーをプログラムから...
-
WindowsAPIでの画像表示について
-
SetWindowRgn()関数について。
-
WinAPIでスクリーン画像を映し...
-
ビットマップの表示について
-
VC++のTextOutの再描画の仕方
-
ダブルバッファの作り方
-
usbデバイスとの通信
-
BitBlt関数について教えてください
おすすめ情報