Создание немодального диалогового окна
Вы создаете немодальное диалоговое окно, используя функцию CreateDialog, определяя идентификатор или имя ресурса шаблона блока диалога и указателя на процедуру диалогового окна. CreateDialog загружает шаблон, создает диалоговое окно и, по выбору, показывает его на экране. Ваше приложение несет ответственность за извлечение и распределение в процедуру диалогового окна сообщений о вводе данных пользователем .
В примере ниже, приложение показывает на экране немодальное диалоговое окно - если оно еще не отображено на экране - когда пользователь щелкает по Перейти в (Go To) в меню программы. Диалоговое окно содержит поле редактирования текста, окошко флажка, и кнопки OK и Отменить (Cancel). Шаблон диалогового окна - ресурс в исполняемом файле приложения и имеет идентификатор ресурса DLG_GOTO. Пользователь вводит номер строки в поле редактирования текста и ставит флажок в окошке флажка, чтобы определить, что это номер строки - относительно текущей строки. Идентификаторы органа управления - ID_LINE, ID_ABSREL, IDOK и IDCANCEL.
Операторы в первой части примера создают немодальное диалоговое окно. Эти операторы, в оконной процедуре главного окна приложения, создают блок диалога тогда, когда оконная процедура получает сообщение WM_COMMAND, имеющее идентификатор меню IDM_GOTO, но только в том случае, если глобальная переменная еще не содержит допустимый дескриптор. Вторая часть примера - главный цикл обработки сообщений приложения. Цикл включает в себя функцию IsDialogMessage, чтобы гарантировать, что пользователь может использовать клавиатурный интерфейс диалогового окна в этом немодальном блоке диалога. Третья часть примера - процедура диалогового окна. Процедура извлекает содержимое поля редактирования текста и окошка флажка, когда пользователь щелкает по кнопке OK. Процедура уничтожает диалоговое окно, когда пользователь щелкает по кнопке Отменить (Cancel).
Пример
HWND hwndGoto = NULL; // дескриптор окна блока диалога . . . case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_GOTO: if (!IsWindow(hwndGoto)) { hwndGoto = CreateDialog(hinst, MAKEINTRESOURCE(DLG_GOTO), hwnd, (DLGPROC) GoToProc); ShowWindow(hwndGoto, SW_SHOW); } break; } return 0L;
|
В данных выше операторах, CreateDialog вызывается только в том случае, если hwndGoto, не содержит допустимый дескриптор окна. Это гарантирует то, что прикладная программа не покажет на экране два диалоговых окна в одно и то же время. Чтобы поддерживать этот метод проверки, процедура диалогового окна должна установиться в ПУСТО (NULL), когда она уничтожает диалоговое окно.
Цикл обработки сообщений программы состоит из нижеследующих операторов:
Пример
BOOL bRet; while ( (bRet = GetMessage(&msg, NULL, 0, 0)) != 0 ) { if (bRet == -1 ) { // обработка ошибки и возможно выход из программы } else if (!IsWindow(hwndGoto) || !IsDialogMessage(hwndGoto, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } |
Цикл проверяет достоверность дескриптора окна блока диалога и только тогда вызывает функцию IsDialogMessage, если дескриптор допустим. IsDialogMessage обрабатывает только то сообщение, если оно принадлежит диалоговому окну. В противном случае, функция возвращает значение ЛОЖЬ (FALSE), а цикл распределяет сообщение в соответствующее окно.
Нижеследующие операторы определяют процедуру диалогового окна:
Пример
int iLine; // получает номер строки BOOL fRelative; // получает состояние окошка флажка BOOL CALLBACK GoToProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { BOOL fError; switch (message) { case WM_INITDIALOG: CheckDlgButton(hwndDlg, ID_ABSREL, fRelative); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: fRelative = IsDlgButtonChecked(hwndDlg, ID_ABSREL); iLine = GetDlgItemInt(hwndDlg, ID_LINE, &fError, fRelative); if (fError) { MessageBox(hwndDlg, SZINVALIDNUMBER, SZGOTOERR, MB_OK); SendDlgItemMessage(hwndDlg, ID_LINE, EM_SETSEL, 0, -1L); } else // Уведомление окно владельца, что задача выполнена. return TRUE; case IDCANCEL: DestroyWindow(hwndDlg); hwndGoto = NULL; return TRUE; } } return FALSE; } |
В предыдущих операторах, процедура обрабатывает сообщения WM_INITDIALOG и WM_COMMAND. В ходе обработки WM_INITDIALOG, процедура инициализирует окошко флажка, передавая текущее значение глобальной переменной в CheckDlgButton. Затем процедура возвращает значение ИСТИНА (TRUE), чтобы предписать системе установить заданный по умолчанию фокус ввода данных.
В ходе обработки WM_COMMAND, процедура закрывает диалоговое окно, только в том случае, если пользователь щелкает по кнопке Отменить (Cancel) - то есть по кнопке, имеющей идентификатор IDCANCEL. Процедура должна вызвать функцию DestroyWindow, чтобы закрыть немодальное диалоговое окно.
Обратите внимание! на то, что процедура также устанавливает переменную в ПУСТО (NULL), гарантируя, что другие операторы, которые зависят от этой переменной, работают правильно. |
Если пользователь щелкает по кнопке OK, процедура извлекает текущее состояние окошка флажка и определяет его в переменную fRelative. Затем она использует переменную, чтобы извлечь номер строки из поля редактирования текста. Функция GetDlgItemInt преобразует текст в поле редактирования в целое число. Значение fRelative выясняет, как воспринимает функция число - как знаковое, или как незнаковое значение. Если текст поля редактирования - не допустимое число, GetDlgItemInt устанавливает значение переменной fError в не нуль. Процедура проверяет это значение, чтобы решить, или показать на экране сообщение об ошибке, или выполнить задачу. В случае ошибки, процедура диалогового окна отправляет сообщение полю редактирования текста, предписывая ему выбрать текст в органе управления так, чтобы пользователь мог легко заменить его. Если GetDlgItemInt не возвращает значение ошибки, процедура может или выполнить затребованную задачу непосредственно, или отправить сообщение окну владельцу, предписывая ему выполнить эту операцию.