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

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

Жанры

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:

ПРИМЕЧАНИЕ

Библиотека MFC не использует функцию DialogBox(Param). Вместо этого она создаёт немодальный диалог, а затем эмулирует поведение модального. Благодаря этому программировать модальные диалоги в MFC гораздо удобнее, чем на "чистом" Win32 API (а значит, и в WTL). Проблема в том, что функция DialogBox(Param) создаёт свой собственный цикл сообщений, до которого не так-то просто добраться. Если нам потребуется, к примеру, внедрить в него трансляцию акселераторов, придётся прибегать к различным неочевидным приёмам.

Немодальный

диалог создаётся с использованием функции Create и разрушается вызовом DestroyWindow. Реализация обоих методов также достаточно очевидна.

// modeless dialogs

HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL) {

 ATLASSERT(m_hWnd == NULL);

 _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT<TBase>*)this);

#ifdef _DEBUG

 m_bModal = false;

#endif //_DEBUG

 HWND hWnd = ::CreateDialogParam(_Module.GetResourceInstance, MAKEINTRESOURCE(T::IDD),

hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);

 ATLASSERT(m_hWnd == hWnd);

 return hWnd;

}

BOOL DestroyWindow {

 ATLASSERT(::IsWindow(m_hWnd));

 ATLASSERT(!m_bModal); // must not be a modal dialog

 return ::DestroyWindow(m_hWnd);

}

С учётом всего сказанного, типичный класс диалога, порождённый от CDialogImpl<>, выглядит так (в качестве параметра шаблона задаётся имя класса, который вы порождаете).

class CMyDialog : public CDialogImpl<CMyDialog> {

public:

 enum { IDD = IDIDD_MY_DIALOG };

 BEGIN_MSG_MAP(CMyDialog)

// Карта сообщений

 END_MSG_MAP

};

Обратите внимание, что константа IDD описывается в секции public. Если описать её в private– секции, функция базового класса CDialogImpl<>::DoModal не сможет к ней обратиться, что приведёт к ошибке.

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

// Создаём модальный диалог

CMyDialog modal;

modal.DoModal;

// Создаём немодальный диалог

CMyDialog modeless;

modeless.Create(HWND_DESKTOP);

Класс CAxDialogImpl<>

Класс CAxDialogImpl<>

очень похож на предыдущий. Вся разница в том, что вместо функции DialogBoxParam он использует функцию AtlAxDialogBox, а вместо функции CreateDialogParam – функцию AtlAxCreateDialog:

// modal dialogs

int DoModal(HWND hWndParent = ::GetActiveWindow, LPARAM dwInitParam = NULL) {

 ATLASSERT(m_hWnd == NULL);

 _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT<TBase>*)this);

#ifdef _DEBUG

 m_bModal = true;

#endif //_DEBUG

 return AtlAxDialogBox(_Module.GetResourceInstance, MAKEINTRESOURCE(T::IDD),

hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);

}

...

// modeless dialogs

HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL) {

 ATLASSERT(m_hWnd == NULL);

 _Module.AddCreateWndData(&m_thunk.cd, (CDialogImplBaseT<TBase>*)this);

#ifdef _DEBUG

 m_bModal = false;

#endif //_DEBUG

 HWND hWnd = AtlAxCreateDialog(_Module.GetResourceInstance, MAKEINTRESOURCE(T::IDD),

hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);

 ATLASSERT(m_hWnd == hWnd);

 return hWnd;

}

Эти функции, в отличие от своих аналогов из Win32 API, могут создавать диалоги, содержащие ActiveX-контролы. Мы не будем рассматривать их реализацию, поскольку тема использования ActiveX-контролов выходит за рамки данной статьи.

Класс CSimpleDialog<>

Чтобы создавать диалоги на базе класса CDialogImpl<>, необходимо каждый раз порождать от него собственные классы. Это довольно утомительно. Класс CSimpleDialog<> предназначен для отображения простейших модальных диалогов, содержащих только статическую информацию и стандартные кнопки, такие как "OK" и "Отмена". Кроме функции DoModal, которая реализована почти так же, как в классе CDialogImpl<>, этот класс предоставляет собственную карту сообщений и обработчики OnInitDialog и OnCloseCmd. Последний вызывается в ответ на нажатие любой кнопки со стандартным идентификатором (IDOK, IDCANCEL, IDABORT, IDRETRY, IDIGNORE, IDYES или IDNO) и закрывает диалог.

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

Война

Валериев Игорь
7. Ермак
Фантастика:
боевая фантастика
альтернативная история
5.25
рейтинг книги
Война

Экономка тайного советника

Семина Дия
Фантастика:
фэнтези
5.00
рейтинг книги
Экономка тайного советника

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Бестужев. Служба Государевой Безопасности. Книга вторая

Измайлов Сергей
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая

Метатель. Книга 3

Тарасов Ник
3. Метатель
Фантастика:
попаданцы
альтернативная история
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель. Книга 3

Студент из прошлого тысячелетия

Еслер Андрей
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Студент из прошлого тысячелетия

Ты не мой BOY

Рам Янка
5. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ты не мой BOY

Идеальный мир для Лекаря 2

Сапфир Олег
2. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 2

Лекарь для захватчика

Романова Елена
Фантастика:
попаданцы
историческое фэнтези
фэнтези
5.00
рейтинг книги
Лекарь для захватчика

Отверженный VI: Эльфийский Петербург

Опсокополос Алексис
6. Отверженный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Отверженный VI: Эльфийский Петербург

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

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

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

Темный Лекарь 11

Токсик Саша
11. Темный Лекарь
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Темный Лекарь 11