Mor*_*hai 7 c++ com winapi windows-shell
如果我有一个IShellFolder接口指针.我怎样才能获得它的PIDL?
我可以看到如何枚举它的孩子,我可以看到如何使用它来比较任何两个孩子.但是我怎么能得到它自己的pidl?
我问,因为我想知道:
这是IShellFolder ==另一个IShellFolder
我可以使用IShellFolder::CompareIDs(),但我必须拥有两个文件夹的ID.
小智 7
Chris或Mordechai在#1上所写的内容无论如何都不是重点.问题不是关于shell命名空间中的对象,而是关于具有IShellFolder接口的对象.拥有IShellFolder接口本身并不意味着存在于shell命名空间中.原始问题是不正确的,因为它假定具有IShellFolder接口的对象必须具有"自己的PIDL".
我认为,你能做的最好的就是Mordechai建议的:看看对象是否还有一个IPersistFolder2接口.此接口的目的是将对象固定在shell命名空间中,这又使文件夹可以保持不变.不要推断任何已发布文档的缺失,而是看看Microsoft实际上对IPersistFolder和IPersistFolder2接口以及Initialize和GetCurFolder方法的说法.最值得注意的是,"您需要实现此接口,以便可以检索Shell文件夹对象的ITEMIDLIST."
在#2,我担心克里斯肯定不正确.当然可以在没有PIDL的情况下获得IShellFolder.Chris为#1引入的控制面板为#2提供了一个现成的反例.只需将CLSID_ControlPanel和IIS_IShellFolder提供给CoCreateInstance即可.您可以获得一个完全可用的控制面板实例,而无需"了解PIDL".在SHELL32中实现了一些其他可创建的shell文件夹,任何DLL都可以设置任意数量的其他文件夹.
我发现你可以向IShellFolder查询它的IPersistFolder2,它有GetCurFolder(),它返回它的绝对PIDL.然后,我可以简单地使用桌面的IShellFolder来CompareIDs()来确定它们是否相等.我在查看SHGetIDListFromObject时找到了这个概述.我不能只使用该功能,因为它的Vista,我需要XP兼容性.
下面是它如何工作的草图(假设你有一个ifolder_desktop和ifolder_other,它们是IShellFolder指针.Pidl是一个简单的帮助器,可以确保正确释放IDLIST):
CComQIPtr<IPersistFolder2> ipf2_desktop(ifolder_desktop);
CComQIPtr<IPersistFolder2> ipf2_folder(ifolder_other);
Pidl pidl_desktop, pidl_folder;
VERIFY(SUCCEEDED(ipf2_desktop->GetCurFolder(pidl_desktop)));
VERIFY(SUCCEEDED(ipf2_folder->GetCurFolder(pidl_folder)));
HRESULT hr = ifolder_desktop->CompareIDs(NULL, pidl_desktop, pidl_folder);
pCmdUI->Enable(SUCCEEDED(hr) && HRESULT_CODE(hr) != 0);
Run Code Online (Sandbox Code Playgroud)
如果有人对我的简单Pidl类感兴趣:
class Pidl
{
public:
// create empty
Pidl() : m_pidl(NULL) { }
// create one of specified size
explicit Pidl(size_t size) : m_pidl(Pidl_Create(size)) {}
// create a copy of a given PIDL
explicit Pidl(const ITEMIDLIST * pidl) : m_pidl(Pidl_Copy(pidl)) {}
// create an absolute PIDL from a parent + child
Pidl(const ITEMIDLIST_ABSOLUTE * pParent, const ITEMIDLIST_RELATIVE * pChild) : m_pidl(Pidl_Concatenate(pParent, pChild)) { }
// return our PIDL for general use (but retain ownership of it)
operator const ITEMIDLIST * () { return m_pidl; }
// return a pointer to our pointer, for use in functions that assign to a PIDL
operator ITEMIDLIST ** ()
{
free();
return &m_pidl;
}
// release ownership of our PIDL
ITEMIDLIST * release()
{
ITEMIDLIST * pidl = m_pidl;
m_pidl = NULL;
return pidl;
}
void free()
{
if (m_pidl)
//Pidl_Free(m_pidl);
ILFree(m_pidl);
}
// automatically free our pidl (if we have one)
~Pidl()
{
free();
}
private:
ITEMIDLIST * m_pidl;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4535 次 |
| 最近记录: |