一開始程式只有 Javascript 呼叫 ActiveX function
但是後來想要讓 ActiveX 能夠呼叫 Javascript function 去改變控制項大小
上網查了一下說是有兩種做法
1.在 visual studio class view 找到該 ActiveX,右鍵 add event
完成後另外在 web page 增加對應的程式
< script language="JavaScript" For="yourActiveX" Event="yourEvent(param)"> alert(param); < /script >

但是我沒成功...

2.利用 IWebBrowser2, IHTMLDocument2 來操作 web page 上所有的物件
首先 ActiveX 要 overwrite OnSetClientSite,用來抓 browser 與 html document

#define CHECK_POINTER(p)\
ATLASSERT(p != NULL);\
if(p == NULL)\
{\
return false;\
}
#define COMRELEASE(p)\
if(p != NULL)\
{\
p->Release();\
p=NULL;\
}

void CActiveXCtrl::OnSetClientSite()
{
    HRESULT hr = S_OK;
    IServiceProvider *isp, *isp2 = NULL;
    if (!m_pClientSite)
    {
        COMRELEASE(pWebBrowser);
    }
    else
    {
        hr = m_pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast (&isp));
        if (FAILED(hr))
        {
            hr = S_OK;
            goto cleanup;
        }
        hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast (&isp2));
        if (FAILED(hr))
        {
            hr = S_OK;
            goto cleanup;
        }
        // get IE
        hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast (&pWebBrowser));
        if (FAILED(hr))
        {
            hr = S_OK;
            goto cleanup;
        }
        // get web page
        hr = pWebBrowser->get_Document((IDispatch**)&pHTMLDocument);

        if(FAILED(hr))
        {
            hr = S_OK;
            goto cleanup;
        }

    cleanup:
        // Free resources.
        COMRELEASE(isp);
        COMRELEASE(isp2);
    }
}

再來就是取得/呼叫 Javascript function
bool CActiveXCtrl::GetJScript(CComPtr & spDisp)
{
    CHECK_POINTER(pHTMLDocument);
    HRESULT hr = pHTMLDocument->get_Script(&spDisp);
    ATLASSERT(SUCCEEDED(hr));
    return SUCCEEDED(hr);
}

bool CActiveXCtrl::GetJScripts(CComPtr & spColl)
{
    CHECK_POINTER(pHTMLDocument);
    HRESULT hr = pHTMLDocument->get_scripts(&spColl);
    ATLASSERT(SUCCEEDED(hr));
    return SUCCEEDED(hr);
}

bool CActiveXCtrl::CallJScript(const CString strFunc, const CStringArray& paramArray,
                                  CComVariant* pVarResult)
{
    CComPtr spScript;
    if(!GetJScript(spScript))
    {
        //ShowError("Cannot GetScript");
        return false;
    }
    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();
    DISPPARAMS dispparams;
    memset(&dispparams, 0, sizeof dispparams);
    dispparams.cArgs = arraySize;
    dispparams.rgvarg = new VARIANT[dispparams.cArgs];
    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;
    }
    dispparams.cNamedArgs = 0;
    EXCEPINFO excepInfo;
    memset(&excepInfo, 0, sizeof excepInfo);
    CComVariant vaResult;
    UINT nArgErr = (UINT)-1;  // initialize to invalid arg
    hr = spScript->Invoke(dispid,IID_NULL,0,
        DISPATCH_METHOD,&dispparams,&vaResult,&excepInfo,&nArgErr);
    delete [] dispparams.rgvarg;
    if(FAILED(hr))
    {
        //ShowError(GetSystemErrorMessage(hr));
        return false;
    }
    if(pVarResult)
    {
        *pVarResult = vaResult;
    }
    return true;
}


參考資料1
參考資料2
arrow
arrow
    全站熱搜

    JohnDX 發表在 痞客邦 留言(0) 人氣()