我的应用程序有一个图标,我想将其用作 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 中的图标。
有谁知道该怎么做?
事实证明我尝试的第一种方法基本是正确的。
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 资源数据。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)