【问题标题】:Unable to get ATL Connection Points working无法使 ATL 连接点正常工作
【发布时间】:2010-11-02 20:44:36
【问题描述】:

我正在尝试使用 ATL 创建一个 COM 组件,并且我想为我的 VB 客户端引发事件。我发现了许多教程,所有这些教程的细节似乎都各不相同,而且似乎都没有生成一个可行的解决方案。这是我正在做的事情:

(使用 Visual Studio 2008):

  1. 创建一个新的 ATL DLL 项目。我称它为ATLEventTest
  2. 类视图:右键单击ATLEventTest,添加了一个新的 ATL 简单对象类。 我称之为MyObject,它生成了CMyObjectIMyObject等...
  3. 创建此对象时: a) 单元线程 b) 聚合 c) 双接口 d) ISupportErrorInfo e) 连接点

  4. 右击CProxy_IMyObjectEvents<T>,点击“添加函数”

  5. 函数返回类型为 void,名为 someEvent,并采用 int testParam
  6. 重建。
    (此时,我应该能够在某处看到“实施连接点”。我没有……)
  7. 右键单击CMyObject。 '添加连接点'
  8. 将“_IMyObjectEvents”移到列表中。
  9. 在我的解决方案中进行了代码搜索。在任何地方都找不到someEvent
  10. 再次添加了someEvent 函数。现在,在 ATLEventTest_i.h 中找到它
  11. 应该可以在我的代码中调用fire_someEvent(...),但不能。

这一直让我发疯,试图让它发挥作用。如果有人能看出我做错了什么,我将不胜感激任何更正、提示、黑客等。

在这一点上,我很想说把向导搞砸了,直接尝试修改c++和idl,但我有一种感觉可能不会好得多:(

【问题讨论】:

  • 我个人鼓励您在没有 ATL 的情况下这样做。这是我为 ActiveX 控件和 JavaScript 写的一篇博客文章。接口和概念本质上是相同的。 jeffcode.blogspot.com/2008/02/…

标签: c++ events com atl connection-points


【解决方案1】:

尝试使用此处列出的方法:

Adding an Event (ATL) @ MSDN

使用上面给出的示例名称,在 MyObject.idl 文件中,即使在调度接口 _IMyObjectEvents 部分下,您也应该看到出站声明。由于您右键单击 CProxy_IMyObjectEvents 而不是库下的 _IMyObjectEvents,因此您的 IDL 可能缺少定义。自动生成的文件 _IMyObjectEvents_CP.h 文件应该存在于您的项目头文件中,并且应该包含 Fire_someEvent() 方法作为正确添加方法的结果。如果没有,您可能会发现它只是创建了一个名为 someEvent() 的方法。

这是您可以在测试项目中尝试的大纲。

  1. 创建一个新的 ATL DLL 项目。我将其命名为 ATLEventTest1。
  2. 构建项目。
  3. 类视图:右键单击 ATLEventTest1,添加一个新的 ATL 简单对象类。称它为 MyObject。
  4. 使用 a) 单元线程 b) 双接口 c) 连接点以及您需要的任何其他内容来创建定义。
  5. 重建项目。
  6. 类视图:找到 ATLEventTest1Lib 库,右键单击 _MyObjectEvents,然后“添加方法”。
  7. 方法是 void 返回类型,命名为 someEvent,并采用带有参数属性 [in] 的 int testParam。
  8. 添加参数后,您应该会看到“[in] int testParam”。
  9. 在 IDL 属性选项卡上,如有必要,更改 ID。点击完成。
  10. 类视图:右键单击 CMyObject,转到添加...,转到实施连接点。
  11. 选择 _IMyObjectEvents 并单击“>”将其移至已实现的连接点列表。点击完成。
  12. 重建。
  13. 现在,在您的 CMyObject 类中,您应该能够调用 Fire_someEvent()。您将在分配接口 _IMyObjectEvents 下的 ATLEventTest1.idl 文件中看到一个新方法;将创建头文件_IMyObjectEvents_CP.h 文件并将创建Fire_someEvent() 的广播代码。

【讨论】:

  • (由于 Visual Studio 2012/2010/maybe2008 中的 BUG) 11.pre 不要使用默认的 'Embedded IDL' item for 'Avaliable type libraires',你应该手动选择项目的 typelib。跨度>
  • 雷蒙德是什么意思?我可以看到它在VS2012中不起作用,右键单击事件界面选择添加方法并完成向导不会将事件添加到IDL。但是'你应该手动选择项目的类型库'是什么意思?选择它在哪里!
【解决方案2】:

您的班级是否有 IProvideClassInfo/IProvideClassInfo2 的实现?如果我记得对于非控制对象,VB 需要它来定位事件源接口。

试试这个:

public IProvideClassInfo2Impl<&CLSID_MyClass NULL, &LIBID_ATLEventTest, 1, 0>,

然后在界面地图中

COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)

【讨论】:

  • IProvideClassInfo/IProvideClassInfo2 是关键点。我浪费了几天,在将我的代码与 MSDN 教程代码进行比较后,我发现了不同之处。
【解决方案3】:

也许您在使用单元线程时遇到了问题。 您是否在 VB 上编写控制台应用程序? 它需要一个经典的消息泵才能正常工作(例如经典的 Windows 应用程序)。 在您的 COM 对象 (MTA) 上尝试不同的公寓模式。

【讨论】:

    【解决方案4】:

    好的。因此,在新系统重建后,我已经安装了 Visual Studio 2005 和 Visual Studio 2008。我可以在 2005 年完美地使用它。仍然无法在 2008 年工作。看起来我只需要在 VS2005 上为我的 ATL 工作......

    再次感谢所有提供帮助的人。

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题。继续阅读MSDN文档并在线搜索。最后,我想通了。

      向导没有做的主要事情是将声明放入 IDL 文件中。我手动添加了它,在我的课堂上,有一个“Fire_”。

      希望对你有所帮助。

      【讨论】:

        【解决方案6】:

        我可以通过从控件的 .h 文件中删除所有 _I***Events 引用来解决类似问题

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-04-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多