0

アイテムを表す構造体のリストを含む所有者描画リストボックスがあります。この構造体には、表示するアイコンと文字列の 2 つのプロパティがあります。16x16 程度の小さなアイコンの表示には問題なく機能しました。ただし、このリストボックスをフォルダーからの画像を表示するように調整しようとしましたが、いくつかの不可解なエラーが発生しました。

public static System.Drawing.Icon BitmapToIcon (System.String String_Bitmap, System.Drawing.Icon Object_Default)
{
    try
    {
        //return System.Drawing.Icon.FromHandle(((System.Drawing.Bitmap)(System.Drawing.Bitmap.FromFile(String_Bitmap))).GetHicon());
        System.IO.Stream s = new System.IO.MemoryStream(System.IO.File.ReadAllBytes(String_Bitmap));
        System.Drawing.Bitmap b = ((System.Drawing.Bitmap)(System.Drawing.Bitmap.FromStream(s, true, true)));
        System.Drawing.Icon i = System.Drawing.Icon.FromHandle(b.GetHicon());
        s.Close();
        b.Dispose();
        return i;
    }
    catch
    {
        return Object_Default;
    }
}

他の場所:

BitmapToIcon("D:/pictures/picture001.jpg", null);

このディレクトリには、すべての形状と形式の約 400 の画像がありますが、実際にリスト ボックスに表示されるのは、ランダムな間隔で配置された約 60 のみです。ListBox.DrawItem() では、Graphics.DrawIcon() が DivideByZero 関数をスローしています。例外をトラップすると、アイコンが 0x0 として登録されます。私の関数は、エラーが発生した場合にデフォルトのアイコン (この場合は null) を返すように書かれていることは明らかです。

Windows ICO フォーマットには 256x256 の制限があることは知っていますが、私が知る限り、ここで起こっていることではありません。それが描画する画像のいくつかは実際にははるかに大きく、正方形でもありません。さらに、400 個のリストにロードされないすべてのイメージは、10 個のリストに問題なくロードされます。GDI のハンドルが多すぎるか何かがあるのではないかと考えたので、関数を変更してソース ビットマップを破棄し、sleep ステートメントを追加しました。しかし、どちらも役に立ちませんでした。アイコンの代わりにビットマップを使用するようにリストボックスを変更すると、描画の問題は修正されましたが、より多くのメモリを消費するようになりました。

GetHIcon() がこのような奇妙な結果を返す理由はありますか?どうすればよいですか?

4

2 に答える 2

0

デフォルトのアイコンが返される原因となっている例外の種類を確認するには、catch 句でエラーをトラップする必要があります。

DestroyIconを呼び出さずにこのメソッドを繰り返し呼び出す場合は、GDI リソースが不足している可能性があります。

このコードがあなたのコードと同等で、少し読みやすいこともお勧めします。

    using ( var b = (Bitmap)Image.FromFile(String_Bitmap))
        return Icon.FromHandle(b.GetHicon());

また、リストボックスの構造体をアイコンではなくビットマップで動作するように変更して、このアイコンの問題を解決してみませんか? :-)

于 2012-05-23T12:15:17.390 に答える
0

ライアン、エリックは、ディレクティブを使用して、次のようなコードを回避する方がよいことを意味します。

System.Drawing.Bitmap b = ((System.Drawing.Bitmap)(System.Drawing.Bitmap.FromStream(s, true, true)));

リファクタリング後は次のようになります。

using System.Drawing.Bitmap;

Bitmap b = ((Bitmap)(Bitmap.FromStream(s, true, true)));

あなたが提供したコードを読むのは難しいです。Image.FromFile() 関数を使用して画像をロードするか、パス パラメーターで Bitmap コンストラクターを使用してみてください。

    Bitmap b = new Bitmap(String_Bitmap);
    Icon i = Icon.FromHandle(b.GetHicon());
于 2012-05-23T04:49:40.927 に答える