locked
In IE7, Cannot main thread pass IHTMLDocument2 to work thread?? RRS feed

  • Question

  • 1 Main thread:

    CComPtr <IHTMLDocument2> pDoc;

    ....

    AfxBeginThread (WorkPrintThread, pDoc);

     

    2 Work Thread:

    static UINT WorkPrintThread (LPVOID pParam)
    {
         UINT ret = 0;

         CoInitialize (NULL);
         IHTMLDocument2* m_pDoc = (IHTMLDocument2*) pParam; 

    //the address for m_pDoc is equal to pDoc in Main thread

         IEnumUnknown** pEnum ;
         DWORD flags = OLECONTF_EMBEDDINGS | OLECONTF_LINKS | OLECONTF_OTHERS;

         CComPtr<IOleContainer> pOC = NULL;

         HRESULT hr = m_pDoc->QueryInterface (&pOC);

       hr = pOC->EnumObjects( flags, pEnum);  // Here will throw exception.

    ............
      
     }

     

    If the task in work thread is put into main thread, there will not be this issue. Why?

    Thanks in advance!

    Friday, October 17, 2008 2:36 AM

Answers

  • In order to pass a COM interface pointer between threads, you need to do marshalling. See the following functions on MSDN:

    CoMarshalInterThreadInterfaceInStream

    CoGetInterfaceAndReleaseStream

     

    For example (untested code):

    1 Main thread:

    CComPtr <IHTMLDocument2> pDoc;

    ....

    IStream* pStream = NULL;

    hr = CoMarshalInterThreadInterfaceInStream(IID_IHTMLDocument2, pDoc, &pStream);

    if (SUCCEEDED(hr))

    {

         AfxBeginThread (WorkPrintThread, pStream);

    }

     

    2 Work Thread:

    static UINT WorkPrintThread (LPVOID pParam)
    {
         UINT ret = 0;

         CoInitialize (NULL);

         IHTMLDocument2* m_pDoc = NULL;

         HRESULT hr = CoGetInterfaceAndReleaseStream((IStream*) pParam, IID_IHTMLDocument2, (void**) &m_pDoc);

    ...

    }

    Friday, October 17, 2008 5:27 PM
  • For further reading, see this article on the Single Threaded Apartment model.

    All IE and Shell COM objects are STA.
    Friday, October 17, 2008 6:39 PM

All replies

  • In order to pass a COM interface pointer between threads, you need to do marshalling. See the following functions on MSDN:

    CoMarshalInterThreadInterfaceInStream

    CoGetInterfaceAndReleaseStream

     

    For example (untested code):

    1 Main thread:

    CComPtr <IHTMLDocument2> pDoc;

    ....

    IStream* pStream = NULL;

    hr = CoMarshalInterThreadInterfaceInStream(IID_IHTMLDocument2, pDoc, &pStream);

    if (SUCCEEDED(hr))

    {

         AfxBeginThread (WorkPrintThread, pStream);

    }

     

    2 Work Thread:

    static UINT WorkPrintThread (LPVOID pParam)
    {
         UINT ret = 0;

         CoInitialize (NULL);

         IHTMLDocument2* m_pDoc = NULL;

         HRESULT hr = CoGetInterfaceAndReleaseStream((IStream*) pParam, IID_IHTMLDocument2, (void**) &m_pDoc);

    ...

    }

    Friday, October 17, 2008 5:27 PM
  • For further reading, see this article on the Single Threaded Apartment model.

    All IE and Shell COM objects are STA.
    Friday, October 17, 2008 6:39 PM
  • Thank AlexGI and jeffdev for youe reply!!

    It works fine now! The method is very useful.  

    BTW, There is no this issue in IE6.

    Saturday, October 18, 2008 12:53 AM