2009-11-11 215 views
1

我正在調試一個在其消息循環中調用IsDialogMessage()的應用程序。偶爾,IsDialogMessage()永遠不會返回(永遠不會超過1小時的間隔)。根據Microsoft的符號服務器提供的user32.dll符號,它似乎卡在GetNextDlgGroupItem()(或同一個內部變體)中,迭代了一些窗口集。爲什麼IsDialogMessage()永遠不會返回?

該應用程序是多線程的,並經常接收外部事件的通知,這些事件以DCOM調用的形式到達。我懷疑這樣的調用是以錯誤的方式處理某種窗口狀態的。如果我能夠知道什麼樣的狀態腐敗可能導致IsDialogMessage()中的無限循環,我想我會更容易地識別腐敗的來源。

回答

0

您是否可能禁用控件(使用::EnableWindow())而未首先檢查該控件是否具有焦點?如果是,那麼焦點會丟失,GetNextDlgGroupItem()會變得混亂。

+0

這是可能的;有很多控件在使用,有些可能會被禁用。 – 2009-11-12 00:48:49

0

這可能發生的另一個原因是如果你重新建立一個無模式的對話框。至少這可以發生在wxWidgets ...

3

我知道這是舊的,但回答後代,因爲沒有人在這裏提到它。

更可能發生什麼事是Windows管理器確定在哪裏轉發消息的麻煩。如果您有Windows的層次結構,那麼您需要確保包含控件的非頂級窗口本身必須具有WS_EX_CONTROLPARENT樣式集。如果它是一個對話框,則使用DS_CONTROL樣式。這些標誌的存在修改了IsDialogMessage的行爲;他們將窗口標識爲擁有自己的控件,這些控件可以接收焦點並處理標籤順序等,而不僅僅是控件本身。

舉例來說,如果你有一個主框架窗口,它與WS_EX_CONTROLPARENT一個子窗口,其中有一個子窗口沒有 WS_EX_CONTROLPARENT,其中有具有焦點的子窗口,和你打標籤,就可能在你提到的同一個地方遇到無限循環。

將第二個孩子的擴展樣式設置爲包含WS_EX_CONTROLPARENT將解決該問題。

0

我做了一些調查,試圖回答這個問題。但只有在情況下,當父窗口在本地MFC項目中,並且子項是託管的C#Windows窗體。如果您有這種情況,那麼您可以嘗試3種分辨率:

  1. 在Windows窗體端運行MFC對話框消息循環。以下是更多信息:Integrate Windows Forms Into Your MFC Applications Through C++ Interop
  2. 創建2個線程:一個用於Windows窗體對話框,一個用於本機對話框。在這裏你可以在Windows窗體中創建對話框,然後用SetParent()將它設置爲本地對話框的父對話框。但是,如果您將TabControl添加到Windows窗體中,則會比「IsDialogMessage()永不返回」掛起。
  3. 爲本地項目中使用的Windows窗體對話框創建一個包裝。對於恩,包裝物可爲WPF,在這裏看到:Windows Form as child window of an unmanaged app

我已經採取了大多來自信息:http://msdn.microsoft.com/en-us/library/ms229600.aspx

而且治標可以改變焦點行爲。例如,禁用它們,或僅將SetFocus()設置爲父窗口或子窗口。但我強烈建議調查真正的原因,爲什麼IsDialogMessage()永遠不會返回你的情況。

相關問題