Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
645 views
in Technique[技术] by (71.8m points)

c# - Why my implementation of IDocHostUIHandler is ignored

I have created derived control from WebBrowser control that has own IDocHostUIHandler implementation following idea from CreateWebBrowserSiteBase method:

The WebBrowser.WebBrowserSite class provides default implementations of the OLE IDocHostUIHandler interface. You can provide your own implementation of this interface or implement any other WebBrowser ActiveX control interface in order to customize the behavior of the control.

The problem that is not working. My code looks next way:

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

My questions are:

  1. Do I have to implement other interfaces to make it working;
  2. Is that by design, I have read some post that it is related to a bug in .net framework implementation of WebBrowser

I know that is possible to go ICustomDoc.SetUIHandler way, but it is not what I am looking for.

I was having idea at some point to give up with c# and do that with unmanaged code. Is that the way?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've just dealt with exactly the same problem: how to provide a custom implementation of IDocHostUIHandler to WinForms WebBrowser control. The problem is that the base class WebBrowserSite has already implemented its own version of IDocHostUIHandler (which is an internal interface, so it's not possible to explicitly re-implement it in the derived class NewWebBrowserSite). However, in theory it should not be a problem to implement another C# interface with the same GIID and methods layout (because that's all the COM client - the underlying WebBrowser ActiveX Control - cares about in this particular case).

Unfortunately, it was not possible until .NET 4.0. Luckily, now it is, by means of the new ICustomQueryInterface feature:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...