Click here to Skip to main content
6,305,776 members and growing! (15,425 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » COM / COM+ » COM     Intermediate

JavaScript call from C++

By Eugene Khodakovsky

A class for easy implementation of JavaScript calls from C++ code
VC6, VC7Win2K, WinXP, MFC, COM, Dev
Posted:28 May 2002
Views:184,747
Bookmarked:91 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
49 votes for this article.
Popularity: 8.00 Rating: 4.73 out of 5
1 vote, 3.4%
1

2
1 vote, 3.4%
3
6 votes, 20.7%
4
21 votes, 72.4%
5

Sample Image

Introduction

Sometimes when we are using the IE Browser Control inside of a C++ application you need to get access to the HTML elements. We can do it by using standard COM objects like IWebBrowser2, IHTMLDocument2, etc. By this method we can easy implement features like click button, click anchor, get input string, get HTML text, etc. Unfortunately, Microsoft did not provide similar objects for JavaScript. At any case to make a control for the JavaScript object inside of HTML page it is possible by using traditional COM approach. This article describes the class CWebPage which allows to do it and technique to call Java Script Function from C++ code.

How to do

As the result of using presented class it will be easy to call any JavaScript function from C++ code. For implement this feature we should to get pointer to the IHTMLDocument2 interface. If we are using CHtmlView class from MFC we can get one by using member function CHtmlView::GetHtmlDocument(). In case of using IWebBrowser or IWebBrowser2 components the function get_Document will bring us desired interface. Here is example:

CComPtr<IDispatch> spDisp = CHtmlView::GetHtmlDocument();
m_webPage.SetDocument(spDisp);

The rest of all things will be done by CWebPage class. Here is example of JavaScript call without parameters.

m_webPage.CallJScript("Welcome");

The example of the JavaScript call with 2 parameters will looks like here.

m_webPage.CallJScript("Miltiply","2.34","3.32");

The Class Implementation

class CWebPage
{
public:
  CWebPage();
  virtual ~CWebPage();

  bool SetDocument(IDispatch* pDisp);
  LPDISPATCH GetHtmlDocument() const;
  const CString GetLastError() const;
  bool GetJScript(CComPtr<IDispatch>& spDisp);
  bool GetJScripts(CComPtr<IHTMLElementCollection>& spColl);
  CString ScanJScript(CString& strAText,CStringArray& args);

  bool CallJScript(const CString strFunc);
  bool CallJScript(const CString strFunc,const CString strArg1);
  bool CallJScript(const CString strFunc,const CString strArg1,
                   const CString strArg2);
  bool CallJScript(const CString strFunc,const CString strArg1,
                   const CString strArg2,const CString strArg3);
  bool CallJScript(const CString strFunc,const CStringArray& paramArray);

protected:

  CComPtr<IHTMLDocument2> m_spDoc;

};

Calling Technique

The mentioned above technique splits on the following steps: 

  • Getting pointer to the IHTMLDocument2 interface. 
  • Getting IDispatch for JavaScript object in HTML document 
  • Getting DISPID for given name of JavaScript function 
  • Putting parameters to DISPPARAM structure
  • Calling JavaScript function by using Invoke method of IDispatch interface

Here is example of getting IDispatch pointer to the Java Scripts objects

bool CWebPage::GetJScript(CComPtr<IDispatch>& spDisp)
{
  HRESULT hr = m_spDoc->get_Script(&spDisp);
  ATLASSERT(SUCCEEDED(hr));
  return SUCCEEDED(hr);
}

And here is final function to call Java Script

CComVariant CWebPage::CallJScript(const CString strFunc,
                                  const CStringArray& paramArray)
{
  //Getting IDispatch for Java Script objects

  CComPtr<IDispatch> spScript;
  if(!GetJScript(spScript))
  {
    ShowError("Cannot GetScript");
    return false;
  }
  //Find dispid for given function in the object

  CComBSTR bstrMember(strFunc);
  DISPID dispid = NULL;
  HRESULT hr = spScript->GetIDsOfNames(IID_NULL,&bstrMember,1,
                            LOCALE_SYSTEM_DEFAULT,&dispid);
  if(FAILED(hr))
  {
    ShowError(GetSystemErrorMessage(hr));
    return false;
  }
  
  const int arraySize = paramArray.GetSize();
  //Putting parameters  

  DISPPARAMS dispparams;
  memset(&dispparams, 0, sizeof dispparams);
  dispparams.cArgs      = arraySize;
  dispparams.rgvarg     = new VARIANT[dispparams.cArgs];
  dispparams.cNamedArgs = 0;
  
  for( int i = 0; i < arraySize; i++)
  {
    CComBSTR bstr = paramArray.GetAt(arraySize - 1 - i); // back reading

    bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
    dispparams.rgvarg[i].vt = VT_BSTR;
  }
  EXCEPINFO excepInfo;
  memset(&excepInfo, 0, sizeof excepInfo);
  CComVariant vaResult;
  UINT nArgErr = (UINT)-1;  // initialize to invalid arg

  //Call JavaScript function         

  hr = spScript->Invoke(dispid,IID_NULL,0,
                        DISPATCH_METHOD,&dispparams,
                        &vaResult,&excepInfo,&nArgErr);
  delete [] dispparams.rgvarg;
  if(FAILED(hr))
  {
    ShowError(GetSystemErrorMessage(hr));
    return false;
  }
  return vaResult;
}

Notes About the Demo

To call a JavaScript function from the demo you should select function in the tree in the left window. After this press the "!" button on the menu bar.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Eugene Khodakovsky


Member

Occupation: Software Developer (Senior)
Location: United States United States

Other popular COM / COM+ articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 59 (Total in Forum: 59) (Refresh)FirstPrevNext
GeneralWhat about cross-platform? PinmemberComaWhite8623:33 13 Dec '08  
Generalcalling java from c++ Pinmemberkioo050918:14 3 Oct '08  
QuestionHi can anybody help me Pinmembersrinileo16:46 23 Sep '08  
GeneralIHTMLDocument without window PinmemberMuran1:52 26 Aug '08  
GeneralRe: IHTMLDocument without window PinmemberMuran3:27 26 Aug '08  
QuestionHow to call external JavaScript ? Pinmembernaren_code5:48 21 Jun '07  
AnswerRe: How to call external JavaScript ? Pinmemberbumbumtrack20:52 2 Jul '07  
Generalsupport for firefox Pinmembervikram19795:04 8 Aug '06  
GeneralDebug Informatoion corrupt PinmemberAdeel68822:22 21 Jun '06  
GeneralReverse task, how to call C++ function from JavaScript? PinmemberM A V15:42 21 Jun '06  
AnswerRe: Reverse task, how to call C++ function from JavaScript? Pinmemberjamesmhall5:05 30 Mar '07  
GeneralRe: Reverse task, how to call C++ function from JavaScript? Pinmemberwww.add-your-page.com5:26 8 Oct '08  
GeneralRe: Reverse task, how to call C++ function from JavaScript? PinmemberM A V5:58 8 Oct '08  
GeneralHow to get the result Pinmemberwww.add-your-page.com11:07 16 May '06  
GeneralBUG, then calling JavaScript PinmemberMicroCell23:06 13 Apr '06  
GeneralHOWTO: Return value from C++ function to JavaScript PinmemberSyed Khasim5:20 28 Mar '06  
GeneralMemory leak while dealing parameters. PinmemberKim Moung Soo21:29 9 Mar '06  
GeneralRe: Memory leak while dealing parameters. PinmemberM A V15:44 21 Jun '06  
AnswerRe: Memory leak while dealing parameters. PinmemberPille_04:27 22 Sep '06  
GeneralRe: Memory leak while dealing parameters. PinmemberAmit22038:10 1 Jul '07  
GeneralGetting the url of an object PinmemberCraig D.10:37 27 Jul '05  
GeneralHow to change the UserAgent of embeded browser Pinmemberakhilesh.kumar8:20 13 Jul '05  
GeneralRe: How to change the UserAgent of embeded browser Pinmemberyu_cg8:48 4 Sep '07  
Generalaccess to the HTML elements PinmemberJomateix5:01 15 Mar '05  
Generalmemory overflow Pinmemberspring20:30 24 Jan '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 28 May 2002
Editor: Chris Maunder
Copyright 2002 by Eugene Khodakovsky
Everything else Copyright © CodeProject, 1999-2009
Web17 | Advertise on the Code Project