2013-05-29 55 views
24

免責聲明:我不熟悉Win32 API,特別是Windows如何工作。當子窗口凍結時,父窗口凍結,雖然它來自另一個進程

我想使某個進程的窗口成爲另一個進程的子窗口。這兩個過程也是父母和孩子。但我認爲這不重要。到目前爲止,一切都像魅力一樣 - 直到我凍結了子窗口的主線程。

想象一個container.exe是「主機」的notepad.exe和someApplication.exe

當我暫停someApplication.exe的主線程幾秒鐘,它的窗口被凍結該金額的時間。這完全可以理解。但container.exe的窗口掛在同一時間。其他託管進程的子窗口(如notepad.exe)將繼續正常工作。

我使用SetParent命令使常規的非子窗口我container.exe的孩子:

SetParent(
    childProcess.HWND, 
    myOwnHWND 
); 

在那之後,我使用setWindowPos

SetWindowPos(
    childProcess.HWND, 
    HWND_TOP, 
    someXPos, 
    someYPos, 
    0, 
    0, 
    SWP_FRAMECHANGED or SWP_NOSIZE or SWP_SHOWWINDOW 
) 

由於MSDN article on SetParent建議,我也清除WS_POPUP樣式屬性並添加一個WS_CHILD屬性。既然這也沒有幫助,我還通過使用SetWindowLongPtr命令添加了WS_EX_NOACTIVATE擴展樣式屬性。最後,我試着發送兩個窗口,一個是WM_UPDATEUISTATE,然後是一個WM_CHANGEUISTATE消息,但這也沒有改變一件事。

令我迷惑的是,父進程的窗口繼續正常繪製,直到我觸摸它。然後它完全凍結,直到子窗口解凍。我懷疑一個叫做'輸入隊列'的東西。 MSDN articleWM_ACTIVATE消息狀態:

發送到正在激活窗口和窗口被停用。如果窗口使用相同的輸入隊列,則同步發送消息,首先到頂層窗口的窗口過程被停用,然後到頂層窗口的窗口過程被激活。如果窗口使用不同的輸入隊列,則消息將異步發送,因此窗口會立即激活。

正因爲如此,我曾經爲WS_EX_NOACTIVATE擴展樣式屬性寄予厚望。

綜上所述:實際上可以託管另一個進程的窗口,並且在子窗口凍結時不凍結自己的窗口?

+8

+1這個問題令人難以置信的徹底。 –

+2

相關閱讀:[呼叫是否有跨進程的父母/子女或擁有者/擁有的窗口關係是合法的?](http://blogs.msdn.com/b/oldnewthing/archive/2013/04/12/10410454 .aspx) – GSerg

+1

*爲什麼*你需要這樣做?我確信有更好更簡單的方法來實現您的實際目的。不要陷入XY問題陷阱。 –

回答

17

你不能期望阻塞任何進程的GUI線程。在你的場景中,事情有點複雜,因爲有兩個GUI線程。每個過程一個。

但是,通過在這些進程的窗口之間建立父/子關係,您還需要及時爲這兩個GUI線程提供服務。

處於父/子關係的Windows將互相發送消息。如果這些消息是同步的,則發送而不是發佈,然後阻止一個GUI線程將導致另一個被阻止。

GUI編程的黃金法則仍然有效:不要屏蔽GUI線程。如果您有長時間運行的任務,請將其移至後臺線程。

更新

OK,因爲解釋here當你涉及來自不同線程窗口您將自己的消息隊列給對方。所以如果你阻止一個線程,你會阻塞所有連接的線程。

所以,不要屏蔽GUI線程。

+1

謝謝。當然,不應該阻止GUI線程。然而,我正在測試一個最壞的情況,像_hosted_應用程序完全凍結。在這種情況下,主機應用程序可能不會凍結。另外,我仍然想知道父母/孩子的過程關係如何在這裏發揮作用。如果子進程窗口不是父進程窗口的子進程,那麼後者當然不會凍結。所以他們不能真正發送**消息。 –

+0

「如果子窗口 不是父進程窗口的子窗口,則後者當然不會凍結。」您致電SetParent讓一個窗口成爲另一個窗口的孩子。 「他們無法真正發送消息。」爲什麼不?整個Windows GUI是基於消息的。這絕對是Windows所做的。如果阻止一個GUI線程,期望您的GUI失敗。 –

+2

所以關鍵是兩個窗口現在使用相同的_input隊列_。核心問題在於將'WM_ACTIVATE'消息同步**發送給凍結窗口。以下是另一篇新聞組帖子,內容涵蓋完全相同的主題:[Link](http://narkive.com/YmRDFrDR)。由於我不希望能夠使用'AttachThreadInput'命令來分離子窗口_input queue_,所以我接受這個答案並且在沒有父/子窗口關係的情況下過着幸福的生活。非常感謝! –