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

来源:互联网 发布:超级基因优化液起点 编辑:程序博客网 时间:2024/06/10 11:05

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

PIDL   

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

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

[cpp] view plaincopyprint?
  1. typedef struct _ITEMIDLIST {  
  2.  SHITEMID mkid;  
  3.  } ITEMIDLIST, *LPITEMIDLIST;  

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

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

[cpp] view plaincopyprint?
  1. #include <Windows.h>  
  2. #include <ShlObj.h>  
  3.   
  4. int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd )  
  5.  {  
  6.      IShellFolder   *g_psfCurFolder = NULL;  
  7.      SHGetDesktopFolder(&g_psfCurFolder);  
  8.      LPENUMIDLIST   pEnum;//其实就是EnumList *  
  9.      if(SUCCEEDED(g_psfCurFolder->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,&pEnum)))  
  10.      {  
  11.          LPITEMIDLIST   pidlTemp;  
  12.          DWORD          dwFetched = 1;    
  13.          while(S_OK == (pEnum->Next(1, &pidlTemp, &dwFetched)) && dwFetched)  
  14.          {  
  15.              char szPath[255];  
  16.              SHGetPathFromIDList(pidlTemp,(LPWSTR)szPath);                             
  17.              MessageBox(NULL,(LPWSTR)szPath,TEXT("Message"),MB_OK);  
  18.          }  
  19.      }     
  20.      return 0;  
原创粉丝点击