C++ 使用SHGetPathFromIDList将PIDL转换为文件路径
我的应用程序以字符串形式接收PIDL:C++ 使用SHGetPathFromIDList将PIDL转换为文件路径,c++,winapi,shell,C++,Winapi,Shell,我的应用程序以字符串形式接收PIDL: QString pidl = "::{20D04FE1-3AEA-1069-A2D8-08002B30309B}"; 在这种情况下,它对应于我的电脑。我需要把它转换成我的电脑 有一个WINAPI函数SHGetPathFromIDList,它需要LPCITEMIDLIST作为第一个参数,并将其转换为字符串 如何构建该LPCITEMIDLIST 更新 到目前为止,我得到的是: LPCWSTR csPath = (LPCWSTR)"::{20D04FE1-3A
QString pidl = "::{20D04FE1-3AEA-1069-A2D8-08002B30309B}";
在这种情况下,它对应于我的电脑。我需要把它转换成我的电脑
有一个WINAPI函数SHGetPathFromIDList
,它需要LPCITEMIDLIST
作为第一个参数,并将其转换为字符串
如何构建该LPCITEMIDLIST
更新
到目前为止,我得到的是:
LPCWSTR csPath = (LPCWSTR)"::{20D04FE1-3AEA-1069-A2D8-08002B30309B}";
LPITEMIDLIST stId = 0;
SFGAOF stSFGAOFIn = 0;
SFGAOF stSFGAOFOut = 0;
if(!FAILED(SHParseDisplayName(csPath, 0, stId, stSFGAOFIn, &stSFGAOFOut)))
msgBox("not failed")
不幸的是,此代码崩溃。您需要的函数不是
SHGetPathFromIDList
,因为没有“我的电脑”的路径
要将QString pidl转换为PIDLIST\u绝对值
,需要使用SHParseDisplayName
要将
PIDLIST\u ABSOLUTE
转换为像“我的电脑”这样的本地化字符串,您需要SHGetNameFromIDList
您需要的函数不是shgetpathfromiddlist
,因为没有“我的电脑”的路径
要将QString pidl转换为PIDLIST\u绝对值
,需要使用SHParseDisplayName
要将PIDLIST\u ABSOLUTE
转换为像“我的电脑”这样的本地化字符串,您需要SHGetNameFromIDList
我认为可能是:
SHParseDisplayName(csPath、0和stId、stSFGAOFIn和stSFGAOFOut)
来自MSDN的SHParseDisplayName声明:
HRESULT SHParseDisplayName(
__in LPCWSTR pszName,
__in_opt IBindCtx *pbc,
__out PIDLIST_ABSOLUTE *ppidl,
__in SFGAOF sfgaoIn,
__out_opt SFGAOF *psfgaoOut
);
我认为可能是:
SHParseDisplayName(csPath、0和stId、stSFGAOFIn和stSFGAOFOut)
来自MSDN的SHParseDisplayName声明:
HRESULT SHParseDisplayName(
__in LPCWSTR pszName,
__in_opt IBindCtx *pbc,
__out PIDLIST_ABSOLUTE *ppidl,
__in SFGAOF sfgaoIn,
__out_opt SFGAOF *psfgaoOut
);
由于未正确设置
SHParseDisplayName()
的第一个和第三个参数,代码崩溃。请尝试以下方法:
LPCWSTR csPath = L"::{20D04FE1-3AEA-1069-A2D8-08002B30309B}";
PIDLIST_ABSOLUTE stId = NULL;
SFGAOF stSFGAOFIn = 0;
SFGAOF stSFGAOFOut = 0;
if (!FAILED(SHParseDisplayName(csPath, NULL, &stId, stSFGAOFIn, &stSFGAOFOut)))
msgBox("not failed")
由于未正确设置
SHParseDisplayName()
的第一个和第三个参数,代码崩溃。请尝试以下方法:
LPCWSTR csPath = L"::{20D04FE1-3AEA-1069-A2D8-08002B30309B}";
PIDLIST_ABSOLUTE stId = NULL;
SFGAOF stSFGAOFIn = 0;
SFGAOF stSFGAOFOut = 0;
if (!FAILED(SHParseDisplayName(csPath, NULL, &stId, stSFGAOFIn, &stSFGAOFOut)))
msgBox("not failed")
此函数在以下定义下的
Shlobj.h
中定义:\if(\u WIN32\u WINNT>=0x0501)/*XP*/
。我不能用它(未定义的引用错误。@Alex如果您打算支持Windows 2000或Windows 98,您可能会遇到问题。但是,如果Windows XP/Vista/7是您的基线,您应该define\u WINNT=0x0501
,然后该函数将可用。感谢您的提示。我成功导入了该函数。不过,运行我添加到其中的代码时文章的结尾会导致崩溃…您不能将单字节字符串强制转换为(LPCWSTR)
。您需要实际声明一个unicode字符串。在它前面加一个L
QString pidl=L:“{20D04FE1-3AEA-1069-A2D8-08002B30309B}”
不是这样的…错误发生在SHParseDisplayName函数中。当它被注释掉时,没有崩溃。此函数在Shlobj.h
中定义为以下定义:\if(\u WIN32\u WINNT>=0x0501)/*XP*/
。我不能使用它(未定义的引用错误。@Alex如果您打算支持Windows 2000或Windows 98,您可能会遇到问题。但是,如果Windows XP/Vista/7是您的基线,您应该define\u WINNT=0x0501
,然后该函数将可用。感谢您的提示。我成功导入了该函数。不过,运行我添加到其中的代码时文章的结尾会导致崩溃…您不能将单字节字符串强制转换为(LPCWSTR)
。您需要实际声明一个unicode字符串。在它前面加一个L
QString pidl=L:“{20D04FE1-3AEA-1069-A2D8-08002B30309B}”
不是这样的…错误发生在SHParseDisplayName函数中。当它被注释掉时,没有崩溃。我正在使用您的代码,并且获取无法将参数“3”的“_itemidlelist**”转换为“lpitemidlelist{aka _itemidlelist*”,以“LONG SHParseDisplayName(LPCWSTR,IBindCtx*,lpitemidlest,SFGAOF,SFGAOF*)”
(我在Qt Creator中编译它)函数没有正确声明,因为第三个参数实际上是:\u out PIDLIST\u ABSOLUTE*ppidl
中的一个PIDLIST\u ABSOLUTE*
(又名LPITEMIDLIST*
)参数(PIDLIST_ABSOLUTE
和LPITEMIDLIST
是相同的,PIDLIST_ABSOLUTE
只是让读者更清楚地了解运行时语义).PIDLIST\u ABSOLUTE/LPITEMIDLIST
是一种指针数据类型,函数必须通过附加指针引用变量,以便更新变量的值,以便代码可以使用它。那么我需要做什么来修复它呢?好的,我已经更新了头,现在它生成了LPITEMIDLIST对象。最后一个问题:是我可以为我的计算机、文档、回收站等找到预设值,以便我可以查看LPItemIdle列表下的确切内容。没关系,所有PIDL对于所有系统都是相同的,因此我可以手动创建包含所有特殊虚拟文件夹的字典。我正在使用您的代码,并且获取无法将“\u ItemIdle**”转换为“LPItemIdle”{aka _ITEMIDLIST*}参数“3”到“LONG SHParseDisplayName(LPCWSTR,IBindCtx*,LPITEMIDLIST,SFGAOF,SFGAOF*)”
(我在Qt Creator中编译它)函数没有正确声明,因为第三个参数实际上是一个PIDLIST_绝对值*
(akaLPITEMIDLIST*
)在:\u out PIDLIST\u ABSOLUTE*ppidl
(PIDLIST\u ABSOLUTE
和LPITEMIDLIST
是相同的,PIDLIST\u ABSOLUTE
只是让读者更清楚运行时语义).PIDLIST\u ABSOLUTE/LPITEMIDLIST
是一种指针数据类型,函数必须通过附加指针引用变量,以便更新变量的值,以便代码可以使用它。那么我需要做什么来修复它呢?好的,我已经更新了头,现在它生成了LPITEMIDLIST对象。最后一个问题:是我可以为我的计算机、文档、回收箱等找到预设值,以便查看LPItemIdle列表下的确切内容。没关系,所有系统的所有PIDL都是相同的,因此我可以手动创建