- •Глава 11 Окна диалога
- •Модальные окна диалога
- •Создание окна диалога About
- •Шаблон окна диалога
- •Диалоговая процедура
- •Вызов окна диалога
- •Дополнительная информация о стиле окна диалога
- •Дополнительная информация об определении дочерних окон элементов управления
- •Более сложное окно диалога
- •Работа с дочерними элементами управления окна диалога
- •Кнопки ok и Cancel
- •Позиции табуляции и группы
- •Рисование в окне диалога
- •Использование с окном диалога других функций
- •Определение собственных окон управления
- •Окна сообщений
- •Информация во всплывающих окнах
- •Немодальные окна диалога
- •Различия между модальными и немодальными окнами диалога
- •Новая программа colors
- •Программа hexcalc: обычное окно или окно диалога?
- •Творческое использование идентификаторов дочерних окон элементов управления
- •Диалоговые окна общего пользования
- •Модернизированная программа poppad
- •Изменение шрифта
- •Поиск и замена
- •Программа для Windows, содержащая всего один вызов функции
Различия между модальными и немодальными окнами диалога
Работа с немодальными окнами диалога похожа на работу с модальными, но есть несколько важных отличий:
Немодальные окна диалога обычно содержат строку заголовка и значок системного меню. Инструкция STYLE в шаблоне окна диалога для немодального окна диалога будет выглядеть примерно так:
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
Строка заголовка и системное меню дают пользователю возможность перемещать немодальное окно диалога по экрану с помощью как мыши, так и клавиатуры. Модальные окна диалога обычно не имеют строки заголовка и системного меню, поскольку пользователь все равно ничего не сможет сделать с окном, в котором появляется модальное диалоговое окно.
Обратите внимание, что в инструкцию STYLE включен стиль WS_VISIBLE. Если этого не сделать, то после вызова функции CreateDialog необходимо вызвать функцию ShowWindow:
hDlgModeless = CreateDialog (...) ;
ShowWindow (hDlgModeless, SW_SHOW) ;
Если не включить в инструкцию STYLE стиль WS_VISIBLE и не вызвать функцию ShowWindow, немодальное окно диалога не появится на экране. Забывая об этом, программисты, которые привыкли работать с модальными окнами диалога, часто на первых порах испытывают трудности при создании немодальных окон диалога.
В отличие от сообщений для модальных окон диалога и окон сообщений, сообщения для немодальных окон диалога проходят через очередь сообщений программы. Поэтому цикл их обработки должен быть изменен таким образом, чтобы эти сообщения передавались в оконную процедуру окна диалога. Вот как это делается: когда для создания немодального окна диалога используется функция CreateDialog, необходимо запомнить в глобальной переменной (например, hDlgModeless) описатель окна диалога, который является возвращаемым значением этой функции. Необходимо изменить цикл обработки сообщений, чтобы он выглядел так:
while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
Если сообщение предназначено для немодального окна диалога, то функция IsDialogMessage отправляет его оконной процедуре окна диалога и возвращает TRUE (ненулевое значение); в противном случае она возвращает FALSE (0). Функции TranslateMessage и DispatchMessage будут вызываться только в том случае, если hDlgModeless равен 0 или если сообщение не для окна диалога. Если для окна приложения используются быстрые клавиши, то цикл обработки сообщений должен стать таким:
while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
{
if (!TranslateAccelerator (hwnd, hAccel, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
}
Поскольку глобальные переменные инициализируются нулем, hDlgModeless останется равной 0 до тех пор, пока окно диалога не будет создано; таким образом гарантируется, что функция IsDialogMessage не будет вызвана с недействительным описателем окна. При закрытии немодального окна диалога необходимо, как это будет показано ниже, принять те же меры предосторожности.
Переменная hDlgModeless может использоваться и в других частях программы для проверки наличия на экране немодального окна диалога. Например, другие окна программы могут посылать окну диалога сообщения, пока hDlgModeless не равна 0.
Для закрытия немодального окна диалога, вместо функции EndDialog, используйте функцию DestroyWindow. После вызова функции DestroyWindow глобальная переменная hDlgModeless должна быть установлена в 0.
По привычке, пользователь закрывает немодальное окно диалога используя опцию системного меню Close. Хотя опция Close разрешена, оконная процедура окна диалога внутри Windows не обрабатывает сообщения WM_CLOSE. Необходимо сделать это в процедуре диалога:
case WM_CLOSE :
DestroyWindow (hDlg) ;
hDlgModeless = 0 ;
break ;
Обратите внимание на отличие между параметром hDlg функции DestroyWindow, передаваемым в процедуру диалога и параметром hDlgModeless — глобальной переменной, являющейся возвращаемым значением функции CreateDialog, которая проверяется внутри цикла обработки сообщений.
Можно также обеспечить пользователю возможность закрывать немодальное окно диалога с помощью кнопки. При этом используйте ту же логику, что и для сообщения WM_CLOSE. Любая информация, которую окно диалога должно вернуть создавшему его окну, может храниться в глобальных переменных.
