2013-03-20 12 views
3

我从WebBrowser控制具有自主IDocHostUIHandler实现以下想法来自CreateWebBrowserSiteBase方法创建的衍生控制:为什么我实现的IDocHostUIHandler被忽略

的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 
} 

我的问题是:

  1. 我一定要实现其他接口,使之工作;
  2. 是这样设计的,我看过一些post,它关系到一个错误在.NET Framework实现的WebBrowser

我知道这是有可能去ICustomDoc.SetUIHandler方式,但它不是我是谁寻找。

我有一些想法放弃与C#和做非托管代码。那是这样吗?

回答

1

您不能简单地覆盖由类实现的接口。如果IDocHostUIHandler的方法未标记为虚拟,则不能替换它们。

界面在UnsafeNativeMethods中定义的事实也是一个线索,你可能不应该搞乱它,除非你对你在做什么有非常好的想法。

+0

好点,http://msdn.microsoft.com/en-us/library/aa664593(v=vs.71).aspx – walter 2013-03-21 07:23:02

4

我刚刚处理完全相同的问题:如何提供IDocHostUIHandler到WinForms WebBrowser控件的自定义实现。问题在于基类WebBrowserSite已经实现了它自己的IDocHostUIHandler版本(它是一个internal接口,所以它不可能在派生类NewWebBrowserSite中的explicitly re-implement)。然而,从理论上讲,使用相同的GIID和方法布局来实现另一个C#接口应该不成问题(因为这是所有COM客户端 - 底层WebBrowser ActiveX控件 - 在这种特殊情况下关心的)。

不幸的是,直到.NET 4.0才有可能。幸运的是,现在是,通过ICustomQueryInterface新功能的方式:

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; 
    } 
}