在做ftp客户端的时候我们常希望我们的ListView会象资源管理器一样工作.对不同类型的文件显示不同的图标.为此我们就需要获取系统的图标:SHGetFileInfo这个API为我们提供了获取系统图标的方法.我这里把我以前写的一段程序弄上来省得要用的时候还得写了:
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Runtime.InteropServices;
using
System.Drawing;
namespace
FTPClient
{
public
static
class
ShellImages
{
#region
DLLIMPORT
//
Retrieves information about an object in the file system,
//
such as a file, a folder, a directory, or a drive root.
[DllImport(
"
shell32
"
,
EntryPoint
=
"
SHGetFileInfo
"
,
ExactSpelling
=
false
,
CharSet
=
CharSet.Auto,
SetLastError
=
true
)]
private
static
extern
IntPtr SHGetFileInfo(
string
pszPath,
FILE_ATTRIBUTE dwFileAttributes,
ref
SHFILEINFO sfi,
int
cbFileInfo,
SHGFI uFlags);
#endregion
#region
STRUCTS
//
Contains information about a file object
[StructLayout(LayoutKind.Sequential, CharSet
=
CharSet.Auto)]
private
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;
};
#endregion
#region
Enums
//
Flags that specify the file information to retrieve with SHGetFileInfo
[Flags]
public
enum
SHGFI :
uint
{
ADDOVERLAYS
=
0x20
,
ATTR_SPECIFIED
=
0x20000
,
ATTRIBUTES
=
0x800
,
DISPLAYNAME
=
0x200
,
EXETYPE
=
0x2000
,
ICON
=
0x100
,
ICONLOCATION
=
0x1000
,
LARGEICON
=
0
,
LINKOVERLAY
=
0x8000
,
OPENICON
=
2
,
OVERLAYINDEX
=
0x40
,
PIDL
=
8
,
SELECTED
=
0x10000
,
SHELLICONSIZE
=
4
,
SMALLICON
=
1
,
SYSICONINDEX
=
0x4000
,
TYPENAME
=
0x400
,
USEFILEATTRIBUTES
=
0x10
}
//
Flags that specify the file information to retrieve with SHGetFileInfo
[Flags]
public
enum
FILE_ATTRIBUTE
{
READONLY
=
0x00000001
,
HIDDEN
=
0x00000002
,
SYSTEM
=
0x00000004
,
DIRECTORY
=
0x00000010
,
ARCHIVE
=
0x00000020
,
DEVICE
=
0x00000040
,
NORMAL
=
0x00000080
,
TEMPORARY
=
0x00000100
,
SPARSE_FILE
=
0x00000200
,
REPARSE_POINT
=
0x00000400
,
COMPRESSED
=
0x00000800
,
OFFLINE
=
0x00001000
,
NOT_CONTENT_INDEXED
=
0x00002000
,
ENCRYPTED
=
0x00004000
}
#endregion
#region
Variables
//
保存小图标列表
private
static
System.Windows.Forms.ImageList smallImageList;
//
保存大图标列表
private
static
System.Windows.Forms.ImageList largeImageList;
//
保存已装载的图标信息<扩展名,在imageList中的索引>
private
static
Dictionary
<
string
,
int
>
loadImageDictionary;
static
ShellImages()
{
smallImageList
=
new
System.Windows.Forms.ImageList();
largeImageList
=
new
System.Windows.Forms.ImageList();
loadImageDictionary
=
new
Dictionary
<
string
,
int
>
();
//
将 ImageList中的图标设置为32位色图标,这样可以得到较好的显示效果
smallImageList.ColorDepth
=
System.Windows.Forms.ColorDepth.Depth32Bit;
largeImageList.ColorDepth
=
System.Windows.Forms.ColorDepth.Depth32Bit;
largeImageList.ImageSize
=
new
Size(
32
,
32
);
addForderIcon();
}
#endregion
#region
PrivateMethods
///
<summary>
///
获取系统图标
///
</summary>
///
<param name="path">
文件名
</param>
///
<param name="dwAttr">
文件信息
</param>
///
<param name="dwFlag">
获取信息控制字
</param>
///
<returns></returns>
private
static
Icon GetIcon(
string
path, FILE_ATTRIBUTE dwAttr, SHGFI dwFlag)
{
SHFILEINFO fi
=
new
SHFILEINFO();
Icon ic
=
null
;
int
iTotal
=
(
int
)SHGetFileInfo(path, dwAttr,
ref
fi,
0
, dwFlag);
ic
=
Icon.FromHandle(fi.hIcon);
return
ic;
}
///
<summary>
///
向smallInamgeList和largeImageList中
///
加入相应文件对应的图标
///
</summary>
///
<param name="fileName"></param>
private
static
void
addFileIcon(
string
fileName)
{
smallImageList.Images.Add(GetIcon(fileName,
FILE_ATTRIBUTE.NORMAL,
SHGFI.USEFILEATTRIBUTES
|
SHGFI.ICON
|
SHGFI.LARGEICON));
largeImageList.Images.Add(GetIcon(fileName,
FILE_ATTRIBUTE.NORMAL,
SHGFI.USEFILEATTRIBUTES
|
SHGFI.ICON
|
SHGFI.LARGEICON));
}
private
static
void
addForderIcon()
{
smallImageList.Images.Add(GetIcon(
"
dic
"
,
FILE_ATTRIBUTE.DIRECTORY,
SHGFI.USEFILEATTRIBUTES
|
SHGFI.ICON
|
SHGFI.LARGEICON));
largeImageList.Images.Add(GetIcon(
"
dic
"
,
FILE_ATTRIBUTE.DIRECTORY,
SHGFI.USEFILEATTRIBUTES
|
SHGFI.ICON
|
SHGFI.LARGEICON));
}
#endregion
#region
PublicMethods
///
<summary>
///
获取系统的小图标列表
///
</summary>
public
static
System.Windows.Forms.ImageList SmallImageList
{
get
{
return
smallImageList;
}
}
///
<summary>
///
获取系统的大图标列表
///
</summary>
public
static
System.Windows.Forms.ImageList LargeImageList
{
get
{
return
largeImageList;
}
}
///
<summary>
///
文件对应的图标在ImageList中的索引号
///
(在SmallImageList,LargeImageList中的索引号是相同的)
///
</summary>
///
<param name="fileName">
文件名
</param>
///
<returns>
索引号
</returns>
public
static
int
ImageIndex(
string
fileName)
{
int
index
=
0
;
int
extIndex
=
fileName.LastIndexOf(
'
.
'
);
if
(extIndex
<
0
)
//
没有扩展名的文件当作文件夹处理
{
extIndex
=
2
;
}
else
//
文件图标索引获取
{
fileName
=
fileName.Substring(extIndex, fileName.Length
-
extIndex);
//
判断该扩展名的文件图标是否已装载到imageList中
if
(
!
loadImageDictionary.TryGetValue(fileName,
out
index))
{
addFileIcon(fileName);
//
装载图标到ImageList中
loadImageDictionary.Add(fileName, smallImageList.Images.Count
-
1
);
index
=
smallImageList.Images.Count
-
1
;
}
}
return
index;
}
#endregion
}
}
这个类为我们提供了一个smallImageList 和largeImageList属性.还有一个ImageIndex(string)方法用来获取获取相关文件的图标对应的索引号.下面是一端使用代码:
//
为listView指定图标列表
this
.listView1.SmallImageList
=
ShellImages.SmallImageList;
this
.listView1.LargeImageList
=
ShellImages.LargeImageList;
//
向listview中动态添加一个节点
ListViewItem item
=
new
ListViewItem();
item.Text
=
"
a.txt
"
;
item.ImageIndex
=
ShellImages.ImageIndex(item.Text);
this
.listView1.Items.Add(item);
欢迎大家指正.