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. C / C++ / MFC
  4. Problem calling JavaScript from C++ [modified]

Problem calling JavaScript from C++ [modified]

Scheduled Pinned Locked Moved C / C++ / MFC
c++javascriptcomdesignsysadmin
4 Posts 2 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.
  • A Offline
    A Offline
    alitokmen
    wrote on last edited by
    #1

    Hello. I'm currently working on a program which uses DHTML for user interface, and some elements of the interface need to be called on network events (so without the user clicking on anything). All samples on CodeProject use user clicks, and actually the other method fails! Let me explain. I've actually created a new project to show the problem. You'll find it on http://temp.alishomepage.com/.RMI/JavaScript.zip. That project has been created to show the JavaScript call problem with the CHtmlView class: failure in the execScript method when called from a thread. The project has been generated by Visual C++ 6 as a standard MFC project with CHtmlView as the view class. All changes in files are marked with the comment "JavaScript problem sample", and involve the JavaScriptView.h and .cpp files. In JavaScriptView.h, there's an override of the OnDocumentComplete method. In JavaScriptView.cpp, we add the two header files (atlbase.h and mshtml.h) as well as the the following function (headers are needed by the function):     // Added for the JavaScript problem sample     DWORD WINAPI CallJScriptLater( LPVOID lpParam )     {         CComQIPtr pHtmlDoc( ((CJavaScriptView*) lpParam)->GetHtmlDocument() );         CComPtr pWnd;         pHtmlDoc->get_parentWindow( &pWnd );         CComBSTR bstrMember(CString("alert('boo')"));         // then simply execute it         CComBSTR vtlanguage(CString("javascript"));         VARIANT vresult;         pWnd->execScript(bstrMember,vtlanguage,&vresult);         return 0;     } And the added function is called on document complete:     // Added for the JavaScript problem sample     void CJavaScriptView::OnDocumentComplete( LPCTSTR lpzsURL )     {         CHtmlView::OnDocumentComplete( lpzsURL );     #if 1         CallJScriptLater( this );     #else         CreateThread( NULL, 0, CallJScriptLater, this, 0, NULL);     #endif     } Finally, OnInitialUpdate has been changed:     void CJavaScriptView::OnInitialUpdate()     {   &

    D 1 Reply Last reply
    0
    • A alitokmen

      Hello. I'm currently working on a program which uses DHTML for user interface, and some elements of the interface need to be called on network events (so without the user clicking on anything). All samples on CodeProject use user clicks, and actually the other method fails! Let me explain. I've actually created a new project to show the problem. You'll find it on http://temp.alishomepage.com/.RMI/JavaScript.zip. That project has been created to show the JavaScript call problem with the CHtmlView class: failure in the execScript method when called from a thread. The project has been generated by Visual C++ 6 as a standard MFC project with CHtmlView as the view class. All changes in files are marked with the comment "JavaScript problem sample", and involve the JavaScriptView.h and .cpp files. In JavaScriptView.h, there's an override of the OnDocumentComplete method. In JavaScriptView.cpp, we add the two header files (atlbase.h and mshtml.h) as well as the the following function (headers are needed by the function):     // Added for the JavaScript problem sample     DWORD WINAPI CallJScriptLater( LPVOID lpParam )     {         CComQIPtr pHtmlDoc( ((CJavaScriptView*) lpParam)->GetHtmlDocument() );         CComPtr pWnd;         pHtmlDoc->get_parentWindow( &pWnd );         CComBSTR bstrMember(CString("alert('boo')"));         // then simply execute it         CComBSTR vtlanguage(CString("javascript"));         VARIANT vresult;         pWnd->execScript(bstrMember,vtlanguage,&vresult);         return 0;     } And the added function is called on document complete:     // Added for the JavaScript problem sample     void CJavaScriptView::OnDocumentComplete( LPCTSTR lpzsURL )     {         CHtmlView::OnDocumentComplete( lpzsURL );     #if 1         CallJScriptLater( this );     #else         CreateThread( NULL, 0, CallJScriptLater, this, 0, NULL);     #endif     } Finally, OnInitialUpdate has been changed:     void CJavaScriptView::OnInitialUpdate()     {   &

      D Offline
      D Offline
      Dennis Gourjii
      wrote on last edited by
      #2

      Now that's really odd... :confused: Have you tried creating the thread with AfxBeginThread? I'm asking because Microsoft claims the other methods aren't MFC-safe.

      A 1 Reply Last reply
      0
      • D Dennis Gourjii

        Now that's really odd... :confused: Have you tried creating the thread with AfxBeginThread? I'm asking because Microsoft claims the other methods aren't MFC-safe.

        A Offline
        A Offline
        alitokmen
        wrote on last edited by
        #3

        Hello, HAND Thank you for your reply. Using AfxBeginThread instead of the CreateThread function doesn't unfortunately solve the problem... If you want to see the exact project, please look at http://temp.alishomepage.com/.RMI/JavaScript.zip I think the issue is due to the fact that the one of those objects there (CHtmlView, presumably) is created in mono-thread mode and does not accept script calls from other threads. Even worse, if the host has Internet Explorer 5 installed (default Windows 2000 SP4 configuration) the script call makes the program crash! See http://support.microsoft.com/kb/318426 I'm starting to have a solution idea, thought: creating the entire HTML output using the IHtmlDocument2::write method and then calling JavaScript from there. It seems to work, but has a majot disadvantage: every JavaScript call adds at least one line to the source code! Another idea would be JavaScript to "ping" the C++ at regular intervals and C++ to catch that and respond using a JavaScript call. Thank you for your reply. S. Ali Tokmen http://ali.tokmen.com

        A 1 Reply Last reply
        0
        • A alitokmen

          Hello, HAND Thank you for your reply. Using AfxBeginThread instead of the CreateThread function doesn't unfortunately solve the problem... If you want to see the exact project, please look at http://temp.alishomepage.com/.RMI/JavaScript.zip I think the issue is due to the fact that the one of those objects there (CHtmlView, presumably) is created in mono-thread mode and does not accept script calls from other threads. Even worse, if the host has Internet Explorer 5 installed (default Windows 2000 SP4 configuration) the script call makes the program crash! See http://support.microsoft.com/kb/318426 I'm starting to have a solution idea, thought: creating the entire HTML output using the IHtmlDocument2::write method and then calling JavaScript from there. It seems to work, but has a majot disadvantage: every JavaScript call adds at least one line to the source code! Another idea would be JavaScript to "ping" the C++ at regular intervals and C++ to catch that and respond using a JavaScript call. Thank you for your reply. S. Ali Tokmen http://ali.tokmen.com

          A Offline
          A Offline
          alitokmen
          wrote on last edited by
          #4

          Hello, everyone First of all, I would like to thank everyone who has helped identifying the cause of this issue and, of course, proposed ideas of solution. The problem seems to be that the scripting object of the IHtmlDocument interface (in its current -Windows XP SP2- implementation) has some protection against access to its inner elements from external threads. As a result, calls from other threads to function that get the content of an HTML document or call scripts on it is prohibited. There's a solution, thought: create a class which would try to call a script using standard methods and on failure queue the request. That class should of course also have a method to execute all queued calls (you can use CList for that queue). Then, you have to find a method to get in the same thread as the CHtmlDocument interface... Which is not that hard: first, put the setInterval("window.navigate('refreshjs:')",1000) line in your HTML document as a JavaScript. This will, every second, try to navigate to refreshjs: Second, you have to modify the OnBeforeNavigate method of CHtmlView to make it call the queue execution method if a navigation to refreshjs: is requested (note that you can also stop navigation at that point -refreshjs: is not a valid protocol anyway!) Using this method, JavaScript calls that fail will be re-executed at most one second later... And shall now not fail, except if you've really called a function that doesn't exist! S. Ali Tokmen http://ali.tokmen.com

          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