Поделиться через


Сведения о полях списка

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

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

Для приложения ANSI система преобразует текст в поле списка в Юникод с помощью CP_ACP кодовой страницы. Это может привести к проблемам. Например, подчеркнутые римские символы в поле списка, отличном от Юникода в Windows, японская версия будет выходить наружу. Чтобы устранить эту проблему, скомпилируйте приложение в виде Юникода или используйте поле со списком, нарисованным владельцем.

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

Создание поля списка

Самый простой способ создать поле списка в диалоговом окне — перетащить его из панели элементов в 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 отправляется, если пользователь завершает операцию перетаскивания, освобождая левую кнопку мыши, даже если курсор не находится над элементом списка. Поле списка перетаскивания освобождает запись мыши перед отправкой любого уведомления. Возвращаемое значение этих двух уведомлений игнорируется. Перетащите список