Неочевидные аспекты программирования элементов управления 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Неочевидные аспекты программирования элементов управления



Одно из преимуществ MFC при программировании ЭУ – простота изменения поведения ЭУ путем создания подкласса от одного из готовых классов ЭУ. Например, легко создать строку ввода для ввода только чисел или список для отображения изображений вместо текста. Вы также можете разрабатывать повторно используемые, самодостаточные классы ЭУ, которые сами обрабатывают свои сообщения с уведомлениями.

 

Строка ввода для приема числовых значений

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

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

Унаследуем класс от CEdit и модифицируем обработчик OnChar для приема только цифровых символов:

class CNumEdit: public CEdit { protected: afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); DECLARE_MESSAGE_MAP() };   BEGIN_MESSAGE_MAP(CNumEdit, CEdit) ON_WM_CHAR() END_MESSAGE_MAP()   void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { if (((nChar >= `0') && (nChar <= `9')) ¦¦ (nChar == VK_BACK)) CEdit::OnChar(nChar, nRepCnt, nFlags); }

Клавиша с кодом VK_BACK в CNumEdit тоже принимается, чтобы пользователь мог удалять символы в строке клавишей Backspace. Проверять коды других клавиш редактирования (например, Home и Del) не надо, т.к. они не генерируют сообщений WM_CHAR.

 

Отражение сообщений

В MFC 4.0 появился набор макросов карты сообщений (табл. 7.5), предназначенных для передачи сообщений с уведомлениями обратно в элементы управления, пославшие эти сообщения – для "отражения сообщений". Отражение сообщений – важный прием для разработки классов повторно используемых ЭУ, т.к. он позволяет реализовать поведение ЭУ независимо от поведения окна-владельца.

С помощью макросов отражения сообщений можно сделать так, чтобы уведомление от ЭУ обрабатывалось функцией-членом класса ЭУ.

Таблица 7.5. Макросы карты сообщений для отражения сообщений ЭУ

Макрос Какие сообщения отражаются
ON_CONTROL_REFLECT Отражение уведомлений, посылаемых в виде сообщений WM_COMMAND
ON_NOTIFY_REFLECT Отражение уведомлений, посылаемых в виде сообщений WM_NOTIFY
ON_UPDATE_COMMAND_UI_REFLECT Отражение уведомлений обновления панелей инструментов, строк состояния и других ЭУ
ON_WM_CTLCOLOR_REFLECT Отражение сообщений WM_CTLCOLOR
ON_WM_DRAWITEM_REFLECT WM_DRAWITEM от ЭУ с собственным отображением
ON_WM_MEASUREITEM_REFLECT WM_MEASUREITEM от ЭУ с собственным отображением
ON_WM_COMPAREITEM_REFLECT WM_COMPAREITEM от ЭУ с собственным отображением
ON_WM_DELETEITEM_REFLECT WM_DELETEITEM от ЭУ с собственным отображением
ON_WM_CHARTOITEM_REFLECT WM_CHARTOITEM от списков
ON_WM_VKEYTOITEM_REFLECT WM_VKEYTOITEM от списков
ON_WM_HSCROLL_REFLECT WM_HSCROLL от полос прокрутки
ON_WM_VSCROLL_REFLECT WM_VSCROLL от полос прокрутки
ON_WM_PARENTNOTIFY_REFLECT Отражение сообщений WM_PARENTNOTIFY

Предположим, что требуется разработать класс списка, самостоятельно обрабатывающий собственное уведомление LBN_DBLCLK для вывода информационного окна с текстом элемента, на котором был двойной щелчок. Ниже приведено описание подкласса CListBox с использованием отраженного сообщения:

class CMyListBox: public CListBox { protected: afx_msg void OnDoubleClick(); DECLARE_MESSAGE_MAP() };   BEGIN_MESSAGE_MAP(CMyListBox, CListBox) ON_CONTROL_REFLECT(LBN_DBLCLK, OnDoubleClick) END_MESSAGE_MAP()   void CMyListBox::OnDoubleClick() { CString string; int nIndex = GetCurSel(); GetText(nIndex, string); MessageBox(string); }

Макрос ON_CONTROL_REFLECT говорит MFC, что надо вызывать CMyListBox::OnDoubleClick каждый раз, когда список посылает уведомление LBN_DBLCLK своему родительскому окну. Важно отметить, что отражение работает только тогда, когда родительское окно само не обрабатывает уведомление – т.е. в карте сообщения родительского окна не должно быть записи ON_LBN_DBLCLK для данного списка. Родительское окно при обработке уведомления имеет больший приоритет. Это объясняется тем, что Windows ожидает выполнения обработки уведомления от ЭУ в его родительском окне, а не в самом ЭУ.

 

Упражнения

8) Изучите англо-русский словарь терминов по теме 7-й лекции (см. CD-ROM).

9) Выполните лабораторную работу №4, "Использование стандартных элементов управления" (см. CD-ROM).


Лекция 8. Диалоговые окна

В большинстве приложений элементы управления используются не в окнах верхнего уровня, а в диалоговых окнах. Диалоговое окно (dialog box), или, диалог – это окно, обычно появляющееся на короткий промежуток времени для получения данных от пользователя. Диалоговые окна создавать гораздо проще, чем окна верхнего уровня, т.к. шаблон диалогового окна с расположением всех его ЭУ можно разработать в интерактивном режиме, поместить в RC-файл, а затем во время выполнения программы создать диалоговое окно на основе шаблона.

Есть две основных разновидности диалоговых окон: модальные и немодальные. Модальные окна запрещают во время работы свое окно-владельца. Немодальное окно больше похоже на обычное окно верхнего уровня (например, окно контекстного поиска и замены в MS Word). Во время работы такого окна пользователь может работать и с его окном-владельцем. Чаще в приложениях используются модельные окна, поэтому далее будут подробно рассматриваться именно они.

В MFC диалоговые окна представлены классом CDialog. Также в MFC есть удобные классы-оболочки для работы со стандартными диалоговыми окнами Windows (для открытия/сохранения файлов, диалоговые окна печати и др.).

Особым видом диалоговых окон являются окна свойств (окна с закладками, property sheet). Это окно выглядит как окно с закладками, каждая из которых является отдельным диалоговым окном. Окна свойств позволяют компактно представить большое количество элементов управления. Они хорошо подходят для разработки объектно-ориентированного пользовательского интерфейса, в котором интенсивно используются контекстные меню. В MFC для работы с окнами свойств есть классы CPropertySheet и CPropertyPage.

 

Модальные диалоговые окна и класс CDialog

В процессе создания модального диалогового окна выделяются три этапа:

1) Разработка шаблона диалогового окна, описывающего внешний вид окна и его элементов управления.

2) Создание объекта класса или подкласса CDialog, являющегося оболочкой для шаблона диалогового окна.

3) Вызов функции-члена CDialog::DoModal для вывода окна на экран.

Для простых диалоговых окон можно непосредственно пользоваться классом CDialog. Однако более часто наследуется подкласс CDialog, в котором реализуется поведение конкретного окна. Сначала рассмотрим отдельные компоненты диалогового окна, а затем создание подклассов CDialog.

 

Шаблон диалогового окна

Первый шаг в создании диалогового окна – разработка шаблона. В нем описываются основные характеристики окна, начиная от его размеров, до свойств элементов управления. Хотя можно создавать шаблон окна программно, обычно они хранятся в виде ресурсов приложения, скомпилированных по содержимому RC-файла.

Ниже в качестве примера приведен шаблон диалогового окна с идентификатором ресурса IDD_MYDIALOG. В этом окне есть 4 ЭУ: строка ввода, статический элемент-метка строки ввода, кнопка OK и кнопка Отмена:

IDD_MYDIALOG DIALOG 0, 0, 160, 68 STYLE DS_MODALFRAME ¦ WS_POPUP ¦ WS_VISIBLE ¦ WS_CAPTION ¦ WS_SYSMENU CAPTION "Введите свое имя" FONT 8, "MS Sans Serif" BEGIN LTEXT "&Имя", -1, 8, 14, 24, 8 EDITTEXT IDC_NAME, 34, 12, 118, 12, ES_AUTOHSCROLL DEFPUSHBUTTON "OK", IDOK, 60, 34, 40, 14, WS_GROUP PUSHBUTTON "Отмена", IDCANCEL, 112, 34, 40, 14, WS_GROUP END

Все координаты и размеры задаются в единицах диалогового окна (dialog box units). Горизонтальная единица равна четверти средней ширины символа шрифта диалога. Вертикальная единица равна одной восьмой высоты символа. Т.к. высота символов с среднем в 2 раза больше ширины, то эти единицы примерно равны. Использование таких единиц позволяет описать окно независимо от экранного разрешения.

В шаблоне окна можно вместо служебных слов вроде LTEXT или EDITTEXT пользоваться словом CONTROL и указывать имя оконного класса элемента управления явно, например:

IDD_MYDIALOG DIALOG 0, 0, 160, 68 STYLE DS_MODALFRAME ¦ WS_POPUP ¦ WS_VISIBLE ¦ WS_CAPTION ¦ WS_SYSMENU CAPTION "Введите свое имя" BEGIN CONTROL "&Имя", -1, "STATIC", SS_LEFT, 8, 14, 24, 8 CONTROL "", IDC_NAME, "EDIT", WS_BORDER ¦ ES_AUTOHSCROLL ¦ ES_LEFT ¦ WS_TABSTOP, 34, 12, 118, 12 CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON ¦ WS_TABSTOP ¦ WS_GROUP, 60, 34, 40, 14 CONTROL "Отмена", IDCANCEL, "BUTTON", BS_PUSHBUTTON ¦ WS_TABSTOP ¦ WS_GROUP, 112, 34, 40, 14 END

Вручную такие описания диалоговых окон делаются очень редко. В среде Visual C++ команда меню InsertÞResource позволяет добавить в проект пустой шаблон диалогового окна и затем отредактировать его в редакторе ресурсов. На рис. 8.1 показано окно редактора диалоговых окон, встроенного в Visual C++. Элементы управления можно выбирать в панели инструментов Controls и "рисовать" их в диалоговом окне (если панель инструментов Controls отсутствует на экране, ее можно включить командой меню ToolsÞCustomizeÞToolbars). Свойства диалогового окна (заголовок, шрифт, стиль) и свойства ЭУ доступны в окнах свойств, вызываемых командой Properties из контекстных меню.

 

Рис. 8.1. Редактор диалоговых окон Visual C++.

 



Поделиться:


Последнее изменение этой страницы: 2016-08-01; просмотров: 345; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.59.82.167 (0.008 с.)