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

本文将从PIDL的定义出发,详细介绍如何通过PIDL获取和操作Shell编程中的外壳名字空间,包括如何获取桌面的PIDL、IShellFolder接口的使用方法,以及如何通过PIDL遍历和操纵整个外壳名字空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        这几天想学习下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;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iot-genius

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值