2011-11-18 103 views
1

我們有一個MFC Visual-C++應用程序不會對任何用戶輸入做出反應。MFC應用程序似乎沒有收到輸入消息?

(注:!目前只知道一臺機器上的行爲偶爾會復發,但只有在應用程序已經運行了數天)

應用重繪,當我們通過切換到它Alt-Tab(或任務欄),但我們不能通過點擊標題欄來激活它的主窗口。


我們已經用WinDbg拉出4個轉儲並檢查了活動指令。我們總是在一些重繪代碼中,或者在主線程(GUI線程)內部。我們在模態消息循環中肯定是而不是,並且主線程的堆棧始終顯示爲「OK」。 (大多數/所有的工作線程都空閒,等待某個事件,沒有發現可疑代碼有兩種。)


在調查與Spy++的問題,我們看到的還指定in this separate question的行爲,即我們似乎得到漆和激活消息,但沒有用戶輸入路由到應用程序。當我在屏幕上的應用程序窗口,並選擇它顯示在主窗口的消息,

App Main Window

它只會顯示「通用」,「referesh」的消息,並沒有別的

Messages for the main Window

如果我更深入的分析,並選擇了整個過程的所有消息,

Windows of same process setting

這就是我們看到:

200 WM_PAINT messages per second

該應用顯然在一個隱藏的子窗口(00CB09F0)只處理消息,並且我們看到的有每秒200 WM_PAINT消息的恆定流

通常這個子窗口根本不處理任何消息(除了Windows發送它們時刷新WM_PAINT等)。它通常用作繪圖區域,並通過它的父級(010A09B8)窗口上的WM_TIMER消息進行繪圖。 (未在懸掛應用中顯示該消息WM_TIMER或者雖然。)

如過程資源管理器中示出的性能曲線看起來像這樣(100%內核的時間,更多或更少):

Process Explorer App Performance Graph

回答

0

我想說,你有一個重繪循環在那個接收WM_PAINT洪水的窗口。

如果您直接或間接地調用Invalidate或類似處理WM_PAINT消息,通常會發生這種情況。

其他可能性是,由於您說您使用計時器重新繪製窗口,實際繪圖花費的時間更多,因此消息堆積在隊列中。

還有一種可能性是,您正在使窗口與創建繪畫的窗口不同,從而使窗口無效。

無論如何,您應該確保您正確呼叫Invalidate*()(您沒有顯示任何代碼),並且從來沒有從OnPaint事件中調用。並且避免調用UpdateWindow(),因爲如果調用該函數,可能會讓事情變得無關緊要。

+0

多個Invalidate調用會壓縮爲單個WM_PAINT消息,因此您永遠不會落後於此。 –

+0

@MarkRansom True,WM_TIMER也不會。除非他手動發送WM_PAINT而不是調用'Invalidate'(是的,我已經看到了)。 – rodrigo

+0

哦,是的,我也看到了。一個很大的禁忌。 –

0

我從對話框中引發異常時看到了這個問題。 MFC的DoModal函數禁用主程序窗口,然後在對話框返回時重新啓用它;例外繞過重新啓用部分,主窗口永遠保持禁用狀態。

+0

嗯......如果窗口/窗口(MDI!)被禁用​​或不應該通過Spy ++檢查並檢查窗口的樣式標誌,不是嗎?我們還沒有這樣做(還)。 (需要等待下一次再次發生。) –

相關問題