为什么我实现的IDocHostUIHandler被忽略(Why my implementation

2019-07-22 02:17发布

我创建了源自控制WebBrowser有自己控制IDocHostUIHandler以下从理念落实CreateWebBrowserSiteBase方法:

该WebBrowser.WebBrowserSite类提供了OLE的IDocHostUIHandler接口的默认实现。 您可以提供自己的实现此接口的或者以定制控件的行为实施任何其他web浏览器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. 是由设计,我看过一些帖子 ,它是在.NET框架的实施涉及到一个错误WebBrowser

我知道这是有可能去ICustomDoc.SetUIHandler方式,但它不是我所期待的。

我在某些时候有想法用C#放弃,去做一些与非托管代码。 是的方式?

Answer 1:

你不能简单地覆盖由一个类实现的接口。 如果的IDocHostUIHandler的方法都没有标记为虚拟的,没人能取代他们。

该接口中定义的事实UnsafeNativeMethods也是你也许不应该用它,除非你有你在做什么一个很好的想法搞乱线索。



Answer 2:

我刚刚处理了完全相同的问题:如何提供的自定义实现IDocHostUIHandler到的WinForms WebBrowser控件。 问题是基类WebBrowserSite已经实现了自己的版本IDocHostUIHandler (这是一个internal接口,因此它不可能明确地重新实现在派生类中它NewWebBrowserSite )。 然而,在理论上它不应该来实现与同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;
    }   
}


文章来源: Why my implementation of IDocHostUIHandler is ignored