Reputation: 767
first question here. I'm developing a program in C# (.NET 3.5) that displays files in a listview. I'd like to have the "large icon" view display the icon that Windows Explorer uses for that filetype, otherwise I'll have to use some existing code like this:
private int getFileTypeIconIndex(string fileName)
{
string fileLocation = Application.StartupPath + "\\Quarantine\\" + fileName;
FileInfo fi = new FileInfo(fileLocation);
switch (fi.Extension)
{
case ".pdf":
return 1;
case ".doc": case ".docx": case ".docm": case ".dotx":case ".dotm": case ".dot":case ".wpd": case ".wps":
return 2;
default:
return 0;
}
}
The above code returns an integer that is used to select an icon from an imagelist that I populated with some common icons. It works fine but I'd need to add every extension under the sun! Is there a better way? Thanks!
Upvotes: 18
Views: 15317
Reputation: 4703
You might find the use of Icon.ExtractAssociatedIcon a much simpler (an managed) approach than using SHGetFileInfo. But watch out: two files with the same extension may have different icons.
Upvotes: 12
Reputation: 4284
Edit: Here is a version without PInvoke.
[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
public const uint SHGFI_SMALLICON = 0x1; // 'Small icon
[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
[DllImport("User32.dll")]
public static extern int DestroyIcon(IntPtr hIcon);
public static System.Drawing.Icon GetSystemIcon(string sFilename)
{
//Use this to get the small Icon
IntPtr hImgSmall; //the handle to the system image list
//IntPtr hImgLarge; //the handle to the system image list
APIFuncs.SHFILEINFO shinfo = new APIFuncs.SHFILEINFO();
hImgSmall = APIFuncs.SHGetFileInfo(sFilename, 0, ref shinfo,
(uint)Marshal.SizeOf(shinfo), APIFuncs.SHGFI_ICON | APIFuncs.SHGFI_SMALLICON);
//Use this to get the large Icon
//hImgLarge = SHGetFileInfo(fName, 0,
// ref shinfo, (uint)Marshal.SizeOf(shinfo),
// Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);
//The icon is returned in the hIcon member of the shinfo struct
System.Drawing.Icon myIcon = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon).Clone();
DestroyIcon(shinfo.hIcon); // Cleanup
return myIcon;
}
Upvotes: 4
Reputation: 1887
I used the following solution from codeproject in one of recent my projects
Obtaining (and managing) file and folder icons using SHGetFileInfo in C#
The demo project is pretty self explanatory but basically you just have to do:
private System.Windows.Forms.ListView FileView;
private ImageList _SmallImageList = new ImageList();
private ImageList _LargeImageList = new ImageList();
private IconListManager _IconListManager;
in the constructor:
_SmallImageList.ColorDepth = ColorDepth.Depth32Bit;
_LargeImageList.ColorDepth = ColorDepth.Depth32Bit;
_SmallImageList.ImageSize = new System.Drawing.Size(16, 16);
_LargeImageList.ImageSize = new System.Drawing.Size(32, 32);
_IconListManager = new IconListManager(_SmallImageList, _LargeImageList);
FileView.SmallImageList = _SmallImageList;
FileView.LargeImageList = _LargeImageList;
and then finally when you create the ListViewItem:
ListViewItem item = new ListViewItem(file.Name, _IconListManager.AddFileIcon(file.FullName));
Worked great for me.
Upvotes: 7
Reputation: 56500
The file icons are held in the registry. It's a little convoluted but it works something like
There is some sample code at on CodeProject
Upvotes: 8