原文:浏览器扩展系列————在WPF中定制WebBrowser快捷菜单
关于如何定制菜单可以参考codeproject上的这篇文章:http://www.codeproject.com/KB/books/0764549146_8.aspx?fid=13574&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26#xx0xx
本文主要讲述如何在这篇文章中的ShowContextMenu方法中弹出自己的ContextMenu。
先来看看在WinForm中是如何实现的:
Code
public void ShowContextMenu( MsHtmlCustomization.ContextMenuTarget dwContext, ref MsHtmlCustomization.POINT pPoint, MsHtmlCustomization.IOleCommandTarget pCommandTarget, object HTMLTagElement) { Point p = new Point(pPoint.x, pPoint.y); p = PointToClient(p); myCustomContextMenu.Show(this, p); //myCustomContextMenu是一个System.Windows.Forms.ContextMenu对象。 const int Ok = ; throw new COMException("", Ok); // return HRESULT = S_OK, so MsHtml // doesn’t display its own menu
先来看看网上一般的实现方法:
myHostBrowser.ContextMenu.PlacementTarget = this;//this即自己的Windows对象,它实现了IDocHostUIHandler接口。
myHostBrowser.ContextMenu.IsOpen = true;
通过此方法可以实现自己控制弹出菜单,比如在某个控件上左击弹出快捷菜单的功能。但是针对这里的WebBrowser控件来说情况就有些不同了,应为WebBrowser是对系统的Internet explorer对象进行了封装,使其处理所有的事件,所以介于WinForm和WPF对ContextMenu对象实现的不同,比如WinForm实现ContextMenu对象的Show方法时,它把菜单的显示委托给了底层的Usr32函数:
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static
extern bool TrackPopupMenuEx(HandleRef hmenu, int fuFlags, int x, int y, HandleRef hwnd, NativeMethods.TPMPARAMS
tpm);
而WPF实现的ContextMenu则采用了新的方法,所以在网上可以看到不少讲解利用ContextMenu实现嵌入许多控件的方法,以丰富其功能的文章。
所以造成的结果就是在ShowContextMenu中弹出WPF的ContextMenu时,第一次可以弹出正确的菜单,但第二次在WebBrowser中右击时菜单会消失,但ShowContextMenu将不会被触发。而在第三次右击时菜单才会弹出。
那我想到的就是将WinForm中的ContextMenu嵌入到WPF中使用,这是只要解决一个问题即可,就是在Show是传入一个Control对象即可,
参考MSDN文章:How
to: Enable Visual Styles in a Hybrid Application
Code
System.Windows.Forms.TextBox tc;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
System.Windows.Forms.Application.EnableVisualStyles();
// Create a WindowsFormsHost element to host
// the Windows Forms control.
System.Windows.Forms.Integration.WindowsFormsHost host =
new System.Windows.Forms.Integration.WindowsFormsHost();
// Create a Windows Forms tab control.
tc = new System.Windows.Forms.TextBox();//此TextBox只是为了显示ContextMenu而构造的一个任意对象。
// Assign the Windows Forms tab control as the hosted control.
host.Child = tc;
// Assign the host element to the parent Grid element.
this.grid2.Children.Add(host);
而在ShowContextMenu中则写上:
System.Windows.Forms.ContextMenu menu
= new System.Windows.Forms.ContextMenu();
menu.MenuItems.Add(new System.Windows.Forms.MenuItem("Test"));
System.Drawing.Point p = new System.Drawing.Point(ppt.x, ppt.y);
p
= tc.PointToClient(p);
menu.Show(tc, p);
即可显示自己的定制的ContextMenu。