您的位置:首页 > 运维架构 > Shell

Windows Shell 学习笔记一:PIDL(The Struture of the Shell)

2012-09-25 14:27 561 查看
这几天想学习下shell编程,首先就从这个shell的结构开始,从结构开始必定会遇到的一个问题就是PIDL,下面就从自己的学习中做点笔记吧,帮助记忆下。

PIDL

“桌面”是最顶级的文件夹,外壳名字空间中其他各项都可以用从“桌面”开始的 PIDL 加以表示。如何获取“桌面”的 PIDL 和其 IShellFolder 接口呢,可以通过 API SHGetDesktopFolder:

PIDL是一个元素类型为ITEMIDLIST结构的数组,数组中元素的个数是未知的,但紧接着数组末尾的必是一个双字节的零。每个数组元素代表了外壳名字空间树中的一层(即一个文件夹或文件),数组中的前一元素代表的是后一元素的父文件夹。由此可见,PIDL实际上就是指向一块由若干个顺序排列的ITEMIDLIST结构组成、并在最后有一个双字节零的空间的指针。所以PIDL的类型就被Windows定义为ITEMIDLIST结构的指针(LPITEMIDLIST)。这个ITEMIDLIST的定义如下:

typedef struct _ITEMIDLIST {
 SHITEMID mkid;
 } ITEMIDLIST, *LPITEMIDLIST;


  中间对象构成的路径名的不同部分映射到项目的标识符的一个PIDL。他们通过一个SHITEMID结构呈现
typedef struct _SHITEMID {
 USHORT cb; 
BYTE abID[1]; 
} SHITEMID, *LPSHITEMID;




我们可以调用SHGetDesktopFolder函数来获得外壳名字空间的根文件夹(即“桌面”)的IshellFolder接口。对于某个文件夹A,以它的子文件夹B的相对PIDL为参数,调用它的IshellFolder接口的BindToObject方法即可得到子文件夹B的IshellFolder接口。如要枚举某个文件夹下的子项,则只需调用它的IshellFolder接口的EnumObjects方法即可获得一个IEnumIDList接口。通过调用该IEnumIDList接口的Next方法我们即可枚举出该文件夹的所有子项(包括文件夹和文件等对象),获得它们的相对PIDL。使用父文件夹的IshellFolder接口和这些相对PIDL,我们即可获得这些子项的各种相关信息,包括显示名称、图标、属性等,甚至还可以获得它的右键菜单。例如,调用该接口的GetDisplayNameOf方法可获得该文件夹下子项的显示名称;调用ParseDisplayName方法可把某个子项的用Unicode内码表示的字符串路径翻译成对应的PIDL。这样通过PIDL和这两个接口,我们就可以遍历和操纵整个外壳名字空间了。

#include <Windows.h>
#include <ShlObj.h>

int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd )
 {
	 IShellFolder   *g_psfCurFolder = NULL;
	 SHGetDesktopFolder(&g_psfCurFolder);
	 LPENUMIDLIST   pEnum;//其实就是EnumList *
	 if(SUCCEEDED(g_psfCurFolder->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,&pEnum)))
	 {
		 LPITEMIDLIST   pidlTemp;
		 DWORD          dwFetched = 1;	
		 while(S_OK == (pEnum->Next(1, &pidlTemp, &dwFetched)) && dwFetched)
		 {
			 char szPath[255];
			 SHGetPathFromIDList(pidlTemp,(LPWSTR)szPath);                           
			 MessageBox(NULL,(LPWSTR)szPath,TEXT("Message"),MB_OK);
		 }
	 }	 
	 return 0;
 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐