1. 程式人生 > >在ActiveX裡呼叫html中的js函式

在ActiveX裡呼叫html中的js函式

其實是抄的別人的程式碼。我改了改而已。

IOleClientSite在ATL和MFC的控制元件類裡都可以拿得到。沒任何問題。

#pragma once
#include <atlbase.h>
#include <SHLGUID.h>
#include <Mshtml.h> 
#include <vector>
#include <string>
#include <comdef.h>


class CJsInvoker
{
public:
    CJsInvoker();
    BOOL   CallJsFunction(const BSTR   strJSFuncName, std::vector<std::wstring> vCallArgs);    
    BOOL   Init(IOleClientSite* pClientSite);
protected:
    IOleClientSite*m_pClientSite;//
    IWebBrowser2*m_spBrowser;//
    IHTMLDocument2*         m_spDoc;//
};

--------------------------無恥的分割線-----------------------------------------------

#include "stdafx.h"
#include "JSInvoker.h"




BSTR Copy(const wchar_t* str) throw()
{
    if (str == NULL)
    {
        return NULL;
    }
    return ::SysAllocStringByteLen((char*)str, (wcslen(str) + 1) * sizeof(wchar_t) );
}




// copy BSTR to VARIANT
_Check_return_ HRESULT CopyTo(const wchar_t* str , _Out_opt_ VARIANT *pvarDest) throw()
{
    ATLASSERT(pvarDest != NULL);
    HRESULT hRes = E_POINTER;
    if (pvarDest != NULL)
    {
        pvarDest->vt = VT_BSTR;
        pvarDest->bstrVal = Copy(str);
#pragma warning(push)
#pragma warning(disable:4068)
#pragma prefast(push)
#pragma prefast(disable:325, "We are checking allocation semantics here")
        if (pvarDest->bstrVal == NULL && str != NULL)
        {
            hRes = E_OUTOFMEMORY;
        }
#pragma prefast(pop)
#pragma warning(pop)
        else
        {
            hRes = S_OK;
        }
    }
    return hRes;
}


BOOL   CJsInvoker::CallJsFunction(const BSTR   strJSFuncName , std::vector<std::wstring> vCallArgs)   
{   
    HRESULT   hr   =   S_OK;   
    try   
    {   
        //   
        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   =   vCallArgs.size();   
        dispparams.rgvarg   =   new VARIANT[dispparams.cArgs];   
        for(size_t   i   =   0;   i   <   vCallArgs.size();   i++)   
        {   
            CopyTo(vCallArgs[i].c_str() ,  &dispparams.rgvarg[i]);   
            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);   


        for(size_t i   =   0;   i   <   vCallArgs.size();   i++)   
        {   
            ::SysFreeString(dispparams.rgvarg[i].bstrVal);
        }  
        delete [] dispparams.rgvarg;
    }   
    catch(...)   
    {   
        return   FALSE;   
    }   
    return   (hr   ==   S_OK   ?   TRUE   :   FALSE);   
}   




CJsInvoker::CJsInvoker()
{
    m_pClientSite = NULL;
    m_spBrowser   = NULL;
    m_spDoc       = NULL;
}


BOOL CJsInvoker::Init(IOleClientSite* pClientSite)
{
    m_pClientSite = pClientSite;
    HRESULT   hr   =   S_OK;   
    ::IServiceProvider*   isp  = NULL;
    ::IServiceProvider*   isp2 = NULL;   
    try   
    {   
        if (m_pClientSite == NULL) 
        {
            return FALSE;
        }


        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; 
        }  


        return TRUE;


    }   
    catch(...)   
    {   
        return   FALSE;   
    }   
}