

お世話になります。
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も見ています
-
それもChatGPT!?と驚いた使用方法を教えてください
仕事やプライベートでも利用が浸透してきたChatGPTですが、こんなときに使うの!!?とびっくりしたり、これは画期的な有効活用だ!とうなった事例があれば教えてください!
-
おすすめの美術館・博物館、教えてください!
美術館・博物館が大好きです。みなさんのおすすめをぜひお聞きしたいです。
-
最強の防寒、あったか術を教えてください!
とっても寒がりなのですが、冬に皆さんがされている最強の防寒、あったか術が知りたいです!
-
AIツールの活用方法を教えて
みなさんは普段どのような場面でAIツール(ChatGPTなど)を活用していますか?
-
集中するためにやっていること
家で仕事をしているのですが、布団をはじめ誘惑だらけでなかなか集中できません。
-
BitBltについて。
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・「これはヤバかったな」という遅刻エピソード
- ・初めて自分の家と他人の家が違う、と意識した時
- ・いちばん失敗した人決定戦
- ・思い出すきっかけは 音楽?におい?景色?
- ・あなたなりのストレス発散方法を教えてください!
- ・もし10億円当たったら何に使いますか?
- ・何回やってもうまくいかないことは?
- ・今年はじめたいことは?
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ハードコピーをプログラムから...
-
デスクトップイメージをメモリ...
-
ダブルバッファの作り方
-
コンテキスト依存とは?
-
領域を塗りつぶしたい
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
コンボボックス内の文字サイズ変更
-
フォントの大きさ
-
Minecraft 統合版(PC)の描画距...
-
グラフの交点の求め方(Excel)
-
コントロールの書式設定で、“コ...
-
VB.NET2005 TextBox 高さ(Heig...
-
[VB.net] DataGridViewの列ヘッ...
-
ActiveXコントロールを.NETにイ...
-
フォームでPDFを表示させた...
-
DateTimePickerでに年月までし...
-
エクセルである行が急に消えて...
-
VBAのフォント変更(エクセルか...
-
VB6,リストボックスの特定行の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
画面がチカチカする
-
BitBlt関数について教えてください
-
コンテキスト依存とは?
-
GetDC()とCreateCompatibleDC()
-
メモリデバイスコンテキストを...
-
C 多角形を半透明に塗る方法
-
VBでFD、USBの有効・無効...
-
画像処理 ビットマップ ダブ...
-
ダイアログにビットマップを貼...
-
Windowsプログラミング 画面描...
-
コントロール内の文字の背景色
-
領域を塗りつぶしたい
-
OpenGLでウィンドウハンドルの取得
-
Rectangleで、リソースが解放さ...
-
Win32APIにて、アイコンの情報...
-
ビットマップファイルの印刷方...
-
ビットマップ(表示速度とサイズ)
-
ハードコピーをプログラムから...
-
VBでデスクトップアクセサリを...
-
VC++でBitmapとText文字を表示...
おすすめ情報