我使用下面的方法在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
      

  2.   

    ATL中的调用
    CComPtr<IWebBrowser2> m_pIWebBrowser;
    CComPtr<IHTMLDocument2> m_pDocument;
    CComPtr<IDispatch> m_pScript;BOOL CSproGcomOcxV1Ctrl::GetIWebBrowser()
    {
    IOleClientSite* pClientSite;
    GetClientSite(&pClientSite); 

    if(pClientSite==NULL)
    return FALSE;
    CComQIPtr<IServiceProvider> pISP(pClientSite);
    if(pISP==NULL)
    return FALSE;
    pISP->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2,(void **)&m_pIWebBrowser);
    if(m_pIWebBrowser==NULL)
    return FALSE;
    m_pIWebBrowser->get_Document((IDispatch**)&m_pDocument);
    if(m_pDocument==NULL)
    return FALSE;
    m_pDocument->get_Script(&m_pScript);
    if(m_pScript==NULL)
    return FALSE;
    return TRUE;
    }void CSproGcomOcxV1Ctrl::InvokeWebScript(BSTR srciptName)
    {
    CComBSTR bstrMember(srciptName);
    DISPID dispid;
    HRESULT hr;
    if(m_pScript!=NULL)
    {
    hr=m_pScript->GetIDsOfNames(IID_NULL,&bstrMember,1,LOCALE_SYSTEM_DEFAULT,&dispid);
    if(SUCCEEDED(hr))
    {
    DISPPARAMS dispparams;
    memset(&dispparams, 0, sizeof dispparams);
    dispparams.cArgs = 0;
    dispparams.cNamedArgs = 0;
    EXCEPINFO excepInfo;
    memset(&excepInfo, 0, sizeof excepInfo);
    CComVariant vaResult;
    UINT nArgErr = (UINT)-1;  // initialize to invalid arg
    hr = m_pScript->Invoke(dispid,IID_NULL,0,DISPATCH_METHOD,&dispparams,&vaResult,&excepInfo,&nArgErr);
    }
    }
    }