На этом шаге мы рассмотрим списки.
Список - это элемент управления, содержащий набор пунктов, которые может выбрать пользователь. Если список содержит больше элементов, чем может быть отображено в окне, и установлен флаг wsf_Vscroll, то автоматически появится вертикальная полоса прокрутки. Пользователь может перемещаться по списку вверх и вниз для изменения текущего значения или дважды щелкнуть на выбранном элементе списка.
Существуют специальные виды списков, такие как раскрывающиеся списки и редактируемые списки. Установкой соответствующих флагов вы можете позволить множественный выбор в списке или создать многоколоночный список (создание нескольких колонок в списке реализовано не на всех платформах).
Списки обычно содержат строки, но, используя стиль wsf_OwnerDraw, можно создавать списки с произвольным типом данных.
В VPI есть несколько предикатов для работы со списками. Все они имеют префикс lbох_. Эти предикаты требуют идентификатор списка, который может быть получен вызовом предиката win_GetCtlHandle, дескриптор родительского окна и ресурсный идентификатор списка. Индекс 0 определяет первый элемент списка, 1 - второй и т. д. Значение индекса - 1 используется для добавления элемента в конец списка.
Предикаты для работы со списками:
lbox_Add(Window,integer Index,string Str)
Этот предикат добавляет новою строку в список и отображает ее, если она находится внутри списка. Новый элемент будет размещен в строке, следующей за строкой с индексом Index. Если Index равен -1, то строка будет добавлена в конец списка, а текущая строка останется выделенной.
lbox_Add(Window,integer Index,slist StringList)
Этот вариант lbox_Add добавляет все строки в список StringList в заданную позицию в существующем списке. Если Index равен -1, то строки будут добавлены в конец списка.
lbox_Add(Window,string Str)
Этот вариант должен применяться, если для списка установлен атрибут сортировки. Для списка с неустановленным атрибутом сортировки элементы будут добавляться в конец списка.
lbox_Add(Window,slist StringList)
Этот вариант должен применяться для добавления набора строк в список с установленным флагом сортировки. Если этот флаг не установлен, строки будут добавлены в конец списка.
lbox_Clear(Window)
При помощи этого предиката можно очистить окно списка и удалить все элементы.
lbox_Delete(Window,integer Index)
Этот предикат может быть использован для удаления конкретного элемента из списка. Если значение параметра Index равно 0, то будет удален первый элемент, если 1 - второй и т. д. Значение -1 будет проигнорировано.
Slist=lbox_GetAll(Window)
Возвращает все элементы списка в виде набора строк.
Integer=lbox_CountAll(Window)
Возвращает количество строк в списке.
lbox_GetItem(Window,integer Index)
Этот предикат может быть использован для получения конкретного элемента в списке. Если значение параметра Index равно 0, то будет возвращен первый элемент, если 1 - второй и т. д. Значение -1 будет проигнорировано.
lbox_GetSel(Window,Slist,Hist)
Этот предикат возвращает список выбранных строк и список их индексов в одном и том же порядке. Хотя этот предикат предназначен для множественного выбора из списка, он работает и для обычного списка с одним выбранным элементом. Если никакой элемент не выбран, то предикат возвратит два пустых списка.
Integer=lbox_GetSelIndex(Window)
Этот предикат возвращает индекс выбранного элемента. Предикат завершится неуспешно,если никакой элемент в списке не будет выбран.
lbox_SetSel(Window,integer Index,boolean Select)
Этот предикат используется для выбора или отмены выбора элемента в списке При возможности множественного выбора из списка этот предикат будет влиять только на один элемент. При одиночном выборе из списка выбор одного элемента автоматически будет отменять выбор других элементов в списке.
lbox_Suspend(Window) lbox_Resume(Window)
Эти два предиката могут использоваться для временного приостановления перерисовки экрана и затем продолжения перерисовки. Такой подход предупреждает эффект мерцания во время процесса перерисовки экрана. Например, при заполнении списка элементами из внешнего источника, включая ряд операций lbox_Add, более правильным будет в начале операции вызвать предикат lbox_Suspend, а в конце операции - предикат lbox_Resume.
lbox_SetColumnWidth(Window,integer width)
Этот предикат может быть использован для установки ширины колонок в многоколоночном списке. Изображенное на рис. 1 диалоговое окно Multicol было создано с использованием стиля многоколоночного списка. Для инициализации был добавлен такой код:
dlg_choose_your_favorite_language_eh(_Window,e_Create(_),0):-!, LB=win_getCtlHandle(_Window,idc_choose_your_favorite_language), lbox_setColumnWidth(LB,20), !.
Рис.1. Диалоговое окно Multicol
Предикат lbox_SetTabstops(WINDOW, ILIST TabList) вы можете использовать для создания списка с флагом wsf_UseTabstops, чтобы установить позиции табуляции определения "видимых колонок". Текстовая информация, представленная в каждой строке списка, - это один элемент. Заметьте, что это не противоречит многоколоночным спискам. Если списки имеют символы табуляции, то символы, следующие за ними, будут выровнены в соответствии с установленным списком позиций . Позиции табуляции даны в диалоговых базовых единицах.
Если шрифт диалогового окна пропорциональный, этот метод применяется для вытаскивания колонок, как показано на рис. 2.
Заметьте, что каждая строка остается одной сущностью.
Рис.2. Диалоговое окно со списком с выровненными колонками
В качестве примера вызова предиката показана инициализация позиций табуляции:
dlg_select_employee_eh(_Window,e_Create(_),0):-!, List=win_getCtlHandle(_Window,idc_select_employee_l), lbox_setTabstops(List,[17,18,19,20]), !.
Действительные значения позиций табуляции получены вычитанием значения диалоговых базовых единиц левой координаты окна списка из левой координаты каждого заголовка.
События уведомления от списков:
% При выборе элемента в списке ehandler(Window,e_Control(CtrlID,CtrlType,CtrlWindow,selchanged),0):- % При двойном щелчке в окне списка ehandler(Window,e_Control(CtrlID,CtrlType,CtrlWindow,activated),0):- % При получении списком фокуса ввода ehandler(Window,e_Control(CtrlID,CtrlType,CtrlWindow,getfocus),0):- % При потере списком фокуса ввода ehandler(Window, e_Control(CtrlID,CtrlType,CtrlWindow,losefocus),0):-
Предикат:
lbox_SetTopIndex(window Window,integer Index)
прокручивает окно списка так, чтобы элемент с индексом Index появился в верхней строке окна списка или была достигнута максимальная позиция полосы прокрутки Index - это номер позиции в списке, начиная с нуля.
На следующем шаге мы рассмотрим раскрывающиеся списки.