Introduction and Background
While attempting to display icons for my application launcher program, DOMercury, I was running into some brick walls. I needed a good way to manage and extract icons from files and display the correct icon for certain file types. I saw many examples using the Windows API, but I decided that since I was writing DOMercury mainly in .NET there should be a simple .NET solution. After scavenging through MSDN, I came across System.Drawing.Icon.ExtractAssociatedIcon(string filename)
. With this little gem, I was able to build a simple and easy to understand Icon Manager class.
Using the Code
Since I planned on sharing it with all of you, I wanted to make the IconManager
class straightforward, with its main points of interest clear to detect and understand.
I wrote it as a single instance class, since there should be only one instance of the IconManager
in each program. However, it does, in essence, wrap around a global dictionary of icons, so it still needs to be initialized. Therefore, the first thing you should do in your code is call:
IconManager.Initialize();
This basically just instantiates the inner dictionary of the IconManager
.
After that, adding icons is easy:
string file = "c:\somefolders\somefile.someextension";
IconManager.AddIcon(file);
Pulling out an icon for later use is equally as easy:
Icon bmpIcon;
string bmpExtension = ".bmp";
IconManager.GetIcon(bmpExtension);
You can either pass in the file name, or just the extension of a file in order to get the icon from it.
Points of Interest
"Why" you ask, "can I not just use ExtractAssociatedIcon
by myself? Why do I have to have some manager do it for me?"
Good question. I'll explain to you a few reasons why you might want to use an icon manager. If you are just going to display a few icons every once in a while that's fine, you can go straight for the extract function, but some programs, especially application launchers, need to display many icons at a time, many of them repeats of the same icon, and, since the idea is to allow the user to get where they want to go quickly, they need to be able to call up and draw these icons fast. While I have provided a small sample application showing you how to use the IconManager
, take DOMercury for a spin and notice how many icons need to be displayed in a very short amount of time. If I were doing the ExtractAssociatedIcon
call every time, it would take five minutes for you to do anything in DOMercury, and therefore defeat the purpose of an application launcher.
The IconManager
has a double advantage in that it saves memory by only extracting one icon of each type and reusing that icon every time a request is made for that file type, and speed that the icon does not need to be extracted every time it is called.
The IconManager
is also smart enough to realize that some file types, such as *.exe, *.lnk, and *.ico each have their own icon despite being the same file type, so it creates a "key" which it uses to determine whether it should extract another icon or not:
<summary>
private static string GetKey(string path) {
{
if (Directory.Exists(path))
{
return "folder";
}
else if (File.Exists(path))
{
string ext = Path.GetExtension(path).ToLower();
if (ext == ".exe" || ext == ".lnk" || ext == ".ico" || ext == ".icn")
{
return Path.GetFileName(path);
}
else
{
return ext;
}
}
else return path;
}
}
The key generated by the previous function is used to add and retrieve icons from the IconManager
.
History
The IconManager
was created to handle the Icon Management of DOMercury, and continues to do so faithfully. Check out DOMercury here.
History
- 12th November, 2007: Initial post