如何在C++的Internet Explorer中创建JavaScript对象

Jim*_*ans 6 c++ com internet-explorer

我正在使用外部C++应用程序来控制Internet Explorer(版本为11,但这对于此示例似乎并不重要).该控件的一部分是能够在浏览器的上下文中运行任意JavaScript.为了启用该控件,我希望能够创建一个JavaScript对象(或数组,或函数等),由适当的IDispatch变体表示,我可以在后续的脚本调用中使用.有一些在线示例,包括一些来自Microsoft的示例,通过查找和调用Object构造函数来表明这样的事情应该是可能的.

下面是一些示例代码,从前面提到的示例中得到证实,应该可以解决这个问题.但是,当我执行代码时,我得到一个E_INVALIDARG("一个或多个参数无效")HRESULT返回.我做错了什么,我该如何解决这个问题?

// Example assumes that you're using an ATL project which give access to
// the "CCom" wrapper classes, and that you have the ability to retrieve
// an IHTMLDocument2 object pointer.
int CreateJavaScriptObject(IHTMLDocument2* script_engine_host, CComVariant* created_object) {
  // NOTE: Proper return code checking and error handling
  // has been omitted for brevity
  int status_code = 0;
  CComPtr<IDispatch> script_dispatch;
  HRESULT hr = script_engine_host->get_Script(&script_dispatch);
  CComPtr<IDispatchEx> script_engine;
  hr = script_dispatch->QueryInterface<IDispatchEx>(&script_engine);

  // Create the variables we need
  DISPPARAMS no_arguments_dispatch_params = { NULL, NULL, 0, 0 };
  CComVariant created_javascript_object;
  DISPID dispatch_id;

  // Find the javascript object using the IDispatchEx of the script engine
  std::wstring item_type = L"Object";
  CComBSTR name(item_type.c_str());
  hr = script_engine->GetDispID(name, 0, &dispatch_id);

  // Create the jscript object by calling its constructor
  // The below InvokeEx call returns E_INVALIDARG in this case
  hr = script_engine->InvokeEx(dispatch_id,
                               LOCALE_USER_DEFAULT,
                               DISPATCH_CONSTRUCT,
                               &no_arguments_dispatch_params,
                               &created_javascript_object,
                               NULL,
                               NULL);

  *created_object = created_javascript_object;
  return status_code;
}
Run Code Online (Sandbox Code Playgroud)

希望完全可编译的解决方案的潜在回答者可以在GitHub仓库中找到上述代码的版本.该repo包含一个Visual Studio 2017解决方案,该解决方案可创建一个可重现该问题的控制台应用程序,包括启动Internet Explorer并获取对所需IHTMLDocument2对象的引用.请注意,repo中的版本比上面的示例具有更完整的错误处理,为简洁起见,省略了它.