如何在Shell命名空间扩展中使用默认文件夹视图?

时间:2011-11-27 13:53:10

标签: winapi com atl explorer windows-shell

我一直在研究如何实现命名空间扩展。

NSE应该显示文件和文件夹(它们是物理文件和文件夹,但位于磁盘上的其他位置)。

此外,NSE必须尽可能接近正常的资源管理器视图,例如它必须有:

  • 通常出现在普通资源管理器视图中的上下文菜单,适用于所选的文件/文件夹
  • 拖放(文件/文件夹和文件碎片等其他内容)
  • '右拖拽'(例如7Zips'Extract here ...')
  • 剪贴板复制/剪切/粘贴
  • 与条目分享
  • 任何已注册的Shell图标叠加处理程序必须正常工作(例如Tortoise SVN / GIT)
  • 列大小调整/重新排序
  • 查看自定义,包括订购和分组

所以,基本上任何资源管理器视图都可以这样做。

看看资源管理器可以做的所有事情(我以前认为理所当然),我感到有些不知所措。

因为我既懒惰又是现实主义者(我意识到在没有问题的情况下复制所有这些功能几乎是不可能的),我的计划是在我的NSE中重用资源管理器视图的功能

我查看了各种NSE样本。其中大多数使用虚拟数据,但正如我所说,我在磁盘上的其他地方表示物理文件和文件夹。我还阅读了SHCreateShellFolderView方法。

有了这些信息,我认为提供PIDL我的根文件夹然后使用IShellFolder::CreateViewObject调用SHCreateShellFolder方法是一个相对简单的案例。这是方法:

STDMETHODIMP CShellFolderImpl::CreateViewObject( 
    HWND hwndOwner, 
    REFIID riid, 
    void** ppvOut )
{
    HRESULT hr=E_NOINTERFACE;

    if ( NULL == ppvOut )
        return E_POINTER;

    *ppvOut = NULL;

    if (riid == IID_IShellView)
    {
        SFV_CREATE SfvCreate = 
        {
            sizeof(SFV_CREATE) 
        };


        if (SUCCEEDED(hr = QueryInterface(IID_PPV_ARGS(&SfvCreate.pshf))))
        {
            hr = ::SHCreateShellFolderView(
                &SfvCreate, 
                reinterpret_cast<IShellView **>(ppvOut));
        }

        SfvCreate.pshf->Release();
    }
    else if (riid == IID_ITransferSource)
    {

    }

    return hr;
}

没有这样的运气。 SHCreateShellFolderView始终返回E_NOTIMPL。事实证明这是因为它需要指向实现IShellFolder2(和IPersist2 GetCurFolder的内容的指针,我可以提供PIDL。我的文件夹刚刚实施了IShellFolderIPerist

因此,在更改这些以实现更新的接口后,我得到了......没有! NSE将由Explorer加载,构造函数将被调用,但紧接着之后,将调用析构函数。如果我将接口更改回原来的样式,它会启动(但仍然存在同样的问题)。

我一直在寻找一个实现IShellFolder2示例,但同样,文档与其他API一样糟糕。

如何使用SHCreateShellFolderView以便我不必重新实现Explorer已经执行的所有操作?

1 个答案:

答案 0 :(得分:2)

即使您能够为命名空间扩展使用和嵌入Windows资源管理器窗口,问题在于您不再能够控制它的功能。例如,如果用户双击文件夹,将浏览实际的文件系统文件夹,而不是代表文件系统文件夹的命名空间扩展节点。

您唯一的选择就是自己实施。查看EZNamespaceExtensionsMFC,这使得开发命名空间扩展变得非常容易。它有一个“FileSystemBrowser”示例,您可以将其用作起点。

免责声明:我为LogicNP工作,这是EZNamespaceExtensionsMFC的开发者。