当源中的数据发生更改时,有时需要通知使用来自外部源的数据的对象。 例如,依赖于某些电子表格中的数据的股票刻度盘磁带查看器需要在数据更改时收到通知,以便它可以更新其显示。 同样,复合文档需要有关其嵌入对象中的数据更改的信息,以便它可以更新其数据缓存。 在这种情况下,如果需要动态更新数据,数据源需要一些机制来通知数据使用者发生更改,而无需使用者删除所有内容以更新其数据。 理想情况下,收到数据源中发生更改的通知后,消耗对象可以在其休闲时请求更新的副本。
COM 处理此类型的异步通知的机制是一种称为建议接收器的对象,它只是实现名为 IAdviseSink的接口的任何 COM 对象。 数据的使用者实现 IAdviseSink。 它们通过向相关数据对象发送指针来注册以接收通知。
IAdviseSink 接口公开了用于接收异步通知的以下方法:
方法 | 通知建议接收器 |
---|---|
OnDataChange |
调用对象的数据已更改。 |
OnViewChange |
绘制调用对象的说明已更改。 |
OnRename |
调用对象的名字对象已更改。 |
OnSave |
调用对象已保存到持久性存储。 |
OnClose |
调用对象已关闭。 |
如表所示,IAdviseSink 接口公开了通知建议接收器调用对象数据更改以外的事件的方法。 调用对象还可以在绘制自身的方式更改或重命名、保存或关闭时通知接收器。 这些其他通知主要或完全用于复合文档的上下文中,尽管通知机制相同。 有关复合文档通知的详细信息,请参阅“复合文档”。
为了利用建议接收器,数据源必须实现 IDataObject::D Advise、IDataObject::D Unadvise,以及 IDataObject::EnumDAdvise。 数据使用者调用 DAdvise 方法,以通知数据对象希望在对象的数据更改时收到通知。 使用的对象调用 DUnadvise 方法来拆除此连接。 任何感兴趣的方都可以调用 EnumDAdvise 方法来了解与数据对象有咨询连接的对象数。
当源数据发生更改时,数据对象对已注册接收通知的所有数据使用者调用 IAdviseSink::OnDataChange。 为了跟踪咨询连接并管理通知的调度,数据源依赖于称为 数据建议持有者的对象。 可以通过实现 IDataAdviseHolder 接口来创建自己的数据建议持有者。 或者,可以通过调用 helper 函数 CreateDataAdviseHolder来让 COM 执行此作。