取得文件夹内容信息(使用IShellFolder接口)
翻译自MSDN 2005 -> Win32 和 COM 开发 -> User Interface -> Windows User Experience -> Windows Shell -> Shell Programmer's Guide -> Shell Basics -> Shell Basics: Programming the Shell -> Getting Information About the Contents of a Folder
Getting a Folder's ID 讨论了两种获取Shell对象PIDL的方法。一个显然的问题是:获取PIDL后,可以用它做什么?一个相关问题是:哪种方法可以用于你的程序,或者适合 你的程序?要回答这两个问题需要更深入考察下名字空间是如何实现的。名字空间实现的关键是IShellFolder接口。
使用IShellFolder接口
前面的文档中,名字空间文件夹被称作“对象”。这个术语的使用好像不太严格,但实际上从严格意义上讲,这个术语也是合适的,因为每个名字空间文件夹都由一 个COM对象表示。每个文件夹对象实现了很多可以用于各种任务的接口。有些接口是可选的,不是每个文件夹都实现了,但每个文件夹都必须实现基本接口IShellFolder 。
要使用文件夹,首先需要获取其IShellFolder 接口指针。IShellFolder接口指针除了可以提供对对象其他接口的访问外,还提供了处理很多通常任务的方法,本文将讨论某些通常任务。
要获取Shell对象的IShellFolder 接口指针,首先调用SHGetDesktopFolder ,它会返回名字空间根,即桌面的IShellFolder 接口指针。获取了桌面对象的IShellFolder接口指针后,有很多方法进行下一步。
如果已经有要处理的文件夹的PIDL了(比如说,通过SHGetFolderLocation 获取的),可以用桌面对象的(IShellFolder接口指针的)BindToObject 方法获取文件夹的IShellFolder 接口指针。如果已经有文件系统对象的路径了,可以先用桌面对象的ParseDisplayName 方法获取其PIDL,然后再调用BindToObject 。如果这两种方法都不可用,可以用IShellFolder 的其他方法浏览名字空间(并定位到要处理的文件夹),详情请参考Navigating the Namespace 。
枚举文件夹内容
文件夹处理的第一件事通常是看看它包含什么内容,这时可以先调用文件夹的EnumObjects 方法。方法会创建标准OLE枚举对象并返回其IEnumIDList 接口。枚举接口含有4个标准方法:Clone 、Next 、Reset 、Skip 。这些方法可用于枚举文件夹内容。
枚举文件夹内容的基本过程是:
- 调用EnumObjects 方法获取枚举对象的IEnumIDList 接口
- 调用IEnumIDList 的Next 方法,传入一个未分配的PIDL。Next 会为PIDL分配内存,但须由调用方释放分配的内存。Next 返回的PID只含有对象的item ID和表示结束的NULL字符。也就是说,返回的是相对于所在文件夹的单层PIDL,不是全限定PIDL。
- 重复步骤2直到Next 方法返回S_FALSE ,这表示所有内容条目已经枚举完成。
- 调用IEnumIDList::Release 释放枚举对象。
注意:要注意当前使用的是相对PIDL还是全限定PIDL。某些函数可以接受两种类型的PIDL,但是有些却只能接受一种类型的。IEnumIDList的另外3个方法可用于重复枚举文件夹内容。这3个方法可以复位枚举过程、跳过一个或者多个对象、制作枚举对象的副本以保存其状态。
确定显示名和其他属性
在枚举了文件夹包含的所有PIDL后,就可以发现它们所代表的对象类型。IShellFolder 接口提供了很多有用的方法,这里只讨论两个。IShellFolder 接口的其他方法和其他Shell文件夹接口在本系列后面的文章中讨论。
显示名是对象的最重要属性之一。要获取对象的显示名,把PIDL传递给GetDisplayNameOf 即可。对象可以位于名字空间中父文件夹以下的任何地方,但PIDL必须是相对于父文件夹的。
GetDisplayNameOf 把显示名作为STRRET 对象的一部分返回。因为从STRRET 结构取出显示名需要一点技巧,所以Shell为你提供了两个函数,StrRetToStr 和StrRetToBuf 。这两个函数都需要一个STRRET 结构体,把显示名作为普通字符串返回。它们的不同在于字符串是如何分配的。
除了显示名外,对象还可以有很多其他属性,比如说,对象是否是文件夹,是否可以被移动。把对象的PIDL传给GetAttributesOf 就可以获取其属性。完整的属性列表很长,细节可以参考相关文档。注意传递给GetAttributesOf 的PIDL必须是单层的。特别是,GetAttributesOf 可以接受Next 返回的PIDL。可以传入一个PIDL数组,GetAttributesOf 会返回数组中所有对象共有的属性。
如果有对象的全限定路径名或者PIDL,SHGetFileInfo 提供了一种获取足够用于多种目的的对象信息的简单方法。SHGetFileInfo 返回的信息包括:
- 对象的显示名
- 对象属性
- 对象图标句柄
- 系统图像列表句柄
- 包含对象图标的文件的路径
获取子文件夹的IShellFolder接口指针
调用GetAttributesOf ,检查SFGAO_FOLDER 标志是否已设置就可以确定文件夹是否含有子文件夹。如果对象是文件夹,就可以绑定到它,这可以提供对象的IShellFolder 接口。
要绑定到文件夹,调用父文件夹的BindToObject 方法。方法要求传入子文件夹的PIDL,并返回其IShellFolder 接口指针。有了这个指针后,就可以枚举文件夹的内容,确定其属性等。
确定对象的父文件夹
如果已有某对象的PIDL,可能需要其父文件夹暴露的某个接口。比如说,如果想用GetDisplayNameOf 确定父文件夹的显示名,必须先获取父对象的IShellFolder 接口。可以用上一节讨论的技术来达到目的,但有一种更简单的方法,就是使用SHBindToParent 方法。这个方法要求传入对象的全限定PIDL,并且返回父文件夹的特定接口指针。SHBindToParent 还可以返回对象的单层PIDL以用于GetAttributesOf 等方法。
下面的示例控制台应用程序获取系统特别文件夹的PIDL,并且返回其显示名。
|
#include <shlobj.h> hr = SH GetMalloc_r(&pMalloc); |
应用程序首先获取Shell分配器的IMalloc 接口指针,并且用SHGetFolderLocation 获取系统文件夹的PIDL。然后程序调用SHBindToParent 获取系统文件夹父文件夹的IShellFolder 接口,以及相对于父文件夹的PIDL。然后使用父文件夹的GetDisplayNameOf 方法获取系统文件夹的显示名。
对于GetDisplayNameOf返回的STRRET结构体,可以用StrRetToBuf把显示名转换成普通字符串。在显示了显示名后,接口指针和系统PIDL都被释放。注意不能释放SHBindToParent返回的相对PIDL。
本文转载自:http://blog.sina.com.cn/s/blog_56dee71a0100frhy.html
http://blog.csdn.net/akof1314/article/details/5490985
取得文件夹内容信息(使用IShellFolder接口)的更多相关文章
- 文件下载Controller,文件夹内容监听,文件上传,运行程序通过url实现文件下载
文件下载Controller @RequestMapping("/fileDownLoad") public ResponseEntity<byte[]> fileDo ...
- C# 获取往控件中拖进的文件或文件夹的信息
C# 获取往控件中拖进的文件或文件夹的信息(原创) 在做C#的WinForm开发的时候,有时需要用户往指定的控件中拖进文件或者文件夹.然后根据用户拖进来的文件或者文件夹获取其信息并进行下一 ...
- PHP批量清空删除指定文件夹内容
PHP批量清空删除指定文件夹内容: cleancache.php <?php // 清文件缓存 $dirs = array( realpath(dirname(__FILE__) . '/../ ...
- Windows 下自动同步文件夹内容到另一个文件夹下
实现windows 使用bat脚本文件,复制文件夹到另一个盘,参考如下代码:/y是可以不显示:提示你需要覆盖一个文件,如下图: bat文件内容为 @echo off echo "使用bat脚 ...
- kafka flumn sparkstreaming java实现监听文件夹内容保存到Phoenix中
ps:具体Kafka Flumn SparkStreaming的使用 参考前几篇博客 2.4.6.4.1 配置启动Kafka (1) 在slave机器上配置broker 1) 点击CDH上的kafk ...
- 用JUNCTION映射文件夹内容 解决多系统跑同一个虚拟机而共享文件夹路径不同的问题
事情由来: 某机器安装了俩系统,WIN7X64用来玩PC游戏,WIN2012R2用来工作,系统分别在两个不同的分区,但进入到系统后,两个系统的系统盘都是C盘.换句话说,在WIN7里,分区1是C盘,分区 ...
- 【linux】复制文件夹内容到另一个文件夹
我一直觉得cp是个非常简单的指令.结果居然遇到坑了.记录一下. 文件夹1:test1/ 文件夹2:test2/ 目标:将test1/中的所有文件和目录拷贝到test2/中 正确指令: cp -rf t ...
- Swift 拷贝文件夹,实现文件夹内容整体复制
我们知道,在沙盒内,iOS要拷贝一个文件,可以使用 fileManager.copyItem(atPath: fullPath, toPath: fulltoPath) 方法简单实现,不过当我们要拷贝 ...
- 使用7za压缩zip包的命令,当中屏蔽部分文件夹内容
7za.exe a -r "D:\paages\prduct\produtConfig.zip" "E:/tm\packaes\poduct" -xr!doc ...
随机推荐
- 【Codeforces Round #438 A】Bark to Unlock
[链接]h在这里写链接 [题意] 在这里写题意 [题解] 枚举它是在连接处,还是就是整个字符串就好. [错的次数] 0 [反思] 在这了写反思 [代码] #include <bits/stdc+ ...
- Struts2——(3)ValueStack(值栈)
一.ValueStack 主要用于存储请求相关信息,内部结构如下 root区:被称为根存储区,是一个栈结构,栈顶元素为当前请求的Action对象. context区:被称为变量存储区,是一个Map结构 ...
- altium designer电气符号和包的常用元素
1. 标准电阻:RES1.RES2.包裹:AXIAL-0.3至AXIAL-1.0 两port可变电阻器:RES3.RES4.包裹:AXIAL-0.3至AXIAL-1.0 三port可变电阻:RESIS ...
- http_load测试初阶
http_load的标准的两个例子是: 1. http_load -parallel 5 -fetches 1000 urls.txt 2. http_load -ra ...
- TBB、OpenCV混合编程
TBB提供了Parallel_for.Parallel_do.Parallel_reduce等通用并行算法,可以应用在不同的并行算法场合,Parallel_for适合用在多个数据或请求之间彼此没有依赖 ...
- WPF Bind 绑定
原文:WPF Bind 绑定 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/koloumi/article/details/74332515 用过W ...
- 好玩的WPF第四弹:用Viewport2DVisual3D实现3D旋转效果
原文:好玩的WPF第四弹:用Viewport2DVisual3D实现3D旋转效果 版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https:// ...
- 各linux版本重启apache命令
各linux版本重启apache命令 Slackware Linux命令: /etc/rc.d/rc.httpd restart ubuntu.Debian 系统命令: /etc/init.d/apa ...
- 【 D3.js 入门系列 --- 6 】 如何使移动图表
我的个人博客是: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. [5.1]节中制作了一个比較完好的图表.但它是静态的.想做出它的动 ...
- .net core service && angular项目 iis发布
项目结构 .net core 后端服务站点 angular 前端页面站点 项目模板来自于abp或者52abp .net core 后端服务站点发布到IIS 发布报错 .Net Core使用IIS部署出 ...