SHGetFileInfo 显示文件类型图标

需要显示远程目录下文件跟文件夹的图标,但是软件并不支持直接获取远程目录下的图标,这时候就需要读取本机对应的目录图标和对应类型文件图标。

初始化的时候。需要将Imagelist设置给ListCtrl控件。


1
2
3
4
5
6
7
8
9
10
// 初始化图标列表
SHFILEINFO    sfi;
HIMAGELIST imagelist;
imagelist=(HIMAGELIST)SHGetFileInfo(_T( "" ),
     0,
     &sfi,
     sizeof (SHFILEINFO),
     SHGFI_SYSICONINDEX | SHGFI_SMALLICON ) ;
this ->m_ListCtrl1.InsertColumn(0, _T( "文件名" ), 0, 200);
this ->m_ListCtrl1.SetImageList(CImageList::FromHandle(imagelist),LVSIL_SMALL)

在设置Item信息的时候读取icon 的索引值


1
2
SHFILEINFO sInfo;
// 在xp下读取目录图标,strFile可以为空,但是读出来的图标可能是不是我们想要的,可以读目录"c:\\windows"的图标来显示普通文件夹,这个文件夹xp、win7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
都有。 
     CString  strFile = _T( "folder" );
     SHGetFileInfo(strFile, FILE_ATTRIBUTE_DIRECTORY, &sInfo, sizeof (sInfo),
         SHGFI_USEFILEATTRIBUTES|SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
     this ->m_ListCtrl1.InsertItem(0, strFile, sInfo.iIcon);
     if (sInfo.hIcon)
         DestroyIcon(sInfo.hIcon);
 
     strFile = _T( "c:\\windows" );
     SHGetFileInfo(strFile, FILE_ATTRIBUTE_DIRECTORY, &sInfo, sizeof (sInfo),
         SHGFI_USEFILEATTRIBUTES|SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
     this ->m_ListCtrl1.InsertItem(1, strFile, sInfo.iIcon);
     if (sInfo.hIcon)
         DestroyIcon(sInfo.hIcon);

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        // 获取本机cpp文件图标的用法,其他文件突变类似,就是读取 .+后缀名 的图标
     strFile = _T( ".cpp" );
     SHGetFileInfo(strFile, FILE_ATTRIBUTE_NORMAL, &sInfo, sizeof (sInfo),
         SHGFI_USEFILEATTRIBUTES|SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
     this ->m_ListCtrl1.InsertItem(2, strFile, sInfo.iIcon);
     if (sInfo.hIcon)
         DestroyIcon(sInfo.hIcon);
 
     strFile = _T( ".h" );
     SHGetFileInfo(strFile, FILE_ATTRIBUTE_NORMAL, &sInfo, sizeof (sInfo),
         SHGFI_USEFILEATTRIBUTES|SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
     this ->m_ListCtrl1.InsertItem(3, strFile, sInfo.iIcon);
     if (sInfo.hIcon)
         DestroyIcon(sInfo.hIcon);


1
2
3
4
5
6
7
8
         // 硬盘盘符的图标跟目录的图标又不一样,这时候直接获取本机c盘的盘符
     strFile = _T( "c:\\" );
     SHGetFileInfo(strFile, FILE_ATTRIBUTE_DIRECTORY, &sInfo, sizeof (sInfo),
         SHGFI_USEFILEATTRIBUTES|SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
     this ->m_ListCtrl1.InsertItem(4, strFile, sInfo.iIcon);
     if (sInfo.hIcon)
         DestroyIcon(sInfo.hIcon);


1
2
3
4
5
6
7
    // 对于没有后缀名的文件类型,只有这么取
strFile = _T( "file" );
SHGetFileInfo(strFile, FILE_ATTRIBUTE_NORMAL, &sInfo, sizeof (sInfo),
     SHGFI_USEFILEATTRIBUTES|SHGFI_SMALLICON|SHGFI_SYSICONINDEX);
this ->m_ListCtrl1.InsertItem(5, strFile, sInfo.iIcon);
if (sInfo.hIcon)
     DestroyIcon(sInfo.hIcon);

调用SHGetFileInfo获取ImageList的时候,系统会给进程创建一个ImageList的拷贝,里面只有很少的系统图标,当你再次用SHGetFileInfo获取某个文件或者文件类型的图标时,系统会把这个图标加到进程的ImageList中,这时候再用InsertItem(5, strFile, sInfo.iIcon);才能显示图标,如果不使用SHGetFileInfo去得文件图标,而是用InsertItem(5, strFile, 7); 直接加个图标索引值,如7。大多数情况是无法正确显示图标的。

工程文件 http://files.cnblogs.com/jianu/SHGetFileInfo.zip


你可能感兴趣的:(应用层)