Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ch-11.doc
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
1.26 Mб
Скачать

Различия между модальными и немодальными окнами диалога

Работа с немодальными окнами диалога похожа на работу с модальными, но есть несколько важных отличий:

  • Немодальные окна диалога обычно содержат строку заголовка и значок системного меню. Инструкция 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. Любая информация, которую окно диалога должно вернуть создавшему его окну, может храниться в глобальных переменных.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]