首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何获得IShellFolder的PIDL

如何获得IShellFolder的PIDL
EN

Stack Overflow用户
提问于 2009-11-19 20:26:41
回答 5查看 5.5K关注 0票数 7

如果我有一个IShellFolder接口指针。我怎样才能获得它的PIDL?

我可以看到如何枚举它的子级,以及如何使用它来比较任何两个子级。但我怎么能得到它自己的皮德尔呢?

我问是因为我想知道:

这是IShellFolder ==另一个IShellFolder吗?

我可以使用IShellFolder::CompareIDs(),但是我必须有两个文件夹的I。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-11-19 23:34:19

我发现您可以查询IShellFolder的IPersistFolder2,它有GetCurFolder(),它返回其绝对PIDL。然后,我可以简单地使用桌面的IShellFolder来确定它们是否相等。在查看SHGetIDListFromObject时,我找到了这方面的轮廓。我不能只使用这个功能,因为它的Vista,我需要XP兼容性。

下面是它如何工作的草图(假设您有一个ifolder_desktop和ifolder_other,它们是IShellFolder指针)。Pidl是一个简单的助手,它确保适当地释放IDLIST):

代码语言:javascript
运行
复制
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);

如果有人对我的简单Pidl课程感兴趣:

代码语言:javascript
运行
复制
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;
};
票数 6
EN

Stack Overflow用户

发布于 2010-11-14 17:09:15

克里斯或莫迪凯在#1上所写的话无论如何都不是重点所在。问题不在于shell命名空间中的对象,而在于具有IShellFolder接口的对象。拥有IShellFolder接口本身并不意味着在shell命名空间中存在。最初的问题是格式不正确的,因为它假设一个具有IShellFolder接口的对象必须有“它自己的PIDL”。

我认为,你能做的最好的就是莫迪凯所建议的:

  • 查看对象是否也具有IPersistFolder2接口

此接口的目的是修复shell命名空间中的对象,这反过来又使文件夹持久。与其从没有发布的文档中推断,不如看看微软对IPersistFolderIPersistFolder2接口以及初始化和方法的实际描述。最值得注意的是:

您需要实现这个接口,以便可以检索Shell文件夹对象的ITEMIDLIST。

第二,我担心克里斯肯定是不对的。一个IShellFolder当然可以得到没有皮德尔。Chris为#1引入的控制面板为#2提供了一个现成的反例。您可以完全可用地实例化控制面板,而不需要“了解PIDL”。

还有一些在SHELL32中实现的其他可创建的shell文件夹,任何DLL都可以设置任意数量的其他文件夹。

票数 8
EN

Stack Overflow用户

发布于 2010-11-16 07:23:02

我忘记提到SHGetIDListFromObject函数了。

它只能在Windows和更高版本中使用。它的优点是被记录下来,尽管很简洁。当然,您可以从我自己的文件获得更多的细节。这表明Microsoft知道另外两种获取指向shell命名空间中对象的任意接口指针的PIDL的方法。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1766275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档