Click here to Skip to main content
15,886,035 members
Articles / Programming Languages / C#
Article

An Easy to Understand Icon Manager Completely in .NET

Rate me:
Please Sign up or sign in to vote.
3.53/5 (5 votes)
12 Nov 2007CPOL3 min read 31.3K   162   23   10
This article demonstrates how to extract and display icons in .NET 2.0 without resorting to the Windows API
Screenshot - IconManager.jpg

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:

C#
IconManager.Initialize(); 

This basically just instantiates the inner dictionary of the IconManager.

After that, adding icons is easy:

C#
string file = "c:\somefolders\somefile.someextension";
IconManager.AddIcon(file);

Pulling out an icon for later use is equally as easy:

C#
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:

C#
<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;
} 
}

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
I live in Milwaukee where I graduated from Milwaukee School of Engineering with a B.S. in Computer Engineering. I work as a Software Engineer at Trisept Solutions, and I develop software and embedded systems in my free time (when not spending time with my wife or watching Star Trek). My major project at the moment is DOMercury, a Quicksilver-like application launcher and productivity tool, but for Windows. Its hosted at http://www.odierno.com/domercury

I also sell humorous programming and math apparel at http://www.cafepress.com/cetshirts

My AIM screen name is lllldom

I enjoy athletics as well, I am an avid powerlifter, I played rugby for MSOE and I compete in Judo and Brazilian Jujitsu, and run the MSOE Judo club.

Comments and Discussions

 
GeneralVista - Explorer Pin
HStrix20-Nov-07 21:52
HStrix20-Nov-07 21:52 
GeneralRe: Vista - Explorer Pin
Dominick O'Dierno21-Nov-07 4:19
Dominick O'Dierno21-Nov-07 4:19 
GeneralRe: Vista - Explorer Pin
HStrix21-Nov-07 6:18
HStrix21-Nov-07 6:18 
Generali am just looking for it, thx. Pin
Huyong Zhao13-Nov-07 1:37
Huyong Zhao13-Nov-07 1:37 
Generalinsert subject here :) [modified] Pin
Emil - Gabriel12-Nov-07 20:19
Emil - Gabriel12-Nov-07 20:19 
Icon bmpIcon;<br />
string bmpExtension = ".bmp";<br />
IconManager.GetIcon(bmpExtension);

I think you meant:
Icon bmpIcon;<br />
string bmpExtension = ".bmp";<br />
bmpIcon = IconManager.GetIcon(bmpExtension);


Basically this is a good idea, but (there's always a "but" Smile | :) )...
To put it shortly, what happens if some file association for a certain file extension changes in the registry, along with the icon for the file type that it represents? Will your manager class update it's icons?

Here's a little excerpt from MSDN:
"The IShellIcon interface is used to obtain an icon index for an IShellFolder object. IShellIcon allows an application to obtain the icon for any object within a folder by using only one instance of the interface. IExtractIcon, on the other hand, requires that a separate instance of the interface be created for each object."
Notice the "Shell" in there? That means if you use one of those (IShellIcon or IExtractIcon), you'll be using the shell's icon cache Wink | ;) . No need to worry about caching or updating the icons... Wink | ;)


Cool | :cool:


-- modified at 2:42 Tuesday 13th November, 2007

P.S.: I took a look at DOMercury. Aside from the rusty interface, there's nothing else that I see useful or cool about it... Why not use a mouse again? Confused | :confused:
GeneralRe: insert subject here :) Pin
aprenot14-Nov-07 5:27
aprenot14-Nov-07 5:27 
GeneralRe: insert subject here :) Pin
Dominick O'Dierno14-Nov-07 12:01
Dominick O'Dierno14-Nov-07 12:01 
GeneralRe: insert subject here :) Pin
Emil - Gabriel14-Nov-07 20:56
Emil - Gabriel14-Nov-07 20:56 
GeneralRe: insert subject here :) Pin
Dominick O'Dierno15-Nov-07 12:07
Dominick O'Dierno15-Nov-07 12:07 
GeneralRe: insert subject here :) Pin
Emil - Gabriel15-Nov-07 20:18
Emil - Gabriel15-Nov-07 20:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.