Программа зависает на MessageBox ()

#windows #visual-studio #winapi #visual-c #mfc

#Windows #visual-studio #winapi #visual-c #mfc

Вопрос:

Вот проблема: основной поток GUI выполняет отправку сообщения в другой поток GUI (да, существует несколько потоков GUI, и, к сожалению, это не может измениться). Когда этот второй поток GUI получает отправленное сообщение, он может решить отобразить окно сообщения. Иногда этот MessageBox «замораживает» все приложение.

Более конкретно, окно сообщения отображается, но весь графический интерфейс зависает (пользовательский ввод нигде не работает).

Я проверил с помощью отладчика, что второй поток GUI запускается в функции DialogBox2 (), определенной в user32.dll . Я вижу при разборке, что выполняется перекачка сообщений (я вижу, что вызывается IsDialogMessage / TranslateMessage / DispatchMessage). Используя spy , я не вижу, чтобы какие-либо сообщения обрабатывались для окна диалогового окна сообщений. Я вижу, что сообщения обрабатываются в главном окне GUI (например, WM_SETCURSOR, хотя я не думаю, что они обрабатываются, поскольку я полагаю, что SendMessage не выполняет перекачку сообщений).

Второй поток выполняет код, который является частью библиотеки DLL с расширением MFC, если это имеет значение.

Я пробовал использовать AfxMessageBox() / CWnd:: MessageBox / ::MessageBox (нулевое родительское окно, …). Все они демонстрируют одну и ту же проблему.

Кто-нибудь видел что-нибудь подобное раньше?

Спасибо, Эндрю

Комментарии:

1. Я обнаружил проблему в первом предложении вашего вопроса, поэтому я не уверен, почему я должен читать дальше. Вы используете несколько потоков GUI, вы знаете, что это плохая идея, и вы задаетесь вопросом, почему вы видите нежелательное поведение? Хм.

2. Более того, MessageBox — это блокирующий вызов, независимо от того, используете ли вы его с помощью MFC или нет. Это означает, что это предотвращает обработку сообщений в соответствии с описанным вами поведением.

3. Я понимаю, что MessageBox блокируется. Хотя MessageBox не должен зависать (например, я должен иметь возможность нажать OK, чтобы закрыть его). И, как я уже сказал, приложение не может переключиться на один поток GUI. Я согласен, что это плохая идея, но я этого не писал.

4. Я попытался вызвать MessageBox с нулевым родительским значением, чтобы попытаться исключить такую возможность.

5. msdn.microsoft.com/en-us/library/ms644928 (v = против 85).aspx и блог Рэймонда Чена — полезное чтение. Например, окна и очереди сообщений связываются с создающим потоком.

Ответ №1:

Должно быть, проблема в блокировке одного из потоков GUI.

Попробуйте это:

Замените ::SendMesage на ::postMessage, за которым следует цикл ::MsgWaitForMultipleObjects. Вам нужно будет передать дескриптор события, который сигнализирует о закрытии окна сообщения.

Вероятно, это решит проблему.

Просто будьте осторожны, какие сообщения вы отправляете в цикле you ::MsgWaitForMultipleObjects.