アプリ版:「スタンプのみでお礼する」機能のリリースについて

前後の処理は省くとして

1.CreateCompatibleDCでメモリデバイスコンテキスト作成
2.SelectObjectでビットマップオブジェクトを選択
3.BitBltで画像を転送
4.SelectObjectで元のオブジェクトを選択
5.DeleteDCでメモリデバイスコンテキストを削除

サンプルを公開されているサイトここのような書き方になっているのですが
5. の段階で削除するのであれば 4. の元に戻す処理の必要性がわかりません。
※BitBltの直後にSelectObjectで戻し、DeleteDCで削除しており、
 間に余計な処理は入っていません。

上記の処理を行う場合、

1.CreateCompatibleDCでメモリデバイスコンテキスト作成
2.SelectObjectでビットマップオブジェクトを選択
3.BitBltで画像を転送
4.DeleteDCでメモリデバイスコンテキストを削除

このようなやり方だと問題ありますでしょうか?

A 回答 (2件)

1.CreateCompatibleDCでメモリデバイスコンテキスト作成


2.SelectObjectでビットマップオブジェクトを選択
3.BitBltで画像を転送
4.SelectObjectで元のオブジェクトを選択
5.DeleteDCでメモリデバイスコンテキストを削除

2の処理で、選択するビットマップハンドルのユースカウントが1だけインクリメントされます。

4の処理で、選択解除するビットマップハンドルのユースカウントが1だけデクリメントされます。

4の処理が無いと、ビットマップハンドルのユースカウントがインクリメントされたままでデクリメントされません。

そして、ユースカウントが0でないビットマップオブジェクトをDeleteObjectしようとすると、DeleteObjectはエラーを返します。

つまり「ビットマップをDCに割り当てたままだと思い込み、そのビットマップを削除出来なくなる」のです。

この「削除できなかったビットマップ」は、OSを再起動するか、OSをシャットダウンするまでずっと生き残るので、もし「同様の処理が繰り返して行われる」と、最後はシステムリソースが尽きてOS自身がリソース不足で落ちてしまいます。

先ほどの1.~5.の処理の前後には、以下のように「0.」と「6.」の処理がある筈です。普通、別の場所に書いてあるので、見落としがちです。

0.(起動時に1回だけ)CreateBitmap等でビットマップ作成

1.CreateCompatibleDCでメモリデバイスコンテキスト作成
2.SelectObjectでビットマップオブジェクトを選択
3.BitBltで画像を転送
4.SelectObjectで元のオブジェクトを選択
5.DeleteDCでメモリデバイスコンテキストを削除

6.(終了時に1回だけ)DeleteObjectでビットマップ破棄

上記の6.の処理を確実に成功させ、確実にビットマップを破棄するためには、4.の処理でDCとの紐付けを解除する必要があるのです。

上記の仕様は最新のWindowsでも変わっていません。4.の処理は必ず必要です。

しかし、このような「DCとの紐付けの解除忘れ」をする人が多かった為か、最近のWindowsでは紐付けられたDCが削除済みであれば、DeleteObjectがエラーを返さないでオブジェクトを破棄出来るように改良されています(「解除を忘れてる」には違わないので、忘れても動いちゃう事が良い事なのかどうか疑問ですが…)
    • good
    • 0

Windows 3.1/95/98の時代では、そうしないとリソースを食いつぶしOSが不安定になることが多かった気がします。


2000/XPになってからはリソースの管理がうまくなっているようなので滅多に不安定になりませんがね。

おそらくビットマップオブジェクトを選択したままデバイスコンテキストを解放してしまうと、ビットマップオブジェクトが解放できない、ということだと思います。つまりお互い必要とされている、というフラグがたったまま片方が解放されると、もう一つが残されたままになる。。

やっぱちゃんとお行儀良くした方がよいですよ 笑
    • good
    • 0

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