使COM互操作事件从接口可见
本文关键字:接口 事件 COM 互操作 | 更新日期: 2023-09-27 17:50:49
我写的代码像下面的例子:
public delegate void ClickDelegate(int x, int y);
public delegate void PulseDelegate();
[Guid("39D5B254-64DB-4130-9601-996D0B20D3E5"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface IButton
{
void Work();
}
// 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 ButtonEvents
{
void Click(int x, int y);
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(ButtonEvents))]
public class Button : IButton
{
public event ClickDelegate Click;
public event PulseDelegate Pulse;
public Button() { }
public void CauseClickEvent(int x, int y) { Click(x, y); }
public void CausePulse() { Pulse(); }
public void Work() { /* Do some stuff */ }
}
这在VB中工作得很好。当我这样定义它时:
Dim WithEvents obj As Button
但是我想用这样的接口定义它:
Dim WithEvents obj As IButton
这是不工作的,因为事件是不可见的IButton接口。
有办法做到这一点吗?
连接到对象事件的变量必须声明为该对象(在您的示例中为Button
)的类型(CoClass)。接口(在您的示例中是IButton
)不知道任何关于事件的信息,因此不能使用它来请求它们。
我喜欢这样想:
接口是两个对象同意使用的东西,因此"客户端"可以向"服务器"发送命令("服务器,做XYZ!")。Event只是两个对象也同意使用的不同接口,但是用于相反的:即用于"服务器"对象向"客户端"发送命令。
是否支持给定的Event接口是对象的属性,而不是对象可能支持的任何接口的属性。服务器对象说:"给我一个ButtonEvents
接口指针,我将用它来告诉你当按钮被点击"。这不是IButton
接口提供的。
这也是为什么您必须将[ComSourceInterfaces]
属性应用于类Button
,而不是接口IButton
。Button
CoClass是提供报价的。
使事件看起来特别或奇怪的事情是,我们需要使用一个有点复杂和令人困惑的舞蹈("连接点")来传递事件的接口指针。WithEvents
是让VB6为你"跳舞"的方式。