【问题标题】:C++ Winapi - Get Directory (path) identifierC++ Winapi - 获取目录(路径)标识符
【发布时间】:2016-05-27 15:57:45
【问题描述】:

我正在使用 Winapi 的函数SHBrowseForFolder,我需要设置一个默认文件夹进行浏览。为此,我需要获取所需的默认文件夹的“PIDL”。我可以使用此函数获得“PIDL”:SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);,但正如您所见,second 参数是另一个标识符“nCSIDL”(类型 int)。

如何通过路径 (LPCSTR) 获取路径标识符?

这是我的代码:

TCHAR szDir[MAX_PATH];
BROWSEINFO bInfo;
HWND hwnd = ObPanelAPI::GetPanelHandleByName("*Current");
bInfo.hwndOwner = hwnd;
bInfo.pszDisplayName = szDir;
bInfo.lpszTitle = "Seleccionar directorio"; //Dialog title
bInfo.ulFlags = 0 ;
bInfo.lpfn = NULL;
bInfo.lParam = 0;
bInfo.iImage = -1;

//Default folder set
LPITEMIDLIST pidlRoot = NULL;

//*******I NEED TO GET nCSIDL HERE********

SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);
bInfo.pidlRoot = pidlRoot; 

LPITEMIDLIST lpItem = SHBrowseForFolder(&bInfo);

【问题讨论】:

  • 您想从路径中解析 CSIDL(常量特殊项 ID 列表)值吗?
  • @Emil 好的,正如您所说,这些数字是引用系统定义文件夹的常量。我不明白,我应该如何获得文件夹标识符? :s
  • 嗯,我从未听说有人需要这样做。为什么需要标识符?查看路径是否为“特殊文件夹”?
  • 这是一个奇怪的线程。 CSIDL 和 KNOWNFOLDERID 是常量值,即使它们引用的磁盘上的实际路径可能会发生变化。因此,如果您想从配置文件文件夹开始,您可以使用 CSIDL_PROFILEFOLDERID_Profile 以及适当的函数将它们转换为 PIDL。这些值都列在 MSDN 文档中。

标签: c++ winapi path directory identifier


【解决方案1】:

我正在使用 Winapi 的函数SHBrowseForFolder,我需要设置一个默认文件夹进行浏览。为此,我需要获取所需的默认文件夹的“PIDL”。

首先,您需要在这里区分一些东西。 BROWSEINFO 有一个 pidlRoot 字段,它指定浏览对话框显示的最顶层文件夹。用户无法选择该文件夹上方的项目。这与“默认文件夹”不同,后者只是对话框出现时在所选根目录中最初选择的文件夹。

要设置“默认文件夹”,您实际上并不需要 PIDL,您可以使用路径字符串来代替(对话框接受两者)。将指向路径字符串的指针分配给BROWSEINFO.lParam 字段,并在BROWSEINFO.lpfn 字段中提供回调函数。在回调内部,当它收到BFFM_INITIALIZED 通知时,它可以向对话框发送BFFM_SETSELECTION 消息,将wParam 参数设置为TRUE,并将lParam 参数设置为路径字符串指针。这记录在 MSDN 上:

BFFCALLBACK function pointer

BFFM_SETSELECTION
指定要选择的文件夹的路径。路径可以指定为字符串或 PIDL。

现在,话虽如此,BROWSEINFO.pidlRoot 字段需要 PIDL,而 BFFM_SETSELECTION 消息确实接受 PIDL 作为输入,所以...

我可以使用这个函数获得“PIDL”:SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);,但正如您所见,second 参数是另一个标识符“nCSIDL”(int 类型)。

该函数用于检索 Microsoft 预定义的特殊文件夹的 PIDL,例如 Documents、AppData、User Profiles 等。这些由常量 CSIDL 值(和 Vista+ 上的 KNOWNFOLDERID 值)标识,它们是在每个 Windows 版本上都保持一致,但根据用户配置,不同系统的特定路径可能会有所不同。

如何通过路径 (LPCSTR) 获取路径标识符?

有几种不同的方法:

  1. IShellFolder::ParseDisplayName()。调用SHGetDesktopFolder()获取Shell命名空间根的IShellFolder,然后调用其ParseDisplayName()解析路径。

  2. SHParseDisplayName()。与上面类似,但有一些额外的选项可用。不过请注意文档中的以下注释:

    您应该从后台线程调用此函数。否则可能会导致 UI 停止响应。

  3. ILCreateFromPath()。然而,据观察,ILCreateFromPath() 并不总是返回与IShellFolder::ParseDisplayName()/SHParseDisplayName() 返回相同的 PIDL,有时这种差异可能会导致诸如 SHBrowseForFolder() 之类的行为不正确。我没有亲身经历过,但其他人声称他们有。您只需要自己尝试一下即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 2019-02-18
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    相关资源
    最近更新 更多