JS和C#访问遇到QueryInterface调用出错

在原来的WinForm里,我们只要在窗体类的头部添加属性[System.Runtime.InteropServices.ComVisibleAttribute(true)],然后 webBrowser1.ObjectForScripting = this;这样设置完后,页面上的JS就能访问窗体类的方法了,但是添加WeifenLuo.WinFormsUI.Docking.DockContent作为窗体的父类后如果这样设置却会出现如下提示:

执行了QueryInterface调用,请求提供 COM 可见的托管类“自己的类”的默认IDispatch 接口。不过,由于该类没有显式默认接口,并且是从非 COM 可见的类“WeifenLuo.WinFormsUI.Docking.DockContent”派生的,QueryInterface 调用将失败。这样做的目的是避免非 COM 可见的基类受 COM 版本规则的约束。

方法一:非常明显是由于WeifenLuo.WinFormsUI.Docking.DockContent不是可见类。所以可以直接到该类前面添加

[System.Runtime.InteropServices.ComVisibleAttribute(true)]即可。

方法二:为了不修改开源的组件,可以通过修改使用过程;

webBrowser1.ObjectForScripting = this这句语句就是让对象和Js脚本能够关联上,且该对象是能够ComVisibleAttribute的属性,我们知道DockContent不可以ComVisibleAttribute,所以在它继承下的类当使用到该类后,也就是不能ComVisibleAttribute,Form是ComVisibleAttribute的;所以我们可以构造一个类是ComVisibleAttribute的,通过webBrowser1.ObjectForScripting = this来绑定我们自己的那个类。那么浏览器调用c#的方法,当然是在该类里的方法。----也就是构造一个中间类来沟通JS和C#数据访问。

附加:若是想去除该异常提示可以:

调试-->异常--->Managed Debugging Assistants---> NonComVisibleBaseClass 将其复选框去除点击确定即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通过 pDispatch* 可以调用 COM 组件的属性和方法,具体步骤如下: 1. 通过 CoCreateInstance 或 CoGetClassObject 创建 COM 对象的实例或类工厂,获取对象的 IUnknown 接口。 2. 通过 IUnknown 接口的 QueryInterface 方法获取对象的 IDispatch 接口。 3. 通过 IDispatch 接口的 GetIDsOfNames 方法获取属性或方法的 DISPID。 4. 通过 IDispatch 接口的 Invoke 方法调用属性或方法,将参数打包成 VARIANT 类型的数组传入。 示例代码如下: ``` // 创建 COM 对象实例 CLSID clsid; HRESULT hr = CLSIDFromProgID(L"YourProgID", &clsid); if (FAILED(hr)) { // 错误处理 } IUnknown* pUnknown; hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IUnknown, (void**)&pUnknown); if (FAILED(hr)) { // 错误处理 } // 获取 IDispatch 接口 IDispatch* pDispatch; hr = pUnknown->QueryInterface(IID_IDispatch, (void**)&pDispatch); if (FAILED(hr)) { // 错误处理 } // 获取属性或方法的 DISPID DISPID dispid; LPOLESTR pszName = L"YourPropertyNameOrMethodName"; hr = pDispatch->GetIDsOfNames(IID_NULL, &pszName, 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { // 错误处理 } // 调用属性或方法 VARIANTARG* pArgs = new VARIANTARG[2]; pArgs[0].vt = VT_BSTR; pArgs[0].bstrVal = SysAllocString(L"YourFirstArgument"); pArgs[1].vt = VT_INT; pArgs[1].intVal = 123; DISPPARAMS params = { pArgs, NULL, 2, 0 }; VARIANT result; VariantInit(&result); hr = pDispatch->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &result, NULL, NULL); if (FAILED(hr)) { // 错误处理 } // 处理返回值 // 释放资源 delete[] pArgs; pDispatch->Release(); pUnknown->Release(); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值