向托管Web浏览器控件添加自定义上下文菜单

时间:2009-07-08 17:01:44

标签: c++ webbrowser-control atl

我正在托管网络浏览器控件,并希望提供我自己的上下文菜单。

理想情况下,我想提供我自己的上下文菜单,其中包含原始浏览器的上下文菜单(包含所有插件等)作为子菜单。

如果那不可能/狡猾,我会好的,例如通常显示我的上下文菜单,并在用户按下SHIFT时显示原始菜单。

我是否需要实施IDocHostUIHandler?如果是,我如何指定自定义上下文菜单,如何强制原始菜单?如何让控件使用我的实现?

控件是这样创建的(省略错误处理):

HRESULT hr=AtlAxCreateControlEx(
   L"Shell.Explorer",m_wndWebCtrl.m_hWnd,
   NULL,NULL,(IUnknown**)&unk,
   IID_IWebBrowser2, NULL); // (IPersistStreamInit*)this);

hr = AtlAdviseSinkMap( this, true);

IUnknownPtr unk;
AtlAxGetControl(m_wndWebCtrl.m_hWnd, &unk);

IWebBrowser2Ptr browser2 = unk;

2 个答案:

答案 0 :(得分:1)

是的,您需要实施IDocHostUIHandler

好吧,我猜你可以拦截右击,击键和其他通常会显示上下文菜单的消息......但是这可能迟早会破坏;至少,我希望它能打破可访问性。

截取IDocHostUIHandler::ShowContextMenu()后,您可以选择在显示自己的内容后返回S_OK来压制内置菜单。您可以使用常规的Win32菜单例程,一个自定义控件,甚至是花哨的HTML,如果它适合您。根据文档,提供了足够的上下文,以允许您确定请求的元素上下文,以及的默认上下文菜单。

不幸的是,我知道无法获得内置菜单的句柄。如果用户选择了“原始”选项,您可以通过显示上下文菜单然后返回S_FALSE来伪造它,但即使这样,也无法将结果菜单附加到现有的弹出菜单(实际上应该已经消失了)如果你正在运行这种弹出窗口常见的模态循环,那么当你返回的时候)。可以add options to the built-in menus

在请求菜单时,您应该可以使用GetKeyboardState()来确定shift键的状态。


假设您只想要正常浏览器功能的子集,只需重新实现所需的选项(后退,前进,打印)并调用相应的命令即可获得更好的服务。用户选择它们。或者,如果您只想在非常特定的场景中使用普通菜单(例如:在textarea中编辑命令),请使用ShowContextMenu()参数来识别它,然后返回S_FALSE以触发默认值。我对后一种技术运气不错;毕竟,他们 应该是上下文菜单......

答案 1 :(得分:1)

我正在添加以下信息,如何将您自己的DocHostUI实现“注入”到浏览器控件中:

默认方式是实现IOleClientSite,并支持实现对象上的IDocHostUIHandler

有一种更简单的方法:在DocumentComplete处理程序中,查询ICustomDocIHTMLDocumennt,它允许您从独立对象提供接口。这允许您保留环境提供的任何IOleClientSite实现。

可以找到更多详细信息here