О полях со списком

Поле со списком объединяет поле редактирования или статический текст и список.

Эта тема описана в следующих разделах.

Типы и стили полей со списком

Поле со списком состоит из списка и поля выбора. В списке представлены параметры, которые пользователь может выбрать, а поле выбора отображает текущий выбор. Если поле выбора является элементом управления редактированием, пользователь может ввести сведения, недоступные в списке; в противном случае пользователь может выбрать только элементы в списке.

Библиотека общих элементов управления включает три основных стиля поля со списком, как показано в следующей таблице.

Тип поля со списком Константы стилей Description
Простой CBS_SIMPLE Отображает список всегда и отображает выбранный элемент в элементе управления редактированием.
Раскрывающийся список CBS_DROPDOWN Отображает список при щелчке значка и отображает выбранный элемент в элементе управления редактирования.
Раскрывающийся список (раскрывающийся список) CBS_DROPDOWNLIST Отображает список при щелчке значка и отображает выбранный элемент в статическом элементе управления.

 

На следующем снимке экрана показаны три вида поля со списком, так как они могут отображаться в Windows Vista. На первом снимке экрана пользователь выбрал элемент в простом поле со списком. Пользователь также может ввести новое значение в поле редактирования этого элемента управления. Список имеет размер в редакторе ресурсов Microsoft Visual Studio и достаточно велик, чтобы разместить два элемента.

screen shot showing an item selected in a simple combo box

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

screen shot showing text typed into a drop-down combo box

На третьем снимке экрана пользователь открыл раскрывающийся список со списком. Поле списка расширяется, чтобы разместить максимальное количество элементов. Пользователь не может ввести новый текст.

screen shot showing an item selected in a drop-down list combo box

Существует также ряд стилей полей со списком, определяющих определенные свойства. Стили полей со списком определяют определенные свойства поля со списком. Вы можете объединить стили; однако некоторые стили применяются только к определенным типам полей со списком. Таблица стилей полей со списком см. в разделе "Стили со списком".

Примечание

Чтобы использовать визуальные стили с полями со списком, приложение должно включать манифест и вызывать InitCommonControls в начале программы. Сведения о стилях визуальных элементов см. в разделе "Стили визуальных элементов". Сведения о манифестах см. в разделе "Включение визуальных стилей".

 

Список полей со списком

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

В этом разделе рассматриваются следующие разделы:

Текущий выбор

Текущий выбор — это элемент списка, выбранный пользователем; Выделенный текст отображается в поле выделения поля со списком. Однако в случае простого поля со списком или раскрывающегося списка текущее выделение является только одной формой возможных входных данных пользователя в поле со списком. Пользователь также может вводить текст в поле выбора.

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

При создании поля со списком отсутствует текущий выбор. Это также верно для простого или раскрывающегося списка, если пользователь редактировал содержимое поля выбора. Чтобы задать текущий выбор, приложение отправляет CB_SETCURSEL сообщение в поле со списком. Приложение также может использовать сообщение CB_SELECTSTRING , чтобы задать текущий выбор элементу списка, строка которого начинается с указанной строки. Чтобы определить текущий выбор, приложение отправляет CB_GETCURSEL сообщение в поле со списком. Если текущего выбора нет, это сообщение возвращает CB_ERR.

Когда пользователь изменяет текущий выбор в поле со списком, родительская процедура или процедура диалогового окна получает WM_COMMAND сообщение с кодом уведомления CBN_SELCHANGE в слове высокого порядка параметра wParam. Этот код уведомления не отправляется, если текущий выбор установлен с помощью сообщения CB_SETCURSEL.

Раскрывающийся список со списком или раскрывающийся список отправляет код уведомления CBN_CLOSEUP в родительское окно или процедуру диалогового окна при закрытии раскрывающегося списка. Если пользователь изменил текущий выбор, поле со списком также отправляет код уведомления CBN_SELCHANGE при закрытии раскрывающегося списка. Чтобы выполнить определенный процесс каждый раз, когда пользователь выбирает элемент списка, можно обрабатывать CBN_SELCHANGE или код уведомлений CBN_CLOSEUP. Как правило, перед обработкой изменения в текущем выборе вы ожидаете, пока CBN_CLOSEUP код уведомления. Это может быть особенно важно, если требуется значительный объем обработки.

Приложение также может обрабатывать коды уведомлений CBN_SELENDOK и CBN_SELENDCANCEL . Система отправляет CBN_SELENDOK, когда пользователь выбирает элемент списка или выбирает элемент, а затем закрывает список. Это означает, что пользователь завершил обработку и должен быть обработан выбор. CBN_SELENDCANCEL отправляется, когда пользователь выбирает элемент, но затем выбирает другой элемент управления, нажимает esc во время открытия раскрывающегося списка или закрывает диалоговое окно. Это означает, что выбор пользователя должен игнорироваться. CBN_SELENDOK отправляется перед каждым сообщением CBN_SELCHANGE .

В простом поле со списком система отправляет код уведомления CBN_DBLCLK, когда пользователь дважды щелкает элемент списка. В раскрывающемся списке или раскрывающемся списке один щелчок скрывает список, поэтому дважды щелкнуть элемент невозможно.

Некоторые уведомления и сообщения применяются только к полям со списком, содержащим раскрывающиеся списки. Когда раскрывающийся список открыт или закрыт, родительское окно поля со списком получает уведомление в виде сообщения WM_COMMAND. Если открывается список, CBN_DROPDOWN слово wParam с высоким порядком. Если список закрывается, он CBN_CLOSEUP.

Приложение может открыть список раскрывающегося списка или раскрывающегося списка с помощью сообщения CB_SHOWDROPDOWN. Он может определить, открыт ли список с помощью сообщения CB_GETDROPPEDSTATE и может определить координаты раскрывающегося списка с помощью сообщения CB_GETDROPPEDCONTROLRECT. Приложение также может увеличить ширину раскрывающегося списка с помощью сообщения CB_SETDROPPEDWIDTH.

Вывод списка содержимого

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

Приложение добавляет элементы списка в поле со списком, отправив в него сообщение CB_ADDSTRING . Указанный элемент добавляется в конец списка или в отсортированного поля со списком в правильной отсортированной позиции на основе строки элемента. В несортном поле со списком приложение может использовать сообщение CB_INSERTSTRING для вставки элемента в определенной позиции. После добавления элемент списка определяется его положением.

С помощью сообщения CB_FINDSTRING или CB_FINDSTRINGEXACT приложение может определить положение элемента списка. CB_FINDSTRING находит элемент, строка которого начинается с указанной строки. CB_FINDSTRINGEXACT находит элемент, строка которого точно соответствует строке. Ни сообщение не учитывает регистр.

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

Чтобы получить строку, связанную с элементом списка, приложение может использовать сообщение CB_GETLBTEXT. Строка элемента копируется в буфер, указанный приложением. Чтобы убедиться, что буфер достаточно велик для получения строки, приложение может сначала использовать сообщение CB_GETLBTEXTLEN для определения длины строки. Чтобы получить количество элементов списка в поле со списком, приложение может использовать сообщение CB_GETCOUNT.

Изменение полей выбора элемента управления

Приложение может получить или задать содержимое поля выбора и определить или задать выбранный вариант. Приложение также может ограничить объем текста, который пользователь может ввести в поле выбора. При изменении содержимого поля выбора система отправляет уведомления в родительское окно или процедуру диалогового окна.

Чтобы получить содержимое поля выбора, приложение может отправить WM_GETTEXT сообщение в поле со списком. Чтобы задать содержимое поля выбора простого или раскрывающегося списка, приложение может отправить WM_SETTEXT сообщение в поле со списком.

Выбор редактирования — это диапазон выделенного текста, если таковой имеется, в поле выбора простого или раскрывающегося списка. Приложение может определить начальные и конечные позиции текущего выделения с помощью сообщения CB_GETEDITSEL. Он также может выбирать символы в выделенном фрагменте редактирования с помощью сообщения CB_SETEDITSEL .

Изначально объем текста, который пользователь может ввести в поле выбора, ограничен размером поля выделения. Однако если поле со списком имеет стиль CBS_AUTOHSCROLL , текст может продолжаться за пределами поля выделения. Приложение может использовать сообщение CB_LIMITTEXT, чтобы ограничить объем текста, который пользователь может вводить в поле выбора независимо от того, имеет ли элемент управления стиль CBS_AUTOHSCROLL.

Когда пользователь изменяет содержимое поля выбора, родительская или диалоговая процедура получает уведомления. Сначала отправляется код уведомления CBN_EDITUPDATE , указывающий, что текст в поле выделения был изменен. После отображения измененного текста система отправляет CBN_EDITCHANGE. Если содержимое поля выбора изменяется в результате выбора элемента списка, эти сообщения не отправляются.

Поля со списком нарисованных владельцем

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

Владелец поля со списком нарисованного владельца должен обработать сообщение WM_DRAWITEM . Это сообщение отправляется всякий раз, когда часть поля со списком должна быть перезабрана. Владельцу может потребоваться обрабатывать другие сообщения в зависимости от стилей, указанных для поля со списком.

Приложение может создать поле со списком, нарисованное владельцем, указав стиль CBS_OWNERDRAWFIXED или CBS_OWNERDRAWVARIABLE. Если все элементы списка в поле со списком имеют одинаковую высоту, например строки или значки, приложение может использовать стиль CBS_OWNERDRAWFIXED . Если элементы списка имеют различную высоту, например растровые изображения разного размера, приложение может использовать стиль CBS_OWNERDRAWVARIABLE .

Владелец поля со списком нарисованного владельца может обработать сообщение WM_MEASUREITEM , чтобы указать размеры элементов списка в поле со списком. Если приложение создает поле со списком с помощью стиля CBS_OWNERDRAWFIXED, система отправляет сообщение WM_MEASUREITEM только один раз. Измерения, указанные владельцем, используются для всех элементов списка. Если используется стиль CBS_OWNERDRAWVARIABLE, система отправляет WM_MEASUREITEM сообщение для каждого элемента списка, добавленного в поле со списком. Владелец может определить или задать высоту элемента списка в любое время с помощью CB_GETITEMHEIGHT и CB_SETITEMHEIGHT сообщений соответственно.

Если сведения, отображаемые в поле со списком владельца, содержат текст, приложение может отслеживать текст для каждого элемента списка, указав стиль CBS_HASSTRINGS. Поля со списком с стилем CBS_SORT отсортированы на основе этого текста. Если поле со списком отсортировано и не CBS_HASSTRINGS стиле, владелец должен обработать сообщение WM_COMPAREITEM.

В поле со списком, нарисованном владельцем, владелец должен отслеживать элементы списка, содержащие сведения, отличные от текста или в дополнение к тексту. Одним из удобных способов этого является сохранение дескриптора в качестве данных элемента. Чтобы освободить объекты данных, связанные с элементами в поле со списком, владелец может обработать сообщение WM_DELETEITEM .

Подклассированные поля со списком

Подкласс — это процедура, которая позволяет приложению перехватывать и обрабатывать сообщения, отправленные или отправленные в окно. Используя подклассы, приложение может заменить собственную обработку для определенных сообщений, оставляя большую часть обработки сообщений в процедуре определенного класса окна.

При создании окна операционная система сохраняет сведения о нем во внутренней структуре данных, которая включает указатель на процедуру окна. Для подкласса окна приложение вызывает функцию SetClassLong , чтобы заменить указатель на данную процедуру указателем на процедуру, определяемую приложением. После этого все сообщения в окно отправляются в процедуру подкласса. Затем эта процедура использует функцию CallWindowProc для передачи необработанных сообщений исходной процедуре окна. Описание обработки сообщений, выполняемой процедурой окна класса CO МБ OBOX, см. в разделе "Поведение поля со списком по умолчанию".

Если поле со списком выходит за рамки диалогового окна, приложение не может обрабатывать клавиши TAB, ВВОД и ESC, если не используется процедура подкласса. Когда простое поле со списком или раскрывающимся списком получает фокус ввода, он сразу же устанавливает фокус на его дочерний элемент управления редактирования. Поэтому приложение должно подклассить элемент управления редактирования для перехвата ввода клавиатуры для простого или раскрывающегося списка. Пример этого см . в разделе "Подкласс" в поле со списком.

Если процедура подкласса обрабатывает сообщение WM_PAINT, он должен использовать функцию BeginPaint для подготовки к рисованию. Перед вызовом функции EndPaint он передает дескриптор контекста устройства (DC) в качестве параметра wParam для процедуры окна. Если EndPaint вызывается первым, процедура окна класса не выполняет рисование, так как EndPaint проверяет все окно.

Метод, связанный с подклассами, является суперклассированием. Суперкласс напоминает любой другой класс, за исключением того, что его процедура окна не вызывает DefWindowProc для обработки необработанных сообщений. Вместо этого он передает необработанные сообщения в процедуру окна для родительского класса окна. Следуйте инструкциям в разделе "Процедуры окна" , чтобы избежать проблем, которые могут возникнуть с подклассами и суперклассами.