

お世話になります。
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で質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- その他(OS) Windowsで大量の画像サイズを半自動で変更する方法 6 2023/02/17 08:45
- Windows 10 2つのウィンドウ選択時の表示について 10 2023/07/25 08:48
- Excel(エクセル) エクセル、画像ファイル名の書かれたセル(複数個所)に画像を一括で表示させる方法 1 2023/04/19 00:19
- Excel(エクセル) エクセル VBA For Next 繰り返しの書き方を教えてください 6 2022/09/01 14:11
- HTML・CSS 詳しい方に質問です。 早急に解決したいと思っています。 ポートフォリオをMacBook で作成したと 2 2023/05/12 17:40
- PHP アップロード画像数でCSSを分けることに成功したのですが、画像の横に文字を並べることが出来ません。 3 2023/07/28 17:16
- Excel(エクセル) エクセルVBA 特殊フォルダのパスを取得の方法を教えてください 3 2022/09/02 13:14
- Android(アンドロイド) AQUOS ZEROの使い方教えて下さい 2 2022/03/27 17:21
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ちらつきについて
-
Windowsプログラミング 画面描...
-
ビットマップの表示について
-
グラフの交点の求め方(Excel)
-
Minecraft 統合版(PC)の描画距...
-
コントロールの書式設定で、“コ...
-
エクセルで作った新しいウイン...
-
WINAPI 他のウインドウを重ね...
-
pygameで画像を描画する方法を...
-
TreeView表示がおかしいです。
-
リッチテキストのフォント
-
表示する方法
-
Paint Shop Pro で
-
勝手にウィンドウが開いて止ま...
-
仮想メモリが移動できない
-
リストコントロールの文字の大...
-
ウインドウが閉じたことを知る方法
-
ExcelVBA上で特定の座標への画...
-
PCで細かな目盛りを作図する方...
-
「アイテムは収集されました」...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンテキスト依存とは?
-
PlgBltでの透過
-
OpenGLでウィンドウハンドルの取得
-
メモリデバイスコンテキストを...
-
GetDC()とCreateCompatibleDC()
-
ちらつきについて
-
VBでFD、USBの有効・無効...
-
Active Basic デバイスコンテ...
-
ExtTextOut
-
デバイスコンテキストとデバイ...
-
VC++のTextOutの再描画の仕方
-
画面がチカチカする
-
ハードコピーをプログラムから...
-
メモリデバイスコンテキスト&...
-
C++でBMP解析
-
C 多角形を半透明に塗る方法
-
領域を塗りつぶしたい
-
コントロール内の文字の背景色
-
GetPixelに使うHDCの作り方
-
丸いボタンの表示でCPU100%
おすすめ情報