【问题标题】:How unmanaged C++ implement COM sink非托管 C++ 如何实现 COM sink
【发布时间】:2012-07-31 14:00:12
【问题描述】:

我有一个 c# COM 服务器为事件处理定义了一些委托。 这是来自 MSDN 的示例代码:

using System;
using System.Runtime.InteropServices;
namespace Test_COMObject
{
public delegate void ClickDelegate(int x, int y);
public delegate void ResizeDelegate();
public delegate void PulseDelegate();

// Step 1: Defines an event sink interface (ButtonEvents) to be     
// implemented by the COM sink.
[GuidAttribute("1A585C4D-3371-48dc-AF8A-AFFECC1B0967")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface MyButtonEvents
{
    void Click(int x, int y);
    void Resize();
    void Pulse();
}
// Step 2: Connects the event sink interface to a class 
// by passing the namespace and event sink interface
// ("EventSource.ButtonEvents, EventSrc").
[ComSourceInterfaces(typeof(MyButtonEvents))]
public class MyButton
{
    public event ClickDelegate Click;
    public event ResizeDelegate Resize;
    public event PulseDelegate Pulse;

    public MyButton()
    {
    }
    public void CauseClickEvent(int x, int y)
    {
        Click(x, y);
    }
    public void CauseResizeEvent()
    {
        Resize();
    }
    public void CausePulse()
    {
        Pulse();
    }
}
}

但是 msdn 只提供了一个 VB 示例来实现 COM 客户端事件接收器,谁能给我一个示例,非托管 c++ 是如何做到这一点的? 下面是实现 COM 事件接收器的 vb 示例

' COM client (event sink)
' This Visual Basic 6.0 client creates an instance of the Button class and 
' implements the event sink interface. The WithEvents directive 
' registers the sink interface pointer with the source.
Public WithEvents myButton As Button

Private Sub Class_Initialize()
Dim o As Object
Set o = New Button
Set myButton = o
End Sub
' Events and methods are matched by name and signature.
Private Sub myButton_Click(ByVal x As Long, ByVal y As Long)
MsgBox "Click event"
End Sub

Private Sub myButton_Resize()
MsgBox "Resize event"
End Sub

Private Sub myButton_Pulse()
End Sub

【问题讨论】:

    标签: events com


    【解决方案1】:

    语言运行时通常隐藏与从 COM 对象接收事件有关的大量管道。但是,如果您在原始 C++ 中执行此操作,则需要通过查询 IConnectionPointContainer 的接口指针来开始。这使您可以枚举所有传出接口。然后,您可以获取特定接口的 IConnectionPoint。然后调用它的 Advise() 方法来设置接收回调的接收器接口。这会给你一个cookie,你需要存储它。稍后当您想通过 Unadvise 呼叫取消订阅时。

    在 MSDN 库中描述得相当好,开始 reading here

    【讨论】:

    • 我创建了一个 c++ 类:class CSubButton:public Test_COMObject::MyButtonEvents 但我无法创建实例,编译器告诉我 IDispath 没有实现。
    • 这对我来说太复杂了,因为我没有任何 COM 经验。最后我导出了一个 c 函数并使用 c# 部分中的加载库将其作为委托覆盖。
    猜你喜欢
    • 1970-01-01
    • 2013-04-28
    • 2020-05-03
    • 2011-04-21
    • 1970-01-01
    • 2010-11-10
    • 2012-02-29
    • 2019-01-01
    • 2013-06-01
    相关资源
    最近更新 更多