COM 可连接对象(源对象)
首先 两个概念:
- 入接口 :源对象提供给客户调用的。
- 出接口 :源对象通过此接口可直接或间接调用客户。类似delegate
如果一个COM对象支持一个或多个出接口,这样的对象称为可连接对象。有时也称源对象。
可连接对象的出接口也是COM接口,它包含一组成员函数,每个成员函数代表了一个事件、一个通知,或一个请求。
如COM对象中的某个属性被改变时,可给客户发送一个通知;而当特定事件发生时,如定时器消息或用户鼠标操作发生时,对象产生一个事件,客户可处理这些事件。请求则是对象给客户发请求,希望客户能提供某些信息。
从COM规范上讲,不管是事件、通知还是请求,都是通过出接口的成员函数来实现。之所以称为出接口,是因为这些接口不是由对象实现,而是由客户程序实现。客户实现这些接口,并把接口指针告诉对象。以后,对象则利用此接口指针与客户进行通信。在客户方,实现这些接口的对象被称为接收器。
可连接对象除了为客户提供入接口外,还提供出接口,使得COM对象与其客户可实现双向通信。入接口由COM对象实现,通过入接口可接收来自客户的调用;而出接口则由客户端的接收器实现,接收来自COM对象的调用。即,COM对象根据其使用意愿定义一个接口,客户端实现该接口。
入接口调用
入接口由COM对象定义并实现,客户通过对象的IUnknown::QueryInterface方法得到入接口,然后通过对象调用入接口的方法,最终由COM对象代表客户执行期望的行为。
出接口调用
出接口也是由COM对象定义的,但其实现则由客户在一个接收器对象中提供,该接收器对象由客户创建。然后,COM对象通过接收器对象调用出接口的方法,来通知客户在对象中发生的变化,或触发客户事件,或从客户端请求某些东西,或者COM对象创建者提出的任何目的。
出接口的一个例子是由按钮控件定义的IButtonSink接口,将按钮事件通知其客户。例如:当用户点击按钮时,按钮对象通过客户的接收器对象调用IButtonSink::OnClick。按钮控件定义出接口,按钮的客户要处理事件,就必须在一个接收器对象中实现该出接口,并将该接收器和按钮控件连接起来。此后,当事件出现在按钮中时,按钮就会调用接收器,客户就可执行任何期望的与按钮点击关联的行为。可连接对象为对象与客户之间的通信提供了一种通用机制。
除通用的可连接对象技术,COM提供许多特殊目的的接收器和站点接口(site interfaces),用于对象通知客户:发生了一些客户感兴趣的事件。例如,IAdviseSink可被COM对象用于通知客户:对象中的数据和视图发生了变化。
对应每一个出接口,可连接对象包含一个称为连接点的对象,其实现IConnectionPoint接口。