图标和DivideByZero异常

时间:2012-05-22 20:27:03

标签: c# winforms icons size gdi+

我有一个所有者绘制的列表框,其中包含表示项目的结构列表。此结构有两个属性,一个图标和一个要显示的字符串。它适用于显示小图标,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有太多句柄或者其他东西所以我改变了功能来处理我的源位图并添加了一个睡眠声明,但没有帮助。更改列表框以使用位图而不是图标修复了绘图问题,但它现在消耗了更多的内存。

是否有某些原因GetHIcon()会返回如此奇怪的结果,我该怎么办呢?

2 个答案:

答案 0 :(得分:0)

Ryan,Eric意味着使用using指令来避免代码更好:

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());

答案 1 :(得分:0)

您应该在catch子句中捕获错误,以查看导致返回默认图标的异常类型。

如果你从不打电话给 DestroyIcon 并反复调用这个方法,很可能你的GDI资源已经用完了。

我可以建议这段代码与您的代码相同,并且更容易阅读:

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

另外 - 为什么不更改列表框的结构以使用位图而不是图标,只是摆脱这个图标问题? : - )