Шаг 19.
Библиотека OWL.
Основы диалоговых окон

    На этом шаге мы рассмотрим создание и использование простого диалогового окна.

    После создания ваших диалоговых окон с помощью Resource Workshop, файл описания диалогового окна готов к компиляции и вставке в вашу программу. Однако, просто скомпилировать программу с ее файлом ресурсов не достаточно для запуска вашего окна диалога. Для появления диалогового окна в нужное время вы должны выполнить следующие три шага:

  1. Создать объект Dialog OWL, описывающий окно диалога.
  2. Вызвать функцию Execute() в объекте диалогового окна для активизации окна диалога.
  3. Проверить результирующий код, возвращенный от Execute() для определения нажатой пользователем кнопки.

    Вышеперечисленные шаги описывают минимум задач, которые вы должны решить для отображения диалогового окна. (Конечно, не всегда требуется проверять, какую кнопку нажал пользователь, но - почти всегда.) Как вы увидите позже, управление сложными диалоговыми окнами включает гораздо большее количество задач. Эти другие задачи включают в себя не только определение нажатой пользователем кнопки, но также передачу данных из и в диалоговое окно и проверку достоверности введенной пользователем информации.

    Очень важно, чтобы вы поняли три вышеперечисленных шага, особенно шаг 1, в котором путаются многие программисты, в первый раз работающие с OWL. В конце концов, разве вы уже не создали свое диалоговое окно в Resource Workshop? Зачем вам снова создавать его в программе?

    Если вы написали вашу программу без использования ObjectWindows, вам необходимо просто вызвать функцию DialogBox() Windows API, чтобы отобразить окно диалога. (Конечно, это означает и наличие диалоговой функции, обрабатывающей сообщения, которые Windows посылает диалоговому окну.) OWL, однако, предоставляет класс для работы с диалоговыми окнами, который выполняет большую часть черновой работы за вас - такой, например, как реакция на нажатие кнопок, передача данных в и из окна диалога, проверка вводимых пользователем данных, закрытие диалогового окна и многое другое.

    Для использования преимуществ, предоставляемых классом диалогового окна, вы должны, конечно, создать экземпляр класса. Этот новый объект TDialog является своего рода оболочкой вокруг диалогового окна, которое вы создали с помощью Resource Workshop, избавляющей вас от ненужных деталей при работе с диалоговым окном. Выполнив шаг 1, вы имеете не только интерфейсный элемент диалоговое окно (который вы создали с помощью Resousce Workshop), но также и объект диалогового окна, который представляет этот интерфейсный элемент диалоговое окно и позволяет вам осуществлять доступ к функциям-членам TDialog OWL.

    Следующий пример демонстрирует основы отображения и работы с диалоговым окном.

#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\dialog.h>
#include "pr19_1.rc"

//Класс приложения
class TApp: public TApplication
{
  public:
	 TApp():TApplication(){}
	 void InitMainWindow();
};

//Класс основного окна
class TWndw:public TFrameWindow
{
  public:
	 TWndw(TWindow *parent, const char far *title);
  protected:
	 void CmTestDialog();

	 DECLARE_RESPONSE_TABLE (TWndw);
};

DEFINE_RESPONSE_TABLE1 (TWndw, TFrameWindow)
  EV_COMMAND(CM_TESTDIALOG,CmTestDialog),
END_RESPONSE_TABLE;


TWndw::TWndw(TWindow *parent, const char far *title):
		  TFrameWindow(parent,title)
{
	// Добавить меню к главному окну.
	AssignMenu("MENU_1");
	// Определить расположение и размеры окна.
	Attr.X=50;
	Attr.Y=50;
	Attr.W=GetSystemMetrics(SM_CXSCREEN)/4;
	Attr.H=GetSystemMetrics(SM_CXSCREEN)/5;
}

// TWndw::CmTestDialog()
// Эта функция реагирует на команду Dialog/Test
// меню Dialog.
void TWndw::CmTestDialog()
{
  // Создать окно диалога.
  TDialog *dialog = new TDialog(this, ADDRDLG);
  // Выполнить окно диалога.
  int result = dialog->Execute();
  // Ответить на выбор пользователем кнопки.
  if   (result == IDOK)
		 MessageBox("Вы нажали кнопку OK", "Результат", MB_OK);
  else MessageBox("Вы нажали кнопку Отмена", "Результат", MB_OK);
}

void TApp::InitMainWindow()
{
  TFrameWindow *wndw=new TWndw(0,"Пример диалогового окна");
  SetMainWindow(wndw);
}

int OwlMain(int,char *[])
{
  return TApp().Run();
}

    Файл ресурсов:

#ifndef WORKSHOP_INVOKED
#include "windows.h"
#endif

#define ADDRDLG         100
#define IDC_NAME        101
#define IDC_ADDR        102
#define IDC_CITY        103
#define IDC_STATE       104
#define IDC_ZIP         105
#define IDC_PHONE       106
#define IDC_BIRTH       107
#define CM_EXIT       24310
#define CM_TESTDIALOG   108


#ifdef RC_INVOKED

ADDRDLG DIALOG 39, 34, 239, 124
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Address Form"
FONT 8, "MS Sans Serif"
{
 EDITTEXT IDC_NAME, 42, 9, 188, 12, WS_BORDER | WS_TABSTOP
 EDITTEXT IDC_ADDR, 42, 26, 188, 12, WS_BORDER | WS_TABSTOP
 EDITTEXT IDC_CITY, 42, 44, 70, 12, WS_BORDER | WS_TABSTOP
 EDITTEXT IDC_STATE, 140, 45, 16, 12, WS_BORDER | WS_TABSTOP
 EDITTEXT IDC_ZIP, 180, 45, 50, 12, WS_BORDER | WS_TABSTOP
 EDITTEXT IDC_PHONE, 43, 67, 65, 12, WS_BORDER | WS_TABSTOP
 EDITTEXT IDC_BIRTH, 147, 67, 45, 12, WS_BORDER | WS_TABSTOP
 LTEXT "Name:", -1, 17, 11, 20, 8
 LTEXT "Address:", -1, 9, 28, 29, 8
 LTEXT "City:", -1, 23, 47, 17, 8
 LTEXT "State:", -1, 116, 47, 20, 8
 LTEXT "Zip:", -1, 163, 46, 13, 8
 LTEXT "Phone:", -1, 16, 69, 24, 8
 LTEXT "Birthday:", -1, 113, 69, 30, 8
 DEFPUSHBUTTON "OK", IDOK, 76, 92, 33, 21
 PUSHBUTTON "Cancel", IDCANCEL, 126, 93, 33, 21
}


MENU_1 MENU
{
 POPUP "&File"
 {
  MENUITEM "E&xit", CM_EXIT
 }
 POPUP "&Dialog"
 {
  MENUITEM "&Test Dialog...", CM_TESTDIALOG
 }
}

#endif
Текст этого приложения можно взять здесь.

    Когда вы запустите эту программу, появится пустое окно. Это окно содержит строку меню с пунктами File и Dialog. Для вывода диалогового окна, изображенного на рисунке 1, выберите опцию Test Dialog в пункте меню Dialog. Когда появится диалоговое окно, вы сможете ввести информацию в элементы управления редактированием окна диалога или просто нажать одну из кнопок, чтобы выйти из него. После выхода из диалогового окна программа отображает окно сообщений, показывающее выбранную кнопку.


Рис.1. Результат работы приложения

    Эта программа охватывает три главных класса:

    Класс приложения почти аналогичен классам, с которыми мы познакомились в предыдущих шагах. Класс главного окна содержит только одну функцию отклика на сообщение CmTestDialog(), которая реагирует на команду Test Dialog меню Dialog.

    Хотя диалоговое окно является главной частью программы, оно не имеет собственного класса. (По крайней мере, в рамках данного примера.) Диалоговое окно полностью управляется функцией CmTestDialog() главного окна:

void TWndw::CmTestDialog()
{
  // Создать окно диалога.
  TDialog *dialog = new TDialog(this, ADDRDLG);
  // Выполнить окно диалога.
  int result = dialog->Execute();
  // Ответить на выбор пользователем кнопки.
  if   (result == IDOK)
		 MessageBox("Вы нажали кнопку OK", "Результат", MB_OK);
  else MessageBox("Вы нажали кнопку Отмена", "Результат", MB_OK);
}

    В первой строке вызывается конструктор TDialog, создающий объект диалогового окна в памяти. Первым аргументом конструктора является указатель на родителя окна диалога. В качестве родителя диалогового окна выступает главное окно, поэтому этим параметром является указатель this, который имеют все объекты C++. Вторым аргументом является идентификатор ресурса диалогового окна.

    Поскольку диалоговое окно - не более, чем особый тип окна, класс TDialog порождается из TWindow и, таким образом, наследует все функции и данные класса. Хотя в данном примере окно диалога описывается только двумя строками программы, в действительности оно использует всю мощь объекта TDialog.

    После создания объекта диалогового окна и связи его с реально существующим элементом диалогового окна (диалоговое окно создано в Resource Workshop) через идентификатор ресурса диалогового окна, CmTestDialog() активизирует диалоговые окна путем вызова функции Execute() диалогового окна. Execute() (и другие вызываемые ею функции OWL) вызывает Windows API для вывода диалогового окна на экран, управляет им и удаляет его с экрана по команде пользователя. Значение, возвращаемае Execute() - это идентификатор кнопки, которую нажал пользователь при выходе из окна диалога. CmTestDialog() использует это возвращаемое значение, чтобы определить, какое окно сообщения отображать.


    Замечание. В ObjectWindows определены константы для общих идентификаторов кнопок стандартных диалоговых окон. Эти идентификаторы включают IDOK, IDCANCEL, IDHELP, IDYES, IDNO. Эти ID соотносятся с пользовательскими настраиваемыми кнопками, когда вы используете библиотеку настраиваемых компонентов управления (это кнопки с 3-мерными индикаторами состояния, крестиками и вопросительными знаками), но вы можете также использовать их для стандартных управляющих кнопок. Фактически функции-члены CmOk() и CmCancel() класса TDialog автоматически реагируют на идентификаторы IDOK и IDCANCEL, так что, если вы хотите использовать все преимущества класса TDialog, вы должны использовать эти идентификаторы для своих кнопок ОК и Cancel.

    На следующем шаге мы рассмотрим настройку класса TDialog.




Предыдущий шаг Содержание Следующий шаг