Изучение немодальных и стандартных диалоговых окон Windows
Немодальные диалоговые окна, позволяют работать с любой частью приложения, даже когда диалоговое окно активно. Программным интерфейсом C++ с группой вспомогательных диалоговых окон Windows (в том числе File Open, Printer Setup, Color Selection и т. д.), которые поддерживает динамически подключаемая библиотека COMDLG32.DLL, служат классы стандартных диалоговых окон.
В первом примере я хотел бы показать как можно построить простое немодальное диалоговое окно, управляемое из класса «вид*», а во втором — класс, производный от класса CPileDialog из COMDLG32, который позволит удалять файлы.
Немодальные диалоговые окна
В MFC-библиотеке 6.0 модальные и немодальные диалоговые окна совместно используют один и тот же базовый класс CDialog и диалоговый ресурс, который создаётся с помощью редактора диалоговых окон. Если Вы захотите применять немодальное диалоговое окно вместе с объектом «вид», Вам придется освоить несколько особых приемов программирования.
Создание немодальных диалоговых окон
При создании модальных диалоговых окон для начала надо воспользоваться конструктором CDtalog с параметром-идентификатором прикрепленного ресурса, чтобы сконструировать объект «диалоговое окно*», а потом вывести модальное диалоговое окно на экран, вызвав функцию-член DoModal. Как только происходит возврат из DoModal, окно прекращает свое существование. Таким образом, зная, что к тому моменту, когда С++-объект «диалоговое окно*» выходит за пределы области видимости, диалоговое окно Windows уже уничтожено, объект «модальное диалоговое окно» можно конструировать на стеке.
Процесс создания немодальных диалоговых окон сложнее. Вы начинаете с вызова конструктора CDialog по умолчанию, создавая, тем самым, объект «диалоговое окно*», а вот нужное диалоговое окно создается вызовом функции-члена CDialog::Create, а не функции DoModal. Create получает идентификатор ресурса как параметр и немедленно возвращает управление;
при этом диалоговое окно остается на экране. Так что теперь именно Вы должны заботиться о том, когда создавать само диалоговое окно, когда конструировать объект «диалоговое окно», когда его уничтожать и когда обрабатывать данные, введенные пользователем.
Класс «вид» библиотеки MFC
Допустим, Вы хотите, чтобы немодальное диалоговое окно уничтожалось, когда пользователь щелкает в этом окне кнопку «ОК». Тут сразу же возникает проблема. Как объект «вид» узнает, что пользователь щелкнул кнопку «ОК»? Диалоговое окно могло бы напрямую обратиться к какой-либо функции-члену класса «вид», но это бы связало данное диалоговое окно с конкретным классом «вид». Более удачное решение — диалоговое окно при вызове обработчика кнопки «ОК» отправляет объекту «вид*» пользовательское сообщение (user-defined message). Получив это сообщение, объект «вид» сможет уничтожить диалоговое окно (но не сам объект). Таким образом, вырисовывается сценарий создания нового диалогового окна.
Есть два варианта отправки Windows-сообщений: через функции CWndr.SendMessage или PostMessage. Первая немедленно вызывает функцию-обработчик сообщения, а вторая отправляет сообщение в очередь сообщений Windows. Поскольку PostMessage вносит лишь небольшую задержку, можно считать, что функция-обработчик кнопки «ОК» уже завершилась, когда объект «вид» получает сообщение.
Принадлежность диалогового окна
Предположим, что Вы приняли стиль диалогового окна по умолчанию, т. е. диалоговое окно не ограничено клиентской областью окна представления. Поскольку речь идет о Windows, «владелец» диалогового окна — основное окно-рамка приложения, а не объект «вид*». Но надо знать, какой именно объект «вид» сопоставлен с диалоговым окном, чтобы отправить этому объекту сообщение. Поэтому ваш класс «диалоговое окно» должен отслеживать свой объект «вид» через переменную-член, которую устанавливает конструктор, параметр pParent конструктора CDialog в данном случае не играет никакой роли.
На этом заканчивается первая часть специально подготовленных мною статей по программированию на «си».
P.S. Надеюсь, что вы нашли для себя что-то новое из этой статьи.