C++如何调用JS函数
2011-09-23 20:19
441 查看
Introduction
Sometimes when you 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 likeIWebBrowser2,
IHTMLDocument2, etc. By this method, we can easily 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 control for
a JavaScript object inside of an HTML page is possible by using the traditional COM approach. This article describes the class
CWebPagewhich allows to do it and a technique to call a JavaScript function from C++ code.
How to do
As a result of using the presented class, it will be easy to call any JavaScript function from C++ code. For implementing this feature, we should get a pointer to theIHTMLDocument2interface. If we are using the
CHtmlViewclass from MFC, we can get one by using the member function
CHtmlView::GetHtmlDocument(). In the case of using
IWebBrowseror
IWebBrowser2components, the function
get_Documentwill bring us the desired interface. Here is an example:
Collapse |Copy
Code
CComPtr<IDispatch> spDisp = CHtmlView::GetHtmlDocument(); m_webPage.SetDocument(spDisp);
The rest of the things will be done by the
CWebPageclass. Here is an example of a JavaScript call without parameters:
Collapse |Copy
Code
m_webPage.CallJScript("Welcome");
An example of a JavaScript call with two parameters will looks like:
Collapse |Copy
Code
m_webPage.CallJScript("Miltiply","2.34","3.32");
The class implementation
Collapse |Copy
Code
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 above mentioned technique can be split into the following steps:Getting a pointer to the
IHTMLDocument2interface.
Getting
IDispatchfor the JavaScript object in the HTML document.
Getting the
DISPIDfor the given name of the JavaScript function.
Putting the parameters to the
DISPPARAMstructure.
Calling the JavaScript function by using the
Invokemethod of the
IDispatchinterface.
Here is an example of getting an
IDispatchpointer to the JavaScript objects:
Collapse |Copy
Code
bool CWebPage::GetJScript(CComPtr<IDispatch>& spDisp) { HRESULT hr = m_spDoc->get_Script(&spDisp); ATLASSERT(SUCCEEDED(hr)); return SUCCEEDED(hr); }
And here is the final function to call JavaScript:
Collapse |Copy
Code
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; }
相关文章推荐
- C中如何调用C++函数
- 如何在C++中创建可被Blueprint调用的全局函数
- cocos2d-js 安卓环境,如何用js代码直接调用java函数
- CDHtmlDialog的基本使用(C++调用JS函数的实现)
- (转)如何在linux C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理
- c++中如何解决函数调用二维数组的问题。
- c++与js脚本交互,C++调用JS函数/JS调用C++函数
- 如何在linux C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理(转)
- C中如何调用C++函数?
- C/C++: 函数调用, 栈的大小是如何被确定的
- ASP.NET前台JS与后台CS函数如何互相调用
- js 定义函数的几种方法 以及如何调用
- python嵌入C++------ boost.python如何在C++中调用含有不定长参数tuple变量和关键字参数dict变量的函数
- ASP.NET前台JS与后台CS函数如何互相调用
- c++ 如何把this指针传入成员函数 像全局函数一样调用成员函数
- C中如何调用C++函数?
- 如何在C/C++语言中调用 sqlite 的函数
- 如何在QT中实现C语言中调用C++的函数
- C++调用JS函数之IScriptControl类库的封装
- 如何在后台CS代码文件中调用前台JS文件中的某一个函数