Подтвердить что ты не робот

Какая логическая разница между PostQuitMessage() и DestroyWindow()?

В моем демонстрационном приложении

case WM_CLOSE:
    DestroyWindow(hndl);
    return 0;

и

case WM_CLOSE:
    PostQuitMessage(0);
    return 0;

делают то же самое. Что позади занавески при вызове? Является ли DestroyWindow более прямым, когда PostQuitMessage должен пройти цикл getmessage, возвращающий false?

4b9b3361

Ответ 1

DestroyWindow уничтожает окно (неожиданность) и отправляет сообщение WM_DESTROY (вы также получите WM_NCDESTROY) в очередь сообщений. Это поведение по умолчанию WM_CLOSE. Однако только потому, что окно было уничтожено, это не значит, что цикл сообщения должен завершиться. Это может иметь место при наличии определенного окна, которое завершает приложение при закрытии, и других, которые ничего не делают для приложения при закрытии (например, страницы параметров).

PostQuitMessage помещает a WM_QUIT в очередь сообщений, что часто приводит к завершению цикла сообщения. Например, GetMessage вернет 0, когда вытащит WM_QUIT. Обычно это вызывается в обработчике WM_DESTROY для вашего главного окна. Это не поведение по умолчанию; вы должны сделать это сами.

Ответ 2

Ни один фрагмент не верен. Первый будет делать то, что уже делает процедура окна по умолчанию, когда обрабатывает сообщение WM_CLOSE, является излишней. Но в противном случае приложение не прекращает работу, оно должно продолжать работать, и обычно вам придется заставить отладчик прекратить работу с Debug + Stop Debugging. Если вы запустите его без отладчика, вы оставите процесс запущенным, но без окна, чтобы вы не могли сказать, что он все еще работает. Используйте вкладку "Taskmgr.exe", "Процессы", чтобы просмотреть эти процессы зомби.

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

Правильный способ сделать это - выйти, когда ваше главное окно будет уничтожено. Вы узнаете об этом из уведомления WM_DESTROY, которое отправляется, когда это произойдет:

case WM_DESTROY:
    PostQuitMessage(0);
    return 0;

Ответ 3

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

В качестве побочного примечания, если вам понадобится больше строк кода для выполнения после цикла сообщений (например, для дальнейшей очистки), PostQuitMessage - лучший способ, потому что DestroyWindow разрушает окно, не проходя через цикл сообщений, игнорируя все коды очистки, оставшиеся после цикла сообщений. Некоторые могут назвать это не очень хорошей практикой кодирования, но иногда вы не можете избежать подобных ситуаций.