Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Элемент управления "Список" содержит простой список, из которого пользователь может выбрать один или несколько элементов. Поля списка обеспечивают ограниченную гибкость по сравнению с контролами представления списка.
Элементы списка могут быть представлены текстовыми строками, растровыми изображениями или обоими. Если поле списка недостаточно большое для отображения всех элементов списка одновременно, поле списка предоставляет полосу прокрутки. Пользователь прокручивает элементы списка и применяет или удаляет состояние выбора по мере необходимости. Выбор элемента списка изменяет внешний вид визуального элемента, как правило, путем изменения цвета текста и фона на те, которые указаны соответствующими метриками операционной системы. Когда пользователь выбирает или отменяет выбор элемента, система отправляет уведомление в родительское окно списка.
Для приложения ANSI система преобразует текст в поле списка в Юникод посредством кодовой страницы CP_ACP. Это может привести к проблемам. Например, акцентированные римские символы в не-Юникодном списке в Windows в японской версии будут отображаться некорректно. Чтобы устранить эту проблему, скомпилируйте приложение в формате Unicode или используйте рисованный пользователем список.
В этом разделе рассматриваются следующие разделы:
- Создание поля списка
- Типы и стили списков
- Функции элементов списка
- уведомления из списков
- сообщения в списки
- обработка сообщений окна по умолчанию
- Owner-Drawn Списковые элементы
- Поля списков для перетаскивания
Создание поля списка
Самый простой способ создать поле списка в диалоговом окне — перетащить его из панели элементов в Microsoft Visual Studio в ресурс диалогового окна. Чтобы динамически создать поле списка или создать поле списка в окне, отличном от диалогового окна, используйте функцию CreateWindowEx, указав класс окна WC_LISTBOX и соответствующие стили списков.
Типы и стили блоков списков
Существует два типа полей списка: одинарный выбор (по умолчанию) и множественный выбор. В списке с одним выделением пользователь может выбрать только один элемент за раз. В списке с несколькими выборами пользователь может выбрать несколько элементов одновременно. Чтобы создать поле с несколькими выборами, укажите LBS_MULTIPLESEL или стиль LBS_EXTENDEDSEL.
Внешний вид и работа поля списка управляются стилями поля списка и стилями окон. Эти стили указывают, сортируется ли список, упорядочивается в нескольких столбцах, рисуется приложением и т. д. Размеры и стили списка обычно определяются в шаблоне диалогового окна, который включается в ресурсы приложения.
Заметка
Чтобы использовать визуальные стили с этими элементами управления, приложение должно включать манифест и вызывать InitCommonControls в начале программы. Для получения информации о визуальных стилях см. Визуальные стили. См. раздел Включение визуальных стилейдля информации о манифестах.
Функции списка
Функция DlgDirList заменяет содержимое поля списка именами дисков, каталогов и файлов, которые соответствуют указанному набору критериев. Функция DlgDirSelectEx извлекает текущий выбор в поле списка, инициализированном с помощью DlgDirList. Эти функции позволяют пользователю выбрать диск, каталог или файл из поля списка без ввода расположения и имени файла.
Кроме того, функция getListBoxInfoвозвращает количество элементов для каждого столбца в указанном поле списка.
Уведомления сообщений из списков
Когда событие происходит в списке, список отправляет код уведомления в виде сообщения WM_COMMAND процедуре диалогового окна окна владельца. Коды уведомлений списка отправляются, когда пользователь выбирает, дважды щелкает или отменяет элемент поля списка; если поле списка получает или теряет фокус клавиатуры; и когда система не может выделить достаточно памяти для запроса списка. Сообщение WM_COMMAND содержит идентификатор поля списка в младшем слове параметра wParam и код уведомления в старшем слове. Параметр lParam содержит дескриптор окна управления.
Процедура диалогового окна не требуется для обработки этих сообщений; Процедура окна по умолчанию обрабатывает их.
Приложение должно отслеживать и обрабатывать следующие коды уведомлений списка.
Код уведомления | Описание |
---|---|
LBN_DBLCLK | Пользователь дважды щелкает элемент в списке. |
LBN_ERRSPACE | Поле списка не может выделить достаточно памяти для выполнения запроса. |
LBN_KILLFOCUS | Поле списка теряет фокус клавиатуры. |
LBN_SELCANCEL | Пользователь отменяет выбор элемента в списке. |
LBN_SELCHANGE | Выбор в списке будет изменен. |
LBN_SETFOCUS | Поле списка получает фокус клавиатуры. |
Сообщения в списки
Процедура диалогового окна может отправлять сообщения в список для добавления, удаления, проверки и изменения элементов списка. Например, процедура диалогового окна может отправить сообщение LB_ADDSTRING в поле списка, чтобы добавить элемент, и сообщение LB_GETSEL, чтобы определить, выбран ли элемент. Другие сообщения задают и извлекают сведения о размере, внешнем виде и поведении поля списка. Например, сообщение LB_SETHORIZONTALEXTENT задает ширину списка с прокруткой. Процедура диалогового окна может отправлять любое сообщение в поле списка с помощью функции SendMessage или SendDlgItemMessage.
Элемент поля списка часто обозначается своим индексом, целым числом, представляющим позицию элемента в поле списка. Индекс первого элемента в поле списка равен 0, индекс второго элемента равен 1 и т. д.
В следующей таблице описывается, как предопределенная процедура работы со списком отвечает на сообщения списка.
Сообщение | Ответ |
---|---|
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 для сообщения, предопределенная процедура окна проверяет сообщение и выполняет действия по умолчанию, как показано в следующей таблице.
Сообщение | Действие по умолчанию |
---|---|
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 для обработки по умолчанию.
Owner-Drawn списковые окна
Приложение может создать список с пользовательской прорисовкой, чтобы взять на себя ответственность за рисование элементов списка. Родительское окно или диалоговое окно владельца со списком, нарисованным в окне владельцем (его владелец ), получает сообщения 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.
Пример поля списка, нарисованного владельцем, см. в разделе Создание Owner-Drawn списка.
Перетаскивание списков
Поле списка перетаскивания — это специальный тип поля списка, который позволяет пользователю перетаскивать элементы из одной позиции в другую. Приложение может использовать поле списка перетаскивания для отображения строк в определенной последовательности и позволяет пользователю изменять последовательность, перетаскивая элементы в положение.
Создание списков перетаскивания
Списки с возможностью перетаскивания имеют те же стили окон и обрабатывают те же сообщения, что и стандартные поля списка. Чтобы создать поле списка перетаскивания, сначала создайте стандартное поле списка, а затем вызовите функцию 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 отправляется, если пользователь завершает операцию перетаскивания, выпуская левую кнопку мыши, даже если курсор не находится над элементом списка. Поле списка перетаскивания освобождает захват мыши перед отправкой одного из уведомлений. Возвращаемое значение этих двух уведомлений игнорируется. Перетащите список