2015-06-17 51 views
1

我有一個STA線程,我正在執行一些操作。由於環境(辦公室)的限制,在某些時候我不能做某些事情。但是,我可以在當前消息泵循環完成後立即執行這些操作。以「PostMessage」方式調用COM對象

我通常會用我自己的message-only窗口句柄來做到這一點,我將使用PostMessage發佈消息。但是,考慮到環境和架構,操作與來自其他線程/進程的其他COM對象調用一起排隊非常重要。或者更準確地說,調用後操作需要在CoWaitForMultipleHandles調用中執行。

COM(+)提供了一種機制來調用方法「稍後」?以外:

  • 自己創建一個線程(或以其他方式重用我自己創建的線程)。使其成爲STA線程。將我的對象接口編組爲該線程。使用ICallFactory爲我的異步界面創建一個調用對象。從這個輔助線程中消失並忘記。
  • 嚴格爲回發創建MTA對象(目標COM服務器仍然是原始STA線程上的STA對象)。實例化時,COM將爲我創建一個線程。調用該MTA對象來安排回發(使用與以前相同的ICallFactory方法)。
  • 挖出COM調度窗口句柄和PostMessage。

前兩個需要單獨的線程,這似乎是不可取的。最後是一個黑客。

+0

很不清楚「當前消息泵循環」可能意味着什麼。如果你需要稍後發生的事情,那麼最簡單和風險最小的方法就是使用SetTimer()。 –

+0

SetTimer將需要我自己的WndProc,我可以通過創建我自己的窗口(其消息不會在CoWaitForMultipleHandles中處理)或覆蓋com調度程序窗口(hack)的WndProc來獲得。 –

+0

[製作和處理異步調用](https://msdn.microsoft.com/en-us/library/windows/desktop/ms692623%28v=vs.85%29.aspx)。 – arx

回答

0

下面是幾個黑客試用。我還沒有嘗試過他們自己在對於CoWaitForMultipleHandles,所以我不知道其中是否會在託管的辦公環境工作:

  • 辦公室提供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用戶界面(針對調用範圍)以限制重新進入的可能性。然後,您將啓動嵌套消息循環,IMsoComponentManager::FPushMessageLoopmsoloopDoEvents,並期望IMsoComponent::FContinueMessageLoop在每次新迭代(泵)時被回調。

+0

IMsoComponentManager是否被棄用? (不一定是交易斷路器,但是......) –

+0

@MichaelGunter,它在Office的所有最新版本(包括2013)中均受支持。它還被.NET用於託管的.NET辦公組件。我相信它不會很快到任何地方。 – Noseratio

+0

我想知道爲什麼這些信息很難找到。搜索時,2010+的文檔不會立即顯示。我確實設法找到Office 2010的文檔,但似乎沒有Office 2013的文檔。我同意這不會發生,但它很好奇。 https://msdn.microsoft.com/en-us/library/office/gg702942(v=office.14).aspx –