我一直在研究如何实现名称空间扩展。如何在Shell命名空间扩展中使用默认的文件夹视图?
的NSE应显示文件和文件夹(它们是物理文件和文件夹,但所在的磁盘上的其他地方)。
此外,NSE必须的行为尽可能接近正常的资源管理器视图,例如,它必须有:
通常会出现在,都适用于选择- 上下文菜单废料)
- “右键拖放”(如7Zips“提取这里...”)
- 剪贴板复制/剪切/粘贴
- 分享条目
- 任何注册壳牌图标叠加处理程序必须工作(如乌龟SVN/GIT)
- 列宽/重新排序
- 查看自定义,包括排序和分组
所以,基本上什么Explorer视图可以这样做,我们必须。
纵观资源管理器可以做的所有事情(以前我认为理所当然),我感觉有点不知所措。我的计划是在我的NSE中重用资源管理器视图的功能。因为我既懒惰又真实(我意识到几乎不可能复制所有这些功能没有问题),我的计划是重用我的NSE中资源管理器视图的功能。
我看了各种样本的NSEs。其中大多数使用虚拟数据,但正如我所说,我代表磁盘上其他地方的物理文件和文件夹。我也读了关于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
)的指针。我的文件夹刚刚实施了IShellFolder
和IPerist
。
所以在改变这些实现更新的接口后,我得到了......什么都没有! NSE将由Explorer加载,构造函数将被调用,但紧接着,析构函数会被调用。如果我将界面改回原来的状态,它就会启动(但仍然存在同样的问题)。
我一直在寻找一个样本,它实现了IShellFolder2
,但是文档和其余的这些API一样糟糕。
我该如何使用SHCreateShellFolderView
以便我不必重新实现浏览器已经做的所有事情?