使用相同的.exe图标和Windows窗体应用程序中的表单而不重复它?

时间:2014-03-11 08:08:01

标签: winforms winforms-interop

我的应用程序有一个图标,我想将它用作EXE图标和主窗体上的图标。当我说“EXE图标”时,我的意思是/ win32icon选项嵌入到C#编译器的图标或Visual Studio中项目设置的应用程序部分中指定的图标。这是Windows资源管理器显示的图标。

但是,申请表格使用默认图标,即标题栏中显示的内容以及按Alt-Tab键时。

我想在不重复数据的情况下为两者使用相同的图标。实际上,这意味着WinForms应用程序必须在运行时读取嵌入的Win32图标。据推测这是可能的,但由于搜索结果与关于从.resx文件等访问嵌入资源的页面混乱,我无法找到任何信息。

我不介意这是否需要p / invoke或类似。我可以在Win32资源查看器中看到该图标嵌入了ID为32512(IDI_APPLICATION)的EXE中。我尝试了以下内容:

IntPtr hInstance = GetModuleHandle(IntPtr.Zero);
IntPtr hIcon = LoadIcon(hInstance, new IntPtr(32512));
icon = Icon.FromHandle(hIcon);

但是hIcon == 0.我也尝试过:

IntPtr hIcon = LoadIcon(IntPtr.Zero, new IntPtr(32512));
icon = Icon.FromHandle(hIcon);

这会加载一个图标,但它是系统默认的应用程序图标,而不是EXE中的图标。

有谁知道怎么做?

1 个答案:

答案 0 :(得分:3)

事实证明,我尝试的第一种方法基本上是正确的。

IntPtr hInstance = GetModuleHandle(null);
IntPtr hIcon = LoadIcon(hInstance, new IntPtr(32512));
icon = Icon.FromHandle(hIcon);

...函数声明如下:

[DllImport("user32.dll")]
static extern IntPtr LoadIcon(IntPtr hInstance, IntPtr iconName);
[DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle(string moduleName);

在Hans Passant的一些含糊不清的评论的帮助下,我发现它不起作用的原因是因为Visual Studio托管过程。我不想禁用它,而是将代码更改为有条件地运行:

IntPtr hInstance = GetModuleHandle(null);
IntPtr hIcon = LoadIcon(hInstance, new IntPtr(32512));
if(hIcon != IntPtr.Zero) icon = Icon.FromHandle(hIcon);

然后我们走了。不再需要将该图标复制为Win32和.NET资源数据。