c++ - 将自定义上下文菜单添加到托管 Web 浏览器控件

标签 c++ webbrowser-control atl

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

理想情况下,我想展示我自己的上下文菜单,它包含原始浏览器的上下文菜单(以及所有插件等)作为子菜单。

如果那不可能/太棘手,我会接受例如通常显示我的上下文菜单,并在用户按下 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;

最佳答案

是的,您确实需要实现 IDocHostUIHandler

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

一旦你拦截了IDocHostUIHandler::ShowContextMenu() ,您可以选择返回 S_OK 以在显示您自己的菜单后压制内置菜单。为此,您可以使用普通的 Win32 菜单例程、自定义控件,或者甚至是精美的 HTML(如果适合您的话)。根据文档,提供了足够的上下文以允许您确定请求的元素上下文,以及默认上下文菜单是什么。

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

您应该能够使用 GetKeyboardState()确定请求菜单时 shift 键的状态。


假设您只需要正常浏览器功能的一个子集无论如何,您可能会通过重新实现您想要的选项(后退、前进、打印)并调用适当的命令来获得更好的服务,如果用户选择它们。或者,如果您只想在非常特定的场景中使用普通菜单(例如:在文本区域中编辑命令),请使用 ShowContextMenu() 参数来识别它,然后才返回 S_FALSE 触发默认值。我很幸运地使用了后一种技术;毕竟,它们应该是上下文菜单...

关于c++ - 将自定义上下文菜单添加到托管 Web 浏览器控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1099334/

相关文章:

c++ - 什么是 CTime(有没有)32 位模拟?

c++ - 在 DHTML/AJAX 页面的情况下,如何使用浏览器帮助对象 (BHO) 获取完整的 HTML 正文?

c++ - MSI - 有条件注册 DLL

c++ - 在线程之间传递数据的最佳实践是什么?队列、消息或其他?

c++ - 如果我有一个顶点数组,我怎样才能以一种适合循环和绘制三角形带的方式对它们进行排序?

c++ - 使用 Qt Creator 编译 PythonQt

c# - WebBrowser控件使用IE9

c++ - 如何用 'malloc' 和 'free' 替换 'new' 和 'delete' ?

Delphi 网络浏览器和 CSS3

c++ - MFC WebBrowser.Navigate 错误 "A null reference pointer was passed to the stub."