Icons in DLL's

O

OpticTygre

Hi folks. I'm currently in the midst of building an explorer - like viewer
for a bigger project I'm going to be working on soon. When building the
class for my Treeview and Listview controls, I'm using the ExtractIconEx API
function (see code below). I found that all the icons windows uses are not
necessarily in the Shell32.dll file, though. I did some digging, and found
a few other places where Icon files are being pulled from to be displayed in
explorer. I'm just curious about the best way one would go about pulling
the icon files out of multiple places, based upon either the folder icon (or
control panel icon) or the files in the folders (for the listview). I'd
rather not create my own library of icons to release with the program, as it
can get big, and I don't see the point when most of them come with windows
anyway. What's the best way to go about getting (from the correct place)
and displaying icons in a treeview (for folders, drives, etc...) and
listview (for folders and files) controls?

Thanks for any advice.

-Jason

Private Declare Function ExtractIconEx Lib "Shell32.dll" Alias
"ExtractIconExA" _
(ByVal lpszFile As String, ByVal nIconIndex As Integer, _
<[In](), Out()> ByVal phIconLarge() As Integer, _
<[In](), Out()> ByVal phIconSmall() As Integer, _
ByVal nIcons As Integer) As Integer

Private Sub GetSystemIconList()
Try
Dim iIndex As Integer
Dim strPath As String
Const iArrUB As Integer = 250
Dim hLargeIcon(iArrUB) As Integer
Dim hSmallIcon(iArrUB) As Integer
Dim IconHnd As IntPtr
Dim iFetchIcons As Integer

strPath = "%systemroot%\system32\shell32.dll"

iFetchIcons = ExtractIconEx(strPath, 0, hLargeIcon, hSmallIcon,
iArrUB)

For iIndex = 0 To iFetchIcons - 1
SmallSystemIconList.Images.Add(Bitmap.FromHicon(IconHnd.op_Explicit(hSmallIcon(iIndex))))
LargeSystemIconList.Images.Add(Bitmap.FromHicon(IconHnd.op_Explicit(hLargeIcon(iIndex))))
Next

Catch ex As Exception

End Try
End Sub
 
K

Ken Tucker [MVP]

Hi,

Use shgetfileinfo to get them. Add a listview control to the form
and name it lv. Here is an example.

Private Function getLocalIcons(ByVal szFolderPath As String)

Dim dirInfo As New System.IO.DirectoryInfo(szFolderPath)

Dim di As System.IO.DirectoryInfo

Dim fi As System.IO.FileInfo

Dim lvitem As ListViewItem

Dim hIcon As Icon

Dim cIcon As New clsGetIcon

Dim htIcons As New Hashtable

Dim intIndex As Integer

imlIcon.Images.Clear()

lv.Items.Clear()

lv.SmallImageList = imlIcon

For Each di In dirInfo.GetDirectories()

lvitem = lv.Items.Add(di.Name)

hIcon = cIcon.getIcon(di.FullName)

If htIcons.ContainsKey(hIcon) Then

intIndex = htIcons(hIcon)

Else

imlIcon.Images.Add(hIcon.ToBitmap)

intIndex = imlIcon.Images.Count - 1

End If

lvitem.ImageIndex = intIndex

Next

For Each fi In dirInfo.GetFiles()

lvitem = lv.Items.Add(fi.Name)

hIcon = cIcon.getIcon(fi.FullName)

If htIcons.ContainsKey(hIcon) Then

intIndex = htIcons(hIcon)

Else

imlIcon.Images.Add(hIcon.ToBitmap)

intIndex = imlIcon.Images.Count - 1

End If

lvitem.ImageIndex = intIndex

Next

End Function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

lv.SuspendLayout()

getLocalIcons("C:\")

lv.ResumeLayout()

End Sub



The helper class.

Imports System.Runtime.InteropServices

Public Class clsGetIcon

Public Structure SHFILEINFO

Dim hIcon As IntPtr

Dim iIcon As Integer

Dim dwAttributes As Integer

<VBFixedString(260),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst:=260)> Public szDisplayName As String

'String that contains the name of the file as it appears in the Microsoft®
Windows® Shell, or the path and file name of the file that contains the icon
representing the file.

<VBFixedString(80),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst:=80)> Public szTypeName As String

End Structure


Private Declare Auto Function SHGetFileInfo Lib "shell32" (ByVal pszPath As
String, _

ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFO, _

ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As Integer

Private Const SHGFI_ICON As Integer = &H100

Private Const SHGFI_SMALLICON As Integer = &H1 'Small icon

Private Const SHGFI_TYPENAME As Integer = &H400 ' get type name



Public Function getIcon(ByVal szFilename As String) As Icon

Try

Dim aSHFileInfo As New SHFILEINFO

Dim cbFileInfo As Integer = _

Marshal.SizeOf(aSHFileInfo)

Dim uflags As Integer = SHGFI_ICON Or SHGFI_SMALLICON

SHGetFileInfo(szFilename, 0, aSHFileInfo, cbFileInfo, uflags)

Dim myIcon As Icon

myIcon = Icon.FromHandle(aSHFileInfo.hIcon)

aSHFileInfo.szTypeName = Space(255)

SHGetFileInfo(szFilename, 0, aSHFileInfo, cbFileInfo, SHGFI_TYPENAME)

Trace.WriteLine(aSHFileInfo.szTypeName)

Return myIcon

Catch ex As Exception

Debug.WriteLine(ex.ToString)

Return Nothing

End Try

End Function

End Class



Ken

---------------------------

Hi folks. I'm currently in the midst of building an explorer - like viewer
for a bigger project I'm going to be working on soon. When building the
class for my Treeview and Listview controls, I'm using the ExtractIconEx API
function (see code below). I found that all the icons windows uses are not
necessarily in the Shell32.dll file, though. I did some digging, and found
a few other places where Icon files are being pulled from to be displayed in
explorer. I'm just curious about the best way one would go about pulling
the icon files out of multiple places, based upon either the folder icon (or
control panel icon) or the files in the folders (for the listview). I'd
rather not create my own library of icons to release with the program, as it
can get big, and I don't see the point when most of them come with windows
anyway. What's the best way to go about getting (from the correct place)
and displaying icons in a treeview (for folders, drives, etc...) and
listview (for folders and files) controls?

Thanks for any advice.

-Jason

Private Declare Function ExtractIconEx Lib "Shell32.dll" Alias
"ExtractIconExA" _
(ByVal lpszFile As String, ByVal nIconIndex As Integer, _
<[In](), Out()> ByVal phIconLarge() As Integer, _
<[In](), Out()> ByVal phIconSmall() As Integer, _
ByVal nIcons As Integer) As Integer

Private Sub GetSystemIconList()
Try
Dim iIndex As Integer
Dim strPath As String
Const iArrUB As Integer = 250
Dim hLargeIcon(iArrUB) As Integer
Dim hSmallIcon(iArrUB) As Integer
Dim IconHnd As IntPtr
Dim iFetchIcons As Integer

strPath = "%systemroot%\system32\shell32.dll"

iFetchIcons = ExtractIconEx(strPath, 0, hLargeIcon, hSmallIcon,
iArrUB)

For iIndex = 0 To iFetchIcons - 1
SmallSystemIconList.Images.Add(Bitmap.FromHicon(IconHnd.op_Explicit(hSmallIcon(iIndex))))
LargeSystemIconList.Images.Add(Bitmap.FromHicon(IconHnd.op_Explicit(hLargeIcon(iIndex))))
Next

Catch ex As Exception

End Try
End Sub
 
O

OpticTygre

Hi Ken,

Thanks for the time you put into this! I'm sure it can help a lot of other
people out as well. I'll definately check out all the code. Thanks again!

-Jason

Ken Tucker said:
Hi,

Use shgetfileinfo to get them. Add a listview control to the form
and name it lv. Here is an example.

Private Function getLocalIcons(ByVal szFolderPath As String)

Dim dirInfo As New System.IO.DirectoryInfo(szFolderPath)

Dim di As System.IO.DirectoryInfo

Dim fi As System.IO.FileInfo

Dim lvitem As ListViewItem

Dim hIcon As Icon

Dim cIcon As New clsGetIcon

Dim htIcons As New Hashtable

Dim intIndex As Integer

imlIcon.Images.Clear()

lv.Items.Clear()

lv.SmallImageList = imlIcon

For Each di In dirInfo.GetDirectories()

lvitem = lv.Items.Add(di.Name)

hIcon = cIcon.getIcon(di.FullName)

If htIcons.ContainsKey(hIcon) Then

intIndex = htIcons(hIcon)

Else

imlIcon.Images.Add(hIcon.ToBitmap)

intIndex = imlIcon.Images.Count - 1

End If

lvitem.ImageIndex = intIndex

Next

For Each fi In dirInfo.GetFiles()

lvitem = lv.Items.Add(fi.Name)

hIcon = cIcon.getIcon(fi.FullName)

If htIcons.ContainsKey(hIcon) Then

intIndex = htIcons(hIcon)

Else

imlIcon.Images.Add(hIcon.ToBitmap)

intIndex = imlIcon.Images.Count - 1

End If

lvitem.ImageIndex = intIndex

Next

End Function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

lv.SuspendLayout()

getLocalIcons("C:\")

lv.ResumeLayout()

End Sub



The helper class.

Imports System.Runtime.InteropServices

Public Class clsGetIcon

Public Structure SHFILEINFO

Dim hIcon As IntPtr

Dim iIcon As Integer

Dim dwAttributes As Integer

<VBFixedString(260),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst:=260)> Public szDisplayName As String

'String that contains the name of the file as it appears in the Microsoft®
Windows® Shell, or the path and file name of the file that contains the
icon
representing the file.

<VBFixedString(80),
System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,
SizeConst:=80)> Public szTypeName As String

End Structure


Private Declare Auto Function SHGetFileInfo Lib "shell32" (ByVal pszPath
As
String, _

ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFO, _

ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As Integer

Private Const SHGFI_ICON As Integer = &H100

Private Const SHGFI_SMALLICON As Integer = &H1 'Small icon

Private Const SHGFI_TYPENAME As Integer = &H400 ' get type name



Public Function getIcon(ByVal szFilename As String) As Icon

Try

Dim aSHFileInfo As New SHFILEINFO

Dim cbFileInfo As Integer = _

Marshal.SizeOf(aSHFileInfo)

Dim uflags As Integer = SHGFI_ICON Or SHGFI_SMALLICON

SHGetFileInfo(szFilename, 0, aSHFileInfo, cbFileInfo, uflags)

Dim myIcon As Icon

myIcon = Icon.FromHandle(aSHFileInfo.hIcon)

aSHFileInfo.szTypeName = Space(255)

SHGetFileInfo(szFilename, 0, aSHFileInfo, cbFileInfo, SHGFI_TYPENAME)

Trace.WriteLine(aSHFileInfo.szTypeName)

Return myIcon

Catch ex As Exception

Debug.WriteLine(ex.ToString)

Return Nothing

End Try

End Function

End Class



Ken

---------------------------

Hi folks. I'm currently in the midst of building an explorer - like
viewer
for a bigger project I'm going to be working on soon. When building the
class for my Treeview and Listview controls, I'm using the ExtractIconEx
API
function (see code below). I found that all the icons windows uses are
not
necessarily in the Shell32.dll file, though. I did some digging, and
found
a few other places where Icon files are being pulled from to be displayed
in
explorer. I'm just curious about the best way one would go about pulling
the icon files out of multiple places, based upon either the folder icon
(or
control panel icon) or the files in the folders (for the listview). I'd
rather not create my own library of icons to release with the program, as
it
can get big, and I don't see the point when most of them come with windows
anyway. What's the best way to go about getting (from the correct place)
and displaying icons in a treeview (for folders, drives, etc...) and
listview (for folders and files) controls?

Thanks for any advice.

-Jason

Private Declare Function ExtractIconEx Lib "Shell32.dll" Alias
"ExtractIconExA" _
(ByVal lpszFile As String, ByVal nIconIndex As Integer, _
<[In](), Out()> ByVal phIconLarge() As Integer, _
<[In](), Out()> ByVal phIconSmall() As Integer, _
ByVal nIcons As Integer) As Integer

Private Sub GetSystemIconList()
Try
Dim iIndex As Integer
Dim strPath As String
Const iArrUB As Integer = 250
Dim hLargeIcon(iArrUB) As Integer
Dim hSmallIcon(iArrUB) As Integer
Dim IconHnd As IntPtr
Dim iFetchIcons As Integer

strPath = "%systemroot%\system32\shell32.dll"

iFetchIcons = ExtractIconEx(strPath, 0, hLargeIcon, hSmallIcon,
iArrUB)

For iIndex = 0 To iFetchIcons - 1

SmallSystemIconList.Images.Add(Bitmap.FromHicon(IconHnd.op_Explicit(hSmallIcon(iIndex))))

LargeSystemIconList.Images.Add(Bitmap.FromHicon(IconHnd.op_Explicit(hLargeIcon(iIndex))))
Next

Catch ex As Exception

End Try
End Sub
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top