Опубликован: 10.03.2009 | Доступ: свободный | Студентов: 2297 / 280 | Оценка: 4.31 / 4.07 | Длительность: 09:23:00
Лекция 2:

Библиотека классов MFC

Элементы управления Windows

В данном пункте рассмотрим подробнее стандартные элементы управления.

Списки

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

Прием идентификационных кодов списка

Список может генерировать сообщения различных типов. Например, сообщения посылаются при двойном щелчке на элементе списка, при потере списком фокуса ввода и при выборе другого элемента из списка. Каждое такое событие описывается идентификационным кодом. Этот код является частью сообщения WM_COMMAND. Некоторые другие элементы также используют идентификационные коды. Рассмотрим код LBN_DBLCLK. Он посылается, когда пользователь выполняет двойной щелчок на элементе списка. При определении списка в ресурсах должна быть установлена опция Notify, чтобы он мог генерировать это сообщение. Когда выбор произведен, необходимо запросить список, чтобы узнать о том, какой элемент выбран. Для обработки сообщения LBN_DBLCLK необходимо поместить его обработчик в карту сообщений. Но это будет не макрос ON_COMMAND(). Вместо этого используются специальные макрокоманды. Для нашего сообщения это будет ON_LBN_DBLCLK(). Она имеет такой вид:

ON_LBN_DBLCLK (ИдентификаторСписка, ИмяОбработчика)

Многие сообщения обрабатываются подобным образом. Названия всех макросов для таких сообщений начинаются с префикса ON_LBN_.

Передача сообщений списку

В традиционных Windows-программах сообщения посылаются элементам управления с помощью API-функций, например SendDlgItemMessage(). Но, в программах на MFC, для этих целей применяются соответствующие функции-члены класса. Эти функции автоматически посылают необходимое сообщение элементу управления. В этом заключается преимущество использования MFC по сравнению с традиционным методом программирования. Списку может быть послано несколько разных сообщений. Для каждого сообщения класс CListBox содержит отдельный член-функцию класса. Например, рассмотрим следующие функции:

int CListBox::AddString(LPCSTR StringToAdd);
int CListBox::GetCurSel() const;
int CListBox::GetText(int Index, LPCSTR StringVariable);

Функция AddString(…) вставляет указанную строку в список. По умолчанию, она вставляется в конец списка, при этом, начало списка имеет индекс 0. Функция GetCurSel() возвращает индекс текущего выделенного элемента. Если ни один элемент не выбран, то функция возвращает LB_ERR. Функция GetText(…) получает строку, связанную с указанным индексом. Строка копируется в символьный массив по адресу StringVariable.

Получение указателя на список

Функции CListBox работают с объектами CListBox. Поэтому, необходимо получить указатель на объект списка, что делается с помощью функции GetDlgItem(), являющейся членом класса CWnd:

СWnd *CWnd::GetDlgItem(int ItemIdentifier) const ;

Функция возвращает указатель на объект, чей идентификатор передан как параметр. Если такой объект не существует, то возвращается 0. Значение, возвращенное функцией, должно быть приведено к типу указателя на конкретный класс управления. Например, в нашем случае это тип CListBox*.

Инициализация списка

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

Поле ввода

На практике поля ввода используются очень широко, так как дают возможность ввести строку по своему усмотрению. Поля ввода принимают многие сообщения и сами могут генерировать несколько типов сообщений. Но, обычно отвечать на большинство из них нет необходимости, так как поля ввода самостоятельно выполняют большинство функций редактирования. Для этого не требуется взаимодействия с программой. Необходимо только решить, когда затребовать содержимое поля ввода. Для получения текущего содержимого поля вода, состоящего из одной строки, используется функция GetWindowText(). Ее прототип:

int CWnd::GetWindowText(LPSTR StringVariable, int MaxStringLen) const;

В результате выполнения функции, содержимое поля ввода будет скопировано в строку по адресу StringVariable. Эта функция позволяет получить текст, связанный с любым окном или элементом управления. Применительно к обычному окну, функция получает заголовок окна. В момент создания поле ввода является пустым. Для инициализации его содержимым используется еще одна функция-член класса CWnd – SetWindowText(). Она отображает строку в элементе управления, который вызвал эту функцию. Ее прототип:

void CWnd::SetWindowText(LPCSTR String);

Контрольные переключатели

Контрольный переключатель – это элемент управления, предназначенный для установки или снятия определенной опции. Визуально он состоит из маленького прямоугольного поля, в котором может стоять метка выбора. Кроме этого, с переключателем связано текстовое поле с описанием предоставляемой переключателем опции. Если в переключателе стоит метка выбора, то говорится, что он выбран (установлен). Контрольные переключатели в MFC описываются с помощью класса CButton (так как контрольный переключатель – разновидность кнопки). Контрольные переключатели могут быть автоматическими и программными. Автоматический переключатель сам меняет свое состояние при щелчке мышью. Программный же этого не делает, а подразумевается, что сообщение о щелчке будет обработано в программе, и она изменит состояние переключателя. На практике почти всегда используются автоматические переключатели.

Сообщения контрольного переключателя

Каждый раз, когда пользователь щелкает мышью на контрольном переключателе (или нажимает клавишу Spacebar, когда фокус ввода находится на переключателе), диалогу посылается сообщение WM_COMMAND с идентификационным кодом BN_CLICKED. Это сообщение обрабатывается с помощью макроса ON_BN_CLICKED(). При работе с автоматическими переключателями отвечать на это сообщение нет необходимости. Но при работе с программными переключателями, чтобы изменять их состояние, необходимо отвечать на это сообщение. Для этого необходимо поместить макрос в карту сообщений и написать обработчик.

Установка и чтение состояния контрольного переключателя

Чтобы установить контрольный переключатель в заданное состояние, необходиимо использовать функцию SetCheck(…) c прототипом:

void CButton::SetCheck(int Status);

Параметр определяет требуемое состояние: если он равен 1, то переключатель устанавливается, если 0 - сбрасывается. По умолчанию, при первом вызове диалога переключатель будет сброшен. Автоматический переключатель также может быть установлен в требуемое состояние этой функцией. Текущее состояние переключателя можно определить с помощью функции GetCheck():

int CButton::GetCheck() const;

Функция возвращает 1, если переключатель установлен, и 0 в противном случае.

Инициализация контрольных переключателей

При вызове диалога переключатели сброшены. Но, обычно они должны устанавливаться в предыдущее состояние при каждом вызове диалога. Таким образом, переключатели необходимо инициализировать. Для этого необходимо переопределить функцию OnInitDialog(), и в ней использовать функкцию SetCheck() для установки начальных состояний.

Статические элементы управления

Статическим называется элемент, который не принимает и не генерирует сообщений. Формально, этим термином называют то, что просто отображается в диалоговом окне, например, текстовая строка или рамка, предназначенная для визуального объединения нескольких элементов управления, или рисунок. Если элементу присвоен идентификатор IDC_STATIC (-1), то он не будет принимать и генерировать сообщений. Но, в общем случае, статические элементы управления могут генерировать и принимать сообщения. Для этого элементу нужно присвоить другой идентификатор. Тогда элемент уже не будет статическим. Это часто используется. Например, можно поменять текст в текстовой строке с помощью функции SetWindowText(), чтобы отобразить некоторую информацию.

Селекторные кнопки

Использование селекторных кнопок очень похоже на использование контрольных переключателей. Только их работа организована таким образом, что из группы кнопок может быть установлена только одна. При установке другой кнопки, предыдущая установка сбрасывается. Селекторные кнопки бывают программные и автоматические; но, так как управлять радиокнопками сложно, то сейчас почти всегда используются автоматические. Радиокнопки объединяются в группы. В одном диалоге может быть несколько групп. Для первой радиокнопки каждой группы в редакторе ресурсов нужно установить опцию Group, а для других радиокнопок группы она должна быть сброшена. Радиокнопки нумеруются в порядке значений их идентификаторов (то есть в порядке их создания в редакторе ресурсов). Если в диалоге все радиокнопки образуют одну группу, то опцию Group можно не устанавливать. Селекторные кнопки управляются с помощью класса CButton. Также как для контрольных переключателей, состояние селекторных кнопок можно изменять с помощью функции SetCheck() и читать с помощью функции GetCheck(). При создании диалога все селекторные кнопки сброшены. Таким образом, в функции OnInitDialog() необходимо установить начальное состояние программно. Хотя из программы можно установить сразу несколько селекторных кнопок или сбросить все, хороший стиль программирования под Windows предполагает, что всегда будет установлена одна и только одна селекторная кнопка.