Сведения о полях списка
Элемент управления "Список" содержит простой список, из которого пользователь может выбрать один или несколько элементов. Поля списка обеспечивают ограниченную гибкость по сравнению с элементами управления "Представление списка".
Элементы списка могут быть представлены текстовыми строками, растровыми изображениями или обоими. Если поле списка недостаточно большое для отображения всех элементов списка одновременно, поле списка предоставляет полосу прокрутки. Пользователь прокручивает элементы списка и применяет или удаляет состояние выбора по мере необходимости. Выбор элемента списка изменяет внешний вид визуального элемента, как правило, путем изменения цвета текста и фона на те, которые указаны соответствующими метриками операционной системы. Когда пользователь выбирает или отменяет выбор элемента, система отправляет уведомление в родительское окно списка.
Для приложения ANSI система преобразует текст в поле списка в Юникод с помощью CP_ACP кодовой страницы. Это может привести к проблемам. Например, подчеркнутые римские символы в поле списка, отличном от Юникода в Windows, японская версия будет выходить наружу. Чтобы устранить эту проблему, скомпилируйте приложение в виде Юникода или используйте поле со списком, нарисованным владельцем.
В этом разделе рассматриваются следующие разделы:
- Создание поля списка
- Типы и стили списка
- Функции List Box
- Уведомления сообщений из списков
- Сообщения в списки
- Обработка сообщений окна по умолчанию
- Поля списка нарисованных владельцем
- Перетаскивание списков
Создание поля списка
Самый простой способ создать поле списка в диалоговом окне — перетащить его из панели элементов в Microsoft Visual Studio в ресурс диалогового окна. Чтобы динамически создать поле списка или создать поле списка в окне, отличном от диалогового окна, используйте функцию CreateWindowEx, указав класс окна WC_LISТБ OX и соответствующие стили списков.
Типы и стили списка
Существует два типа полей списка: одинарный выбор (по умолчанию) и множественный выбор. В списке с одним выделением пользователь может выбрать только один элемент за раз. В списке с несколькими выборами пользователь может выбрать несколько элементов одновременно. Чтобы создать поле с несколькими выборами, укажите LBS_MULTIPLESEL или стиль LBS_EXTENDEDSEL.
Внешний вид и операция поля списка управляется стилями списков и стилями окон. Эти стили указывают, сортируется ли список, упорядочивается в нескольких столбцах, рисуется приложением и т. д. Размеры и стили списка обычно определяются в шаблоне диалогового окна, который включается в ресурсы приложения.
Примечание.
Чтобы использовать визуальные стили с этими элементами управления, приложение должно включать манифест и вызывать InitCommonControls в начале программы. Сведения о стилях визуальных элементов см. в разделе "Стили визуальных элементов". Сведения о манифестах см. в разделе "Включение визуальных стилей".
Функции List Box
Функция DlgDirList заменяет содержимое поля списка именами дисков, каталогов и файлов, которые соответствуют указанному набору критериев. Функция DlgDirSelectEx извлекает текущий выбор в поле списка, инициализированном DlgDirList. Эти функции позволяют пользователю выбрать диск, каталог или файл из поля списка без ввода расположения и имени файла.
Кроме того, функция GetListBoxInfo возвращает количество элементов на столбец в указанном поле списка.
Уведомления сообщений из списков
Когда событие происходит в списке, поле списка отправляет код уведомления в виде сообщения WM_COMMAND в диалоговое окно окна владельца. Коды уведомлений списка отправляются, когда пользователь выбирает, дважды щелкает или отменяет элемент поля списка; если поле списка получает или теряет фокус клавиатуры; и когда система не может выделить достаточно памяти для запроса списка. Сообщение WM_COMMAND содержит идентификатор поля списка в слове с низким порядком параметра wParam и код уведомления в слове высокого порядка. Параметр lParam содержит дескриптор окна управления.
Процедура диалогового окна не требуется для обработки этих сообщений; Процедура окна по умолчанию обрабатывает их.
Приложение должно отслеживать и обрабатывать следующие коды уведомлений списка.
Код уведомления | Description |
---|---|
LBN_DBLCLK | Пользователь дважды щелкает элемент в списке. |
LBN_ERRSPACE | Поле списка не может выделить достаточно памяти для выполнения запроса. |
LBN_KILLFOCUS | Поле списка теряет фокус клавиатуры. |
LBN_SELCANCEL | Пользователь отменяет выбор элемента в списке. |
LBN_SELCHANGE | Выбор в списке будет изменен. |
LBN_SETFOCUS | Поле списка получает фокус клавиатуры. |
Сообщения в списки
Процедура диалогового окна может отправлять сообщения в список для добавления, удаления, проверки и изменения элементов списка. Например, процедура диалогового окна может отправить сообщение LB_ADDSTRING в поле списка, чтобы добавить элемент, и сообщение LB_GETSEL, чтобы определить, выбран ли элемент. Другие сообщения задают и извлекают сведения о размере, внешнем виде и поведении поля списка. Например, сообщение LB_SETHORIZONTALEXTENT задает ширину списка с прокруткой. Процедура диалогового окна может отправлять любое сообщение в поле списка с помощью функции SendMessage или SendDlgItemMessage.
Элемент списка часто ссылается на его индекс, целое число, представляющее позицию элемента в поле списка. Индекс первого элемента в поле списка равен 0, индекс второго элемента равен 1 и т. д.
В следующей таблице описывается, как предопределенная процедура списка отвечает на сообщения списка.
Message | Response |
---|---|
LB_ADDFILE | Вставляет файл в поле списка каталогов, заполненное функцией DlgDirList , и извлекает индекс списка вставленного элемента. |
LB_ADDSTRING | Добавляет строку в поле списка и возвращает его индекс. |
LB_DELETESTRING | Удаляет строку из поля списка и возвращает количество строк, оставшихся в списке. |
LB_DIR | Добавляет список имен файлов в поле списка и возвращает индекс добавленного последнего имени файла. |
LB_FINDSTRING | Возвращает индекс первой строки в поле списка, начинающегося с указанной строки. |
LB_FINDSTRINGEXACT | Возвращает индекс строки в поле списка, равный указанной строке. |
LB_GETANCHORINDEX | Возвращает индекс элемента, который последняя выбранная мышью. |
LB_GETCARETINDEX | Возвращает индекс элемента с прямоугольником фокуса. |
LB_GETCOUNT | Возвращает количество элементов в поле списка. |
LB_GETCURSEL | Возвращает индекс выбранного элемента. |
LB_GETHORIZONTALEXTENT | Возвращает ширину прокрутки (в пикселях) списка. |
LB_GETITEMDATA | Возвращает значение, связанное с указанным элементом. |
LB_GETITEMHEIGHT | Возвращает высоту элемента в списке в пикселях. |
LB_GETITEMRECT | Извлекает координаты клиента указанного элемента списка. |
LB_GETLOCALE | Извлекает языковой стандарт списка. Слово высокого порядка содержит код страны или региона, а слово с низким порядком содержит идентификатор языка. |
LB_GETSEL | Возвращает состояние выбора элемента списка. |
LB_GETSELCOUNT | Возвращает количество выбранных элементов в списке с несколькими выборами. |
LB_GETSELITEMS | Создает массив индексов всех выбранных элементов в списке с несколькими выборами и возвращает общее количество выбранных элементов. |
LB_GETTEXT | Извлекает строку, связанную с указанным элементом, и длину строки. |
LB_GETTEXTLEN | Возвращает длину в символах строки, связанной с указанным элементом. |
LB_GETTOPINDEX | Возвращает индекс первого видимого элемента в поле списка. |
LB_INITSTORAGE | Выделяет память для указанного количества элементов и связанных строк. |
LB_INSERTSTRING | Вставляет строку по указанному индексу в поле списка. |
LB_ITEMFROMPOINT | Извлекает отсчитываемый от нуля индекс элемента, ближайшего к указанной точке в списке. |
LB_RESETCONTENT | Удаляет все элементы из списка. |
LB_SELECTSTRING | Выбирает первую строку, которая находит, соответствует указанному префиксу. |
LB_SELITEMRANGE | Выбирает указанный диапазон элементов в списке. |
LB_SELITEMRANGEEX | Выбирает указанный диапазон элементов, если индекс первого элемента в диапазоне меньше индекса последнего элемента в диапазоне. Отменяет выбор в диапазоне, если индекс первого элемента больше последнего. |
LB_SETANCHORINDEX | Задает элемент, который последний раз выбран мышью для указанного элемента. |
LB_SETCARETINDEX | Задает прямоугольник фокуса указанному элементу списка. |
LB_SETCOLUMNWIDTH | Задает ширину (в пикселях) всех столбцов в поле списка. |
LB_SETCOUNT | Задает количество элементов в поле списка. |
LB_SETCURSEL | Выбирает указанный элемент списка. |
LB_SETHORIZONTALEXTENT | Задает ширину прокрутки (в пикселях) списка. |
LB_SETITEMDATA | Связывает значение с элементом списка. |
LB_SETITEMHEIGHT | Задает высоту элемента или элементов в списке в пикселях. |
LB_SETLOCALE | Задает языковой стандарт списка и возвращает предыдущий идентификатор языкового стандарта. |
LB_SETSEL | Выбирает элемент в списке с несколькими выборами. |
LB_SETTABSTOPS | Задает для табуляции значения, указанные в указанном массиве. |
LB_SETTOPINDEX | Прокручивает поле списка, поэтому указанный элемент находится в верхней части видимого диапазона. |
Обработка сообщений окна по умолчанию
Процедура окна для предопределенного класса окна списка выполняет обработку по умолчанию для всех сообщений, которые не обрабатываются в списке. Когда процедура списка возвращает значение FALSE для сообщения, предопределенная процедура окна проверка сообщение и выполняет действия по умолчанию, как показано в следующей таблице.
Message | Действие по умолчанию |
---|---|
WM_CHAR | Перемещает выделение на первый элемент, начинающийся с символа, введенного пользователем. Если в списке есть стиль LBS_OWNERDRAW , действие не выполняется. Несколько символов, типизированных в течение короткого интервала, обрабатываются как группа, и выбирается первый элемент, начинающийся с этой серии символов. |
WM_CREATE | Создает пустое поле списка. |
WM_DESTROY | Уничтожает поле списка и освобождает все используемые ресурсы. |
Передает сообщение в процедуру диалогового окна или родительский процесс окна. | |
WM_ENABLE | Если элемент управления виден, делает прямоугольник недействительным, чтобы строки могли быть окрашены серым цветом. |
WM_ERASEBKGND | Удаляет фон поля списка. Если в списке есть стиль LBS_OWNERDRAW , фон не удаляется. |
WM_GETDLGCODE | Возвращает DLGC_WANTARROWS | DLGC_WANTCHARS, указывая, что процедура списка по умолчанию обрабатывает клавиши со стрелками и WM_CHAR сообщения. |
WM_GETFONT | Возвращает дескриптор текущего шрифта для поля списка. |
WM_HSCROLL | Прокручивает поле списка по горизонтали. |
WM_KEYDOWN | Обрабатывает виртуальные ключи для прокрутки. Виртуальный ключ — это индекс элемента для перемещения курсора. Выбор не изменяется. |
WM_KILLFOCUS | Отключает и уничтожает его. Отправляет код уведомления LBN_KILLFOCUS владельцу поля списка. |
WM_LBUTTONDBLCLK | Отслеживает мышь в клиентской области списка. Это позволяет пользователю отменить выбор, если кнопка мыши освобождается за пределами клиентской области списка. |
WM_LBUTTONDOWN | Отслеживает мышь в клиентской области списка. Это позволяет пользователю отменить выбор, если кнопка мыши освобождается за пределами клиентской области списка. |
WM_LBUTTONUP | Отслеживает мышь в клиентской области списка. Это позволяет пользователю отменить выбор, если кнопка мыши освобождается за пределами клиентской области списка. |
WM_MOUSEMOVE | Отслеживает мышь в клиентской области списка. Это позволяет пользователю отменить выбор, если кнопка мыши освобождается за пределами клиентской области списка. |
WM_PAINT | Выполняет подклассовую операцию краски с помощью дескриптора списка для контекста устройства (DC). |
WM_SETFOCUS | Включает и отправляет код уведомления LBN_SETFOCUS владельцу поля списка. |
WM_SETFONT | Задает новый шрифт для поля списка. |
WM_SETREDRAW | Задает или очищает флаг перерасчета на основе значения wParam. |
WM_SIZE | Изменяет размер поля списка на целое число элементов. |
WM_VSCROLL | Прокручивает поле списка по вертикали. |
Предопределенная процедура списка передает все остальные сообщения в DefWindowProc для обработки по умолчанию.
Поля списка нарисованных владельцем
Приложение может создать поле со списком , нарисованным владельцем, чтобы взять на себя ответственность за рисование элементов списка. Родительское окно или диалоговое окно со списком, нарисованным владельцем, получает WM_DRAWITEM сообщения, когда часть поля списка должна быть окрашена. Поле со списком, нарисованным владельцем, может содержать сведения, отличные от текстовых строк или в дополнение к текстовым строкам.
Владелец поля списка, нарисованного владельцем, должен обработать сообщение WM_DRAWITEM . Это сообщение отправляется всякий раз, когда часть поля списка должна быть перезаписна. Владельцу может потребоваться обрабатывать другие сообщения в зависимости от стилей, указанных для поля списка.
Приложение может создать поле со списком, нарисованным владельцем, указав стиль LBS_OWNERDRAWFIXED или LBS_OWNERDRAWVARIABLE. Если все элементы списка в списке имеют одинаковую высоту, например строки или значки, приложение может использовать стиль LBS_OWNERDRAWFIXED . Если элементы списка имеют различную высоту (например, растровые изображения разного размера), приложение может использовать стиль LBS_OWNERDRAWVARIABLE .
Владелец поля списка, нарисованного владельцем, может обработать сообщение WM_MEASUREITEM , чтобы указать размеры элементов списка. Если приложение создает поле списка с помощью стиля LBS_OWNERDRAWFIXED, система отправляет сообщение WM_MEASUREITEM только один раз. Измерения, указанные владельцем, используются для всех элементов списка. Если используется стиль LBS_OWNERDRAWVARIABLE, система отправляет WM_MEASUREITEM сообщение для каждого элемента списка, добавленного в поле списка. Владелец может определить или задать высоту элемента списка в любое время с помощью LB_GETITEMHEIGHT и LB_SETITEMHEIGHT сообщений соответственно.
Если данные, отображаемые в поле списка с изображением владельца, содержат текст, приложение может отслеживать текст для каждого элемента списка, указав стиль LBS_HASSTRINGS. Списки со стилем LBS_SORT отсортированы на основе этого текста. Если поле списка отсортировано, но не является стилем LBS_HASSTRINGS, владелец должен обработать сообщение WM_COMPAREITEM.
В поле со списком, нарисованным владельцем, владелец должен отслеживать элементы списка, содержащие сведения, отличные от текста или в дополнение к тексту. Одним из удобных способов этого является сохранение дескриптора в качестве данных элемента с помощью сообщения LB_SETITEMDATA. Чтобы освободить объекты данных, связанные с элементами в списке, владелец может обработать сообщение WM_DELETEITEM .
Пример поля со списком, нарисованным владельцем, см. в разделе "Создание списка нарисованных владельцем".
Перетаскивание списков
Поле списка перетаскивания — это специальный тип поля списка, который позволяет пользователю перетаскивать элементы из одной позиции в другую. Приложение может использовать поле списка перетаскивания для отображения строк в определенной последовательности и позволяет пользователю изменять последовательность, перетаскивая элементы в положение.
Создание списков перетаскивания
Списки перетаскивания имеют те же стили окон и обрабатывают те же сообщения, что и стандартные поля списка. Чтобы создать поле списка перетаскивания, сначала создайте стандартное поле списка, а затем вызовите функцию MakeDragList . Чтобы преобразовать поле списка в диалоговом окне в поле перетаскивания, можно вызвать MakeDragList при обработке сообщения WM_INITDIALOG.
Перетаскивание сообщений списка
Поле списка перетаскивания уведомляет родительское окно о событиях перетаскивания, отправив ему сообщение списка перетаскивания. Родительское окно должно обрабатывать сообщение списка перетаскивания.
Поле списка перетаскивания регистрирует это сообщение при вызове функции MakeDragList . Чтобы получить идентификатор сообщения (числовое значение) сообщения списка перетаскивания, вызовите функцию RegisterWindowMessage и укажите значение DRAGLISTMSGSTRING.
Параметр wParam сообщения списка перетаскивания — это идентификатор элемента управления для поля списка перетаскивания. Параметр lParam — это адрес структуры DRAGLISTINFO, которая содержит код уведомления для события перетаскивания и другие сведения. Возвращаемое значение сообщения зависит от уведомления.
Коды уведомлений списка перетаскивания
Код уведомления списка перетаскивания, который определяется элементом uNotification структуры DRAGLISTINFO, включенной в сообщение списка перетаскивания, может быть DL_BEGINDRAG, DL_DRAGGING, DL_CANCELDRAG или DL_DROPPED.
Код уведомления DL_BEGINDRAG отправляется, когда курсор находится на элементе списка, а пользователь нажимает левую кнопку мыши. Родительское окно может вернуть ЗНАЧЕНИЕ TRUE , чтобы начать операцию перетаскивания или FALSE , чтобы запретить перетаскивание. Таким образом, родительское окно может включить перетаскивание для некоторых элементов списка и отключить его для других. Вы можете определить, какой элемент списка находится в указанном расположении с помощью функции LBItemFromPt.
Если перетаскивание действует, DL_DRAGGING код уведомления отправляется при перемещении мыши или через регулярные интервалы, если мышь не перемещается. Родительское окно сначала должно определить элемент списка под курсором с помощью LBItemFromPt, а затем нарисовать значок вставки с помощью функции DrawInsert. Указав ЗНАЧЕНИЕ TRUE для параметра bAutoScroll для LBItemFromPt, можно вызвать прокрутку списка по одной строке, если курсор выше или ниже его клиентской области. Значение, возвращаемое для этого уведомления, указывает тип курсора мыши, который должен задать поле списка перетаскивания.
Код уведомления DL_CANCELDRAG отправляется, если пользователь отменяет операцию перетаскивания, нажав правую кнопку мыши или нажав клавишу ESC. Код уведомления DL_DROPPED отправляется, если пользователь завершает операцию перетаскивания, освобождая левую кнопку мыши, даже если курсор не находится над элементом списка. Поле списка перетаскивания освобождает запись мыши перед отправкой любого уведомления. Возвращаемое значение этих двух уведомлений игнорируется. Перетащите список