C#
 言归正传,既然已经获得绝对 PIDL,那么获取图标就是很简单的事情了,我们使用的是 SHGetFileInfo 这个API<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />[DllImport("shell32", EntryPoint = "SHGetFileInfo", ExactSpelling = false
    CharSet = CharSet.Auto, SetLastError = 
true)]
public static extern IntPtr SHGetFileInfo(
    IntPtr ppidl, 
    FILE_ATTRIBUTE dwFileAttributes, 
    
ref SHFILEINFO sfi, 
    
int cbFileInfo, 
    SHGFI uFlags);

[DllImport("Shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(
    
string Path, 
    FILE_ATTRIBUTE fileAttributes, 
    
out SHFILEINFO sfi, 
    
int cbFileInfo, SHGFI flags);


这里提供了一个重载,你可以选择是通过 PIDL 还是 路径 获取图标(如果是路径,那么仅仅能获取 文件夹/文件 的图标)。

/**//// <summary>
/// 
获取小图标索引
///   </summary>
public static int GetSmallIconIndex(string strFilename)
{
    SHFILEINFO psfi = 
new SHFILEINFO();
    IntPtr ipIcon = SHGetFileInfo(strFilename, 0, 
out psfi, Marshal.SizeOf(psfi),
        SHGFI.ICON | SHGFI.SMALLICON | SHGFI.SYSICONINDEX);

    
return psfi.iIcon;
}

public static int GetSmallIconIndex(IntPtr ipIDList)
{
    SHFILEINFO psfi = 
new SHFILEINFO();
    IntPtr ipIcon = SHGetFileInfo(ipIDList, 0, 
ref psfi, Marshal.SizeOf(psfi),
        SHGFI.ICON | SHGFI.PIDL | SHGFI.SMALLICON | SHGFI.SYSICONINDEX);

    
return psfi.iIcon;
}


大家也许会觉得奇怪,GetSmallIconIndex 返回的是 int ,到底要怎么使用?

其实没错,GetSmallIconIndex 仅仅是返回该图标在系统图像列表(System ImageList)的索引(Index)而已。我们只要获取系统图像列表的指针,再把它关联到你的 TreeView ListView ,即可通过 Icon Index 来显示图标了。

IntPtr m_ipSmallSystemImageList;
IntPtr m_ipLargeSystemImageList;

//
获取系统  ImageList
SHFILEINFO shfi =  new  SHFILEINFO();

m_ipSmallSystemImageList = API.SHGetFileInfo("", 0, 
out  shfi, Marshal.SizeOf( typeof (SHFILEINFO)),
    SHGFI.SYSICONINDEX | SHGFI.SMALLICON | SHGFI.USEFILEATTRIBUTES);

m_ipLargeSystemImageList = API.SHGetFileInfo("", 0, 
out  shfi, Marshal.SizeOf( typeof (SHFILEINFO)),
    SHGFI.SYSICONINDEX | SHGFI.LARGEICON | SHGFI.USEFILEATTRIBUTES);

// 把系统  ImageList  关联到  TreeView   ListView
API.SendMessage(Tree1.Handle, API.TVM_SETIMAGELIST, API.TVSIL_NORMAL, m_ipSmallSystemImageList);
API.SendMessage(lvFile.Handle, API.LVM_SETIMAGELIST, API.LVSIL_NORMAL, m_ipLargeSystemImageList);


OK
,我们修改以往的例子,就可以在 Tree 节点上显示图标了:


ShellItem shellItem=
new ShellItem(pidlSub, iSub, sItem);
int imgIndex = API.GetSmallIconIndex(shellItem.PIDLFull.Ptr);
TreeNode nodeSub = 
new TreeNode(name, imgIndex, imgIndex);