zoukankan      html  css  js  c++  java
  • ActiveX组件与JavaScript交互

    1.在COM组件中调用JavaScript函数
    // 连接点方式页面javascript脚本
    <object classid="CLSID:B568F111-DFE4-4944-B67F-0728AB2AB30F" id="testCom" VIEWASTEXT></object>
    <script language="JavaScript" for="testCom" event="staTe(s)">
            alert("State(" + s + ")");
            return 123;
    </script>
    <script language="JavaScript">
            testCom.FireStateEvent("Hello");
    </script>

    // 事件属性方式页面javascript脚本
    function onState(s){
            alert("onState(" + s + ")");
            return 456;
    }
    var o = new ActiveXObject("TestATL.TestCom");
    o.onstaTe=onState;
    o.FireStateEvent("Hello");

    // Com组件VC7.1 ATL代码
    __interface _ITestComEvents{
            [id(1), helpstring("State事件")] HRESULT State([in] BSTR str);
    };
    __event __interface _ITestComEvents;
    IDispatchPtr m_onState;        // 事件属性
    STDMETHOD(get_onState)(IDispatch** pVal) {
            *pVal = m_onState;
            return S_OK;
    };
    STDMETHOD(put_onState)(IDispatch* newVal) {
            m_onState = newVal;
            return S_OK;
    };
    STDMETHOD(FireStateEvent)(BSTR str) {
            __raise State(str);        // 激发连接点事件
            CComVariant result;
            CComVariant avarParams[1] = {str};
            DISPPARAMS dispParams = {avarParams, NULL, 1, 0};
            EXCEPINFO excepInfo;
            memset(&excepInfo, 0, sizeof excepInfo);
            UINT nArgErr = (UINT)-1;      // initialize to invalid arg
            if (m_onState)        // 激发属性事件
                HRESULT hr = m_onState->Invoke(0, IID_NULL, LOCALE_USER_DEFAULT,
                    DISPATCH_METHOD, &dispParams, &result, &excepInfo, &nArgErr);
            return S_OK;
    }
    参见:
    How To Call a Script Function from a VC WebBrowser Application
    如何在COM object中使用 Javascript function object?
    在COM组件中调用JavaScript函数

    2.从页面javascript向Com组件传递结构数组
    // 页面脚本
    var o = new ActiveXObject("TestATL.TestCom");
    o.onstaTe=onState;
    o.Put("array", {0: 123, 1: "abc"});
    o.Put("array", [456, "def"]);
    o.Put("array", [{name: "tom", age: 8}, {name: "jack", age: 10}]);
    var a = new Array(789, "ghi"); // has "length" property
    o.Put("array", a);

    // Com组件VC7.1 ATL代码
    STDMETHODIMP CTestCom::Put(BSTR key, VARIANT value)
    {
    WCHAR output[4096] = L"";
    if(0 == wcsicmp(key, L"array") && VT_DISPATCH == value.vt)
    {
         IDispatchPtr spDisp = value.pdispVal;
         DISPID dispID = 0;
         DISPPARAMS dispParams = {NULL, NULL, 0, 0};
         CComVariant result;
         EXCEPINFO excepInfo;
         memset(&excepInfo, 0, sizeof excepInfo);
         UINT nArgErr = (UINT)-1; // initialize to invalid arg
         unsigned int length = 0; // 数组长度 或 属性 个数

         LPOLESTR func = L"length";
         HRESULT hr = spDisp->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
         if(S_OK == hr){       // 如果有"length"属性
          hr = spDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
          if(S_OK == hr && VT_I4 == result.vt)
           length = result.intVal;       // 直接读取数组长度
         }else{
          unsigned int nTypeInfo = 0;
          hr = spDisp->GetTypeInfoCount(&nTypeInfo);
          ATLASSERT(1 == nTypeInfo);
          ITypeInfoPtr spTypeInfo;
          hr = spDisp->GetTypeInfo(0, 0, &spTypeInfo);
          TYPEATTR *pTypeAttr = NULL;
          hr = spTypeInfo->GetTypeAttr(&pTypeAttr);
          //ATLASSERT("{C59C6B12-F6C1-11CF-8835-00A0C911E8B2}" == pTypeAttr->guid);     // JScript:
          length = pTypeAttr->cVars;       // 从类型信息读取数组长度
          spTypeInfo->ReleaseTypeAttr(pTypeAttr);
         }
         for(unsigned int i=0; i<length; i++)
         {
          WCHAR buf[32];
          _itow(i, buf, 10);
          func = buf;
          hr = spDisp->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
          hr = spDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
          if(S_OK != hr)
           continue;
          if(VT_DISPATCH == result.vt){
           IDispatchPtr spItem = result.pdispVal;
           func = L"name";
           hr = spItem->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
           hr = spItem->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
           if(S_OK == hr && VT_BSTR == result.vt)
            swprintf(output + wcslen(output), L"name=%s", result.bstrVal);
           func = L"age";
           hr = spItem->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
           hr = spItem->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, &excepInfo, &nArgErr);
           if(S_OK == hr && VT_I4 == result.vt)
            swprintf(output + wcslen(output), L" age=%d/n", result.intVal);
          }else if(VT_BSTR == result.vt)
           swprintf(output + wcslen(output), L"BSTR:%s/n", result.bstrVal);
          else if(VT_I4 == result.vt)
           swprintf(output + wcslen(output), L"I4:%d/n", result.intVal);
          else
           swprintf(output + wcslen(output), L"item.vt=%d/n", result.vt);
         }
    }
    FireStateEvent(output);
    return S_OK;
    }

    3.枚举IE窗口的内容,并调用其中的脚本
    #import <mshtml.tlb>       // Internet Explorer 5
    #import <shdocvw.dll>
            SHDocVw::IShellWindowsPtr spSHWinds;
            spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows));
            long nCount = spSHWinds->GetCount();
            IDispatchPtr spDisp;
            for (long i = 0; i < nCount; i++)
            {
             _variant_t va(i, VT_I4);
             spDisp = spSHWinds->Item(va);
             SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
             if (spBrowser != NULL)
             {
              _bstr_t location = spBrowser->GetLocationName();
              if(_bstr_t(L"Test DapCtrl") == location)       // 找指定IE窗口
              {
               IHTMLDocument2Ptr spDoc(spBrowser->GetDocument());
               if (spDoc != NULL)
               {
                _bstr_t exp = m_onState;
                IDispatch *pdis = NULL;
                hr = spDoc->get_Script(&pdis);
                if(pdis){
                 DISPID tmpDispID = 0;
                 LPOLESTR func = L"Test"; // javascript 函数名
                 hr = pdis->GetIDsOfNames(GUID_NULL, &func, 1, LOCALE_SYSTEM_DEFAULT, &tmpDispID);
                 if(S_OK == hr)
                  hr = pdis->Invoke(tmpDispID, IID_NULL, LOCALE_USER_DEFAULT,
                   DISPATCH_METHOD, &dispParams, &result, &excepInfo, &nArgErr);
                }
               }
              }
             }
            }
    参见:
    HOWTO: Connect to a Running Instance of Internet Explorer
    ActiveX组件与JavaScript交互
    ActiveX组件控制其所在的IE窗口

    4.在VC中执行脚本
    #import <msscript.ocx>       // msscript.ocx
    using namespace MSScriptControl;
            IScriptControlPtr pScriptControl(__uuidof(ScriptControl));
            LPSAFEARRAY psa;
            SAFEARRAYBOUND rgsabound[]       = { 1, 0 }; // 1 elements, 0-based
            int i;
            psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
            if (!psa)
            {
             return E_OUTOFMEMORY;
            }
            VARIANT vFlavors[1];
            for (i = 0; i < 1; i++)
            {
             VariantInit(&vFlavors[i]);
             V_VT(&vFlavors[i]) = VT_BSTR;
            }
            V_BSTR(&vFlavors[0]) = SysAllocString(bstr);
            long lZero = 0;
            hr = SafeArrayPutElement(psa, &lZero,&vFlavors[0]);
            for(i=0;i<1;i++)
            {
             SysFreeString(vFlavors[i].bstrVal);
            }
            pScriptControl->Language = "JScript";
            pScriptControl->AllowUI = TRUE;
            _bstr_t exp = L"1+2+3";
            _variant_t outpar = pScriptControl->Eval(exp);
            //_variant_t outpar = pScriptControl->ExecuteStatement(exp);
            //_variant_t outpar = pScriptControl->Run("MyStringFunction", &psa);
            _bstr_t bstrReturn = (_bstr_t)outpar;
            char *pResult = (char *)bstrReturn;
            SafeArrayDestroy(psa);
    参见:

    How To Call Run() Method of the Microsoft Script Control in C++

    来自CSDN网站ssli博客

  • 相关阅读:
    【leetcode】1365. How Many Numbers Are Smaller Than the Current Number
    【leetcode】1363. Largest Multiple of Three
    【leetcode】1362. Closest Divisors
    【leetcode】1361. Validate Binary Tree Nodes
    【leetcode】1360. Number of Days Between Two Dates
    【leetcode】1359. Count All Valid Pickup and Delivery Options
    【leetcode】1357. Apply Discount Every n Orders
    【leetcode】1356. Sort Integers by The Number of 1 Bits
    ISE应用入门的一些问题
    DDR的型号问题
  • 原文地址:https://www.cnblogs.com/lidabo/p/2750197.html
Copyright © 2011-2022 走看看