为什么我的IDocHostUIHandler实现被忽略
我已经从WebBrowser
控件创建了派生控件,该控件具有自己的IDocHostUIHandler
实现,遵循CreateWebBrowserSiteBase
方法的想法:
WebBrowser.WebBrowserSite类提供OLE IDocHostUIHandler接口的默认实现。 您可以提供自己的此接口实现,也可以实现任何其他WebBrowser ActiveX控件接口,以自定义控件的行为。
这个问题不起作用。 我的代码看起来如下:
[PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")] public MyBrowser(){} protected override WebBrowserSiteBase CreateWebBrowserSiteBase() { var manager = new NewWebBrowserSite(this); return manager; } protected class NewWebBrowserSite : WebBrowserSite, UnsafeNativeMethods.IDocHostUIHandler { private MyBrowser host; public NewWebBrowserSite(MyBrowser h) : base(h) { this.host = h; } int UnsafeNativeMethods.IDocHostUIHandler.ShowContextMenu(int dwID, NativeMethods.POINT pt, object pcmdtReserved, object pdispReserved) { MyBrowser wb = (MyBrowser)this.host; // other code } // rest of IDocHostUIHandler methods }
我的问题是:
- 我是否必须实现其他接口才能使其正常工作;
- 这是设计,我读了一些post ,它与
WebBrowser
.net框架实现中的一个错误有关
我知道可以采用ICustomDoc.SetUIHandler
方式,但它不是我想要的。
我当时有想法放弃使用c#并使用非托管代码执行此操作。 那是这样的吗?
您不能简单地覆盖类实现的接口。 如果IDocHostUIHandler的方法未标记为虚拟,则无法替换它们。
接口在UnsafeNativeMethods
定义的事实也是一个线索,除非你非常清楚自己在做什么,否则你可能不应该弄乱它。
我刚刚处理了完全相同的问题:如何向WinForms WebBrowser
控件提供IDocHostUIHandler
的自定义实现。 问题是基类WebBrowserSite
已经实现了自己的IDocHostUIHandler
版本(这是一个internal
接口,所以不可能在派生类NewWebBrowserSite
显式地重新实现它)。 但是,从理论上讲,实现具有相同GIID和方法布局的另一个C#接口应该不是问题(因为这是所有COM客户端 – 底层WebBrowser ActiveX控件 – 在这种特殊情况下关心)。
不幸的是,直到.NET 4.0才有可能。 幸运的是,现在它是通过新的ICustomQueryInterfacefunction:
protected class NewWebBrowserSite : WebBrowserSite, UnsafeNativeMethods.IDocHostUIHandler ICustomQueryInterface { private MyBrowser host; public NewWebBrowserSite(MyBrowser h): base(h) { this.host = h; } int UnsafeNativeMethods.IDocHostUIHandler.ShowContextMenu(int dwID, NativeMethods.POINT pt, object pcmdtReserved, object pdispReserved) { MyBrowser wb = (MyBrowser)this.host; // other code } // rest of IDocHostUIHandler methods // ICustomQueryInterface public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv) { if (iid == typeof(UnsafeNativeMethods.IDocHostUIHandler).GUID) { ppv = Marshal.GetComInterfaceForObject(this, typeof(UnsafeNativeMethods.IDocHostUIHandler), CustomQueryInterfaceMode.Ignore); } else { ppv = IntPtr.Zero; return CustomQueryInterfaceResult.NotHandled; } return CustomQueryInterfaceResult.Handled; } }