在实际应用中,很多情况需要获取电脑上显示的各种文件的图标,我们可以用 SHGetFileInfo 这个API函数来获得磁盘上的文件或者文件夹。
SHGetFileInfo 函数属于Shell32.dll,它的定义如下:
Private Declare Function SHGetFileInfo Lib "shell32" (ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef sfi As shfileinfo, ByVal cbsfi As Integer, ByVal uFlags As Integer) As Integer
pszPath 参数:指定文件名。当uFlags的取值中不包含 SHGFI_PIDL时,可直接指定; 当uFlags的取值中包含 SHGFI_PIDL时pszPath要通过计算获得,不能直接指定。
dwFileAttributes参数:文件属性。仅当uFlags的取值中包含SHGFI_USEFILEATTRIBUTES时有效,一般我们设置此参数为0。
psfi 参数:返回获得的文件信息,是一个记录类型,,有以下字段:
hIcon: HICON { out: icon } '文件的图标句柄
iIcon: Integer { out: icon index } '图标的系统索引号
dwAttributes: DWORD { out: SFGAO_ flags } '文件的属性值
szDisplayName: array [0..MAX_PATH-1] of AnsiChar { out: display name (or path) } '文件的显示名
szTypeName: array [0..79] of AnsiChar { out: type name } '文件的类型名
如下代码就是我们定义的一个psfi参数:
Private Structure shfileinfo
Public hicon As IntPtr
Public iicon As Integer
Public dwattributes As Integer
'限制szdisplayname 字段的长度为260
<MarshalAs(UnmanagedType.LPStr, sizeconst:=260)> _
Public szdisplayname As String
'限制sztypename 字段的长度为80
<MarshalAs(UnmanagedType.LPStr, sizeconst:=80)> _
Public sztypename As String
End Structure
cbFileInfo 参数:psfi的比特值
uFlags 参数:指明需要返回的文件信息标识符,常用的有以下常数:
SHGFI_ICON '获得图标
SHGFI_DISPLAYNAME '获得显示名
SHGFI_TYPENAME '获得类型名
SHGFI_ATTRIBUTES '获得属性
SHGFI_LARGEICON '获得大图标
SHGFI_SMALLICON '获得小图标
SHGFI_PIDL 'pszPath是一个标识符
函数SHGetFileInfo()的返回值也随uFlags的取值变化而有所不同。
由上可见通过调用SHGetFileInfo()可以由psfi参数得到文件的图标句柄,注意只有在uFlags参数中使用SHGFI_PIDL时,SHGetFileInfo()才能获得“我的电脑”等虚似文件夹的信息。
下面我们就用一个实例来演示如何获取磁盘驱动器列表的图标并显示出来。
首先布局窗口,拖放一个ListView 控件,一个Button按钮,一个ImageList 组件,布局如下图一所示:
 图一:窗体布局
添加引用
Imports System.runtime.interopservices
Imports System.IO
然后添加 SHGetFileInfo 函数的调用:
Private Declare Function SHGetFileInfo Lib "shell32" (ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef sfi As shfileinfo, ByVal cbsfi As Integer, ByVal uFlags As Integer) As Integer
http://www.qqread.com/book/myvbnet/my0056.html
定义psfi参数的结构:
Private Structure shfileinfo
Public hicon As IntPtr
Public iicon As Integer
Public dwattributes As Integer
<MarshalAs(UnmanagedType.LPStr, sizeconst:=260)> _
Public szdisplayname As String
<MarshalAs(UnmanagedType.LPStr, sizeconst:=80)> _
Public sztypename As String
End Structure
定义uFlags 参数的几个常量值
Private Const shgfi_smallicon As Integer = &H1
Private Const shgfi_largeicon As Integer = &H0
Private Const shgfi_icon As Integer = &H100
Private Const shgfi_usefileattributes As Integer = &H10
Private Const SHGFI_PIDL As Integer = &H8
Private Const SHGFI_SYSICONINDEX As Integer = &H4000
最后在Button 按钮中添加如下执行代码:
http://www.qqread.com/book/myvbnet/my0056.html
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim ico As Icon
Dim shfi_Large As New shfileinfo
Me.ImageList1.Images.Clear()
Me.ListView1.Items.Clear()
Me.ImageList1.ImageSize = New System.Drawing.Size(32, 32)
Me.ListView1.LargeImageList = Me.ImageList1
Dim strDrive As String() = IO.Directory.GetLogicalDrives'获取驱动器列表
Try
Dim i As Integer = 0
Dim LstItem As ListViewItem
For i = 0 To strDrive.GetUpperBound(0)
SHGetFileInfo(strDrive(i), 0, shfi_Large, Marshal.SizeOf(shfi_Large), shgfi_largeicon Or shgfi_icon)
ico = Icon.FromHandle(shfi_Large.hicon)
ImageList1.Images.Add(ico) '把获得的图片装在ImageList里
LstItem = New ListViewItem(strDrive(i))
LstItem.ImageIndex = i
ListView1.Items.Add(LstItem)
Next
Catch ex As Exception
MsgBox(ex.ToString())
End Try
End Sub
添加代码完毕后,运行,效果如下图二所示: 
在我们前面的一篇文章《vb.net使用ListView 控件显示系统驱动器》中,我们介绍了如何获取系统驱动器以及它的相关信息,但是文中我们还需要专门指定某个驱动器的显示图标,在本文中,我们知道了如何通过API函数来获取驱动器以及它里面的文件夹,乃至可执行文件等的系统图标,所以可以在前文的基础上,加入本文学习到的知识,我们就可以完成一个可以浏览本地文件的功能了。 |