描述:
我使用下面的方法在ActiveX控件里调用JavaScript里的函数:
.h文件
IOleClientSite* m_pClientSite; //
IWebBrowser2* m_spBrowser; //
ComPtr<IHTMLDocument2> m_spDoc; //
.cpp文件
//----------------------------------------------------------------------------
// 名称:InvokeJSFunc
// 简介:执行JavaScript里的函数
// 参数:strJSFuncName:i:JavaScript函数名
// 返回:执行成功返回TRUE,否则返回FALSE
//----------------------------------------------------------------------------
BOOL COpenGLWnd::InvokeJSFunc(BSTR strJSFuncName)
{
HRESULT hr = S_OK;
::IServiceProvider *isp, *isp2 = NULL;
try
{
hr = m_pClientSite->QueryInterface(::IID_IServiceProvider, reinterpret_cast<void **>(&isp));
if (FAILED(hr)) return FALSE;
hr = isp->QueryService(::SID_STopLevelBrowser, ::IID_IServiceProvider, reinterpret_cast<void **>(&isp2));
if (FAILED(hr)) return FALSE;
hr = isp2->QueryService(::SID_SWebBrowserApp, ::IID_IWebBrowser2, reinterpret_cast<void **>(&m_spBrowser));
if (FAILED(hr)) return FALSE;
//
if(m_spDoc != NULL)
{
delete m_spDoc;
m_spDoc = NULL;
}
hr = m_spBrowser->get_Document((IDispatch**)&m_spDoc);
if(FAILED(hr)) return FALSE;
//
CComPtr<IDispatch> pScript;
hr = m_spDoc->get_Script(&pScript);
//
CComBSTR bstrMember(strJSFuncName);
DISPID dispid;
hr = pScript->GetIDsOfNames(::IID_NULL, &bstrMember, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
//
DISPPARAMS dispparams;
memset(&dispparams, 0, sizeof dispparams);
dispparams.cArgs = 2;
dispparams.rgvarg = new VARIANT[dispparams.cArgs];
for( int i = 0; i < 2; i++)
{
CComBSTR bstr = "111"; // back reading
bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
dispparams.rgvarg[i].vt = VT_BSTR;
}
//
dispparams.cNamedArgs = 0;
EXCEPINFO excepInfo;
memset(&excepInfo, 0, sizeof excepInfo);
CComVariant vaResult;
UINT nArgErr = (UINT)-1; //initialize to invalid arg
hr = pScript->Invoke(dispid, ::IID_NULL, 0, DISPATCH_METHOD, &dispparams, &vaResult, &excepInfo, &nArgErr);
}
catch(...)
{
return FALSE;
}
return (hr == S_OK ? TRUE : FALSE);
}
//----------------------------------------------------------------------------
我在C++Bulider的ActiveX Form工程里使用这个方法执行htm文件里的JavaScript函数,没有问题。但是在VC的atl工程里,使用这个方法就有点问题了。如果所执行的JavaScript函数里调用了控件本身的接口函数的话就会出现“指针错误”、“无效的被呼叫方”、甚至是崩溃的问题。例如执行函数:
function StartEngine() {
Sun3D.S3D_SetCameraInfo(60, 100, 100000);
}
的时候就出现“无效指针”的错误,而且断点跟踪根本就没有进接口函数。如果把函数改成
function StartEngine() {
alert("aaa");
}
又没有问题。
出现异常时,指向atlwin.h文件的
template <class TBase, class TWinTraits>
HWND CWindowImplBaseT< TBase, TWinTraits >::Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName,
DWORD dwStyle, DWORD dwExStyle, UINT nID, ATOM atom, LPVOID lpCreateParam)
{
ATLASSERT(m_hWnd == NULL); //本句异常,因为m_hWnd不为空
……
}
不知道是不是atl和C++Bulider里有什么区别,希望知道的兄弟给个帮助!
谢谢!
解决方案1:
http://www.pconline.com.cn/pcedu/empolder/gj/vc/0312/259928.html
这里有啊。我有这个的列子。如果需要的话,留下email