Почему IsDialogMessage () никогда не вернется? - PullRequest
1 голос
/ 11 ноября 2009

Я отлаживаю приложение, которое в цикле сообщений вызывает IsDialogMessage () . Иногда IsDialogMessage () никогда не возвращается (где никогда не интервал больше 1 часа). Основываясь на символах для user32.dll, доступных на сервере символов Microsoft, он, похоже, застрял в GetNextDlgGroupItem () (или во внутреннем аналогичном варианте), повторяя некоторые наборы окон.

Приложение является многопоточным и часто получает уведомления о внешних событиях, которые поступают в виде вызовов DCOM. Я подозреваю, что такой вызов обрабатывается неправильно, что портит состояние окна. Если я смогу узнать, какой тип повреждения состояния может вызвать бесконечный цикл в IsDialogMessage (), я думаю, что мне будет легче определить источник повреждения.

Ответы [ 4 ]

3 голосов
/ 19 июня 2012

Я знаю, что это старо, но отвечает за потомство, так как никто здесь не упомянул это.

Скорее всего, проблема в том, что менеджер окон определяет, куда переслать сообщение. Если у вас есть иерархия окон, как вы, вероятно, делаете, то вам нужно убедиться, что окна не верхнего уровня, которые сами содержат элементы управления, должны иметь набор стилей WS_EX_CONTROLPARENT. Если это диалог, вы используете стиль DS_CONTROL. Наличие этих флагов изменяет поведение IsDialogMessage; они идентифицируют окно как имеющее свои собственные элементы управления, которые могут получать фокус и обрабатывать порядок табуляции и т. д., а не просто быть самим элементом управления.

Например, если у вас есть главное окно фрейма, у которого есть дочернее окно с WS_EX_CONTROLPARENT, у которого есть дочернее окно без WS_EX_CONTROLPARENT, у которого есть дочернее окно с фокусом, и вы нажимаете TAB, скорее всего, вы встретите бесконечный цикл в том же месте, о котором упоминаете.

Установка расширенного стиля второго дочернего элемента для включения WS_EX_CONTROLPARENT решит проблему.

0 голосов
/ 25 февраля 2014

Я провел некоторое расследование, пытаясь ответить на этот вопрос. Но только в ситуации, когда родительское окно находится в собственном проекте MFC, а дочернее - управляемый C # Windows Forms. Если у вас такая ситуация, вы можете попробовать 3 разрешения:

  1. Запуск цикла диалоговых сообщений MFC на стороне Windows Forms. Вот дополнительная информация: Интеграция Windows Forms в ваши приложения MFC через C ++ Interop
  2. Создайте 2 потока: один для диалога Windows Forms и один для собственного диалога. Здесь вы можете создать диалог в Windows Forms, а затем с помощью SetParent () установить его родительский для родного диалога. Но будьте осторожны: если вы добавите TabControl в Windows Forms, произойдет зависание с IsDialogMessage () никогда не вернется.
  3. Создание оболочки для диалогового окна Windows Forms для использования в собственном проекте. Например, оболочкой может быть WPF, см. Здесь: Форма Windows как дочернее окно неуправляемого приложения

Я взял информацию в основном из: http://msdn.microsoft.com/en-us/library/ms229600.aspx

И временным лекарством может быть изменение поведения фокуса. Например, отключите их или SetFocus () только для родительских или дочерних окон. Но я настоятельно рекомендую выяснить реальную причину, почему IsDialogMessage () никогда не возвращается в вашем случае.

0 голосов
/ 28 июля 2011

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

0 голосов
/ 12 ноября 2009

Возможно, вы отключаете элементы управления (используя ::EnableWindow()), не проверив сначала, имеет ли этот элемент управления фокус? Если да, то фокус теряется и GetNextDlgGroupItem () запутывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...