Windows предусматривает ряд стандартных интерфейсных элементов, называемых управляющими элементами. Управляющие элементы это специальные окна с некоторым предопределенным поведением. ObjectWindows обеспечивает интерфейсные объекты для стандартных управляющих элементов Windows, так что вы можете использовать эти интерфейсные элементы в своих приложениях. Интерфейсные объекты для управляющих элементов называются объектами управляющих элементов или просто управляющими объектами.
    Примечание: Об интерфейсных объектах рассказывается в Главе 9.
    Кроме того, в данной главе подробно описывается использование каждого интерфейсного объекта для стандартных управляющих элементов Windows.
    Управляющие элементы - это специализированные окна, которые
позволяют пользователю предопределенным образом задавать или
выбирать данные. Чаще всего управляющие элементы содержатся в
диалоговом блоке. Диалоговый блок управляет их определением с
помощью ресурса диалогового блока, так что вам не потребуется часто
использовать в них объекты. Режимные диалоговые блоки не
располагают способами взаимодействия с управляющим объектом, поэтому в
диалоговых блоках объекты управляющих элементов используются
обычно для установки и считывания значений управляющих элементов
с помощью передачи. Передача для объектов управляющих элементов в
диалоговых блоках и в окнах выполняется одинаково (как
описывается ниже в этой главе).
    Примечание: Диалоговые блоки и их управляющие элементы
описываются в Главе 11 "Объекты диалоговых блоков".
    Возможно вы захотите использовать управляющие элементы в
окнах, поэтому в данной главе описывается использование управляющих
элементов вне диалоговых блоков. Следующая таблица описывает
управляющие элементы Windows, поддерживаемые типами объектов
ObjectWindows:
    Для Windows управляющие элементы - это просто
специализированные виды окон. В ObjectWindows тип TControl является потомком
типа TWindow, так что большинство объектов управляющих элементов
можно использовать как все другие оконные объекты. Объекты
управляющих элементов по способу их создания и уничтожения и способу
их поведения (как дочерние окна) аналогичны оконным объектам.
Однако они отличаются от других окон способом реакции на сообщения.
Например, методы Paint объектов управляющих элементов запрещены.
Windows берет на себя функции по отображению своих стандартных
управляющих элементов.
    Может оказаться, что перечисленные в приведенной выше
таблице управляющие элементы отвечают всем потребностям вашего
приложения. Однако могут возникать случаи, когда требуется определить
наследующие типы управляющих элементов. Например, вы можете
создать специализированный блок списка TFontListBox, производный от
TListBox, содержащий имена всех доступных вашему приложению
шрифтов и автоматически выводящих их при создании нового экземпляра
объекта.
    Тип TControl, как и TWindowsObject, является абстрактным
объектным типом. Вы можете создать экземпляры его потомков
TListBox, TButton и другие - но не можете создать экземпляр
TControl.
    Заметим, что вам, возможно, никогда не потребуется создавать
новый объектный тип, наследующий непосредственно из TControl.
TControl инкапсулирует свойства и стандартные управляющие
элементы, о которых уже знает Windows. Создание специализированных
управляющих элементов описывается в данной главе ниже.
    Обычно в объекта порождающего окна для каждого из дочерних
окон определяется поле данных. Независимо от того, какой вид
объектов вы используете, для каждого из них вы можете выполнить
несколько задач:
    Построение управляющих элементов отличается от построения
любых других дочерних окон. Обычно конструктор порождающего окна
вызывает конструкторы всех его дочерних окон. Однако в случае
управляющих элементов не просто создается связь "родитель -
потомок", но устанавливается также связь "окно - управляющий
элемент". Это очень важно, поскольку кроме обычных связей между
предком и потомком управляющие элементы взаимодействуют с
порождающими окнами особыми способами (через уведомления).
    Примечание: Уведомления описываются в Главе 16
"Сообщения Windows".
    Чтобы построить и инициализировать объект управляющего
элемента, нужно сделать следующее:
    В то время как обычный конструктор объекта дочернего окна
имеет только два параметра (порождающее окно и строку заголовка),
конструктор управляющего объекта имеет их не менее шести. Объект
блока списка имеет наиболее простой из всех управляющих элементов
конструктор, который требует задания только шести параметров:
    TListBox.Init описывается следующим образом:
    Все объекты управляющих элементов ObjectWindows (кроме
TMDIClient) требуют не менее 6 параметров. Большинство из них
воспринимают также параметр, задающий текст управляющего
элемента.
    Часто при построении управляющего элемента в окне желательно
сохранять указатель на управляющий элемент в поле оконного
объекта. Например, чтобы добавить в окно, определенное типом
TSampleWindow блок списка, вы можете задать в поле TSampleWindow
поле TheList и присвоить ему блок списка:
    Порождающие окна автоматически поддерживают список своих
дочерних окон, включая управляющие элементы. Однако удобнее
манипулировать управляющими объектами, когда имеются соответствующие
поля объекта. Управляющие элементы, с которыми часто работать не
требуется (такие как статический текст или групповые блоки) могут
не иметь соответствующих полей.
    При наличии поля объекта построение объекта управляющего
элемента не представляет труда. Например, чтобы добавить в
TSampleWindow групповой блок, нужно сделать следующее:
    Все управляющие объекты, кроме TMDIClient, получает от
вызова TControl.Init используемые по умолчанию стили ws_Child и
ws_Visible. Если вы хотите изменить стиль управляющего элемента,
то можно изменить поле Attr.Style (как это описывается для окон в
Главе 10). Каждый тип управляющего элемента имеет также другие
стили, определяющие его конкретные характеристики.
    Экранный элемент управляющего объекта автоматически
создается методом SetupWindow, наследуемым объектом порождающего окна.
Убедитесь, что при создании новых производных типов окон вы
вызываете наследуемый метод SetupWindow перед любой другой
инициализацией окна.
    При необходимости методом SetupWindow порождающего окна
также устанавливаются и заполняются управляющие элементы. Приведем
пример типичного метода SetupWindow:
    Заметим, что инициализация управляющего элемента, такая как
добавление строк в блок списка, должна выполняться в SetupWindow,
а не в конструкторе. Вызов такого метода как TListBox.AddString
приводит к передаче сообщений экранному управляющему элементу.
Так как экранный элемент до вызова наследуемого метода
SetupWindow не создается, попытки инициализации управляющих
элементов до этого момента завершится неудачно.
    Для вывода на экран управляющих элементов нет необходимости
вызывать метод Show. Как дочерние окна, они автоматически
выводятся на экран и повторно отображаются вместе с порождающим
окном. Однако, вы можете использовать Show для сокрытия или вывода
управляющих элементов по запросу.
    Порождающее окно отвечает за уничтожение управляющих
элементов. Экранный управляющий элемент автоматически уничтожается
вместе с элементом порожденного окна, когда пользователь
закрывает окно или приложение. Деструктор порождающего окна
автоматически уничтожает все дочерние объекты.
    Связь между оконным объектом и его управляющими объектами в
некотором смысле аналогичны взаимодействию между объектом
диалогового блока и его управляющими элементами. Как и диалоговому
блоку, окну требуется механизм для работы с его управляющими
элементами и для ответа на управляющие события, такие как выбор в
блоке списка.
    Диалоговые окна работают с их управляющими элементами путем
передачи им сообщений с помощью метода SendDlgItemMsg с
константой управляющего сообщения (такой как lb_AddString) в качестве
параметра (см. Главу 11). Объекты управляющих элементов сильно
упрощают этот процесс путем использования методов (таких как
TListBox.AddString) для непосредственной работы с управляющими
элементами на экране.
    Когда объекты управляющих элементов окна имеют
соответствующие поля объекта, то вызвать управляющие методы достаточно
просто:
    Реакция на взаимодействие с пользователем с помощью
управляющих элементов несколько более сложна, чем просто вызов методов
объектов управляющих элементов. Чтобы узнать, как отвечать на
сообщения управляющих элементов, см. раздел "Команды, уведомления и
идентификаторы управляющих элементов" в Главе 16.
    Диалоговый блок с управляющими элементами позволяет
пользователю с помощью клавиши Tab циклически перемещаться по всем
элементам диалогового блока. Он может также использовать клавиши
стрелок для выбора в групповом блоке кнопок с зависимой
фиксацией. Чтобы эмулировать этот клавиатурный интерфейс для окон с
управляющими элементами, вызовите для оконного объекта в его
конструкторе метод EnableKBHandler объекта TWindowsObject.
    Каждый вид управляющих элементов работает в чем-то отлично
от других. В данном разделе вы можете найти конкретную информацию
о том, как использовать объекты для каждого из стандартных
управляющих элементов Windows.
    Использование блока списка - это простейший способ запросить
пользователя программы Windows выбрать что-либо из списка. Блоки
списка инкапсулируются объектным типом TListBox. TListBox
определяет методы для создания блоков списка, модификации списка
элементов, запроса состояния списка элементов и поиска выбранного
пользователем элемента.
    Конструктор Init в TListBox воспринимает только шесть
параметров, которые необходимы всем объектам управляющих элементов.
Этими параметрами являются порождающее окно, идентификатор и
размеры управляющего элемента X, Y, W и H:
    TListBox получает используемый по умолчанию стиль
управляющего элемента ws_Child or ws_Visible, затем прибавляется
lbs_Standard. lbs_Standard - это комбинация lbs_Notify (для
получения уведомляющих сообщений), ws_VScroll (для получения
вертикально полосы прокрутки), lbs_Sort (для сортировки списка
элементов в алфавитном порядке) и ws_Border (для вывода рамки). Если вы
хотите получить другой стиль блока списка, то можете
модифицировать поле Attr.Style в TListBox. Например, для блока списка, не
сортирующего свои элементы, можно использовать следующее:
    После создания блока списка вам нужно заполнить его
элементами списка, который должны представлять собой строки. Позднее вы
можете добавить, вставить или удалить элементы, либо полностью
очистить список. Указанные действия вы можете выполнить с помощью
методов, приведенный в следующей таблице:
    Существует пять методов, которые вы можете вызвать для
получения информации о списке, содержащейся в объекте блока списка.
Эти методы перечислены в следующей таблице:
    Методы модификации и запроса блока списка позволяют вам
установить значения или определять в каждый конкретный момент
состояние блока списка. Однако, чтобы знать, что делает пользователь
в данный момент с блоком списка, вам нужно реагировать на
уведомляющие сообщения управляющего элемента.
    Пользователь может выполнять с блоком списка только
следующие действия: прокрутку списка, щелчок кнопкой "мыши" на элементе
списка, двойной щелчок кнопкой "мыши" на элементе. Когда
выполняется одно из этих действий, Windows посылает порождающему окну
блока списка уведомляющее сообщение блока списка. Обычно метод
реакции на уведомление для обработки сообщений для каждого
управляющего элемента порождающего объекта определяется в порождающем
оконном объекте.
    Каждое уведомляющее сообщение блока списка содержит в поле
lParamHi параметра Msg код уведомления (константу lbn_), который
специфицирует характер действия. Наиболее общие коды lbn
перечислены в следующей таблице:
    Приведем пример метода порождающего окна по обработке
сообщений блока списка:
    Пользователь делает выбор, если Msg.lParamHi совпадает с
константой lbn_SelChange. Если это так, то берется длина
выбранной строки, проверяется, что она помещается в строку из 10
символов, и выбранная строка показывается в блоке сообщения.
    Программа LBoxTest - это полная программа, которая создает
окно с блоком списка. После запуска приложения появляется
основное окно с блоком списка. Когда пользователь выбирает элемент
блока списка, появляется диалог с выбранным элементом. Обратите
внимание на взаимоотношения между объектом окна и объектом блока
списка. Блок списка - это не просто дочернее окно основного окна,
основное окно владеет им как полем объекта. LB1 - это одно из
полей объекта основного окна, и оно содержит объект блока списка.
Полный текст программы содержится в файле LBOXTEST.PAS на ваших
дистрибутивный дискетах.
    Статические управляющие элементы - это обычно неизменяемые
модули текста или простые изображения, которые могут появляться
на экране в окне или блоке диалога. Пользователь не
взаимодействует со статическими управляющими элементами, хотя программа и
может изменять их текст. Рис. 12.2 показывает множество стилей
статического управления и соответствующих констант стиля Windows.
    Пользователь никогда не взаимодействует непосредственно со
статическими управляющими элементами, поэтому приложение будет
очень редко, если вообще будет, принимать уведомляющие сообщения
управляющих элементов относительно статического управляющего
элемента. Следовательно, большинcтво статических управляющих
элементов можно сконструировать с идентификатором ресурса -1 или
некоторым другим неиспользуемым числом.
    Конструктор Init в TStatic конструирует новый объект
статического управления и описывается следующим образом:
    Кроме обычных параметров Init управляющего объекта,
TStatic.Init имеет два дополнительных параметра - текстовую
строку ATitle и максимальную длину текста ATextLen. Текст должен
заканчиваться нулевым символом, поэтому в действительности число
отображаемых символов на единицу меньше заданной в конструкторе
длины текста. Типичный вызов для построения статического
управляющего элемента может выглядеть так:
    После его создания обращаться к статическому управляющему
объекту или манипулировать им требуется редко, поэтому поле,
содержащее статический управляющий объект, в общем случае
присваивать не нужно.
    Используемым по умолчанию стилем статического управляющего
элемента является назначенный по умолчанию стиль управляющего
элемента, то есть ws_Child or ws_Visible (выравнивание влево).
Чтобы изменить стиль, модифицируйте поле Attr.Style. Например,
чтобы центрировать текст управляющего элемента, сделайте
следующее:
    В статическом управляющем элементе есть возможность
подчеркивания одного или нескольких символов в строке текста.
Реализация и действие этого эффекта аналогичны подчеркиванию первого
символа в выборе меню: Insert и & должны непосредственно
предшествовать символу в строке, который будет подчеркиваться.
Например, для подчеркивания T в слове 'Text' нужно в вызове Init
строку '&Text'. Если в строке вам нужно использовать &, применяйте
статический стиль Windows ss_NoPrefix (см. Рис. 12.2). Для
уточнения текущего текста, который хранится в статическом управляющем
элементе, используется метод GetText.
    Для изменения текста статического управляющего элемента
TStatic имеет два метода. SetText устанавливает статический
текст, передаваемый аргументом PChar. Clear удаляет статический
текст. Однако, вы не можете сменить текст статического
управляющего элемента, созданный со стилем ss_Simple.
    Чтобы считать текст, содержащийся в статическом управляющем
элементе, используйте метод GetText.
    Программа StatTest создает статическое тестовое приложение,
показанное на Рис.12.2. Обратите внимание на то, что метки
('Default Static' и 'ss_Simple') представляют собой
статистические управляющие элементы, также как и 'Sample Text', черные и
серые прямоугольники. Полный текст программы содержится в файле
STATTEST.PAS на ваших дистрибутивных дискетах.
    Управляющие элементы типа командных кнопок (которые иногда
называют "нажимаемыми" кнопками) выполняют некоторое действие при
"нажатии" такой кнопки. Есть два стиля командных кнопок, и оба
они имеют тип TButton. Эти два стиля - bs_PushButton и
DefPushButton. Используемые по умолчанию командные кнопки
аналогичны командным другим кнопкам, но имеют жирную рамку и обычно
используются для указания реакции пользователя по умолчанию. На
Рис. 12.3 показан пример программы Windows, в которой
используются обычные кнопки нажатия и командные кнопки по умолчанию.
    Кроме обычных 6 параметров, конструктор Init объекта TButton
воспринимает текстовую строку типа PChar, AText и флаг типа
Boolean IsDefaultButton, указывающий, должна ли кнопка быть
используемой по умолчанию или обычной командной кнопкой.
Конструктор Init объекта TButton описывается следующим образом:
    Типичный конструктор для обычной кнопки выглядит так:
    Когда пользователь щелкает на командной кнопке "мышью",
порождающее окно кнопки принимает уведомляющее сообщение. Если
объект порождающего окна перехватывает сообщение, он может
отреагировать на эти события выводом блока диалога, записью файла или
другим контролируемым программой действием.
    Для организации реакции на сообщения кнопок нужно определить
основанный на дочернем идентификаторе метод для обработки каждой
кнопки. Например, следующий метод IDBut1 обрабатывает реакцию на
"нажатие" пользователем кнопки. Единственный код уведомления,
определенный в Windows для командных кнопок - это bn_Clicked,
поэтому код уведомления не нужно проверять.
    Примечание: Пример использования командных кнопок
показывает программа BtnTest, которую вы можете найти на
дистрибутивных дисках.
    Тип TCheckBox наследует от TButton, а тип TRadioButton - от
TCheckBox. Кнопки с зависимой и независимой фиксацией мы будем
иногда кратко называть блоками выбора.
    Кнопки с независимой фиксацией обычно используются для
предоставления пользователю выбора одного из двух возможных
вариантов. Пользователь может установить или не установить управляющий
элемент, или оставить его так, как он установлен. Если имеется
группа кнопок с независимой фиксацией, то может устанавливаться
не одна кнопка, а несколько. Например, вы можете использовать
кнопку с независимой фиксацией для выбора трех шрифтов для их
загрузки в приложение.
    Кнопки с зависимой фиксацией используются для выбора одного
из нескольких взаимоисключающих вариантов. Например, кнопка с
зависимой фиксацией может использоваться для выбора шрифта для
конкретного символа. Когда пользователь щелкает "мышью" на кнопке
с зависимой фиксацией, это событие приводит к генерации сообщения
Windows. Как и в случае других управляющих элементов, порождающее
окно кнопки с независимой фиксацией обычно перехватывает эти
сообщения и выполняет по ним действия.
    Однако, вы можете для выполнения ими некоторых действий при
нажатии создать типы, производные от TCheckBox и TRadioButton.
Если ваш тип определяет метод для nf_First + bn_Clicked, то он
сначала должен вызывать метод реакции BNClicked, а уже затем
выполнять любые дополнительные действия.
    Кроме обычных 6 параметров, конструктор Init для кнопок с
зависимой и независимой фиксацией воспринимает текстовую строку и
указатель на объект группового блока (см. "Групповые блоки"),
который логически и визуально выделяет кнопки. AGroup - это
указатель на объект группового блока. Если AGroup имеет значение nil,
то блок выбора не является частью какой-либо логической группы.
Конструкторы описываются следующим образом:
    Для обоих видов блоков выбора синтаксис идентичен.
Конструкторы различаются только присваиваемым стилем, используемым по
умолчанию. Типичное использование конструкторов блока выбора
имеет вид:
    Кнопки с независимой фиксацией по умолчанию инициализируются
со стилем bs_AutoCheckBox, а кнопки с независимой фиксацией
имеют стиль bs_AutoRadioButton. В соответствии с этими стилями в
каждый момент времени может выбираться только одна клавиша выбора
в группе. Если одна выбрана, то другие автоматически остаются
невыбранными.
    Если вы переопределяете стили объектов кнопок с зависимой
или независимой фиксацией как "неавтоматические", то тогда уже вы
отвечаете за их выбор или не выбор в ответ на произведенные
пользователем нажатия.
    Модификация (выбор или отмена выбора) блоков выбора выглядит
задачей пользователя программы, а не вашей. Но в некоторых
случаях программе требуется явно управлять состоянием блоков выбора.
Одним из таких случаев является вывод на экран параметров,
которые были выбраны и сохранены ранее. Для модификации состояния
кнопки с независимой фиксацией TCheckBox определяет 4 метода:
    Когда вы используете данные методы с кнопками с зависимой
фиксацией, ObjectWindows обеспечивает выбор в группе только одной
кнопки с зависимой фиксацией.
    Опрос блока выбора - это один из способов выяснения его
состояния и организации реакции на него. Кнопки с зависимой и
независимой фиксацией имеют два состояния: выбранные и невыбранные.
Для получения состояния блока выбора используется метод GetCheck
типа TheckBox:
    Для определения состояния блока возвращаемое GetCheck
значение можно сравнить с заданными константами bf_Unchecked,
bf_Checked и bf_Grayed.
    Примечание: Использование кнопок обоих видов показано
в примере программы BtnTest на ваших дистрибутивных дисках.
    В своей простейшей форме блок группы представляет собой
статический прямоугольник с меткой, который обычно объединяет другие
управляющие элементы.
    Конструктор Init группового блока кроме обычных 6 параметров
воспринимает текстовую строку метки группы.
    Типичное использование конструктора группового блока может
быть следующим:
    Поскольку блок группы визуально связывает группу других
управляющих элементов, он может логически связывать группу блоков
выбора (кнопок с зависимой и независимой фиксацией). Логическая
группа автоматически отменяет выбор характеристик блоков выбора
"автоматического" стиля.
    Для добавления в группу, нужно при конструировании блока
выбора указать указатель на блок группы. Например, чтобы добавить в
окно группу кнопок с независимой фиксацией, в оконный объект и
его конструктор можно включить следующее:
    Заметим, что передаваемый блоку выбора параметр группы - это
указатель на объект блока группы, а не идентификатор группового
управляющего элемента (как в API Windows). Использование
указателя позволяет вам строить объекты перед созданием методом
SetupWindows порождающего окна экранных элементов.
    Когда происходит событие, которое может изменить выбор блока
группы (например, "нажатие" пользователем кнопки или вызов
программой метода Check), порождающее окно блока группы принимает
сообщение, основанное на дочернем идентификаторе. Порождающий
объект воспринимает сообщение, используя сумму id_First и
идентификатора группового блока. Это позволяет вам определить методы для
каждой группы вместо их задания для каждого блока выбора в
группе.
    Для определения управляющего элемента в группе, на который
было оказано воздействие, вы можете прочитать текущее состояние
каждого управляющего элемента.
    BtnTest - это полная программа, которая создает окно с
командной кнопкой, кнопками с зависимой и независимой фиксацией и
блоком группы управляющих элементов. После запуска приложения
появляется основное окно с управляющими элементами. Когда
пользователь "нажимает" на управляющий элемент, приложение реагирует на
это различными способами. См. Рис. 12.4.
    Примечание: Полный текст программы содержится в файле
BTNTEST.PAS на ваших дистрибутивных дискетах.
    Полосы прокрутки являются важнейшим механизмом изменения
обзора пользователем окна приложения, блока списка или
комбинированного блока. Однако, может возникнуть ситуация, когда нужна
отдельная полоса прокрутки для выполнения некоторой
специализированной задачи (например, управление температурой в программе
термостата или цветом в программе рисования). Когда нужна отдельная
специализированная полоса прокрутки, используются объекты
TScrollBar. Рис. 12.5 показывает типичное использование объекта
TSсrollBar.
    Кроме обычных 6 параметров управляющего объекта, конструктор
Init полосы прокрутки воспринимает флаг типа Boolean,
указывающий, является ли полоса прокрутки горизонтальной. Приведем
описание конструктора полосы прокрутки:
    Если вы зададите нулевую ширину вертикальной полосы
прокрутки, Windows присвоит ей стандартную ширину (аналогичную полосе
прокрутки блока списка). То же самое касается задания нулевой
высоты горизонтальной полосы прокрутки. Вызов:
создает горизонтальную полосу прокрутки стандартной высоты, как
это показано на Рис. 12.5. Init конструирует полосы прокрутки со
стилями ws_Child, ws_Visible и sbs_Horz или sbs_Vert для
горизонтальной или вертикальной полосы прокрутки соответственно.
Разнообразные полосы прокрутки показаны на Рис. 12.6.
    Один из атрибутов полосы прокрутки, инициализируемый при ее
конструировании, это диапазон. Диапазон полосы прокрутки - это
набор всевозможных положений указателя (маркера полосы
прокрутки). Маркер полосы прокрутки - это подвижный прямоугольник,
который пользователь может перемещать по ней. Каждой позиции
соответствует целое число. Порождающее окно использует эту целую
величину, позицию, для установки и запроса по полосе прокрутки.
После конструирования объекта полосы прокрутки его диапазон
устанавливается от 1 до 100.
    Положению маркера в "самой верхней" позиции (вершина
вертикальной полосы прокрутки или крайнее левое положение
горизонтальной полосы прокрутки) соответствует позиция 1. "Самой нижней"
позиции маркера соответствует позиция 100. Для установки иного
диапазона нужно использовать метод SetRange, описанный в разделе
"Модификация полосы прокрутки".
    Два других атрибута объекта полосы прокрутки - это его
приращение по строкам и страницам. Приращение по строкам,
установленное в 1, это расстояние в единицах диапазона, на которое
переместится указатель при нажатии пользователем стрелок на полосе
прокрутки. Приращение по страницам, установленное в 10, это
расстояние в единицах диапазона, на которое переместится указатель
при нажатии пользователем в области прокрутки. Эти значения можно
изменить непосредственной модификацией полей объекта TScrollBar,
LineSize и PageSize.
    TScrollBar определяет два метода опроса полосы прокрутки:
GetRange и GetPosition. Метод GetRange - это процедура,
использующая два целочисленных переменных аргумента. Процедура заносит в
эти целые значения верхнюю и нижнюю позиции из диапазона полосы
прокрутки. Этот метод очень удобен, когда нужно, чтобы ваша
программа переместила указатель в его верхнюю или нижнюю позицию.
    GetPosition - это функция, которая возвращает в виде целой
величины позицию указателя. Ваша программа очень часто будет
запрашивать диапазон и позицию и сравнивать их.
    Модификация полос прокрутки - это скорее работа для
пользователя вашей программы, и часто это действительно так. Однако,
ваша программа также может модифицировать полосу прокрутки.
Используемые для этого методы перечислены в следующей таблице.
    SetRange - это процедура, которая воспринимает два
целочисленных аргумента, наименьшую и наибольшую позицию диапазона. По
умолчанию новая полоса прокрутки имеет диапазон от 1 до 100. Вы
можете изменить этот диапазон для наилучшего расположения
управляющих элементов полос прокрутки. Например, полоса прокрутки в
приложении для термостата может иметь диапазон от 32 до 120
градусов Фаренгейта:
    SetPosition - это процедура, которая воспринимает один
целочисленый аргумент - позицию, в которую нужно переместить
указатель полосы прокрутки. В рассмотренном ранее приложении для
термостата, ваша программа может непосредственно установить
температуру 78 градусов:
    Третий метод DeltaPos передвигает позицию указателя полосы
прокрутки вверх (налево) или вниз (направо) на величину, заданную
целым аргументом. Положительная целая величина перемещает
указатель вниз (направо). Отрицательная целая величина перемещает его
вверх (налево). Например, для уменьшения температуры термостата
на 5 градусов используется:
    При работе пользователя с полосой прокрутки ее порождающее
окно получает от нее уведомляющие сообщения Windows. Если нужно,
чтобы ваше окно реагировало на сообщения прокрутки, реакция на
информационные сообщения должна быть обычной, путем определения
методов реакции, основанных на дочерних идентификаторах.
    Однако, уведомляющие сообщения полосы прокрутки несколько
отличаются от других уведомляющих сообщений элемента управления.
Они основаны на сообщениях Windows wm_HScroll и wm_VScroll, а не
wm_Command. Единственное отличие, на которое нужно обратить
внимание состоит в том, что уведомляющие коды полосы прокрутки
записаны в Msg.wParam, а не в Msg.lParamHi.
    Чаще всего встречаются коды sb_LineUp, sb_LineDown,
sb_PageUp, sb_PageDown, sb_ThumbPosition и sb_ThumbTrack.
Наиболее часто вы будете реагировать на каждое событие проверкой новой
позиции полосы прокрутки и организацией соответствующего
действия. В данном случае вы можете игнорировать уведомляющий код.
Например:
    Часто альтернатива состоит в том, чтобы не реагировать на
перемещение указателя до тех пор, пока пользователь не выберет
его нового местоположения. В этом случае нужно реагировать на
сообщение с кодом sb_ThumbTrack.
    Иногда может потребоваться, чтобы объекты полосы прокрутки
сами реагировали на уведомляющие сообщения полосы прокрутки. При
этом конкретная реакция поведения должна быть встроена в объект
полосы прокрутки. Для программирования объекта полосы прокрутки,
который непосредственно реагировал бы на его информационные
сообщения, нужно определить для его типа метод реакции, основанный на
информации. В качестве идентификатора заголовка метода нужно
использовать сумму nf_First и информационного кода полосы
прокрутки. Этот процесс описан в разделе "Уведомляющие сообщения
управляющих элементов" Главы 16.
    Программа SBarTest создает приложение для термостата,
показанное на Рис. 12.5. Полный текст программы содержится в файле
SBARTEST.PAS на ваших дистрибутивных дискетах.
    Управляющие элементы редактирования могут быть описаны, как
интерактивные статические управляющие элементы. Это прямоугольные
области (с рамкой или без) на экране, которые пользователь
приложения может заполнять текстом, изменять или удалять. Управляющий
элемент редактирования наиболее удобен в качестве поля для ввода
данных на экране. Они обеспечивают следующие операции:
    На Рис. 12.7 показано окно с двумя управляющими элементами
редактирования.
    Конструктор Init управляющего элемента редактирования
аналогичен конструктору статического управляющего элемента и
воспринимает 6 обычных параметров, плюс начальная текстовая строка,
максимальная длина строки и флаг Multiline типа Boolean. Конструктор
TEdit описывается следующим образом:
    По умолчанию управляющий элемент редактирования имеет стили
ws_Child, ws_Visible, es_TabStop, es_Left и es_AutoHScroll. Так
как управляющий элемент должен включать в себя завершающий
нулевой символ, параметр длины текста на самом деле на 1 превышает
максимальное число символов, допустимых в строке редактирования.
    Если Multiline имеет значение True, то управление
редактированием имеет стиль es_MultiLine, es_AutoVScroll, ws_VScroll и
ws_HScroll. Приведем типичные конструкторы управляющих элементов
редактирования (один для однострочного элемента, другой - для
многострочного):
    Вы можете передавать текст непосредственно между объектом
управляющего элемента редактирования и буфером вырезанного
изображения Windows, используя для этого вызовы методов. Часто вам
бывает нужно предоставить пользователю доступ к этим методам
через меню редактирования. Объект управляющего элемента
редактирования автоматически отреагирует на выбор из меню таких вариантов,
как Edit|Copy и Edit|Undo. TEdit определяет основанные на
командах методы (например, CMEditCopy и CMEditUndo), которые
вызываются в ответ на конкретный выбор (команду) меню в порождающем окне
управляющего элемента редактирования. CMEditCopy вызывает Copy, а
CMEditUndo вызывает Undo.
    Следующая таблица содержит список методов, которые
вызываются в ответ на выбор пункта меню:
    Чтобы добавить в окно меню редактирования, содержащее
управляющий элемент редактирования, определите для окна с помощью
команд, перечисленных в Таблице 12.7, ресурс меню. Никаких новых
методов вам писать не нужно.
    Имеется также один дополнительный метод в виде булевской
функции CanUndo, который определяет, можно ли отменить последнюю
операцию редактирования.
    Иногда нужно организовать опрос управляющих элементов
редактирования для проверки допустимости введенного текста, записи
ввода для его последующего использования или копирования ввода в
другой управляющий элемент. TEdit поддерживает несколько методов
опроса. Многие из опросов управляющих элементов редактирования и
методов модификации возвращают или требуют от вас указать номер
строки или позицию символа в строке. Все эти индексы начинаются с
нуля. Другими словами, первая строка - это нулевая строка, а
первый символ в любой строке это нулевой символ. Самыми важными
методами запроса являются GetText, GetLine, NumLines и LineLength.
    Вы можете заметить, что методы запросов TEdit, которые
возвращают текст из управляющего элемента редактирования, сохраняют
форматирование текста. Это важно только для многострочных
управляющих элементов редактирования, которые допускают появление
нескольких строк текста. В этом случае возвращаемый текст, который
занимает несколько строк в управляющем элемента редактирования
содержит в конце каждой строки два дополнительных символа:
возврат каретки (#13) и смена строки (#10). Если этот текст снова
помещается в управляющий элемент редактирования, вставляется из
буфера вырезанного изображения, записывается в файл или выводится
на принтер, то строки разбиваются так, как это было в управляющем
элемента редактирования.
    Следовательно, при использовании метода запроса для
получения определенного числа символов, нужно учитывать эти два
символа, которые заканчивают строку. GetText ищет текст в управляющем
элементе редактирования. Он заполняет строку, на которую
указывает переданный аргумент PChar, содержимым управляющего элемента
редактирования, включая перевод строки. Общее число символов
задается вторым параметром. Он возвращает значение False, если
управляющий элемент редактирования пуст, или содержит текста
больше, чем помещается в предоставленную строку. Следующая процедура
считывает из управляющего элемента редактирования строку и
выделенный текст:
    Для традиционной программы ввода текста вам может не
потребоваться непосредственно модифицировать управляющий элемент
редактирования. Пользователь модифицирует текст, а программа
считывает этот текст методом опроса. Однако, во многих других случаях
использование управляющего элемента редактирования требует, чтобы
ваше приложение явно заменяло, вставляло, удаляло и выбирало
текст. ObjectWindows обеспечивает подобное поведение и кроме того
предоставляет возможность использовать прокрутку управляющего
элемента редактирования.
    EditTest - это программа, которая помещает на экран основное
окно, которое будет порождающим для двух управляющих элементов
редактирования, двух статических управляющих элементов и кнопки.
Данное окно показано на Рис. 12.7.
    Когда пользователь щелкает на командной кнопке кнопкой
"мыши", текст из левого управляющего элемента редактирования (EC1)
копируется в правый управляющий элемент редактирования (EC2). В
EC2 текст преобразуется в буквы верхнего регистра, поскольку оно
было построено со стилем es_UpperCase. Если в C1 никакой текст не
выбран, то в EC2 копируется весь текст. Если в EC1 выбран
некоторый текст, то будет скопирован именно он. Меню редактирования
обеспечивает функции редактирования независимо от того, с каким
управляющим элементов редактирования идет работа. Полный файл
EDITTEST.PAS и файл ресурса EDITTEST содержатся на ваших
дистрибутивных дискетах.
    Управляющий элемент типа комбинированного блока является
сочетанием двух других управляющих элементов: блока списка и
управляющего элемента редактирования. Он служит тем же целям, что и
блок списка - позволяет пользователю выбрать один элемент списка
из прокручиваемого списка элементов текста, нажимая на кнопку
"мыши". Управление редактированием, вынесенное в верхнюю часть
блока списка предоставляет иной механизм выбора, позволяя
пользователю ввести текст нужного элемента. Если отображается область
списка комбинированного блока, то автоматически выбирается нужный
элемент. Тип TComboBox является производным от типа TListBox и
наследует его методы модификации, опроса и выбора элементов
списка. Кроме того, TComboBox предоставляет методы по манипулированию
списком, находящемся в комбинированном блоке, который в некоторых
случаях может раскрываться по запросу.
    Имеются три типа комбинированных блоков: простые,
раскрывающиеся и раскрывающиеся со списком. На Рис. 12.8 показан вывод
трех типов комбинированных блоков с блоком списка.
    С точки зрения пользователя между различными стилями
комбинированных блоков существуют следующие различия:
    Раскрывающиеся комбинированные блоки списка удобно
использовать тогда, когда не допускаются никакие другие варианты, кроме
перечисленных в области списка. Например, при выборе принтера для
печати можно выбрать только принтер, к которому есть доступ в
вашей системе.
    С другой стороны, раскрывающиеся комбинированные блоки могут
воспринимать выбор, который отличается от приведенных в списке
элементов. Раскрывающийся комбинированный блок можно использовать
для выбора файлов на диске при их открытии или записи.
Пользователь может либо просматривать каталоги в поисках нужного файла,
либо ввести полный маршрут и имя файла в области редактирования,
независимо от того, присутствует ли это имя файла в области
списка.
    Кроме обычных 6 параметров объектов управляющих элементов
конструктор Init для TComboBox воспринимает в качестве аргументов
стиль и максимальную длину текста. Конструктор TComboBox
описывается следующим образом:
    Все комбинированные блоки, построенные с помощью Init,
имеют стили ws_Child, ws_Visible, cbs_AutoHScroll, cbs_Sort
(отсортированный список), и VScroll (вертикальная полоса прокрутки).
Параметр стиля - это один из стандартных стилей комбинированных
блоков Windows: cbs_Simple, cbs_DropDown или cbs_DropDownList.
Параметр длины текста работает подобно соответствующему параметру
управляющего элемента редактирования, ограничивая число символов,
которые можно ввести в область редактирования комбинированного
блока.
    Следующие строки приведут к созданию спускающегося
комбинированного блока списка с неотсортированным списком:
    TComboBox определяет два метода для демонстрации и сокрытия
области списка в раскрывающихся комбинированных блоках и
раскрывающихся комбинированных блоках списка: ShowList и HideList. Обе
эти процедуры не нуждаются в аргументах. Вызывать эти методы для
демонстрации или сокрытия списка, когда пользователь нажимает
стрелку вниз справа от области редактирования, не нужно. В этом
случае работает автоматический механизм комбинированных блоков.
Эти методы полезны только для принудительного вывода или сокрытия
списка.
    Программа CBoxTest реализует приложение, показанное на Рис.
12.8. В нем использованы все три типа комбинированных блоков. CB1
- это простой комбинированный блок, CB2 это раскрывающийся
комбинированный блок, а CB3 - это раскрывающийся комбинированный блок
списка. Нажатие кнопок Show и Hide выполняет принудительный вывод
и сокрытие правого верхнего комбинированного блока, CB3, путем
вызова методов ShowList и HideList.
    Примечание: Полный текст файла CBOXTEST.PAS содержится
на ваших дистрибутивных дискетах.
    Для управления сложными блоками диалога или окнами с
множеством дочерних окон управляющих элементов вы обычно можете для
хранения и выяснения состояния его управляющих элементов создать
производный тип объекта. Состояние управляющего элемента включает
в себя текст управляющего элемента редактирования, положение
полосы прокрутки и установку кнопки с зависимой фиксацией.
    В качестве альтернативы вы можете не определять производный
объект, а определить соответствующую запись, представляющую
состояние управляющих элементов окна или диалога. Эта запись
называется буфером передачи, поскольку легко передает информацию о
состоянии между буфером и набором управляющих элементов.
    Например, ваша программа может иметь режимный блок диалога
и после его закрытия, выделить информацию из буфера передачи
относительно состояния каждого из его управляющих элементов.
Следовательно, при повторном вызове пользователем блока диалога, его
управляющие элементы будут выведены в соответствии с их
состоянием перед последним закрытием диалога. Кроме того, вы можете
установить начальное состояние каждого из управляющих элементов и на
основании данных буфера передачи. Вы можете явно передавать
данные в любом направлении в любой момент времени, например,
установить значения управлений равными их предыдущим значениям. Окно
или безрежимный блок диалога с управляющими элементами также
могут использовать механизм передачи для установки или выяснения
информации о состоянии в любой момент времени.
    Механизм передачи требует для представления управляющих
элементов, для которых вы будете передавать данные, использования
объектов ObjectWindows. Это означает, что вы должны использовать
InitResource для связывания объектов с управляющими элементами в
блоках и окнах диалога.
    Примечания: Связь управляющих элементов с управляющими
объектами описывается в Главе 11 "Объекты диалоговых
блоков".
    Чтобы использовать механизм передачи, вы можете сделать
следующее:
    Буфер передачи - это запись с одним полем для каждого
управляющего элемента, участвующего в передаче. Окно или диалог могут
также иметь управляющие элементы, значения которых не
устанавливаются механизмом передачи. Например, командные кнопки, у которых
нет состояния, не участвуют в передаче. Это же справедливо для
групповых блоков.
    Для определения буфера передачи нужно определить поле для
каждого участвующего управляющего элемента диалога или окна.
Определять поля для каждого управления диалога или окна не
требуется - нужно лишь определить поля для тех из них, которые будут
получать и принимать значения по вашему желанию. Этот буфер
передачи хранит один из каждых типов управляющих элементов, кроме
командной кнопки и блока группы:
    В каждом типе управляющего элемента хранится различная
информация. Буфер передачи для каждого стандартного управляющего
элемента поясняется в следующей таблице:
    Тип TScrollBarTransferRec имеет вид:
    Окно или диалоговый блок, которые используют буфер передачи,
должны создавать объекты участвующих управляющих элементов в той
последовательности, в которой определяются их соответствующие
поля буфера передачи. Для подключения механизма передачи к объекту
окна или диалога нужно просто установить значение его поля
TransferBuffer в указатель на определенный вами буфер передачи.
    Для случая окон с управляющими элементами объекты
управляющих элементов конструируются с использованием Init. Для диалогов
и окон диалогов нужно использовать конструктор InitResource.
Например (используется определенный ранее тип TSampleRecord):
    Для управляющих элементов, построенных с помощью
InitResource, механизм передачи разрешается автоматически.
    Для случая окна с управляющими элементами используйте для
конструирования объектов управления в надлежащей
последовательности Init, а не InitResource. Другое отличие между диалогами и
окнами состоит в том, что механизм передачи по умолчанию для
управляющих элементов окна запрещен. Для разрешения использования
механизма вызывается EnableTransfer:
    Чтобы явно исключить управляющий элемент из механизма
передачи, вызовите после его создания метод DisableTransfer.
    В большинстве случаев передача данных в окно выполняется
автоматически, но в любой момент вы можете явно передать данные.
    После создания окна или диалогового блока данные
автоматически. Для создания экранного элемента, представляющего оконный
объект, конструктор вызывает SetupWindow. Затем для загрузки
данных из буфера передачи вызывается TransferData. Окно SetupWindow
интерактивно вызывает SetupWindow для каждого из дочерних окон,
так что дочерние окна имеют возможность передать свои данные.
Поскольку порождающее окно устанавливает свои дочерние окна в
порядке их построения, данные в буфере передачи должны следовать в
том же порядке.
    Если объект управляющего элемента был построен с помощью
InitResource или если порождающее окно явным образом разрешило
межанизм передачи путем вызова для управляющего элемента
EnableTransfer, то методы управляющего объекта SetupWindow
вызывают TransferData.
    Когда режимное диалоговое окно получает командной сообщение
с идентификатором управляющего элемента id_OK, оно автоматически
передает данные из управляющего элемента в буфер передачи. Обычно
это сообщение указывает, что пользователь для завершения диалога
щелкнул "мышью" на кнопке OK, так что диалог автоматически
обновляет свой буфер передачи. Затем, если вы снова выполняете диалог,
диалоговый блок передает текущие данные в управляющие элементы.
    Однако, вы можете явно передавать данные в любом направлении
в любой момент времени. Например, вы можете передать данные из
управляющих элементов окна или безрежимного диалога. Вы также
можете сбросить состояния управляющих элементов, используя данные
буфера передачи, в ответ на щелчок "мышью" на кнопке Reset
(сброс). В обоих случаях используется метод TransferData.
Константа tf_SetData обозначает передачу данных из буфера в
управляющий элемент, а константа tf_GetData - передачу в другом
направлении. Например, вы можете вызвать TransferData в методе Destroy
объекта окна:
    Вы можете изменить способ передачи данных для конкретного
управляющего элемента или включить новый управляющий элемент,
определенный вами в механизме передачи. В обоих случаях вам просто
нужно написать метод Transfer для вашего управляющего объекта,
который если установлен флаг tf_GetData копирует данные из
управляющего элемента в место, задаваемое указателем. Если установлен
флаг tf_SetData, то просто скопируйте данные по заданному
указателю в управляющий элемент. Рассмотрим в качестве примера
TStatic.Transfer:
    Метод Transfer должен всегда возвращать число переданных
байт информации.
    Основное окно программы TranTest воспроизводит режимный
диалог с полями, в которые пользователь вводит данные об имени и
адресе. Буфер передачи используется для хранения этой информации и
отображения ее в управляющих элементах диалога при повторном его
выполнении. Обратите внимание на то, что нам не нужно определять
новый тип объекта диалога для установки и поиска данных диалога.
Также обратите ваше внимание на то, что мы непосредственно
манипулируем данными буфера передачи, поэтому статическое управление
при первом выводе диалога гласит "First Mailing Label" (первая
почтовая этикетка), а при всех остальных появлениях "Subsequent
Mailing Label" (следующая почтовая этикетка).
    Примечание: Полный текст программы содержится в файле
TRANTEST.PAS на ваших дистрибутивных дискетах.
    Windows обеспечивает механизм, позволяющий вам создавать
свои собственные виды управляющих элементов, а ObjectWindows
облегчает создание объектов, использующих преимущества управляющих
элементов. В данном разделе обсуждается использование
специализированных управляющих элементов Borland, которые придают
своеобразный вид работающим в Windows приложениям Borland, а затем
описывается, как создавать свои собственные уникальные управляющие
элементы.
    Специализированные управляющие элементы Borland для Windows
(BWCC) обеспечивают выразительный внешний вид приложений Borland
для Windows. Основными средствами BWCC являются:
    ObjectWindows дает вам возможность простого доступа к BWCC,
так что вы можете придать своим приложениями стандартный для
Borland вид.
    ObjectWindows позволяет легко добавлять BWCC в ваши
приложения Windows. Нужно просто добавить модуль BWCC в оператор uses
программы:
    Использование BWCC автоматически позволяет вам делать
следующее:
    Например, с помощью пакета разработчика ресурсов Resource
WorkShop вы можете создать ресурсы диалоговых блоков,
использующие специализированные управляющие элементы Borland. Включение в
оператор uses программы модуля BWCC обеспечивает для вашей
программы информацию о том, где искать динамически компонуемую
библиотеку (BWCC.DLL), содержащую код, который обеспечивает работу
BWCC.
    Кроме того, после добавления модуля BWCC любые создаваемые в
программе объекты управляющих элементов будут иметь вид и
характеристики управляющих элементов Borland.
    BWCC добавляет к стандартным управляющим элементам в стиле
Windows некоторые новые стили, но подчиняется также новым
соглашения и предположениям. Если вы создаете все свои новые
управляющие элементы из ресурсов, то беспокоиться об этом вам не нужно.
Однако при построении управляющих элементов в программном коде
вам может потребоваться использовать некоторые новые стили и
следовать соглашениям.
Где можно использовать объекты управляющих элементов?
Управляющий элемент Тип объекта Использование блок списка TListBox Прокручиваемый список элементов, из которых можно сделать выбор. полоса прокрутки TScrollBar Полоса прокрутки, аналогичная тем, которые выводятся в прокручиваемых окнах и блоках списка. "нажимаемая" кнопка TButton Кнопка для "нажатия" со связанным с ней текстом. кнопка с независимой фиксацией TCheckBox Состоящая из блока кнопка, которая может выбираться или нет, со связанным текстом. кнопка с зависимой фиксацией TRadioButton Кнопка, которая может выбираться или нет. Обычно используется во взаимоисключающих группах. блок группы TGroupBox Статический прямоугольник с текстом в левом верхнем углу. управляющий элемент редактирования TEdit Поле для ввода текста пользователем. статический управляющий элемент TStatic Фрагмент отображаемого текста который не может быть изменен пользователем. Комбинированный блок TComboBox Комбинация блока списка и управляющего элемента редактирования.
Рис. 12.1 Стандартные управляющие элементы Windows.Что такое объекты управляющих элементов?
Построение и уничтожение объектов управляющих элементов
Построение объекта управляющего элемента
Вызов конструкторов объектов управляющих элементов
constructor TListBox.Init(AParent: PWindowsObject;
AnID: Integer; X, Y, W, H: Integer);
Присваивание полям объекта
constructor SampleWindow.Init(AParent: PWindowsObject;
ATitle: PChar);
begin
inherited Init(AParent, ATitle);
TheList := New(PListBox,
Init(@Self, id_LB1, 20, 20, 100, 80));
end;
constructor SampleWindow.Init(AParent: PWindowsObject;
ATitle: PChar);
begin
inherited Init(AParent, ATitle);
TempGroupBox := New(PListBox,
Init(@Self, id_LB1, 'Group name',
140, 20, 100, 80));
end;
Изменение атрибутов объекта управляющего элемента
Инициализация управляющего элемента
procedure TSampleWindows.SetupWindow;
begin
inherited SetupWindow; { создает дочерние управляющие элементы }
{ добавляет элементы в список }
TheList^.AddString('Элемент 1');
TheList^.AddString('Элемент 2');
end;
Сохранение управляющих элементов
Уничтожение управляющих элементов
Связь с управляющими элементами
Работа с управляющими элементами окна
TheListBox^.AddString('Scotts Valley');
Реакция на управляющие элементы
Действие, аналогичное диалоговому блоку
Использование конкретных управляющих элементов
Использование блока списка
Построение объектов блока списка
LB1 := New(PListBox, Init(@Self, id_LB1, 20, 20, 340, 100));
LB1 := New(PListBox, Init(@Self, id_LB1, 20, 20, 340, 100));
LB1^.Attr.Style := LB1^.Attr.Style and not lbs_Sort;
Модификация блоков списка
Выполняемое действие Метод Добавление элемента AddString Вставка нового элемента InsertString Добавление элемента InsertString Удаление элемента DeleteString Удаление каждого элемента ClearList Выбор элемента SetSellIndex или SetSelString Запрос в блоках списка
Получаемая информация Вызываемый метод Число элементов в списке GetCount Элемент с конкретным индексом GetString Длина конкретного элемента GetStringLen Выбранный элемент GetSelString Индекс выбранного элемента SEgSelIndex Реакция на блок списка
wParam Действие lbn_SelChange Отдельным нажатием кнопки "мыши" был выбран элемент. lbn_DblClk Элемент был выбран двойным щелчком кнопки "мыши". lbn_SetFocus Пользователь переместил фокус на блок списка простым или двойным нажатием кнопки "мыши", либо клавишей Tab. Предшествует lbn_SelChange.
procedure TLBoxWindow.HandleLB1Msg(var Msg: TMessage);
var
Idx: Integer;
ItemText: string[10]
begin
if Msg.lParamHi=lbn_SelChange then
begin
Idx:=LB1^.GetSelIndex;
if LB1^.GetStringLenIdx)<11 then
begin
LB1^.GetSelString(@ItemText, 10);
MessageBox(HWindow, @ItemText, 'Вы выбрали:', mb_OK);
end;
end;
else DefWndProc(Msg);
end;
Пример программы: LBoxTest
Использование статических управляющих элементов
Рис. 12.2 Стили статических управляющих элементов.Построение статических управляющих элементов
constructor TStatic.Init(AParent: PWindowsObject;
AnID: Integer; ATitle: PChar;
X, Y, W, H: Integer; ATextLen: Word);
Stat1 := New(Static, Init(@Self, id_ST1, '&Text', 20, 50,
200, 24, 6));
Stat1^.Attr.Style := Stat1^.Attr.Style and (not ss_Left) or
ss_Center;
Пример программы StatTest
Использование командных кнопок
Рис. 12.3 Программа Windows, использующая командные кнопки.Построение командных кнопок
constructor TButton.Init(AParent: PWindowsObject;
AnID: Integer; AText: PChar;
X, Y, W, H: Integer; IsDefault: Boolean);
Push1 := New(PButton, Init(@Self, id_Push1, 'Test Button',
38, 48, 316, 24, False));
Реакция на командные кнопки
type
TTestWindow = object(TWindow)
But1: PButton;
procedure IDBut1(var Msg: TMessage);
virtual id_First + idBut1;
.
.
.
end;
procedure TestWindow.IDBut1(var Msg: TMessage);
begin
MessageBox(HWindow, 'Clicked', 'The Button was:' mb_OK)
end;
Использование блоков выбора
Построение кнопок с зависимой и независимой фиксацией
constructor Init(AParent: PWindowsObject; AnID: Integer;
ATitle: PChar; X, Y, W, H: Integer;
AGroup: PGroupBox);
GroupBox1 := New(PGroupBox, Init(@Self, id_GB1,
'A Group Box', 38, 102, 176, 108));
ChBox1 := New(PCheckBox, Init(@Self, id_Check1,
'Check Box Text', 235, 12, 150, 26, GroupBox1));
Модификация блоков выбора
Выполняемое действие Вызов метода Выбор кнопки Check или SetCheck(bf_Chacked) Отмена выбора кнопки Uncheck или SetCheck(bf_Unchecked) Переключение кнопки Toggle Опрос блоков выбора
MyState:=Check1^.GetCheck;
Использование групповых блоков
Построение групповых блоков
constructor TGroupBoxInit(AParent: PWindowsObject;
AnID: Integer;
AText: PChar; X, Y, W, H: Integer);
GroupBox1 := New(PGroupBox, Init(@Self, id_GB1, 'A Group Box',
38, 102, 176, 108));
Группирование управляющих элементов
type
TSomeWindow = object(TWindow)
Group: PGroupBox;
FirstCheck, SecondCheck: PCheckBox:
constructor Init(AParent: PWindowsObject,
ATitle: PChar);
end;
constructor TSomeWindow.Init(AParent: PWindowsObject;
ATitle: PChar);
begin
inherited Init(AParent, ATitle);
Group := New(PCheckBox, Init(@Self, id_TheGroup,
'Various boxes', 10, 01, 100, 50));
FirstCheck := New(PCheckBox, Init(@Self, id_FirstCheck,
'One', 15, 20, 90, 10, Group));
SecondCheck := New(PCheckBox, Init(@Self, id_SecondCheck,
'Two', 15, 20, 90, 10, Group));
end;
Реакция на групповые блоки
Пример программы: BtnTest
Рис. 12.4 Окно с различными видами кнопок.
Использование полос прокрутки
Рис. 12.5 Объект полосы прокрутки.Построение полос прокрутки
constructor TScrollBarInit(AParent: PWindowsObject;
AnID: Integer; X, Y, W, H: Integer;
IsHScrollBar: Boolean);
ThermScroll := New(PScrollBar, Init(@Self, id_ThermScroll,
20, 170, 340, 0, True));
Рис. 12.6 Окно с разнообразными полосами прокрутки.Управление диапазоном полосы прокрутки
Управление параметрами полосы прокрутки
Опрос полосы прокрутки
Модификация полос прокрутки
Выполняемое действие Вызываемый метод Задание диапазона прокрутки SetRange Установка позиции маркера SetPosition Перемещение позиции маркера DeltaPos
ThermScroll^.SetRange(32, 120);
ThermScroll^.SetPosition(78);
ThermScroll^.DeltaPos(-5);
Реакция на полосы прокрутки
procedure TestWindow.HandleThermScrollMsg(var Msg:
TMessage);
var
NewPos: Integer;
begin
NewPos:=ThermScroll^.GetPosition;
{ обработка с помощью NewPos }
end;
procedure TestWindow.HandleThermScrollMsg(var Msg:
TMessage);
var
NewPos: Integer;
begin
if Msg.wParam <> sb_ThumbTrack
then begin
NewPos:=ThermScroll^.GetPosition;
{ некоторая обработка на основе NewPos. }
end;
end;
Пример программы: SBarTest
Использование управляющих элементов редактирования
Рис. 12.7 Окно с управляющими элементами редактирования.Построение управляющих элементов редактирования
constructor TEdit.Init(AParent: PWindowsObject;
AnID: Integer; ATitle: PChar;
X, Y, W, H, ATextLen: Integer; Multiline: Boolean);
EC1 := New(PEdit, Init(@Self, id_EC1, 'Default Text', 20, 50,
150, 30, 40, False));
EC2 := New(PEdit, Init(@Self, id_EC2, '', 20, 20, 200, 150,
40, True));
Использование буфера вырезанного изображения и меню Edit
Операция Метод TEdt Команда меню Копирование текста в буфер вырезанного изображения. Cut cm_EditCut Вырезание текста в буфер вырезанного изображения. Copy cm_EditCopy Вставка текста из буфера вырезанного изображения. Paste cm_EditPaste Очистка всего элемента редактирования. Clear cm_EditClear Удаление выделенного текста. DeleteSelection cm_EditDelete Отмена последнего редактирования. Undo cm_EditUndo Опрос управляющих элементов редактирования
Выполняемое действие Вызываемый метод Определение изменения текста IsModified Считывание всего текста GetText Считывание строки GetLine Получение числа строк GetNumLines Получение длины данной строки GetLineLength Получение индекса выделенного текста GetSelection Получение диапазона символов GetSubText Подсчет символов перед строкой LineIndex Поиск строки, содержащей индекс GetLineFromProc
procedure TTestWindow.ReturnText(RetText: PChar);
var TheText: array[0..20] of Char;
begin
if EC1^.GetText(@TheText, 20) then
RetText:=@TheText
else RetText:=nil;
end;
procedure TTestWindow.ReturnText(RetText: PChar);
var TheText: array[0..20] of Char;
begin
RetText:=nil;
with EC^ do
if NumLines >= LineNum then
if LineLength(LineNum) < 11 then
if GetLine(@TheText, 20, LineNum) then
RetText := @TheText;
end;
procedure TestWindow.ReturnLineText(RetText: PChar;
LineNum: Integer);
var
TheText: array[0..20] of Char;
begin
with EC1^ do
begin
GetSelection(SelStart, SelEnd);
GetSubText(TheText, SelStart, SelEnd);
end;
RetText := TheText;
end;
Модификация управляющих элементов редактирования
Выполняемое действие Вызываемый метод Удаление всего текста Clear Удаление выделенного текста DeleteSelection Удаление диапазона символов DeleteSubText Удаление строки текста DeleteLine Вставка текста Insert Вставка текста из буфера вырезанного изображения Paste Замена всего текста SetText Выделение диапазона текста SelectRange Прокрутка текста Scroll Пример программы: EditTest
Использование комбинированных блоков
Три типа комбинированных блоков
Рис. 12.8 Три типа комбинированных блоков и блок списка.
Стиль Возможность скрытого списка Соответствие текста списку Простой нет нет Раскрывающийся есть нет Раскрывающийся со списком есть да
Простой комбинированный блок не может делать область
списка скрытой. Его область редактирования ведет себя
аналогично управляющему элементу редактирования. Пользователь
может вводить и редактировать текст, и текст не обязан
совпадать ни с одним из элементов в списке. При совпадении
выбирается соответствующий элемент списка.
Раскрывающиеся комбинированные блоки ведут себя аналогично
простым комбинированным блокам, но с одним исключением. В
начальной стадии работы их область списка не отображается.
Она появляется, когда пользователь нажимает стрелку вниз,
расположенную справа от области редактирования.
Раскрывающиеся комбинированные блоки и раскрывающиеся
комбинированные блоки списков очень удобны, когда нужно поместить
большое число управляющих элементов в маленькую область.
Когда они не используются, то занимают значительно меньшую
площадь, чем простой комбинированный блок или блок списка.
Область списка в раскрывающемся комбинированном блоке
списка ведет себя подобно области списка в спускающемся
комбинированном блоке - появляется при необходимости и
исчезает, когда не нужна. Эти два типа комбинированных
блоков отличаются поведением их областей редактирования.
Раскрывающиеся области редактирования ведут себя подобно
обычным управляющим элементам редактирования.
Раскрывающиеся области редактирования списка ограничиваются только
отображением одного элемента списка. Если редактируемый
текст соответcтвует элементу списка, то никаких
дополнительных символов ввести нельзя.
Выбор типа комбинированного блока
Построение комбинированных блоков
constructor TComboBox.Init(AParent: PWindowsObject;
AnID: Integer: X, Y, W, H: Integer;
AStyle, ATextLen: Word);
CB3: = New(PComboBox, Init(@Self, id_CB3, 190, 160,
150, 100, cbs_DropDownList, 40));
CB3^.Attr.Style:=CB3^.Attr.Style and (not cbs_Sort);
Модификация комбинированных блоков
Пример программы: CBoxTest
Установка значений управляющих элементов
Для чего используется буфер передачи?
Определение буфера передачи
type
TSampleTransferRecord = record
Stat1: array[0..TextLen-1] of Char; { статический текст }
Edit1: array[0..TextLen-1] of Char; { текст управляющего
элемента редактирования }
List1Strings: PStrCollection; { строки блока списка }
List1Selection: Integer; { индекс выбранных строк }
ComboStrings: PStrCollection; { строки комбинированного
блока }
ComboSelection: array[0..TextLen-1] of Char; { выбранные
строки }
Check1: Word; { проверка состояния блока}
Radio1: Word; { состояние кнопки с независимой фиксацией }
Scroll1: ScrollBarTransferRec; { диапазон полосы
прокрутки и т.д. }
end;
Тип управляющего элемента Буфер передачи Статический Символьный массив размером до максимальной длины текста, плюс завершающий нулевой символ. Редактирование Текстовый буфер управляющего элемента редактирования размером до длины, определенной в текстовом поле TextLen. Блок списка одиночный выбор Набор строк в списке, плюс целочисленный индекс выделенной строки. Блок списка множественный выбор Набор строк в списке, плюс запись, содержащая индексы всех выделенных элементов. Комбинированный блок Набор строк в списке, плюс выбранная строка. Кнопка с независимой фиксацией Значения Word с указывающими состояния bf_Unchecked, bf_Checked и bf_Grayed. Кнопка с зависимой фиксацией Значения Word с указывающими состояния bf_Unchecked, bf_Checked и bf_Grayed. Полоса прокрутки Запись типа TScrollBarTransferRec, сохраняющая диапазон полосы прокрутки и позицию в ней.
TScrollBarTransferRec := record
LowValue : Integer;
HighValue: Integer;
Position : Integer;
end;
Определение окна
Использование буфера передачи с диалоговым блоком
type
TSampleTransferRecord = record
.
.
.
PParentWindow = ^TParentWindow;
TParentWindow = object(TWindow)
TheDialog: PDialog;
TheBuffer: SampleTransferRecord;
.
.
.
.
constructor TParentWindow.Init(AParent: PWindowsObject;
ATitle: PChar);
var
Stat1: PStatic;
Edit1: PEdit;
List1: PListBox;
Combo1: PComboBox;
Check1: PCheckBox;
Radio1: PRadioButton;
Scroll1: PScrollBar;
begin
TWindow.Init(AParent, ATitle);
TheDialog^.Init(@Self, PChar(101));
New(Stat1, InitResource(TheDialog, id_Stat1));
New(Edit1, InitResource(TheDialog, id_Edit1));
New(List1, InitResource(TheDialog, id_List1));
New(Combo1, InitResource(TheDialog, id_Combo1));
New(Check1, InitResource(TheDialog, id_Check1));
New(Radio1, InitResource(TheDialog, id_Radio1));
New(Scroll1, InitResource(TheDialog, id_Scroll1));
TheDialog^.TranssferBuffer:=@TheBuffer;
end;
Использование буфера передачи с окном
constructor TSampleWindow.Init(AParent: PWindowsObject;
ATitle: PChar);
begin
inherited Init(AParent, ATitle);
Edit1 := New(PEdit, Init(@Self, id_Edit1, '', 10, 10,
100, 30, 40, False));
Edit1^.EnableTransfer;
end;
Передача данных
Передача данных в окно
Передача данных из диалогового окна
Передача данных из окна
procedure TSampleWindow.Destroy;
begin
TransferData(tf_GetData);
TWindow.Destroy;
end;
Поддержка передачи для специализированных управляющих элементов
function TStatic.Transfer(DataPrt: Pointer;
TransferFlag: Word): Word;
begin
if TransferFlag = tf_GetData then
GetText(DataPrt, TextLen)
else if TransferFlag = tf_SetData then
SetText(DataPtr);
Transfer:=TextLen;
end;
Пример программы: TranTest
Использование специализированных управляющих элементов
Специализированные управляющие элементы Borland для Windows
Использование стандартных BWCC
uses BWCC;
Средства BWCC