我有一个STA线程,我正在执行某些操作。由于环境的限制(Office),有些事情我现在还做不到。但是,在当前的消息泵循环完成后,我可以立即执行这些操作。
我通常使用自己的仅消息窗口句柄来执行此操作,我将使用PostMessage向其发布消息。但是,考虑到环境和手头的体系结构,操作与来自其他线程/进程的其他COM对象调用一起排队是至关重要的。或者更准确地说,调用后操作需要在CoWaitForMultipleHandles调用期间执行。
COM(+)是否提供了一种调用方法的机制"稍后"?除了:
前两个需要一个单独的线程,这似乎是不可取的。最后一个是黑客。
答案 0 :(得分:0)
以下是一些可以尝试的黑客攻击。我自己没有尝试CoWaitForMultipleHandles
,所以我不确定它们中的任何一个是否适用于托管的Office环境:
Office提供IMsoComponentManager
服务。您实施IMsoComponent
(查看this以获取一些示例代码)。希望IMsoComponent::FDoIdle
可能有用。
SetTimer
可以接受TIMERPROC lpTimerFunc
。你不必为它创建一个窗口,你可以使用ATL thunk或类似的技术来创建一个C ++闭包。我已使用SetTimer
完成此操作并且它可以正常工作,但我不确定它是否适用于CoWaitForMultipleHandles
,因为计时器回调通常会在DispatchMessage
内调用。此外,timer gets low priority in message dispatching,所以可能不按顺序。
WH_FOREGROUNDIDLE/ForegroundIdleProc
可能很有趣,使用ATL thunk。当后者空闲时,也应该从CoWaitForMultipleHandles
内部调用它。
查看您的STA线程上的自定义COM message filter是否有用。 已更新,您澄清了它是一个Office线程,因此很可能它有自己的COM消息过滤器。也许,你可以在你的通话范围内覆盖它。
查看对象上实现IAdviseSink
是否有用。此接口是AFAIK COM规则的唯一异常,因为当通过另一个公寓的COM代理调用时,其方法称为异步。也许,这是解决问题的最佳选择。
已更新,既然我们确定您已经在MSO STA线程上运行,那么还有另一个黑客攻击。您可以为调用范围启动嵌套模式消息循环。然后,您可以控制每个消息泵循环。这是我通常不推荐的DoEvents
式黑客攻击,但您已经处于黑客攻击区。您至少需要禁用Office UI(针对调用范围)以限制重新入侵的机会。然后,您使用IMsoComponentManager::FPushMessageLoop
msoloopDoEvents
启动嵌套消息循环,并在每次新迭代(泵)时调用IMsoComponent::FContinueMessageLoop
。