textpub.neocities.org . [ список статей ]

Мой перевод англоязычной статьи «Closing the Window» с сайта компании Microsoft (ссылка на оригинал), автор статьи там не указан, дата публикации оригинала: 05.10.2010 г. (оригинал изменен 31.05.2018 г.)

Закрытие окна

Когда пользователь закрывает окно, это его действие запускает последовательность сообщений окну от операционной системы.

Пользователь может закрыть окно приложения, нажав кнопку «Закрыть» в заголовке окна, либо воспользовавшись комбинацией клавиш «ALT+F4». Любое из этих действий послужит причиной того, что окно получит сообщение WM_CLOSE. Это сообщение дает нам возможность проверить намерение пользователя (действительно ли он хочет закрыть окно или ошибся) перед закрытием окна. Если он действительно хочет закрыть окно, вызываем функцию DestroyWindow. Иначе просто возвращаем ноль в ветке, в которой обрабатывается сообщение WM_CLOSE, операционная система проигнорирует сообщение и не станет уничтожать окно.

Приведем пример того, как программа может обработать сообщение WM_CLOSE:

case WM_CLOSE:
    
    if (MessageBox(hwnd, L"Действительно выйти?",
        L"Моё приложение", MB_OKCANCEL) == IDOK)
    {
        DestroyWindow(hwnd);
    }
    
    // Иначе: Пользователь отказался от закрытия. Не делаем ничего.
    return 0;

В этом примере функция MessageBox показывает на экране модальное окно-диалог, в котором есть кнопки «OK» (согласиться) и «Cancel» (отказаться). Если пользователь нажмет кнопку «OK», программа вызовет функцию DestroyWindow. Иначе, если пользователь нажмет кнопку «Cancel», вызов функции DestroyWindow будет пропущен, и окно останется открытым. В обоих случаях возвращение нуля покажет операционной системе, что наша программа успешно закончила обработку сообщения.

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

Непосредственно перед уничтожением окна оно получает сообщение WM_DESTROY. Это сообщение посылается после того, как окно убрано с экрана, но перед тем, как начнется его ликвидация (в частности, перед тем, как любое из окон-потомков будет уничтожено).

В нашем главном окне приложения мы обычно будем отвечать на сообщение WM_DESTROY вызовом функции PostQuitMessage.

case WM_DESTROY:

    PostQuitMessage(0);
    return 0;

В статье «Сообщения окну от операционной системы» мы отметили, что функция PostQuitMessage помещает сообщение WM_QUIT в очередь сообщений, и это инициирует окончание цикла обмена сообщениями.

Чтобы проиллюстрировать обычный ход обработки сообщений WM_CLOSE и WM_DESTROY, приведем такую блок-схему:

textpub.neocities.org . [ список статей ]