Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. COM
  4. Using MSHTML/CHtmlView in a thread

Using MSHTML/CHtmlView in a thread

Scheduled Pinned Locked Moved COM
c++htmlcomdata-structuresquestion
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Neville Franks
    wrote on last edited by
    #1

    Hi, I want to add content to a view derived from MFC's CHtmlView from a thread. The following code is a stripped back version of the code executed by the thread. CMyHTMLView::AddHTML() { HRESULT hr = CoInitialize( NULL ); ASSERT( SUCCEEDED( hr ) ); string shtml( "**Hello World**" ); try { CComQIPtr< IHTMLDocument2 > pHtmlDoc( GetHtmlDocument() ); if ( pHtmlDoc ) { CComQIPtr< IHTMLElement > pBodyElement; HRESULT hr = pHtmlDoc->get_body( &pBodyElement ); //get body element if ( SUCCEEDED( hr ) ) hr = pBodyElement->insertAdjacentHTML( _bstr_t(L"beforeEnd"), _bstr_t( shtml.c_str() ) ); // exception here to catch(...) ASSERT( SUCCEEDED( hr ) ); } } catch( _com_error e ) { REPORT_COM_ERROR(e); } catch(...) { } CoUninitialize(); } If the contents of shtml is small as shown above it works fine. However when shtml is a few K of HTML the call to insertAdjacentHTML() throws an exception which is caught in catch(...). The HTML is valid and the same code works fine when it isn't in a thread. In the real code, shtml is on the heap or maybe the stack? Any clues about what I'm doing wrong? Neville Franks, Author of Surfulater www.surfulater.com "Save what you Surf" and ED for Windows www.getsoft.com

    K P 2 Replies Last reply
    0
    • N Neville Franks

      Hi, I want to add content to a view derived from MFC's CHtmlView from a thread. The following code is a stripped back version of the code executed by the thread. CMyHTMLView::AddHTML() { HRESULT hr = CoInitialize( NULL ); ASSERT( SUCCEEDED( hr ) ); string shtml( "**Hello World**" ); try { CComQIPtr< IHTMLDocument2 > pHtmlDoc( GetHtmlDocument() ); if ( pHtmlDoc ) { CComQIPtr< IHTMLElement > pBodyElement; HRESULT hr = pHtmlDoc->get_body( &pBodyElement ); //get body element if ( SUCCEEDED( hr ) ) hr = pBodyElement->insertAdjacentHTML( _bstr_t(L"beforeEnd"), _bstr_t( shtml.c_str() ) ); // exception here to catch(...) ASSERT( SUCCEEDED( hr ) ); } } catch( _com_error e ) { REPORT_COM_ERROR(e); } catch(...) { } CoUninitialize(); } If the contents of shtml is small as shown above it works fine. However when shtml is a few K of HTML the call to insertAdjacentHTML() throws an exception which is caught in catch(...). The HTML is valid and the same code works fine when it isn't in a thread. In the real code, shtml is on the heap or maybe the stack? Any clues about what I'm doing wrong? Neville Franks, Author of Surfulater www.surfulater.com "Save what you Surf" and ED for Windows www.getsoft.com

      K Offline
      K Offline
      Keith Worden
      wrote on last edited by
      #2

      It could be something to do with thread-local data, a lot of MFC uses it. I've had problems trying to manipulate objects from threads - usually you have to do the work in the thread that created the object, but presumably this takes away the point of what you're trying to do. It won't matter if shtml is on the stack or heap, but you should check if insertAdjacentHTML completes when the function returns or maybe it takes the data, returns and then some other thread processes it. Some of the html stuff has other threads to do work. Have you tried putting a sleep in after the insert to give it time to complete?

      N 1 Reply Last reply
      0
      • K Keith Worden

        It could be something to do with thread-local data, a lot of MFC uses it. I've had problems trying to manipulate objects from threads - usually you have to do the work in the thread that created the object, but presumably this takes away the point of what you're trying to do. It won't matter if shtml is on the stack or heap, but you should check if insertAdjacentHTML completes when the function returns or maybe it takes the data, returns and then some other thread processes it. Some of the html stuff has other threads to do work. Have you tried putting a sleep in after the insert to give it time to complete?

        N Offline
        N Offline
        Neville Franks
        wrote on last edited by
        #3

        Hi Keith, Thanks for the reply. I got the following reply on an MS Newgroup, which explains things. You cannot simply pass COM interface pointers to a worker thread - you need to marshal them. See http://support.microsoft.com/?kbid=150777 MSHTML is a single-threaded component. If you don't marshal the pointers - in violation of COM rules - you'll likely get random crashes. If you do marshal, then any call you make in the worker thread though such a pointer gets marshalled back to the main thread, executed there, and any results marshalled back to the worker. Essentially, the worker thread isn't doing any work, it spends all its time waiting for the main thread to serve its calls. Bottom line: it's pointless to perform DHTML manipulations from a worker thread. You add pure overhead, without gaining anything at all. I was already working on implementation that built the HTML in a thead and added it to a queue for the app thread to display. My main problem was getting the main thread to be a bit more responsive when large chunks of HTML are in play. After a few different implementations, I've now got something I'm quite happy with. Neville Franks, Author of Surfulater www.surfulater.com "Save what you Surf" and ED for Windows www.getsoft.com

        1 Reply Last reply
        0
        • N Neville Franks

          Hi, I want to add content to a view derived from MFC's CHtmlView from a thread. The following code is a stripped back version of the code executed by the thread. CMyHTMLView::AddHTML() { HRESULT hr = CoInitialize( NULL ); ASSERT( SUCCEEDED( hr ) ); string shtml( "**Hello World**" ); try { CComQIPtr< IHTMLDocument2 > pHtmlDoc( GetHtmlDocument() ); if ( pHtmlDoc ) { CComQIPtr< IHTMLElement > pBodyElement; HRESULT hr = pHtmlDoc->get_body( &pBodyElement ); //get body element if ( SUCCEEDED( hr ) ) hr = pBodyElement->insertAdjacentHTML( _bstr_t(L"beforeEnd"), _bstr_t( shtml.c_str() ) ); // exception here to catch(...) ASSERT( SUCCEEDED( hr ) ); } } catch( _com_error e ) { REPORT_COM_ERROR(e); } catch(...) { } CoUninitialize(); } If the contents of shtml is small as shown above it works fine. However when shtml is a few K of HTML the call to insertAdjacentHTML() throws an exception which is caught in catch(...). The HTML is valid and the same code works fine when it isn't in a thread. In the real code, shtml is on the heap or maybe the stack? Any clues about what I'm doing wrong? Neville Franks, Author of Surfulater www.surfulater.com "Save what you Surf" and ED for Windows www.getsoft.com

          P Offline
          P Offline
          peterchen
          wrote on last edited by
          #4

          If you are using the use the interfaces in a different thread than the one creating the control, you need to marshal it to this thread (CoMarshalInterThreadInterfaceInStream and CoGetInterfaceAndReleaseStream, which probably were made to win the WIN 32 API lyrics award) chopping strings usually isn't a symptom of violating apartment boundaries, but MSHTML ctrl has a few message loop interacitons that make that possible.


          Some of us walk the memory lane, others plummet into a rabbit hole
          Tree in C# || Fold With Us! || sighist

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups