【问题标题】:Return value from execScript(IHTMLWindow2)从 execScript(IHTMLWindow2) 返回值
【发布时间】:2026-01-08 08:25:07
【问题描述】:

从 IHTMLWindow2::execScript 获取返回值的最佳方法是什么?

我找到了这个链接,http://social.msdn.microsoft.com/Forums/en/ieextensiondevelopment/thread/712db8ec-0ceb-4efa-afe3-590dc6bbb7bf,我没试过,这个方法对吗?

问候 马诺杰

【问题讨论】:

    标签: com winapi


    【解决方案1】:

    是的,这就是 System.Windows.Forms.HtmlDocument.InvokeScript 获取返回值的方式。

    【讨论】:

      【解决方案2】:

      这是一个good article,它展示了如何使用 C++ 执行此操作。

      接下来是我的解读。假设您的客户端 JavaScript 是:

      function myMethod(name)
      {
          alert("Hello " + name);
      
          return "Got it!";
      }
      

      你可以这样称呼它:

      CStringArray arrArgs;
      arrArgs.Add(L"John Smith");
      
      CComVariant varRes;
      if(CallClientScript(L"myMethod", &arrArgs, &varRes))
      {
          if(varRes.vt == VT_BSTR)
              AfxMessageBox(varRes.bstrVal);
      }
      

      IHTMLWindow2 接口的实际函数是这样的:

      BOOL CallClientScript(LPCTSTR pStrFuncName, CStringArray* pArrFuncArgs, CComVariant* pOutVarRes)
      {
          //Call client function in HTML
          //'pStrFuncName' = client script function name
          //'pArrFuncArgs' = if not NULL, list of arguments
          //'pOutVarRes' = if not NULL, will receive the return value
          //RETURN:
          //      = TRUE if done
          BOOL bRes = FALSE;
      
          CComVariant vaResult;
      
          CComPtr<IHTMLDocument2> pIDoc2;
          if(SUCCEEDED(this->GetDHtmlDocument(&pIDoc2)))  //Uses CDHtmlDialog as 'this'
          {
              //Getting IDispatch for Java Script objects
              CComPtr<IDispatch> spScript;
              if(SUCCEEDED(pIDoc2->get_Script(&spScript)))
              {
                  //Find dispid for given function in the object
                  CComBSTR bstrMember(pStrFuncName);
                  DISPID dispid = NULL;
                  if(SUCCEEDED(spScript->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_USER_DEFAULT, &dispid)))
                  {
      
                      const int arraySize = pArrFuncArgs ? pArrFuncArgs->GetSize() : 0;
      
                      //Putting parameters  
                      DISPPARAMS dispparams;
                      memset(&dispparams, 0, sizeof dispparams);
                      dispparams.cArgs      = arraySize;
                      dispparams.rgvarg     = new VARIANT[dispparams.cArgs];
                      dispparams.cNamedArgs = 0;
      
                      for( int i = 0; i < arraySize; i++)
                      {
                          CComBSTR bstr = pArrFuncArgs->GetAt(arraySize - 1 - i); // back reading
                          bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
                          dispparams.rgvarg[i].vt = VT_BSTR;
                      }
      
                      EXCEPINFO excepInfo;
                      memset(&excepInfo, 0, sizeof excepInfo);
                      UINT nArgErr = (UINT)-1;  // initialize to invalid arg
      
                      //Call JavaScript function         
                      if(SUCCEEDED(spScript->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, &dispparams, &vaResult, &excepInfo, &nArgErr)))
                      {
                          //Done!
                          bRes = TRUE;
                      }
      
                      //Free mem
                      delete [] dispparams.rgvarg;
                  }
              }
          }
      
          if(pOutVarRes)
              *pOutVarRes = vaResult;
      
          return bRes;
      }
      

      【讨论】: