视图缓存
当文档打开但对象的服务器应用程序未运行或未安装在用户的机器上时,容器应用程序必须能够获得对象的演示,以便为用户显示或输出该对象。 然而,假设文档中可能找到的所有对象的服务器都安装在每个用户的机器上,并且总是可以按需运行,这是不现实的。 默认的对象处理程序始终可用,它通过将对象表示缓存在文档的存储中并在任何平台上操作这些表示来解决这一难题,而不管容器的任何特定安装上的对象服务器是否可用。
容器可以维护一个或多个特定目标设备的图形演示,此外还可以维护屏幕上对象所需的设备。 此外,如果将对象从一个平台移植到另一个平台,OLE 会自动将该对象的数据格式转换为新平台上支持的格式。 例如,如果将对象从 Windows 移动到 Macintosh,OLE 会将其图元文件演示转换为 PICT 格式。
为了向用户提供嵌入对象的准确表示,对象的容器应用程序会启动与对象处理程序的对话框,请求数据和绘图指令。 为了能够满足容器的请求,处理程序必须实现 IDataObject、IViewObject2 和 IOleCache 接口。
IDataObject 使 OLE 容器应用程序能够从中获取数据并将其发送到其嵌入对象或链接对象。 当对象中的数据发生变化时,此接口为对象提供了一种方法,使其新数据可用于其容器,并为容器提供了更新对象副本中数据的方法。 (有关数据传输的一般讨论,请参阅第 4 章“数据传输”。)
IViewObject2 接口与 IDataObject 接口非常类似,接口非常相似,只是它要求对象在设备上下文(如屏幕、打印机或图元文件)上绘制自己,而不是将其数据移动或复制到内存或其他传输介质。 该接口的目的是使 OLE 容器能够获得其嵌入对象的替代图形表示,它已经具有嵌入对象的数据,从而避免了为了获得新的绘图指令而必须传输相同数据对象的全新实例的开销。 相反,IViewObject2 接口使容器能够要求对象通过绘制容器指定的设备上下文来提供其自身的图形表示。
调用 IViewObject2 接口时,容器应用程序还可以指定对象在不同于实际呈现对象的目标设备上绘制自己。 这使容器能够根据需要从单个对象生成不同的呈现。 例如,即使生成的图形将在屏幕上呈现,调用方也可以要求对象为打印机自行组合。 当然,结果将是对象的打印预览。
IViewObject2 接口还提供使容器能够注册查看更改通知的方法。 与数据和 OLE 公告一样,视图公告连接使容器能够自行更新对象的呈现,而不是响应来自对象的调用。 例如,如果对象的服务器应用程序的新版本提供相同数据的其他视图,该对象的默认处理程序将调用每个容器的 IAdviseSink::OnViewChange 实现,让他们知道新的演示可用。 仅当需要时,容器才会从建议接收器中检索此信息。
由于 Windows 设备上下文仅在单个进程中具有意义,因此不能跨进程边界传递 IViewObject2 指针。 因此,OLE 本地和远程服务器根本不需要实现该接口;即使实现了,也无法正常工作。 只有对象处理程序和进程内服务器实现 IViewObject2接口。 OLE 提供默认实现,只需聚合 OLE 默认处理程序,即可在自己的 OLE 进程内服务器和对象处理程序中使用。 或者,可以编写自己的 IViewObject2 实现。
对象实现 IOleCache 接口,以便让处理程序知道它应缓存哪些功能。 对象处理程序还拥有缓存并确保其保持最新状态。 当嵌入对象进入运行状态时,处理程序在服务器对象上设置适当的咨询连接,并自行充当接收器。 IDataObject 和 IViewObject2 接口实现在客户端缓存的数据中运行。 处理程序的 IViewObject2 实现负责确定要缓存的数据格式以满足客户端绘制请求。 处理程序的 IDataObject 实现负责在内存和嵌入式对象的基础 IStorage 实例之间获取各种格式的数据等。 自定义处理程序可以通过聚合默认处理程序来使用这些实现。
注意
IViewObject2 接口是 IViewObject 的一个简单的功能扩展,用来代替现在已经过时的后一个接口。 除了提供 IViewObject 方法外,IViewObject2 接口还提供了一个单独的附加成员 GetExtent,该成员使容器应用程序能够从缓存中获取对象表示的大小,而无需首先通过调用 IOleObject::GetExtent 将对象移动到运行状态。
相关主题