为什么我的IDocHostUIHandler实现被忽略

时间:2013-03-20 04:47:28

标签: c# .net browser webbrowser-control

我已经从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
}

我的问题是:

  1. 我是否必须实现其他接口才能使其正常工作;
  2. 是否按设计,我读了一些post,它与WebBrowser
  3. 的.net框架实现中的错误有关

    我知道可以走ICustomDoc.SetUIHandler方式,但这不是我想要的。

    我当时有想法放弃使用c#并使用非托管代码执行此操作。那是这样的吗?

2 个答案:

答案 0 :(得分:4)

我刚刚处理了完全相同的问题:如何为WinForms IDocHostUIHandler控件提供WebBrowser的自定义实现。问题是基类WebBrowserSite已经实现了自己的IDocHostUIHandler版本(这是一个internal接口,因此在派生类中不可能explicitly re-implementNewWebBrowserSite)。但是,从理论上讲,使用相同的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;
    }   
}

答案 1 :(得分:1)

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

接口在UnsafeNativeMethods中定义的事实也是一个线索,除非你非常清楚自己在做什么,否则你可能不应该弄乱它。