This is handy for things like filling the ImageLists that are used for TreeViews or ListViews when building your own file/folder browsers or explorer type windows. However, it can be used for any purpose where you need the icon image for a file or folder. For example, a Button or PictureBox Image.
The only downfall to this method is that you are limited to only the 32x32 or 16x16 sizes for the images. Getting the larger images such as 48x48, 64x64, 128x128, and 256x256 sizes requires a bit more complex method. Perhaps i will post a snippet of how to do that at a later date. For now i will just show this simpler example.
I have put together the small Iconhelper class below which you can add to your project and call the GetIconImage function to get the icon image. The SHGetFileInfo Win32 Api function is used to do the work of getting the icon. However, since Icons are not so nice to work with in VB.Net and can appear blurry/distorted in the ListView or TreeView controls, i convert the Icon to a Bitmap image which makes the image clearer/cleaner looking and can be used easily with the Image property of any control.
So, enough rambling on. Add the Iconhelper class below to your project.
Imports System.Runtime.InteropServices Public Enum IconSizes As Integer Large32x32 = 0 Small16x16 = 1 End Enum Public Class Iconhelper Private Const SHGFI_ICON As Integer = &H100 Private Const SHGFI_USEFILEATTRIBUTES As Integer = &H10 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> Private Structure SHFILEINFOW Public hIcon As IntPtr Public iIcon As Integer Public dwAttributes As Integer <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szDisplayName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> Public szTypeName As String End Structure <DllImport("shell32.dll", EntryPoint:="SHGetFileInfoW")> Private Shared Function SHGetFileInfoW(<MarshalAs(UnmanagedType.LPTStr)> ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFOW, ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As Integer End Function <DllImport("user32.dll", EntryPoint:="DestroyIcon")> Private Shared Function DestroyIcon(ByVal hIcon As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean End Function ''' <summary>Gets a Bitmap image of the specified file or folder icon.</summary> ''' <param name="FileOrFolderPath">The full path to the folder or file to get the icon image from, or just a file extension (.ext) to get the registered icon image of the file type.</param> ''' <param name="IconSize">The size of the icon to retrieve.</param> Public Shared Function GetIconImage(ByVal FileOrFolderPath As String, ByVal IconSize As IconSizes) As Bitmap Dim bm As Bitmap = Nothing Dim fi As New SHFILEINFOW Dim flags As Integer = If(FileOrFolderPath.StartsWith("."), (IconSize Or SHGFI_USEFILEATTRIBUTES), IconSize) If SHGetFileInfoW(FileOrFolderPath, 0, fi, Marshal.SizeOf(fi), SHGFI_ICON Or flags) <> 0 Then bm = Icon.FromHandle(fi.hIcon).ToBitmap End If DestroyIcon(fi.hIcon).ToString() Return bm End Function End Class
Now i will give you a few examples of how you can use the Iconhelper class to get both sizes of the icon image from a Folder, a HardDrive, and a File.
First add 2 PictureBoxes to the form and set their SizeMode property to CenterImage. You can then use any of the next few code examples below in the Form Load event or a Button Click event if you want for testing.
'get the icon image for the Pictures folder Dim PictureFolderPath As String = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) PictureBox1.Image = Iconhelper.GetIconImage(PictureFolderPath, IconSizes.Large32x32) PictureBox2.Image = Iconhelper.GetIconImage(PictureFolderPath, IconSizes.Small16x16)
'gets the icon images for the hard drive PictureBox1.Image = Iconhelper.GetIconImage("C:\", IconSizes.Large32x32) PictureBox2.Image = Iconhelper.GetIconImage("C:\", IconSizes.Small16x16)
'gets the icon images from a Rich Text file PictureBox1.Image = Iconhelper.GetIconImage("C:\TestFolder\MyRtfFile.rtf", IconSizes.Large32x32) PictureBox2.Image = Iconhelper.GetIconImage("C:\TestFolder\MyRtfFile.rtf", IconSizes.Small16x16)
It should be pretty easy to see how it is used but, i will show an example of getting the icon image of a registered file extension type. It is done the same way but, you just supply the extension instead of a file or folder path. The extension must begin with the . character.
'get the icon image for a .zip type file PictureBox1.Image = Iconhelper.GetIconImage(".zip", IconSizes.Large32x32) 'get the icon image for a .vbproj type file. PictureBox2.Image = Iconhelper.GetIconImage(".vbproj", IconSizes.Large32x32)
Here i added several PictureBoxes to a form to show the Pictures Folder, the Hard Drive, and a Rich Text file icon.