Приложение MFC не получает входные сообщения? - PullRequest
1 голос
/ 18 ноября 2011

У нас есть приложение MFC Visual-C ++, которое не реагирует ни на один пользовательский ввод.

(Примечание. В настоящее время известно только на одном компьютере. Такое поведение иногда повторяется, но толькопосле запуска приложения в течение нескольких дней!)

Приложение перерисовывается , когда мы переключаемся на него через Alt-Tab (или панель задач), но мы не можем, например,активируйте главное окно, нажав на строку заголовка.


Мы уже вытащили 4 дампа с WinDbg и проверили активные инструкции.Мы всегда были в некотором перерисовываемом коде или в каком-то подобном внутри основного потока (потока GUI).Мы определенно были / 101 * * не в модальном цикле сообщений, и стек основного потока всегда выглядел "хорошо".(Большинство / все рабочие потоки бездействовали, ожидая какого-либо события, там также нет подозрительного кода.)


При исследовании проблемы с Spy ++ мы видим также указанное поведение в этом отдельном вопросе , а именно о том, что мы, кажется, получаем сообщения рисования и активации, но пользовательский ввод не направляется в приложение .Когда у меня есть окно приложения на экране, и я выбираю его для отображения сообщений главного окна,

App Main Window

, оно будет показывать только "общие" сообщения "обновить" и ничего больше

Messages for the main Window

Если я углублюсь и выберу все сообщения для всего процесса,

Windows of same process setting

это то, что мы видим:

200 WM_PAINT messages per second

Приложение, по-видимому, обрабатывает сообщения только в одном скрытом подокне (00CB09F0), и мы видим постоянный поток 200 сообщений WM_PAINT в секунду.

Обычно это подокно вообще не обрабатывает никаких сообщений (кроме обновления WM_PAINT и т. Д., Когда Windows отправляет их).Обычно он используется как область рисования, и рисование происходит через сообщение WM_TIMER в его родительском (010A09B8) окне.(Однако это сообщение WM_TIMER также не отображается в зависшем приложении.)

Профиль производительности, показанный в проводнике процессов, выглядит примерно так (100% времени ядра, более или менее):

Process Explorer App Performance Graph

Ответы [ 2 ]

0 голосов
/ 19 ноября 2011

Я видел эту проблему, когда из диалога выдается исключение.Функция DoModal в MFC отключает главное окно программы, а затем снова включает его, когда диалоговое окно возвращается;исключения исключают часть повторного включения, и главное окно остается отключенным навсегда.

0 голосов
/ 19 ноября 2011

Я бы сказал, что у вас есть цикл перерисовки в этом окне, которое получает флуд WM_PAINT.

Это обычно происходит, если вы вызываете Invalidate или подобное с обработкой сообщения WM_PAINT, прямо или косвенно.

Другая возможность заключается в том, что, поскольку вы говорите, что вы используете таймер для перерисовки окна, собственно рисование отнимает больше времени, чем само по себе, поэтому сообщения накапливаются в очереди.

Еще одна возможность состоит в том, что вы делаете недействительным окно из другой нити, отличной от той, которая создает картину.

В любом случае, вы должны убедиться, что вы правильно вызываете Invalidate*() (вы не указали код), и никогда из события OnPaint. И избегайте вызова UpdateWindow(), так как эта функция может запутаться, если вызывается без особой заботы.

...