一个易于理解的完全用 .NET 编写的图标管理器






3.53/5 (5投票s)
本文演示了如何在 .NET 2.0 中提取和显示图标,而无需求助于 Windows API

引言和背景
在尝试为我的应用程序启动程序 DOMercury 显示图标时,我遇到了一些障碍。 我需要一种好的方法来管理和从文件中提取图标,并为某些文件类型显示正确的图标。 我看到了许多使用 Windows API 的示例,但我决定,由于我主要用 .NET 编写 DOMercury,应该有一个简单的 .NET 解决方案。 在翻阅 MSDN 后,我遇到了 System.Drawing.Icon.ExtractAssociatedIcon(string filename)
。 借助这个小宝石,我能够构建一个简单易懂的 IconManager 类。
Using the Code
由于我计划与大家分享它,我想让 IconManager
类简单明了,其主要兴趣点清晰可辨。
我将其编写为单例类,因为每个程序中应该只有一个 IconManager
的实例。 但是,它本质上是围绕一个全局图标字典进行封装的,因此仍然需要初始化。 因此,您在代码中应该做的第一件事是调用
IconManager.Initialize();
这基本上只是实例化了 IconManager
的内部字典。
之后,添加图标很容易
string file = "c:\somefolders\somefile.someextension";
IconManager.AddIcon(file);
提取图标以供以后使用也同样容易
Icon bmpIcon;
string bmpExtension = ".bmp";
IconManager.GetIcon(bmpExtension);
您可以传入文件名,或者只传入文件的扩展名,以便从中获取图标。
关注点
您可能会问:“为什么我不能自己使用 ExtractAssociatedIcon
? 为什么我必须让一些管理器为我做这件事?”
好问题。 我将向您解释您可能要使用图标管理器的几个原因。 如果您只是偶尔显示几个图标,那没关系,您可以直接使用提取功能,但有些程序,尤其是应用程序启动程序,需要一次显示许多图标,其中许多是同一图标的重复,并且,由于目的是允许用户快速到达他们想去的地方,因此他们需要能够快速调用和绘制这些图标。 虽然我提供了一个小示例应用程序,向您展示如何使用 IconManager
,但可以试用 DOMercury,并注意需要在很短的时间内显示多少图标。 如果我每次都调用 ExtractAssociatedIcon
,那么您在 DOMercury 中做任何事情都需要五分钟,因此会违背应用程序启动程序的初衷。
IconManager
具有双重优势,因为它通过仅提取每个类型的一个图标并重复使用该图标来节省内存,并且在每次请求该文件类型时无需提取图标来提高速度。
IconManager
也很聪明,可以意识到某些文件类型(例如 *.exe、*.lnk 和 *.ico)都有自己的图标,尽管它们是相同的文件类型,因此它会创建一个“键”,该“键”用于确定是否应提取另一个图标
<summary>
/// Generates a key based on the file name to use to store with the icon.
/// A key generation function is used so that one icon which is used
/// for multiple files of the same type (such as Word documents) will only be
/// stored once.
/// </summary>
/// <param name="path">the filename from which a key is being generated</param>
/// <returns></returns>
private static string GetKey(string path) {
//if path is a directory, return the key as "folder"
{
if (Directory.Exists(path))
{
return "folder";
}
//If path is an existing file, return the extension as the key
else if (File.Exists(path))
{
string ext = Path.GetExtension(path).ToLower();
//.exe, .lnk, .ico, and .icn often have individual icons
//even though they are the same file type
//Therefore they must be treated specially
if (ext == ".exe" || ext == ".lnk" || ext == ".ico" || ext == ".icn")
//return the specific path as the key
{
return Path.GetFileName(path);
}
else
{
return ext;
}
}
//If the path is no known file or folder, return itself as the key
else return path;
}
}
由上一个函数生成的键用于从 IconManager
添加和检索图标。
历史
IconManager
创建的目的是处理 DOMercury 的图标管理,并继续忠实地执行此操作。 在 此处 查看 DOMercury。
历史
- 2007年11月12日:初始发布