动机:创建我们自己的文件对话框,其外观和行为与标准通用对话框非常相似
问题:如何获取当前文件夹/shell容器的视图下拉
明显的死胡同:
- 查询 IShellFolder 的 IContextMenu < NULL 接口指针。
- 查询 IShellView 的 IContextMenu < NULL 接口指针。
- IShellFolder::CreateViewObject(IID_IContextMenu...) < 非常有限的上下文菜单(新)。
- IShellFolder::GetUIObjectOf(IID_IContextMenu...) < 有限的上下文菜单(打开、探索、...)。
- 实现 IShellBrowser 的 InsertMenusSB、RemoveMenusSB 和 SetMenuSB
我花了一些时间阅读实现文件夹视图和如何托管 IContextMenu。这似乎表明上面的最终方法(实现 InsertMenuSB,...)应该有效。IShellView 应该使用适当的项目填充 IShellBrowser 的共享菜单,包括其视图子菜单。但是,到目前为止,我从中得到的只是一个空菜单(除非我用项目填充它——在这种情况下,我只得到我用它填充的项目)。
当然有办法做到这一点。Windows 资源管理器从某个地方到达它显示的菜单(如果您在 Vista 或更高版本上按下 ALT)。而且我无法想象这个菜单是由 Explorer 本身静态构建的 - 它肯定是动态创建的,与当前显示的 IShellView 一致,以允许 shell 扩展显示正确的视图选项列表(和其他菜单选项)。
但是有关InsertMenuSB、RemoveMenuSB和SetMenuSB的文档令人困惑。这似乎表明,作为容器服务器,我应该填充提供的OLEMENUGROUPWIDTHS,“在元素 0、2 和 4 中以反映它在文件、视图和窗口菜单组中提供的菜单元素的数量。”
我已实施以下措施以尝试正确履行本合同:
HRESULT STDMETHODCALLTYPE ShellBrowserDlgImpl::InsertMenusSB(__RPC__in HMENU hmenuShared, /* [out][in] */ __RPC__inout LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
TRACE("IShellBrowser::InsertMenusSB\n");
// insert our main pull-downs
struct
{
UINT id;
LPCTSTR label;
} pull_downs[] = {
{ FCIDM_MENU_FILE, "File" },
{ FCIDM_MENU_EDIT, "Edit" },
{ FCIDM_MENU_VIEW, "View" },
{ FCIDM_MENU_TOOLS, "Tools" },
{ FCIDM_MENU_HELP, "Help" },
};
for (size_t i = 0; i < countof(pull_downs); ++i)
{
VERIFY(AppendMenu(hmenuShared, MF_POPUP, pull_downs[i].id, pull_downs[i].label));
ASSERT(GetMenuItemID(hmenuShared, i) == pull_downs[i].id);
}
// set the count of menu items we've inserted into each *group*
lpMenuWidths->width[0] = 2; // FILE: File, Edit
lpMenuWidths->width[2] = 2; // VIEW: View, Tools
lpMenuWidths->width[4] = 1; // WINDOW: Help
return S_OK;
}
有没有人实现了一个类似资源管理器的项目,可以正确地向最终用户公开当前 IShellView 的菜单?
是否有关于IOLEInPlaceFrame实现的文档/示例可以阐明这个模糊的主题?
啊!@ - 我觉得我必须很接近 - 但还不够接近!