Применение Windows API - страница 13

Шрифт
Интервал

стр.

Рис. 1. Классы, включаемые в образец проектирования "Диалоговое окно".

Давайте, начнем с клиентского кода. В нашей обобщенной программе мы нуждаемся в диалоговом окне, которое позволяет пользователю редактировать строку. Используя редактор ресурса, мы создаем шаблон диалога, который содержит средства редактирования и две кнопки, OK и CANCEL. Идентификатор ресурса (id) этого диалога – IDD_EDITDIALOG. Затем мы определяем наш собственный класс списка параметров по имени EditorData и специальный класс контроллера по имени EditorCtrl. Когда пользователь выбирает пункт меню Edit, будет выполняться следующий код:

>void Controller::Edit(HWND hwnd) {

> EditorData data(_model.GetText ());

> ControllerFactory factory(&data);

> ModalDialog dialog(_hInst, hwnd, IDD_EDITDIALOG, &factory);

> if (dialog.IsOk()) {

>  _model.SetText(data.GetName());

>  // Force repaint

>  InvalidateRect(hwnd, 0, TRUE);

> }

>}

Сначала создается и инициализируется строкой объект EditorData. Затем, формируется шаблон ControllerFactory. Мы параметризуем его двумя клиентскими классами EditorCtrl и EditorData. Объект фабрики инициализирован указателем на наши данные. Затем создается объект ModalDialog. Он получет указатель на нашу фабрику в качестве параметра. Это используется для того, чтобы создать объект контроллера и восстанавливать данные из списка параметров. После того, как проведено взаимодействие с пользователем, мы проверяем, подтверждал ли пользователь результаты, нажимая кнопку OK, и если так, то мы фиксируем результаты редактирования и используем их в нашей программе. Этот способ создания диалогового окна является наиболее типичным.

Класс EditorData в нашем примере предельно прост.

>class EditorData {

>public:

> enum { maxLen = 128 };

> EditorData(char const* name) {

>  SetName(name);

> }

> BOOL IsNameOK() { return (_name[0] != '\0'); }

> void SetName(char const *name) {

>  strcpy(_name, name);

> }

> char const* GetName() { return _name; }

>private:

> char _name[maxLen];

>};

Класс контроллера, EditorCtrl, содержит все операции. Прежде всего он встраивает в себя элемент редактирования. Этот объект ответствен за взаимодействие с элементом редактирования, внедренным в диалоговое окно. Элемент имеет идентификатор IDC_NAME_EDIT, заданныйс помощью редактора ресурсов. Во-вторых, контроллер хранит указатель на EditorData. Этот указатель взят из базового класса DlgController. Три виртуальных метода DlgController должны быть переписаны в нашем EditorControl. Это OnInitDialog, который вызывается немедленно после того, как диалог был инициализирован, OnCommand, который вызывается всякий раз, когда любой элемент диалогового окна посылает нам команду и, в заключение, OnNotify, который используется новыми элементами управления Windows95.

>class EditorCtrl : public DlgController {

>public:

> EditorCtrl(HWND hwndDlg, void *argList) : DlgController(argList), _nameEdit(hwndDlg, IDC_NAME_EDIT) {

>  _dlgData = (EditorData*)GetArgList();

> }

> void OnInitDialog(HWND hwnd);

> bool OnCommand(HWND hwnd, int ctrlID, int notifyCode);

> bool OnNotify(HWND hwnd, int idCtrl, NMHDR *hdr);

>private:

> Edit _nameEdit;

> EditorData *_dlgData;

>};

В методе OnInitDialog мы обрабатываем строку, которая была передана в EditorData и используем ее, чтобы инициализировать элемент редактирования.

>void EditorCtrl::OnInitDialog(HWND hwnd) {

> char const* name = _dlgData->GetName();

> _nameEdit.SetString(name);

>}

OnCommand получает команды от различных элементов. Элементы идентифицированы их идентификаторами. Например, если идентификатор — IDC_NAME_EDIT, это означает что что-то произошло с элементом редактирования. В нашей реализации мало функциональности, и мы реагируем на каждое изменение, копируя целую строку в объект EditorData. Хотя встречаются случаи, когда Вы должны проверять правильность строки или отображать ее в некотором другом элементе управления, а также Вы должны реагировать на каждое сообщение об изменении.

Когда пользователь нажимает кнопку OK, мы получаем команду с идентификатором IDOK. Мы проверяем строку и, если она правильная, то заканчиваем диалог, передающий TRUE как код возврата. Когда идентификатор — IDCANCEL (от кнопки Cancel) мы заканчиваем диалог с кодом возврата FALSE.


стр.

Похожие книги