Чтение онлайн

на главную - закладки

Жанры

Применение Windows API

Легалов А. И.

Шрифт:

Диалоговое окно обычно взаимодействует со всеми видами элементов управления (виджетами, устройствами, гизмозами — называйте их как хотите). Код диалогового окна взаимодействует с этими элементами, посылая и получая сообщения через свою «Процедуру диалога». В реализациях различных диалоговых окон имеется много общего кода. Нам хотелось бы написать и отладить этот код только один раз, а затем многократно использовать его.

Что изменяется от диалога к диалогу:

• Разновидность данных, которые передаются в диалог и возвращаются из него.

• Разновидность элементов внутри диалогового окна.

• Взаимодействие между элементами.

Эта изменчивость

может быть инкапсулирована в двух специальных клиентских классах: классе списка параметров и классе контроллера диалога.

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

Класс контроллера диалога содержит объекты управления для всех элементов диалога и осуществляет взаимодействия между ними. Клиент, как предполагается, получает этот класс от абстрактного класса DlgController и реализует все его чистые виртуальные методы.

Остальное — только клей. Нам необходимо параметризировать шаблон класса CtrlFactory, который используется нашей обобщенной реализацией класса ModalDialog. Фабрика контроллера создает соответствующий, определенный клиентом, контроллер и возвращает полиморфный указатель на него. Рис. 1 показывает связи между различными классами, включаемыми в реализацию диалогового окна.

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

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

void Controller::Edit(HWND hwnd) {

 EditorData data(_model.GetText );

 ControllerFactory<EditorCtrl, EditorData> 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. Хотя встречаются случаи, когда Вы должны проверять правильность строки или отображать ее в некотором другом элементе управления, а также Вы должны реагировать на каждое сообщение об изменении.

Поделиться:
Популярные книги

Печать Пожирателя

Соломенный Илья
1. Пожиратель
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Печать Пожирателя

Привет из Загса. Милый, ты не потерял кольцо?

Лисавчук Елена
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Привет из Загса. Милый, ты не потерял кольцо?

Мастер 2

Чащин Валерий
2. Мастер
Фантастика:
фэнтези
городское фэнтези
попаданцы
технофэнтези
4.50
рейтинг книги
Мастер 2

Нечто чудесное

Макнот Джудит
2. Романтическая серия
Любовные романы:
исторические любовные романы
9.43
рейтинг книги
Нечто чудесное

Клан

Русич Антон
2. Долгий путь домой
Фантастика:
боевая фантастика
космическая фантастика
5.60
рейтинг книги
Клан

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Запасная дочь

Зика Натаэль
Фантастика:
фэнтези
6.40
рейтинг книги
Запасная дочь

Убивать чтобы жить 7

Бор Жорж
7. УЧЖ
Фантастика:
героическая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 7

У врага за пазухой

Коваленко Марья Сергеевна
5. Оголенные чувства
Любовные романы:
остросюжетные любовные романы
эро литература
5.00
рейтинг книги
У врага за пазухой

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Оцифрованный. Том 1

Дорничев Дмитрий
1. Линкор Михаил
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Оцифрованный. Том 1

Его маленькая большая женщина

Резник Юлия
Любовные романы:
современные любовные романы
эро литература
8.78
рейтинг книги
Его маленькая большая женщина

Хуррит

Рави Ивар
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Хуррит