苍梧县沙头镇地震图片:获取文件夹ID

来源:百度文库 编辑:九乡新闻网 时间:2024/05/05 01:06:46

获取文件夹ID

(2009-09-24 21:05:28)转载 标签:

shell

it

分类: Windows 翻译自MSDN 2005 -> Win32 和 COM 开发 -> User Interface -> Windows User Experience -> Windows Shell -> Shell Programmer's Guide -> Shell Basics -> Shell Basics: Programming the Shell -> Getting a Folder's ID    在使用Shell对象前,需要有一种标识它的方法,也就是要获取其PIDL,或者对于文件系统对象,获取其路径。本文介绍两种较简单的获取对象ID的方法。   还有一种更强大的适合任何文件夹的方法,就是使用IShellFolder接口,详情见Getting Information About the Contents of a Folder。 SHBrowseForFolder对话框    要让用户可以浏览名字空间然后选择一个文件夹,可以简单地调用SHBrowseForFolder。调用这个函数会显示一个对话框,其界面跟通用的打开或者另存为对话框相似。   用户选择某文件夹后,函数会返回其全限定PIDL和显示名。如果选定的文件夹位于文件系统中,可以用SHGetPathFromIDList把PIDL转换成文件夹路径。SHBrowseForFolder也可以指定根文件夹,以限制用户可以选取文件夹的范围,因为只有指定的根文件夹下层的文件夹才显示在对话框中。下图是一个根文件夹设置为Program FilesSHBrowseForFolder对话框。 

 

   本文后面会提供一个关于如何使用SHBrowseForFolder的简单例子。

 

特殊文件夹和CSIDL

 

   系统中一些常用的文件夹经过了特殊设计。这些文件夹具有良好定义的用途,并且其中大部分在所有系统中都存在。即使有些文件夹当前不存在,其名字和位置还是定义了的,可以在未来增加。这些特殊文件夹包括所有的系统标准虚拟文件夹,像打印机我的文档网上邻居等。当然也包括一些标准的文件系统文件夹,如程序(Program Files)系统(System)文件夹。

   虽然这些文件夹是系统的标准组件,但它们的名称和在名字空间中的位置却可能不同。比如说,系统文件夹在某些系统上是C:\Winnt\System32,在另一些系统上却是C:\Windows\System32。过去是用环境变量来确定特殊文件夹的名字和位置的,现在Shell提供了更健壮和灵活的方法来标识这些特殊文件夹,即CSIDL。现在应该使用CSIDL了,而不是环境变量。

   CSIDL提供了标识和定位特殊文件夹的统一方法。与环境变量不同的是,CSIDL不仅可以用于文件系统文件夹,还可以用于虚拟文件夹。每个特殊文件夹都分配了一个唯一的CSIDL,比如说,分配给程序文件夹的是CSIDL_PROGRAM_FILES,分配给网上邻居的是CSIDL_NETWORK

   CSIDL与一些Shell函数结合使用可以获取特殊文件夹的PIDL,或者其路径。如果请求的特殊文件夹在系统中还不存在,可以结合CSIDL_FLAG_CREATE标志来创建它。CSIDL可以传给下列函数:

  • SHGetFolderLocation 获取某个特殊文件夹的PIDL
  • SHGetFolderPath  获取某文件系统特殊文件夹的路径

   这两个函数在5.0版的Shell中引入,取代了原来的SHGetSpecialFolderLocationSHGetSpecialFolderPath函数。要在5.0版以前的Shell中使用这两个函数,需要包含可重新发布的DLL: ShFolder.dll

 

使用CSIDL和SHBrowseForFolder的简单例子

 

   下面的示例函数PidlBrowse展示了如何获取Shell分配器IMalloc接口,如何使用CSIDL获取文件夹的PIDL,如何用SHBrowseForFolder让用户选择一个文件夹,函数返回选定文件夹的PIDL和显示名。

 

LPITEMIDLIST PidlBrowse(HWND hwnd, int nCSIDL, LPSTR pszDisplayName)
{
    LPITEMIDLIST pidlRoot NULL;
    LPITEMIDLIST pidlSelected NULL;
    BROWSEINFO bi {0};
    LPMALLOC pMalloc NULL;

    SHGetMalloc(&pMalloc);

    if(nCSIDL)
    {
        SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);
    }

    else
    {
        pidlRoot NULL;
    }

    bi.hwndOwner hwnd;
    bi.pidlRoot pidlRoot;
    bi.pszDisplayName pszDisplayName;
    bi.lpszTitle "Choose folder";
    bi.ulFlags 0;
    bi.lpfn NULL;
    bi.lParam 0;

    pidlSelected SHBrowseForFolder(&bi);

    if(pidlRoot)
    {
        pMalloc->Free(pidlRoot);
    }
    pMalloc->Release();
    return pidlSelected;
}

 

  

   调用者传入一个窗口句柄,这是SHBrowseForFolder需要的;nCSIDL参数是可选的,它用于指定根文件夹,只有层次结构中根文件夹以下的文件夹才会显示。本文前面的那幅图片就是以CSIDL_PROGRAM_FILES作为nCSIDL参数值调用函数时产生的。调用者还需要传入由pszDisplayName参数指定的字符串缓冲区,用于在函数返回时保存选定文件夹的显示名。

    PidlBrowse首先调用SHGetMalloc来获取Shell分配器接口指针。虽然PidlBrowse本身没有分配PIDL,但随后需要用IMalloc接口来释放(别处分配的)PIDL。如果调用者用CSIDL指定了某根文件夹,PidlBrowse会调用SHGetFolderLocation获取文件夹的PIDL。然后PidlBrowse会为BROWSEINFO结构体各成员指定合适的值,并调用SHBrowseForFolder

    用户选择某文件夹后,SHBrowseForFolder会返回其PIDL。选定文件夹的显示名在BROWSEINFO结构体的pszDisplayName成员中返回,然后通过PidlBrowse函数的pszDisplayName参数返回给调用者。最后,PidlBrowse释放根PIDL,释放IMalloc接口,返回选定文件夹的PIDL给调用者。