我正在托管 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/