
- •Глава 8 Дочерние окна управления
- •Класс кнопок
- •Создание дочерних окон
- •Сообщения дочерних окон родительскому окну
- •Сообщения родительского окна дочерним окнам
- •Нажимаемые кнопки
- •Переключатели
- •Окна группы
- •Изменение текста кнопки
- •Видимые и доступные кнопки
- •Кнопки и фокус ввода
- •Дочерние окна управления и цвета
- •Системные цвета
- •Цвета кнопок
- •Сообщение wm_ctlcolorbtn
- •Кнопки, определяемые пользователем
- •Класс статических дочерних окон
- •Класс полос прокрутки
- •Программа colors1
- •Интерфейс клавиатуры, поддерживаемый автоматически
- •Введение новой оконной процедуры
- •Закрашивание фона
- •Окрашивание полос прокрутки и статического текста
- •Класс редактирования
- •Стили класса редактирования
- •Коды уведомления управляющих окон редактирования
- •Использование управляющих окон редактирования
- •Сообщения управляющему окну редактирования
- •Класс окна списка
- •Стили окна списка
- •Добавление строк в окно списка
- •Выбор и извлечение элементов списка
- •Получение сообщений от окон списка
- •Простое приложение, использующее окно списка
- •Список файлов
- •Использование атрибутов файлов
- •Упорядочивание списков файлов
- •Утилита Head для Windows
Добавление строк в окно списка
После того, как вы создали окно списка, следующим шагом должно стать добавление в список строк текста. Вы делаете это, используя функцию SendMessage для отправки сообщения окну списка. Ссылка на строки текста обычно осуществляется через индекс, который начинается с 0, что соответствует самому верхнему элементу списка. В приводимых далее примерах hwndList — это описатель дочернего окна управления, т. е. окна списка, а iIndex — это значение индекса. В тех случаях, когда вы с помощью вызова функции SendMessage передаете строку текста, параметр lParam является указателем на эту оканчивающуюся нулем строку.
В большинстве приводимых примеров функция SendMessage может вернуть значение LB_ERRSPACE (равное —2), если оконной процедуре не хватит памяти для сохранения содержимого списка. Если случится любая другая ошибка, то возвращаемым значением функции SendMessage будет LB_ERR (—1), а при ее нормальной работе — LB_OKAY (0). Вы можете проверять функцию SendMessage на 0, чтобы определить наличие каждой из этих двух ошибок.
Если вы используете стиль LBS_SORT (или, если вы располагаете строки в списке в том порядке, в котором вы хотите, чтобы они появлялись), то простейшим способом заполнить список будет использование сообщения LB_ADDSTRING:
SendMessage (hwndList, LB_ADDSTRING, 0, (LPARAM) szString);
Если вы не используете стиль LBS_SORT, то можете вставить строку в ваш список, задав индекс и используя сообщение LB_INSERTSTRING:
SendMessage(hwndList, LB_INSERTSTRING, iIndex, (LPARAM) szString);
Например, если iIndex равен 4, то szString становится новой, пятой строкой, начиная от вершины списка (поскольку счет начинается с 0) со значением индекса, равным 4. Все расположенные ниже строки сдвигаются вниз. При iIndex равном —1 строка становится последней строкой списка. Сообщение LB_INSERTSTRING можно использовать и со списком стиля LBS_SORT, но тогда содержимое списка не будет пересортировано. (Вы также можете вставить строку с помощью сообщения LB_DIR, о котором более подробно будет рассказано в конце главы.)
Удалить строку из списка можно с помощью сообщения LB_DELETESTRING, указав значение индекса:
SendMessage (hwndList, LB_DELETESTRING, iIndex, 0);
Полностью очистить список можно с помощью сообщения LB_RESETCONTENT:
SendMessage (hwndList, LB_RESETCONTENT, 0, 0);
Оконная процедура окна списка обновляет окно, если к списку добавляется или из списка удаляется элемент. Если вам известно число строк, которые необходимо добавить или удалить, то вам может понадобиться временно приостановить это обновление, сбросив флаг обновления окна:
SendMessage (hwndList, WM_SETREDRAW, FALSE, 0);
После окончания работы по изменению списка, вам следует восстановить флаг обновления окна:
SendMessage (hwndList, WM_SETREDRAW, TRUE, 0);
Окно списка, созданное со стилем LBS_NOREDRAW, открывается со сброшенным флагом обновления окна.
Выбор и извлечение элементов списка
Вызовы функции SendMessage, которые выполняются в представленных ниже задачах, обычно возвращают какое-то значение. Если имеет место ошибка, то это значение устанавливается в LB_ERR (определено как —1).
После того, как вы вставили в список несколько элементов, вы можете определить количество элементов в списке:
iCount = SendMessage (hwndList, LB_GETCOUNT, 0, 0);
Некоторые другие вызовы различаются для списков с единичной выборкой и для списков с множественной выборкой. Сначала рассмотрим список с единичной выборкой.
Обычно вы разрешаете пользователю выбирать из списка. Но если вы хотите выделить элемент, выбираемый по умолчанию, то можете использовать такой вызов:
SendMessage (hwndList, LB_SETCURSEL, iIndex, 0);
При установки в качестве iIndex значения —1, выборка для всех элементов отменяется.
Вы также можете выбирать элемент списка на основе его первых символов:
iIndex = SendMessage (hwndList, LB_SELECTSTRING, iIndex,
(LPARAM) szSearchString);
Величина iIndex, заданная в качестве параметра lParam функции SendMessage, является номером пункта, с которого начинается поиск пункта, начальные символы которого заданы в szSearchString. При значении iIndex равном —1, поиск начинается с начала списка. Возвращаемым значением функции SendMessage является индекс выбранного элемента или LB_ERR, если в списке нет элементов, с начальными символами из строки szSearchString.
Когда вы получаете от окна списка сообщение WM_COMMAND (или в любое другое время), с помощью сообщения LB_GETCURSEL вы можете определить индекс текущего выбранного элемента:
iIndex = SendMessage (hwndList, LB_GETCURSEL, 0, 0);
Если возвращаемое значение функции SendMessage равно LB_ERR, то это означает отсутствие выбранных элементов.
Вы можете определить длину строки любого элемента списка:
iLength = SendMessage (hwndList, LB_GETTEXTLEN, iIndex, 0);
Копировать выбранную строку в буфер можно следующим образом:
iLength = SendMessage (hwndList, LB_GETTEXT, iIndex,
(LPARAM) szBuffer);
В обоих случаях возвращаемое значение функции SendMessage, т. е. iLength, это длина строки. Массив szBuffer должен быть достаточно большим, чтобы вместить строку и завершающий NULL-символ. Для предварительного выделения памяти для хранения строки, можно использовать сообщение LB_GETTEXTLEN.
В списке с множественным выбором нельзя использовать сообщения LB_SETCURSEL, LB_GETCURSEL или LB_SELECTSTRING. Вместо них вы используете сообщение LB_SETSEL для установки состояния выборки конкретного элемента, при этом не оказывая влияния на другие элементы, которые могли бы быть выбраны:
SendMessage (hwndList, LB_SETSEL, wParam, iIndex);
Параметр wParam не равен 0 для выбора и выделения элемента списка и равен 0 для отмены выбора. Если параметр lParam равен —1, то все элементы списка либо выбираются, либо их выбор отменяется. Определить, выбран или нет конкретный элемент списка, можно с помощью вызова:
iSelect = SendMessage (hwndList, LB_GETSEL, iIndex, 0);
где iSelect не равно нулю, если пункт с номером iIndex выбран, и равно 0 — в противном случае.