Tuesday, December 13, 2005
« How to NOT dispose a dialog form | Main | ASP.NET Website Compilation »

I've seen a lot of questions about implementing KB196340 in managed code as well as getting an IWebBrowser2 interface from an IHTMLDocument2 or IHTMLWindow2 interface.  I had the same questions, so I dug in and below is what I came up with.  I have yet to have any problems with it, but it may need some work with releasing the COM objects (feel free to comment if you have suggestions.)


IEnumUnknown

[

ComImport,

Guid("00000100-0000-0000-C000-000000000046"),

InterfaceType(ComInterfaceType.InterfaceIsIUnknown)

]

public interface IEnumUnknown

{

    [PreserveSig]

    int Next(

        [In, MarshalAs(UnmanagedType.U4)] int celt,

        [Out, MarshalAs(UnmanagedType.IUnknown)] out object rgelt,

        [Out, MarshalAs(UnmanagedType.U4)] out int pceltFetched

    );

 

    [PreserveSig]

    int Skip(

        [In, MarshalAs(UnmanagedType.U4)] int celt

    );

 

    void Reset();

 

    void Clone(

        out IEnumUnknown ppenum

    );

}

 


IOleContainer

[Flags()]

public enum tagOLECONTF

{

    OLECONTF_EMBEDDINGS = 1,

    OLECONTF_LINKS = 2,

    OLECONTF_OTHERS = 4,

    OLECONTF_ONLYUSER = 8,

    OLECONTF_ONLYIFRUNNING = 16,

}

 

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000011B-0000-0000-C000-000000000046")]

public interface IOleContainer

{

    [PreserveSig]

    int ParseDisplayName(

        [In, MarshalAs(UnmanagedType.Interface)] object pbc,

        [In, MarshalAs(UnmanagedType.BStr)] string pszDisplayName,

        [Out, MarshalAs(UnmanagedType.LPArray)] int[] pchEaten,

        [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppmkOut

    );

 

    [PreserveSig]

    int EnumObjects(

        [In, MarshalAs(UnmanagedType.U4)] tagOLECONTF grfFlags,

        out IEnumUnknown ppenum

    );

 

    [PreserveSig]

    int LockContainer(

        bool fLock

    );

}


GetBrowserFromWindow (added method to the WebBrowserEx control)

public IWebBrowser2 GetBrowserFromWindow(IHTMLWindow2 win)

{

  if(win == null)

  {

    throw new ArgumentNullException("win");

  }

 

  IWebBrowser2 result = null;

 

  //if the document is the top level document, we don't have to look for it

  if(win.document == this.CurrentDocument)

  {

    result = this.IWebBrowser2; //internal reference to the top-level IWebBrowser2

  }

  else

  {

    //get the OLE container from the window's parent

    IOleContainer oc = win.parent.document as IOleContainer;      //OC ALLOC

 

    //get the OLE enumerator for the embedded objects

    int hr = 0;

    IEnumUnknown eu;

    hr = oc.EnumObjects(tagOLECONTF.OLECONTF_EMBEDDINGS, out eu); //EU ALLOC

    Marshal.ReleaseComObject(oc);                                 //OC FREE

    Marshal.ThrowExceptionForHR(hr);

 

    Guid IID_IWebBrowser2 = typeof(SHDocVw.IWebBrowser2).GUID;

    object pUnk = null;

    int fetched = 0;

    const int MAX_FETCH_COUNT = 1;

 

    //get the first embedded object

    hr = eu.Next(MAX_FETCH_COUNT, out pUnk, out fetched);         //PUNK ALLOC

    Marshal.ThrowExceptionForHR(hr);

 

    //while sucessfully get a new embedding, continue

    for(int i = 0; HRESULTS.S_OK == hr; i++)

    {

      //QI pUnk for the IWebBrowser2 interface

      SHDocVw.IWebBrowser2 brow = pUnk as SHDocVw.IWebBrowser2;

 

      if(brow != null)

      {

        //if the document for this browser matches the one passed in, we found it

        if(brow.Document == win.document)

        {

          result = brow;

          break;

        }

        else

        {

          Marshal.ReleaseComObject(brow);                         //PUNK FREE

        }

 

      } //if(brow != null)

 

      //get the next ebmedded object

      hr = eu.Next(MAX_FETCH_COUNT, out pUnk, out fetched);       //PUNK ALLOC

      Marshal.ThrowExceptionForHR(hr);

 

    } //for(int i = 0; HRESULTS.S_OK == hr; i++)

 

    Marshal.ReleaseComObject(eu);                                 //EU FREE

  }

 

  return result;

}

Wednesday, December 14, 2005 4:14:38 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Related posts:
MNUG – Introduction to Silverlight 2 – October 23, 2008
Nikhil Kothari's Web Development Helper
dasBlog "Use Post Title for Permalink" now working
Tab Mix Plus - Get it now!
Memphis Code Camp 2006 - Atlas Talk
Google Groups Link Missing!
Tracked by:
"http://9lr-free-porn.info/11210608/index.html" (http://9lr-free-porn.info/11210... [Pingback]
"http://9lp-free-porn.info/48168878/index.html" (http://9lp-free-porn.info/48168... [Pingback]
"http://9lr-free-porn.info/79103216/top-girls-novel-feminism.html" (http://9lr-f... [Pingback]
"http://9lp-free-porn.info/14524725/index.html" (http://9lp-free-porn.info/14524... [Pingback]
"http://9lr-free-porn.info/67802463/index.html" (http://9lr-free-porn.info/67802... [Pingback]
"http://9lk-free-porn.info/66509966/pc-interface-audio-video.html" (http://9lk-f... [Pingback]
"http://9lt-free-porn.info/89524876/index.html" (http://9lt-free-porn.info/89524... [Pingback]
"http://9ll-free-porn.info/04752195/free-sample-videos-of-big-breasted-blonds.ht... [Pingback]
"http://9ln-free-porn.info/66664759/index.html" (http://9ln-free-porn.info/66664... [Pingback]
"http://9ls-free-porn.info/78411685/index.html" (http://9ls-free-porn.info/78411... [Pingback]
"http://9lq-free-porn.info/90953574/index.html" (http://9lq-free-porn.info/90953... [Pingback]
"http://9nr-information.info/68581962/index.html" (http://9nr-information.info/6... [Pingback]
"http://9ne-information.info/96659775/waja-campro-test-drive.html" (http://9ne-i... [Pingback]
"http://9nq-information.info/87483806/home-made-beef-jerky-recipes.html" (http:/... [Pingback]