Windows Vista 和 Office: 使用托管预览处理程序框架以自己的方式查看数据
2009-02-09 17:43:48 来源:WEB开发网当然,问题不在这里,如果我在此前知道该准则,那么为什么我还要从构造函数中调用 CreatePreviewHandlerControl 而违反该准则呢?因为我需要在 VI 线程中创建控件。这导致了我要解决的第二个问题。在前面显示的构造函数的末尾,您将注意到我已检索了 _previewControl.Handle 的值,但我没有用结果做任何事情。我这样做是为了调用控件 Handle 属性的 get 访问器。换句话说,我不需要该结果;我只是想执行访问器。通过调用 Control.Handle get 访问器,可以强制创建控件的基本窗口。这很重要,因为实例化预览处理程序组件并调用其构造函数的线程是单线程单元 (STA) 线程,但稍后调用接口成员的线程是多线程单元 (MTA) 线程。您可能知道,Windows 窗体控件需要运行在 STA 线程上,如果试图从 MTA 线程使用它们,有时会导致可怕的后果。因此,创建 Windows 窗体预览窗口的最佳时机是在预览处理程序的构造函数中。在随后调用需要与预览控件交互的其他接口方法时,需要封送回 STA 主线程。通过使用控件的 ISynchronizeInvoke 接口,很容易完成此操作。请注意,实现本机预览处理程序时,并不存在这两个线程的问题,并且很可能是 CLR 如何处理 COM Interop 的问题。
(值得指出的是,尽管我要讨论依赖于 Windows 窗体的实现,但可能有时最容易显示预览的方式是使用 ActiveX 控件。有关这方面的讨论,请参见“使用 ActiveX 控件”边栏。)
使用 COM 接口
不管您是否相信,构造函数是整个 PreviewHandler 实现中最难的部分。该实现的其余部分只是用于将 COM 接口上的调用引向 Windows 窗体控件,并处理一些基本的簿记。我将首先讨论最容易的接口。
IOleWindow IOleWindow 允许承载应用程序获得参与就地激活的窗口的句柄,换句话说,这是我们的控件的句柄(对于预览处理程序,永远不会调用 ContextSensitiveHelp)。这使该接口非常容易实现,如下所示:
更多精彩
赞助商链接