アイコンハンドルの破棄について

解決


ぴょぴょ  2007-08-01 06:56:40  No: 65931

単刀直入にお聞きしたいですが Win32 API の ExtractIconEx() 関数で
取得したアイコンのハンドルはプログラム終了時に DestroyIcon() 関数で
破棄しないといけませんか?
それとも破棄はしなくてもいいのか?
どちらでしょうか。


ぴょぴょ  2007-08-01 07:09:47  No: 65932

追加。

リソースのアイコンを LoadIcon、LoadImage で読み込んだときは
破棄しなくてもいいですよね?


wclrp ( 'o')  2007-08-01 07:58:32  No: 65933

リソースのアイコンを LoadIcon、LoadImage で読み込んだときは
破棄しなくてもいいですよ。


ぴょぴょ  2007-08-01 13:59:02  No: 65934

>リソースのアイコンを LoadIcon、LoadImage で読み込んだときは
>破棄しなくてもいいですよ。
有り難うございます。

MSDN マニュアルを読んだら ExtractIconEx() は必ず DestroyIcon() で
破棄するようにと明記されていました。
確認できました。これは。

あともう一つ。
SHGetFileInfo() で取得したアイコンのハンドルは利用しなくなった時点で
破棄すべきなのでしょうか?

日本語のマニュアルがなく上手く確認できないのですが
>If SHGetFileInfo returns an icon handle in the hIcon member of the SHFILEINFO
>structure pointed to by psfi, you are responsible for freeing it with
>DestroyIcon when you no longer need it.
と書かれています。
「DestroyIcon」とか「longer need it」となっているのですが破棄すべきでしょうか?
前どこかのサイトには破棄しなくてもいいよう事が書いてあったので
ここで詳しい方にどうすべきかをお聞きしたいです。
お願いします。


tetrapod  2007-08-01 18:16:20  No: 65935

http://msdn2.microsoft.com/en-us/library/ms647761.aspx
英語にそのまま書いてある通りぢゃん。超訳してみる
< psfi で指す SHFILEINFO 構造体の hIcon メンバに SHGetFileInfo が 
< icon ハンドルを返す場合、それが不要になった時 DestroyIcon で
< 破棄するのはあなたの責任です。

> 前どこかのサイトには破棄しなくてもいいよう事が書いてあったので
どこか知らないけど、本家本元の解説のほうを信じるのが筋だろうね

つまるところ、こーいう話って良く聞く
「特定条件で malloc() したメモリを free() しなくていいか」論争
int main() {
  char* p=malloc(1000);
  return 0;
}
ここで free せずに終了してるのは是か非か?と同等な話しぢゃないの

そのアイコンハンドルをプログラム終了時点までずっと使い続けるか?
単に話はそれだけだと思うのだが。
・使い続けるなら DestroyIcon せずに終了しても問題ないだろう
  (むしろ破棄→再取得のコストがかかるのが無駄っぽい)
・使い続けないなら適宜破棄しなきゃならん。リソースリークするから。

LoadImage も LR_SHARED 非指定の時は
・使い終わったら破棄するといい (メモリの節約になる)
・明示破棄しなくてもプログラム終了時点で破棄される
とある。ごく普通に malloc/free と同じ挙動をするようだぞ


ぴょぴょ  2007-08-01 22:48:37  No: 65936

>どこか知らないけど、本家本元の解説のほうを信じるのが筋だろうね
確かにそうですね。
そこで本家ではどうかかれているか探してみましたがシェル関数全般に
日本語での解説ページがありません。
辛いよ〜。日本語でさえままならないから僕。

分かりやすく解説してくれたのでやっと意味が分かりました。

>・使い続けるなら DestroyIcon せずに終了しても問題ないだろう
>  (むしろ破棄→再取得のコストがかかるのが無駄っぽい)
問題ないのね。
多分どこかのサイトでも使い方によっては破棄しなくてもいいと
書かれていたのかもしれない。今は良く覚えていないけど。

>・使い続けないなら適宜破棄しなきゃならん。リソースリークするから。
一時的に必要で直ぐに不要になる場合は破棄すべきなのは分かるんです。

>ごく普通に malloc/free と同じ挙動をするようだぞ
ここの部分を知りたかったのです。
以前にランチャープログラムを作ったときに SHGetFileInfo() で
アイコンを起動時に取得してプログラム終了時にハンドルを破棄すべきか
ずっと不安でした。

SHGetFileInfo() で取得したアイコンについてはずっと使い続ける使い方ですので
プログラムの終了時に明示的にアイコンのハンドルを破棄しなくて良いという事で
よろしいんですよね。了解しました。やっと不安解消しました。
有り難うございました。


tetrapod  2007-08-02 00:34:24  No: 65937

んっと、誤解があるといけないので蛇足

> プログラムの終了時に明示的にアイコンのハンドルを破棄しなくて良い
破棄してもいいんだ。
破棄しなくてもいいんだ。

なぜなら、プログラム終了時にOSが行う終了処理の一環として
開いたままのアイコン・ファイル・リソース・その他もろもろの
閉じる処理(廃棄など)が行われるから。
自分で破棄すれば、OSが破棄する必要が無いというだけのこと。
自分で破棄処理しても、OSに任せても、結果は同じことになる。
# LR_SHARED を使った場合は例外で、OSに廃棄処理を任せる必要がある

LoadImage にかぎったことぢゃないんだが
OSが面倒見てくれる範囲のものなら、OSに後始末をお任せする
ことも可能である、と、そういう話なわけだ。
OSが面倒見てくれない範囲のものならば、自分で後始末するのが必須
ネットワークセッションを閉じるとかが該当するわけね。
通信相手は自分のOSぢゃないからさ。

例:
1.電話をかけました (初期化処理)
2.いろいろと会話を交わしました (本処理)
ここまではとりあえず良いとして、用件が終了したので
3-a.さよならを告げて電話を切りました --- 後始末処理を自分で
3-b.電話を切らずに電話口を離れました --- 後始末処理は相手にお任せ
---相手は電話から声がしなくなったので腹を立てて電話切っちゃった
---電話料金が余計にかかりました
どっちが正しいかは言うまでも無い


ぴょぴょ  2007-08-02 00:53:00  No: 65938

>tetrapod 2007/08/01(水) 15:34:24 
>んっと、誤解があるといけないので蛇足
さらに詳しく解説してくださり有り難うございます。
「誤解」というより理解度が不完全のようでした。

C言語の fopen() でファイルを開いてもプログラム終了時に自動的に
クローズされるのは覚えていましたが、Win32 の場合は良く分かって
いなかったようです。ファイル以外にアイコン・リソース・その他も
閉じる処理は一通り自動的に行われるのですね。
ここが一番知りたかった。
もう一度質問しようかと思っていましたので助かりました。

>破棄してもいいんだ。
>破棄しなくてもいいんだ。
これは自分で破棄しても良い(正常)という事が含まれるのですね。了解。

># LR_SHARED を使った場合は例外で、OSに廃棄処理を任せる必要がある
これは知っていました。なので普通にリソースをロードした場合は
明示的に破棄すべきか、破棄してはいけないのかを知りたかったのです。

いろいろと有り難うございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加