问题标签 [idispatch]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
330 浏览

c# - 如何在 C# 中创建一个继承自 IDispatch 的对象,该对象可以合并到使用 ActiveX 的旧程序中

第一次在 SO 虽然我使用该网站很多,我会直截了当。

我的实际最终目标是创建一个从 C# 中的 IDispatch 接口继承的对象,该对象可用于 Oracle Forms Builder(Oracle Developer Suite 10g (10.1.2.0.2))内的 Canvases

有没有人有任何资源可以让我学习如何执行此操作或显示任何示例?

为了实现我的目标,我去了这个网站: http: //www.codeproject.com/Articles/24089/Create-ActiveX-in-NET-Step-by-Step

在这里,我得到了一些允许我创建和测试 activeX 对象的代码。我相信COM结构所使用的所有对象。然后我使用 regasm 注册了它,然后我尝试调用它。我能够在 IE 中称其为成功。

一段时间后,我正要重新创建这个活动的 X 对象;但是,每当我尝试将其导入 Oracle 表单时,都会收到如下错误:

在此处输入图像描述

对我来说这个错误似乎很清楚,我显然没有实现oracle表单需要我实现的一些方法。我需要实现哪些方法以及应该如何实现。

很抱歉这个问题很长,对此的任何帮助将不胜感激。

0 投票
1 回答
1283 浏览

c# - C# COM 自动化的 Dual interface 和 Dispatch only interface 之间的区别

我正在针对 C++ COM 服务器实现 ac# COM 客户端。当我将 COM 接口标记为“Dual”时,COM 客户端可以正常运行,但是当我删除“Dual”属性时它会引发 InvalidCastException。

因此,对我来说最简单的解决方法是将其标记为 Dual。但从网上阅读来看,这似乎不是用于 COM 服务器的推荐方法。谁能向我解释将接口标记为双重的重要性(用外行术语)以及为什么不推荐它?

我只需要它来进行测试,而且我正在使用 C# 客户端(不要指望我会使用 VB)

或者,谁能指出我为非双接口创建 C# COM 客户端的一个很好的演练(MSDN 上的示例都是双接口)谢谢!

0 投票
2 回答
2927 浏览

c# - 具有动态接口的 C# COM 对象

我想构建一个COM 可见的C# 类,例如DynamicComponent,它将通过 COM提供动态接口。

在内部,此类将维护一个代表字典:

客户端代码将是一些 VBA。

这是我天真地想象的工作流程:

  • 从 Excel/VBA 编辑器中,用户引用TLB
  • 用户实例化一个新的DynamicComponent(至少得到一个由 Excel/VBA 提供的存根)
  • Excel/VBA COM 基础结构通过其IDispatch接口查询组件
  • 组件使用 disp-ids 映射回答,例如["GetTheAnswer" -> 1, "Add" -> 2]
  • 用户可以从自动完成中受益并看到两种方法:GetTheAnswerAdd
  • 用户调用这些方法中的任何一个,就好像它是静态定义的一样

我的第一个问题:有可能吗?

如果不是:为什么

如果是:如何

根据我对 COM 的了解,如果可能的话,IDispatch COM 接口是我最好的朋友。

此外,据我了解,.Net 4 的ICustomQueryInterface接口也可以提供很大帮助。

但是现在 COM 并不是真正的前沿 ;) 很难找到像代码示例这样的资源。

我发现了这个有趣的示例:https ://clrinterop.codeplex.com/releases/view/32350,它使用ICustomQueryInterface接口实现 COM 聚合

但它不是动态的,并且基于静态定义的类型和接口。

任何帮助将不胜感激。

谢谢。

0 投票
2 回答
1109 浏览

.net - 从 Visual Studio 2010 迁移到 2012 时,类接口的 uuid 和 DispID 发生了变化

我们开发了一个名为 XXadapter 的 .NET 程序集。目标是让 XXadapter 充当非托管客户端的 COM 对象。XXadapter 类实现了一个 C++ COM IDL 定义的接口。添加 C++ COM 对象作为对 C# 项目的引用,从而通过 Interop 公开 COM API。因此,类接口 _XXadapter 接口由 COM Interop 生成,并由非托管客户端使用。

在我尝试将 XXadapter 项目从 VS2010 迁移到 VS2012 之前,一切都很好(请注意,没有源代码更改)。_XXadapter 的 uuid 和 _XXadapter 中的一些方法的 DispID更改。

这是 XXadapter 类的属性:

这是迁移前类型库中的_XXadapter定义(由 oleview.exe 查看):

迁移后,_XXadapter定义为

不仅_XXadapter的uuid变了,所有Methods_XXXX()的DispID也变了。

结果,_XXadapter 程序集失去了与其 COM 客户端的向后兼容性。

通过对此问题的调查和搜索,我发现类型库中 Method_three/four/five() 的重新排序可能是由于这三个方法部分声明在单独的文件中造成的。我尝试将所有 COM 可见方法的声明移动到同一个文件中,这个问题可以解决。但是,这会产生一个我们原本想要避免的巨大文件。是否有任何解决方案可以在不移动 COM 可见方法的情况下保持向后兼容性?有谁知道重新排序方法的根本原因?太感谢了。

0 投票
1 回答
58 浏览

idispatch - 实现 IDispatch 的“公共”与“内部”C# 类

我正在编写一个用作 IE WebBrowser 容器的类,它也将实现 IDispatch 接口,因此它的一些方法具有 DispID 属性:

这可以正常工作,并且仅当类为“公共”时才调用 Idispatch_AmbiantDlControl 方法。如果我将其声明为“内部”,则不再收到 IDispatch 调用。有人可以解释为什么吗?有什么办法吗?我不希望这个类可以公开访问。

提前致谢。

0 投票
1 回答
299 浏览

c++ - Free Pascal 中 ActiveX 方法中 VARIANT* 参数的使用

我想在 Free Pascal 项目中使用 ActiveX-Object,从文档中我知道一种方法被声明为

其中 vVariant 将在调用后包含一个结果(整数或浮点值)。

LazActiveX“导入类型库”函数已将其转换为

我对 OleVariant 有点惊讶,因为应该只返回简单的数据类型。当使用 v: OleVariant 调用 Fetch(v) 时,我还会收到一个 EOleSysError(类型不匹配)。

谁能向我解释如何在 TLB 中正确声明此方法或如何访问数据?不幸的是,我没有 Fetch() 的来源,并且其中一些内容已包含在 NDA 中...

0 投票
1 回答
453 浏览

delphi - 为什么会失败,通过AccessibleObjectFromEvent获取的idispatch接口。调用idispatch的成员

我得到一个ms-word的句柄,然后用AccessibleObjectFromEvent得到is的IDispatch(late bingding)。然后我想调用它的属性或方法,它失败了。</p>

但可以使用 c#。

如何使用后期绑定获取excel实例?

像这样的代码。

0 投票
1 回答
821 浏览

c++ - 使用 DispEventAdvise 注册多个对象的事件

我有一个继承自“DispEventAdvise”的类(对于outlook2010,但它并不重要):

现在,我想注册 item_2010_event_handler 的单个实例以从多个对象获取事件,因此我多次调用 DispEventAdvise()(每个对象一次),但是从第二次调用 DispEventAdvise() 开始,我得到“未知错误”异常从功能上。

有可能不支持吗?如果没有,为什么不呢???

如果可能的话,我错过了什么(显然,如果需要,我会添加更多代码......)?

0 投票
1 回答
562 浏览

c++ - Windows MessageBox 如何显示“未找到成员”消息。是生成的?可以拦截吗?

我有一个基于 MFC 的带有 GUI 的 Windows 应用程序,它是用 C++ 编写的,并且有很多 COM 对象;我们称之为“HelloWorld”。

一位用户向我发送了错误报告:有时,为了响应特定的用户操作,会显示一个 MessageBox(在下图中,我删除了标题栏标题)。

在此处输入图像描述

1) MessageBox 的标题栏标题是HelloWorld,并且在代码中查找该字符串,在我看来,它是由AFX_IDS_APP_TITLE(在.rc应用程序的源文件中)标识的资源字符串;以下是.rc源文件的相关部分:

2) 在具有英语语言的 Windows 7 上,MessageBox 的消息是“未找到成员”。

3) 在具有不同语言的 Windows 7 中,消息被翻译成正确的语言。

我认为问题描述在这里 HOWTO: Troubleshoot "Member Not Found" 0x80020003 Error并且与 DISP_E_MEMBERNOTFOUND错误有关;我实际上在用户站点解决了这个问题。

但是还有一个问题没有解决,那就是用户体验问题:给我发bug报告的用户不是程序员,不知道“成员”在表达中的含义,例如“成员函数”和因此,由于“成员”一词的多种含义(至少在英语和意大利语中),该消息使用户感到有些冒犯。

我检查了应用程序的源代码,在我看来 MessageBox 不是由应用程序生成的;现在我想知道 MessageBox 是如何生成的,以便拦截它并显示不同的 MessageBox:有可能吗?

0 投票
1 回答
1067 浏览

c# - 从 C# COM dll 回调到 Delphi 应用程序导致内存泄漏

我有一个用 C# 编写的 COM 服务器和一个用 Delphi 编写的 COM 客户端。我已经实现了一个简单而优雅的回调机制,它就像一个魅力。但是,FastMM4 报告我的 Delphi 客户端正在创建内存泄漏。我已经将应用程序提炼为泄漏来源的本质。我的泄漏是由对象被引用计数的方式引起的(它永远不会变为零,所以永远不会被破坏),所以我试图理解为什么引用计数以它的方式工作,并且是这是因为我在执行过程中做错了什么。

我已经尽可能地减少了代码,但在问题中包含的内容似乎仍然很多。但我真的不知道如何解释我在做什么。我将两个项目(C# 和 Delphi)整齐地包装在一个 zip 文件中,但似乎我无法将其附加到任何地方。

我在 C# 端(ICOMCallbackContainerICOMCallbackTestServer)声明了两个接口,并在那里实现其中一个(COMCallbackTestServer)。我在 Delphi 端 ( TCOMCallbackContainer) 实现另一个接口,并将 Delphi 类传递给 C# 类。

这是 C# COM 服务器:

这是德尔福回调容器:

TCOMCallbackContainer 继承自 TAutoIntfObject,因此它实现了 IDispatch。我不知道我在构造函数中是否做对了。我不像我想的那样熟悉如何使用 IDispatch。

这是 Delphi COM 客户端:

上面的 TCOMCallbackContainer 实例永远不会被破坏,因为 RefCount 永远不会低于 2。

所以我的问题是,为什么将我的回调容器对象分配给 COM 属性会使引用计数增加 2,为什么将 nil 分配给 COM 属性根本不会减少引用计数?

编辑

我创建了 TMyInterfacedObject(与 TInterfacedObject 相同)并将其用作 TCOMCallbackContainer 的基类。我在 TMyInterfacedObject 的每个方法中都设置了断点。在每个断点,我都记录了调用堆栈(以及其他一些信息)。对于每个更新 RefCount 的方法,行尾的数字显示 RefCount 的新值。对于 QueryInterface,我包含了 IID 和相应的接口名称(通过 Google 找到)以及调用结果。

列出的所有断点都发生在FServer.CallbackContainer := TCOMCallbackContainer.Create(Process_Callback);TfrmMain.Create 的语句中。在 Destroy 方法中,尤其是在FServer.CallbackContainer := nil;语句中,没有一个断点被命中。

我想,也许是 COM 库在调用析构函数之前就被卸载了,所以我将这FServer.CallbackContainer := nil;一行复制到构造函数的末尾。它没有任何区别。

传递给 QueryInterface 调用的接口在 Delphi 环境中似乎不可用,因此我将尝试将其中一些继承到 C# 端的 ICOMCallbackContainer 中以使其可用(在研究了它们应该做什么之后以及它们应该如何工作)。

编辑 2

我尝试实现 INoMarshal 和 IAgileObject 只是为了看看会发生什么。我尝试了这两个,因为它们都是标记接口,实际上没有什么要实现的。它稍微改变了这个过程,但没有任何帮助。似乎如果 CLR 找到 INoMarshal,那么它就不会寻找 IAgileObject 或 IMarshal,如果它没有找到 INoMarshal,但找到 IAgileObject,那么它就不会寻找 IMarshal。(这似乎并不重要,甚至对我来说没有意义。)

将 INoMarshal 添加到 TCOMCallbackContainer 后:

将 IAgileObject 添加到 TCOMCallbackContainer 后: