2016-12-12 4 views
-3

Я нахожусь в проекте MFC, который имеет очень странную настройку режима окон. Я думаю, что эта настройка искажает, как отображается отображаемое окно сообщений.Почему окно сообщений не отображается?

Происходит то, что окно сообщения не будет отображаться до тех пор, пока не будет нажата клавиша ALT.

Я все еще пытаюсь обернуть голову вокруг установки окна, которую они используют, но, возможно, кто-то сможет дать мне ключ к тому, что искать?

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

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

+0

Это может быть проблема с краской/перерисованием. – 1201ProgramAlarm

+0

@ 1201ProgramAlarm, так как это обычный Windows MessageBox, я не знаю, как это будет. – Adrian

+0

Вы используете настройку с несколькими мониторами? Может ли окно сообщения находиться на мониторе, который вы отключили? – sergiol

ответ

2

Это вызвано функцией «MFC CDialog DoModal can't show window if parent window message queue is 'busy'», где, если очередь сообщений содержит любые сообщения, она не отображает системное сообщение. (.. Пожалуйста, оцените или комментарий на этой ошибки поведение очень неожиданно)

Я отслеживал это вниз, пытаясь чавкать до всех сообщений в очереди с помощью этого:

MSG msg = { 0 }; 
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
{ 
    TRACE(_T(R"--(,"% *.*s",PEEK,0x%08x,"%s",0x%08x,0x%08x,0x%08x)--" "\n"), 
       0, 0, _T(""), msg.hwnd, "Window HAS msg", 
       msg.message, msg.wParam, msg.lParam); 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

Это было выводит все сообщения в очереди и показывает мне, какое окно и какое сообщение (в данном случае WM_PAINT) было нарушителем.

Затем я отследил, какой объект класса это окно было прикреплено к нему и посмотрел на его OnPaint() обработчик.

Оказывается, предыдущий программист положил if x после этого return условие перед построением объекта CPaintDC. Его конструктор вызывает BeginPaint(), что, в свою очередь, подтверждает недопустимую область. Не проверяя недопустимую область, система продолжает генерировать сообщения WM_PAINT, пока недопустимая область не будет пуста. Это приведет к тому, что очередь сообщений не станет пустой.

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

-ROOT       -ROOT 
+-CHILD       +-MESSAGE BOX 
    +-MESSAGE BOX     +-CHILD 
    +-CHILD       +-CHILD 
    +-CHILD       +-CHILD < Offender 
    +-CHILD < Offender    +-CHILD 
    +-CHILD      
+0

Возможно, это было бы полезно для будущего посещения rs, если вы коротко описали связь между оскорбительным окном и диалоговым окном, которое не появилось бы. – IInspectable