将自定义上下文菜单添加到托管的 Web 浏览器控件 [英] add custom context menu to hosted web browser control

查看:30
本文介绍了将自定义上下文菜单添加到托管的 Web 浏览器控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am hosting a web browser control, and want to provide my own context menu.

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

Ideally, I want to present my own context menu, that contains the original browser's context menu (with all addins etc.) as a sub menu.

如果这不可能/很棘手,我可以接受例如通常显示我的上下文菜单,并在用户按下 SHIFT 时显示原始菜单.

If that's not possible / to tricky, I'd be ok with e.g. normally showing my context menu, and showing the original one when the user presses SHIFT.

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

Do I need to implement IDocHostUIHandler? if yes, how do I specify a custom context menu, how can I force the original one? How do I get the control to use my implementation?

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

The control is created as such (error handling omitted):

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.

Yes, you do need to implement IDocHostUIHandler.

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

Ok, i guess you could intercept right-clicks, keystrokes, and that other message that'll normally display a context menu... But that's probably gonna break badly sooner or later; at very least, i'd expect it to break accessibility.

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

Once you've intercepted IDocHostUIHandler::ShowContextMenu(), you have the option of returning S_OK to squelch the built-in menu after showing your own. You can use the normal Win32 menu routines for this purpose, a custom control, or even fancy HTML if that's what does it for you. Per the documentation, enough context is provided to allow you to determine what element context is requested for, and what the default context menu would be.

不幸的是,我不知道如何获得内置菜单的句柄.如果用户选择了原始"选项,您可能会通过显示上下文菜单然后返回 S_FALSE 来伪造它,但即使如此,也无法将结果菜单附加到现有的弹出菜单(这确实是如果您正在运行此类弹出窗口常见的模态循环,则无论如何都应该在您返回时消失).可以添加选项到内置- 在菜单中.

Unfortunately, I know of no way to get a handle to the built-in menu. You could probably fake it by showing your context menu and then returning S_FALSE if the user chose the "original" option, but even then there's no way to attach the resulting menu to an existing popup menu (which really should be gone by the time you return anyway if you're running the modal-loop common to such popups). It is possible to add options to the built-in menus.

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

You should be able to use GetKeyboardState() to determine the state of the shift key when the menu was requested.

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

Assuming you only want a subset of the normal browser functionality anyway, you might be better served by just re-implementing the options you want (back, forward, print) and invoking the appropriate command if the user chooses them. Alternately, if you only want normal menus in a very specific scenario (for instance: editing commands in a textarea), use the ShowContextMenu() arguments to identify this and only then return S_FALSE to trigger the default. I've had pretty good luck with this latter technique; after all, they are supposed to be context menus...

这篇关于将自定义上下文菜单添加到托管的 Web 浏览器控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆