避免在.NET(C#)项目中重复的图标资源

时间:2009-02-27 21:55:23

标签: c# winforms winapi resources

我正在使用Visual C#2008 Express。我想为应用程序使用相同的图标(即.exe显示的图标),以及主窗体。不幸的是,VC#似乎并不是很聪明,并且坚持要复制图标数据。

似乎没有办法选择在表单或项目图标中使用的“已嵌入”图标(仅选择文件),并且对两个图标使用相同的文件只是将文件嵌入两次到目前为止我所看到的。这不是什么大问题(现在硬盘空间很便宜,对吧?),但它让我感到烦恼。

知道如何避免这种情况吗?有没有办法以编程方式加载可执行文件的图标,以便在构建表单时使用,比如说?一些关于类似事情的论坛帖子似乎暗示.NET资源不使用普通的旧Windows资源系统 - 在获取旧式资源的框架内有没有办法?或者我必须绑定Win32 API函数来执行此操作吗?

5 个答案:

答案 0 :(得分:14)

你是对的,这很烦人。

您必须自己加载图标,而不是依赖设计器生成的代码。将图标保存为项目资源,然后将资源加载到窗体构造函数中的窗体Icon属性中:

this.Icon = Properties.Resources.myIconResourceName;

答案 1 :(得分:11)

您正在寻找Icon.ExtractAssociatedIcon。调用传递您的可执行文件:

var icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);

答案 2 :(得分:6)

是的,这很烦人。但是Icon.ExtractAssociatedIcon的建议答案的问题在于它将检索32x32图标,然后在表单窗口或任务栏上下采样到16x16图标,除非你的32x32图标构造得非常巧妙,否则看起来很糟糕。 / p>

我正在做的方式是使用interop(将第一行放在表单构造函数中):

this.Icon = ExtractSmallIconFromLibrary(Application.ExecutablePath);
...

public static Icon ExtractSmallIconFromLibrary(string file) {
    IntPtr[] reficon = new IntPtr[1];
    int nextracted = ExtractIconEx(file, 0, null, reficon, 1);
    if (nextracted < 1)
        return null;
    Icon unmanaged_icon = Icon.FromHandle(reficon[0]);
    Icon icon = (Icon)unmanaged_icon.Clone();
    DestroyIcon(unmanaged_icon.Handle);
    return icon;
}

[DllImport("Shell32", CharSet = CharSet.Auto)]
extern static int ExtractIconEx(
    [MarshalAs(UnmanagedType.LPTStr)] 
    string lpszFile,
    int nIconIndex,
    IntPtr[] phIconLarge,
    IntPtr[] phIconSmall,
    int nIcons
    );

[DllImport("user32.dll", CharSet = CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);

但这也不是很好,因为你想要像Alt-Tab图标列表那样的32x32图标。所以你真的需要提取整个图标,这是一个更大的工作。也许有一种直接的方法将两个图标合二为一。或者你可以这样做codeproject程序,它首先用大量的代码提取整个图标。

答案 3 :(得分:3)

我认为在许多情况下,包括重复图标在一天结束时比尝试从非托管资源中提取它更有效 - 考虑到你不能将Icon.ExtractAssociatedIcon用于UNC路径。

答案 4 :(得分:1)

我遇到了类似的问题。

我有和exe图标我想在不增加文件大小的情况下重用子表单。

//From MyApp
MySubForm msf = new MySubForm();
msf.Icon = this.Icon;
msf.Show();

我不知道这是否有用,但无论如何我想分享它。