2009-12-28 80 views
3

我已經寫了,其中有兩個線程的樣本MFC應用程序: - 主線程(UI線程) -Worker線程(非UI線程)如何在工作線程(非UI線程)中創建模態對話框?

我有一個具體的要求,以創建一個非對話框Modal -UI(工作者線程)。 當我創建CDialog對象並調用DoModal時,它可以工作。對話框被創建並作爲應用程序的模態。 (Win XP SP2機器)但是這在Windows 2003服務器機器中不起作用。 2003服務器的行爲是,模態對話框在應用程序的主窗口後面,只有當我點擊主窗口時,對話框纔會出現在前面。它不作爲我的應用程序的模態對話框。

可能是什麼問題 - 任何想法?

如果在非UI線程中創建UI控件是問題,那麼是否有任何Win32 API將允許我將我的工作線程鏈接到主UI線程,使得DoModal發生在主線程中。我試過AttachThreadInput,但它不工作。

回答

1

儘管我不知道Server 2003上的對話框處理的具體細節,但獲得主線程的最簡單的解決方法是使用自定義窗口消息,執行::SendMessage()並在消息處理程序中顯示對話框。

0

我建議你不要做什麼問題的主題建議,並限制所有的用戶界面到一個線程。如果您需要其他線程與用戶進行通信,請創建一些消息傳遞機制,以便要求UI線程執行此操作,然後將結果傳回。

2

首先,我想同意其他海報,最好在主UI線程上顯示對話框。

不過,如果你一定要,你可以在下面的步驟另一個線程模式一個對話框:

  1. 創建對話框時,通過你的活動窗口作爲所有者。
  2. 當顯示對話框時,遍歷其他窗口並執行它們EnableWindow(FALSE)。當對話框隱藏時,請做相反的操作。您可能必須記住Windows的啓用狀態並恢復原始狀態,而不僅僅是EnableWindow(TRUE)
  3. 確保在顯示對話框時忽略加速器和其他全局命令。

請注意,(2)不應該是必要的,只要你做(1),但你已經提到MFC,我不記得它究竟是如何表現。它有自己的模式對話框實現,它可能不完全符合Win32。如果你幸運的話,(1)和(3)就足夠了。

2

沒有可靠的方法來跨多個線程傳播GUI模態。每個窗口都由一個HWND引用的對象表示,而該對象又具有線程關聯性。這是從Windows的16位日子剩下的,那裏沒有多線程。因此,HWND不受併發訪問保護。 The Old New Thing在「用戶界面對象的線程親和性」(部分123Addendum)上有很好的系列。

Modality通過首先啓用對話框窗口然後禁用其父項來實現。第一步是安全的,而第二步則嘗試從不是窗口擁有線程的線程中禁用窗口。由於en//禁用窗口修改通過HWND引用的對象,它代表競爭條件。

建議的解決方案是將GUI限制到單個線程,並從工作線程到GUI線程進行通信,以便代表工作線程執行用戶交互。最簡單的方法是從worker線程調用SendMessage,直到GUI線程的消息處理程序返回。如果在顯示對話框時應該繼續運行工作線程,則可以使用PostMessage,並使用PostThreadMessage或者發信號通知一個同步對象(如Event Object)與工作線程通信。