Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

VPS в 21 локации

От 104 рублей в месяц

Безлимитный трафик. Защита от ДДоС.

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Глава 12. Объекты управляющих элементов

             Windows предусматривает ряд стандартных интерфейсных элемен-
        тов, называемых  управляющими элементами.  Управляющие элементы -
        это специальные окна  с  некоторым  предопределенным  поведением.
        ObjectWindows  обеспечивает  интерфейсные объекты для стандартных
        управляющих элементов Windows, так что вы можете использовать эти
        интерфейсные  элементы в своих приложениях.  Интерфейсные объекты
        для управляющих элементов называются объектами  управляющих  эле-
        ментов или просто управляющими объектами.

                   Примечание: Об  интерфейсных объектах рассказывается в
              Главе 9.

             Данная глава охватывает следующие темы:

             * Задачи, общие для всех управляющих объектов:

               - построение и уничтожение объектов управляющих элементов;

               - взаимодействие с другими управляющими объектами.

             * Установка и чтение значений управляющих элементов.

             * Использование специализированных управляющих элементов.

             Кроме того,  в данной главе подробно описывается использова-
        ние каждого  интерфейсного  объекта  для  стандартных управляющих
        элементов Windows.

                Где можно использовать объекты управляющих элементов?
        -----------------------------------------------------------------

             Управляющие элементы - это специализированные окна,  которые
        позволяют пользователю предопределенным образом задавать или  вы-
        бирать данные.  Чаще всего управляющие элементы содержатся в диа-
        логовом блоке.  Диалоговый блок управляет их определением  с  по-
        мощью ресурса диалогового блока, так что вам не потребуется часто
        использовать в них объекты. Режимные диалоговые блоки не распола-
        гают способами  взаимодействия с управляющим объектом,  поэтому в
        диалоговых блоках  объекты  управляющих  элементов   используются
        обычно для  установки и считывания значений управляющих элементов
        с помощью передачи. Передача для объектов управляющих элементов в
        диалоговых блоках и в окнах выполняется одинаково (как описывает-
        ся ниже в этой главе).

                   Примечание: Диалоговые блоки и их управляющие элементы
              описываются в Главе 11 "Объекты диалоговых блоков".

             Возможно вы захотите использовать управляющие элементы в ок-
        нах, поэтому в данной главе описывается использование управляющих
        элементов вне диалоговых блоков.  Следующая таблица описывает уп-
        равляющие  элементы  Windows,  поддерживаемые   типами   объектов
        ObjectWindows:

                          Управляющие элементы Windows,
                         поддерживаемые в ObjectWindows      Таблица 12.1
        +---------------+------------+----------------------------------+
        | Управляющий   | Тип объекта|          Использование           |
        |    элемент    |            |                                  |
        +---------------+------------+----------------------------------|
        | блок списка   |TListBox    |Прокручиваемый  список  элементов,|
        |               |            |из которых можно сделать выбор.   |
        +---------------+------------+----------------------------------|
        | полоса        |TScrollBar  |Полоса   прокрутки,    аналогичная|
        | прокрутки     |            |тем,  которые выводятся в  прокру-|
        |               |            |чиваемых окнах и блоках списка.   |
        +---------------+------------+----------------------------------|
        | "нажимаемая"  |TButton     |Кнопка для "нажатия" со  связанным|
        | кнопка        |            |с ней текстом.                    |
        +---------------+------------+----------------------------------|
        | кнопка с      |TCheckBox   |Состоящая из блока кнопка, которая|
        | независимой   |            |может выбираться или нет, со  свя-|
        | фиксацией     |            |занным текстом.                   |
        +---------------+------------+----------------------------------|
        | кнопка с      |TRadioButton|Кнопка,  которая может  выбираться|
        | зависимой     |            |или   нет.   Обычно   используется|
        | фиксацией     |            |во взаимоисключающих группах.     |
        +---------------+------------+----------------------------------|
        | блок группы   |TGroupBox   |Статический  прямоугольник с текс-|
        |               |            |том в левом верхнем углу.         |
        +---------------+------------+----------------------------------|
        | управляющий   |TEdit       |Поле  для ввода текста пользовате-|
        | элемент       |            |лем.                              |
        | редактирования|            |                                  |
        +---------------+------------+----------------------------------|
        | статический   |TStatic     |Фрагмент   отображаемого   текста |
        | управляющий   |            |который  не  может  быть  изменен |
        | элемент       |            |пользователем.                    |
        +---------------+------------+----------------------------------|
        | Комбиниро-    |TComboBox   |Комбинация блока списка и управля-|
        | ванный блок   |            |ющего элемента редактирования.    |
        +---------------+------------+----------------------------------+


                            +----------------------------------+
          Командная строка: |                                  |
                            +----------------------------------+
                                     ^
                                     + редактируемый упрвляющий элемент

         +----------+            +----------+
         |###OK#####|            |##Cancel##|   <- командные кнопки
         +----------+            +----------+

             +---+-----------------------------------------------+---+
             | < |########################X######################| > |
             +---+-----------------------------------------------+---+
                               ^
             полоса прокрутки -+


              +--------------+-+
              |collect3.pas  |^|  <- блок списка
              |collect4.pas  +-|
              |diatest.pas   |#|
              |edittest.pas  |X|            +----------------+
              |ewndtest.pas  |#|            | *.txt          |
              |helpwind.pas  |#|            +-+--------------+-+
              |lboxtest.pas  |#|              |netlect3.txt  |^|
              |mditest.pas   +-|              |netlect4.txt  +-|
              |paltest.pas   |v|              |diatext.txt   |#|
              +--------------+-+              |readtxt.txt   |X|
                                              |vwndtext.txt  |#|
                     комбинированный блок ->  |whelpwnd.txt  |#|
                                              |wboxtext.txt  |#|
                                              |ydrtest.txt   +-|
                                              |xaltesx.txt   |v|
                                              +--------------+-+

             Рис. 12.1 Стандартные управляющие элементы Windows.

                       Что такое объекты управляющих элементов?
        -----------------------------------------------------------------

             Для Windows управляющие элементы - это просто  специализиро-
        ванные виды окон.  В ObjectWindows тип TControl является потомком
        типа TWindow,  так что большинство объектов управляющих элементов
        можно использовать как все другие оконные объекты. Объекты управ-
        ляющих элементов по способу их создания и уничтожения  и  способу
        их поведения (как дочерние окна) аналогичны оконным объектам. Од-
        нако они отличаются от других окон способом реакции на сообщения.
        Например, методы  Paint объектов управляющих элементов запрещены.
        Windows берет на себя функции по  отображению  своих  стандартных
        управляющих элементов.

             Может оказаться, что перечисленные в приведенной выше табли-
        це управляющие элементы отвечают всем потребностям вашего  прило-
        жения. Однако могут возникать случаи,  когда требуется определить
        наследующие типы управляющих элементов.  Например, вы можете соз-
        дать специализированный блок списка TFontListBox,  производный от
        TListBox, содержащий имена всех доступных вашему приложению шриф-
        тов и  автоматически  выводящих их при создании нового экземпляра
        объекта.

             Тип TControl,  как и  TWindowsObject,  является  абстрактным
        объектным типом.  Вы  можете  создать  экземпляры  его  потомков -
        TListBox, TButton и другие  -  но  не  можете  создать  экземпляр
        TControl.

             Заметим, что вам, возможно, никогда не потребуется создавать
        новый объектный тип,  наследующий  непосредственно  из  TControl.
        TControl инкапсулирует свойства и стандартные управляющие элемен-
        ты, о которых уже знает Windows.  Создание специализированных уп-
        равляющих элементов описывается в данной главе ниже.

               Построение и уничтожение объектов управляющих элементов
        -----------------------------------------------------------------

             Обычно в объекта порождающего окна для каждого  из  дочерних
        окон определяется поле данных. Независимо от того, какой вид объ-
        ектов вы используете, для каждого из них вы можете выполнить нес-
        колько задач:

             * Построение объекта управляющего элемента.

             * Вывод управляющего элемента.

             * Уничтожение управляющего элемента.


                       Построение объекта управляющего элемента
        -----------------------------------------------------------------

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

                   Примечание: Уведомления  описываются в Главе 16 "Сооб-
                               щения Windows".
             Чтобы построить и инициализировать объект управляющего  эле-
        мента, нужно сделать следующее:

             * добавить в объект порождающего окна поле (не обязательно);
             * вызвать конструктор объекта управляющего элемента;
             * изменить атрибуты управляющего элемента;
             * инициализировать управляющий элемент в SetupWindows.

                  Вызов конструкторов объектов управляющих элементов
        -----------------------------------------------------------------

             В то время как обычный конструктор  объекта  дочернего  окна
        имеет только два параметра (порождающее окно и строку заголовка),
        конструктор управляющего объекта имеет их не менее шести.  Объект
        блока списка имеет наиболее простой из всех управляющих элементов
        конструктор, который требует задания только шести параметров:

             - объекта порождающего окна;
             - идентификатора управляющего элемента;
             - координату x верхнего левого угла;
             - координату y верхнего левого угла;
             - ширину;
             - высоту.

             TListBox.Init описывается следующим образом:

             constructor TListBox.Init(AParent: PWindowsObject;
                                     AnID: Integer; X, Y, W, H: Integer);

             Все объекты   управляющих   элементов  ObjectWindows  (кроме
        TMDIClient) требуют не менее 6  параметров.  Большинство  из  них
        воспринимают также параметр,  задающий текст управляющего элемен-
        та.

                              Присваивание полям объекта
        -----------------------------------------------------------------
             Часто при построении управляющего элемента в окне желательно
        сохранять указатель на управляющий элемент в поле оконного объек-
        та. Например,  чтобы  добавить   в   окно,   определенное   типом
        TSampleWindow блок списка,  вы можете задать в поле TSampleWindow
        поле TheList и присвоить ему блок списка:

             constructor SampleWindow.Init(AParent: PWindowsObject;
                                           ATitle: PChar);
             begin
                inherited Init(AParent, ATitle);
                TheList := New(PListBox,
                               Init(@Self, id_LB1, 20, 20, 100, 80));
             end;

             Порождающие окна автоматически поддерживают список своих до-
        черних окон, включая управляющие элементы. Однако удобнее манипу-
        лировать управляющими объектами,  когда  имеются  соответствующие
        поля объекта.  Управляющие элементы, с которыми часто работать не
        требуется (такие как статический текст или групповые блоки) могут
        не иметь соответствующих полей.

             При наличии  поля  объекта  построение  объекта управляющего
        элемента не  представляет  труда.  Например,  чтобы  добавить   в
        TSampleWindow групповой блок, нужно сделать следующее:

             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;


                  Изменение атрибутов объекта управляющего элемента
        -----------------------------------------------------------------

             Все управляющие объекты, кроме TMDIClient, получает от вызо-
        ва TControl.Init  используемые  по  умолчанию  стили  ws_Child  и
        ws_Visible. Если вы хотите изменить стиль управляющего  элемента,
        то можно изменить поле Attr.Style (как это описывается для окон в
        Главе  10).  Каждый  тип управляющего элемента имеет также другие
        стили, определяющие его конкретные характеристики.

                         Инициализация управляющего элемента
        -----------------------------------------------------------------

             Экранный элемент управляющего объекта автоматически создает-
        ся методом SetupWindow,  наследуемым объектом порождающего  окна.
        Убедитесь, что при создании новых производных типов окон вы вызы-
        ваете наследуемый метод SetupWindow перед любой другой  инициали-
        зацией окна.

             При необходимости методом SetupWindow порождающего окна так-
        же устанавливаются и заполняются управляющие  элементы.  Приведем
        пример типичного метода SetupWindow:

             procedure TSampleWindows.SetupWindow;
             begin
               inherited SetupWindow;  { создает дочерние управляющие
                                         элементы }
               { добавляет элементы в список }
               TheList^.AddString('Элемент 1');
               TheList^.AddString('Элемент 2');
             end;

             Заметим, что инициализация управляющего элемента,  такая как
        добавление строк в блок списка, должна выполняться в SetupWindow,
        а не в конструкторе.  Вызов такого метода как  TListBox.AddString
        приводит к  передаче  сообщений  экранному управляющему элементу.
        Так как  экранный   элемент   до   вызова   наследуемого   метода
        SetupWindow не создается,  попытки инициализации управляющих эле-
        ментов до этого момента завершится неудачно.


                           Сохранение управляющих элементов
        -----------------------------------------------------------------

             Для вывода  на экран управляющих элементов нет необходимости
        вызывать метод Show.  Как дочерние окна,  они автоматически выво-
        дятся на  экран  и повторно отображаются вместе с порождающим ок-
        ном. Однако,  вы можете использовать Show для сокрытия или вывода
        управляющих элементов по запросу.

                          Уничтожение управляющих элементов
        -----------------------------------------------------------------

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

                           Связь с управляющими элементами
        -----------------------------------------------------------------

             Связь между  оконным объектом и его управляющими объектами в
        некотором смысле аналогичны взаимодействию между объектом  диало-
        гового блока  и  его  управляющими элементами.  Как и диалоговому
        блоку, окну требуется механизм для работы с его управляющими эле-
        ментами  и  для ответа на управляющие события,  такие как выбор в
        блоке списка.

                        Работа с управляющими элементами окна
        -----------------------------------------------------------------

             Диалоговые окна  работают с их управляющими элементами путем
        передачи им сообщений с помощью метода SendDlgItemMsg с  констан-
        той управляющего  сообщения  (такой  как lb_AddString) в качестве
        параметра (см.  Главу 11).  Объекты управляющих элементов  сильно
        упрощают этот  процесс  путем  использования  методов (таких  как
        TListBox.AddString) для непосредственной  работы  с  управляющими
        элементами на экране.

             Когда объекты управляющих элементов окна имеют соответствую-
        щие поля объекта,  то вызвать управляющие методы достаточно прос-
        то:

             TheListBox^.AddString('Scotts Valley');


                           Реакция на управляющие элементы
        -----------------------------------------------------------------

             Реакция на взаимодействие с пользователем с помощью управля-
        ющих элементов  несколько более сложна,  чем просто вызов методов
        объектов управляющих элементов. Чтобы узнать, как отвечать на со-
        общения управляющих элементов, см. раздел "Команды, уведомления и
        идентификаторы управляющих элементов" в Главе 16.

                       Действие, аналогичное диалоговому блоку
        -----------------------------------------------------------------

             Диалоговый блок  с управляющими элементами позволяет пользо-
        вателю с помощью клавиши Tab циклически перемещаться по всем эле-
        ментам диалогового  блока. Он  может  также  использовать клавиши
        стрелок для выбора в групповом блоке кнопок с зависимой  фиксаци-
        ей. Чтобы  эмулировать этот клавиатурный интерфейс для окон с уп-
        равляющими элементами,  вызовите для оконного объекта в его конс-
        трукторе метод EnableKBHandler объекта TWindowsObject.

                    Использование конкретных управляющих элементов
        -----------------------------------------------------------------

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

                              Использование блока списка
        -----------------------------------------------------------------

             Использование блока списка - это простейший способ запросить
        пользователя программы Windows выбрать что-либо из списка.  Блоки
        списка инкапсулируются объектным типом TListBox. TListBox опреде-
        ляет методы  для создания блоков списка,  модификации списка эле-
        ментов, запроса состояния списка элементов  и  поиска  выбранного
        пользователем элемента.


                           Построение объектов блока списка
        -----------------------------------------------------------------

             Конструктор Init  в TListBox воспринимает только шесть пара-
        метров, которые необходимы всем объектам  управляющих  элементов.
        Этими параметрами являются порождающее окно, идентификатор и раз-
        меры управляющего элемента X, Y, W и H:

             LB1 := New(PListBox, Init(@Self, id_LB1, 20, 20, 340, 100));

             TListBox получает используемый по умолчанию стиль  управляю-
        щего элемента   ws_Child   or   ws_Visible,   затем  прибавляется
        lbs_Standard. lbs_Standard - это комбинация lbs_Notify (для полу-
        чения  уведомляющих сообщений),  ws_VScroll (для получения верти-
        кально полосы прокрутки), lbs_Sort (для сортировки списка элемен-
        тов в алфавитном порядке) и ws_Border (для вывода рамки). Если вы
        хотите получить другой стиль блока списка,  то можете модифициро-
        вать поле Attr.Style в TListBox.  Например,  для блока списка, не
        сортирующего свои элементы, можно использовать следующее:

             LB1 := New(PListBox, Init(@Self, id_LB1, 20, 20, 340, 100));
             LB1^.Attr.Style := LB1^.Attr.Style and not lbs_Sort;

                              Модификация блоков списка
        -----------------------------------------------------------------

             После создания  блока списка вам нужно заполнить его элемен-
        тами списка, который должны представлять собой строки. Позднее вы
        можете добавить,  вставить  или удалить элементы,  либо полностью
        очистить список. Указанные действия вы можете выполнить с помощью
        методов, приведенный в следующей таблице:

                        Методы модификации блоков списка     Таблица 12.2
        +--------------------------------+------------------------------+
        |   Выполняемое действие         |            Метод             |
        +--------------------------------+------------------------------|
        |   Добавление элемента          | AddString                    |
        |   Вставка нового элемента      | InsertString                 |
        |   Добавление элемента          | InsertString                 |
        |   Удаление элемента            | DeleteString                 |
        |   Удаление каждого элемента    | ClearList                    |
        |   Выбор элемента               | SetSellIndex или SetSelString|
        +--------------------------------+------------------------------+



             Существует пять методов, которые вы можете вызвать для полу-
        чения информации о списке,  содержащейся в объекте блока  списка.
        Эти методы перечислены в следующей таблице:

                           Методы запроса блока списка       Таблица 12.3
        +-------------------------------------------+-------------------+
        |    Получаемая информация                  |  Вызываемый метод |
        +-------------------------------------------+-------------------|
        |    Число элементов в списке               |   GetCount        |
        |    Элемент с конкретным индексом          |   GetString       |
        |    Длина конкретного элемента             |   GetStringLen    |
        |    Выбранный элемент                      |   GetSelString    |
        |    Индекс выбранного элемента             |   SEgSelIndex     |
        +-------------------------------------------+-------------------+

                                Реакция на блок списка
        -----------------------------------------------------------------

             Методы модификации и запроса блока списка позволяют вам  ус-
        тановить значения  или определять в каждый конкретный момент сос-
        тояние блока списка. Однако, чтобы знать, что делает пользователь
        в данный момент с блоком списка, вам нужно реагировать на уведом-
        ляющие сообщения управляющего элемента.

             Пользователь может выполнять с блоком списка только  следую-
        щие действия: прокрутку списка, щелчок кнопкой "мыши" на элементе
        списка, двойной щелчок кнопкой "мыши" на элементе. Когда выполня-
        ется одно из этих действий,  Windows посылает  порождающему  окну
        блока  списка  уведомляющее сообщение блока списка.  Обычно метод
        реакции на уведомление для обработки сообщений для каждого управ-
        ляющего  элемента порождающего объекта определяется в порождающем
        оконном объекте.

             Каждое уведомляющее  сообщение  блока списка содержит в поле
        lParamHi параметра Msg код уведомления (константу lbn_),  который
        специфицирует характер действия. Наиболее общие коды lbn перечис-
        лены в следующей таблице:

                    Информационные сообщения блока списка    Таблица 12.2
        +-------------+-------------------------------------------------+
        |   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;

             Пользователь делает  выбор,  если  Msg.lParamHi  совпадает с
        константой lbn_SelChange.  Если это так, то берется длина выбран-
        ной строки, проверяется, что она помещается в строку из 10 симво-
        лов, и выбранная строка показывается в блоке сообщения.

                              Пример программы: LBoxTest
        -----------------------------------------------------------------

             Программа LBoxTest  - это полная программа,  которая создает
        окно с блоком списка.  После запуска приложения появляется основ-
        ное  окно  с  блоком списка.  Когда пользователь выбирает элемент
        блока списка,  появляется диалог с выбранным элементом.  Обратите
        внимание на  взаимоотношения между объектом окна и объектом блока
        списка. Блок списка - это не просто дочернее окно основного окна,
        основное окно владеет им как полем объекта. LB1 - это одно из по-
        лей объекта основного окна,  и оно содержит объект блока  списка.
        Полный  текст  программы содержится в файле LBOXTEST.PAS на ваших
        дистрибутивный дискетах.

                   Использование статических управляющих элементов
        -----------------------------------------------------------------

             Статические управляющие  элементы  - это обычно неизменяемые
        модули текста или простые изображения,  которые могут  появляться
        на экране  в окне или блоке диалога.  Пользователь не взаимодейс-
        твует со статическими управляющими элементами,  хотя программа  и
        может  изменять их текст.  Рис.  12.2 показывает множество стилей
        статического управления и соответствующих констант стиля Windows.

        +-----------------------------------------------------------+-+-+
        |#=#XXXXXXXXXXXXXXXXXStatic Control TesterXXXXXXXXXXXXXXXXXX|^|v|
        +-----------------------------------------------------------+-+-|
        |                                                               |
        | Default Static             Sample Text                        |
        |                                                               |
        | ss_Simple                  Sample Text                        |
        |                                                               |
        | ss_Left                    Sample Text                        |
        |                                                               |
        | ss_Center                           Sample Text               |
        |                                                               |
        | ss_Right                                         Sample Text  |
        |                            +------------------------------+   |
        | ss_BlackFrame              |                              |   |
        |                            +------------------------------+   |
        |                            +------------------------------+   |
        | ss_BlackRect               |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|   |
        |                            +------------------------------+   |
        |                            +------------------------------+   |
        | ss_GrayFrame               |                              |   |
        |                            +------------------------------+   |
        |                            +------------------------------+   |
        | ss_GrayRect                |##############################|   |
        |                            +------------------------------+   |
        |                                                               |
        | ss_NoPrefix                                   Sample & Text   |
        |                                                               |
        +---------------------------------------------------------------+

             Рис. 12.2 Стили статических управляющих элементов.

                     Построение статических управляющих элементов
        -----------------------------------------------------------------

             Пользователь никогда  не  взаимодействует непосредственно со
        статическими управляющими элементами,  поэтому  приложение  будет
        очень редко,  если вообще будет, принимать уведомляющие сообщения
        управляющих элементов относительно статического управляющего эле-
        мента. Следовательно, большинcтво статических управляющих элемен-
        тов можно сконструировать с идентификатором ресурса -1 или  неко-
        торым другим неиспользуемым числом.

             Конструктор Init  в TStatic конструирует новый объект стати-
        ческого управления и описывается следующим образом:

             constructor TStatic.Init(AParent: PWindowsObject;
                                   AnID: Integer; ATitle: PChar;
                                   X, Y, W, H: Integer; ATextLen: Word);

             Кроме обычных   параметров   Init   управляющего    объекта,
        TStatic.Init имеет два дополнительных параметра - текстовую стро-
        ку ATitle и максимальную длину текста ATextLen.  Текст должен за-
        канчиваться  нулевым  символом,  поэтому в действительности число
        отображаемых символов на единицу меньше заданной  в  конструкторе
        длины текста. Типичный вызов для построения статического управля-
        ющего элемента может выглядеть так:

             Stat1 := New(Static, Init(@Self, id_ST1, '&Text', 20, 50,
                                       200, 24, 6));

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

             Используемым по умолчанию стилем  статического  управляющего
        элемента является назначенный  по  умолчанию  стиль  управляющего
        элемента,  то  есть  ws_Child or ws_Visible (выравнивание влево).
        Чтобы изменить стиль,  модифицируйте поле  Attr.Style.  Например,
        чтобы центрировать текст управляющего элемента,  сделайте следую-
        щее:

             Stat1^.Attr.Style := Stat1^.Attr.Style and (not ss_Left) or
                                  ss_Center;

             В статическом  управляющем элементе есть возможность подчер-
        кивания одного или нескольких символов в строке текста.  Реализа-
        ция  и  действие  этого  эффекта аналогичны подчеркиванию первого
        символа в выборе меню:  Insert и & должны  непосредственно  пред-
        шествовать символу в строке, который будет подчеркиваться. Напри-
        мер, для подчеркивания T в слове 'Text' нужно в вызове Init стро-
        ку  '&Text'.  Если в строке вам нужно использовать &,  применяйте
        статический стиль Windows ss_NoPrefix (см.  Рис. 12.2). Для уточ-
        нения текущего текста, который хранится в статическом управляющем
        элементе, используется метод GetText.

                 Модификация статического управляющего элемента

             Для изменения  текста  статического  управляющего   элемента
        TStatic  имеет  два  метода.  SetText  устанавливает  статический
        текст,  передаваемый аргументом PChar.  Clear удаляет статический
        текст.  Однако, вы не можете сменить текст статического управляю-
        щего элемента, созданный со стилем ss_Simple.

                     Опрос статических управляющих элементов

             Чтобы считать текст,  содержащийся в статическом управляющем
        элементе, используйте метод GetText.

                              Пример программы StatTest
        -----------------------------------------------------------------

             Программа StatTest  создает статическое тестовое приложение,
        показанное на  Рис.12.2.  Обратите  внимание  на  то,  что  метки
        ('Default  Static' и 'ss_Simple') представляют собой статистичес-
        кие управляющие элементы, также как и 'Sample Text', черные и се-
        рые прямоугольники.  Полный текст программы  содержится  в  файле
        STATTEST.PAS на ваших дистрибутивных дискетах.


                            Использование командных кнопок
        -----------------------------------------------------------------

             Управляющие элементы  типа  командных кнопок (которые иногда
        называют "нажимаемыми" кнопками) выполняют некоторое действие при
        "нажатии"  такой кнопки.  Есть два стиля командных кнопок,  и оба
        они  имеют  тип  TButton.  Эти  два  стиля  -   bs_PushButton   и
        DefPushButton.  Используемые по умолчанию командные кнопки анало-
        гичны командным другим кнопкам,  но имеют жирную рамку  и  обычно
        используются  для указания реакции пользователя по умолчанию.  На
        Рис. 12.3 показан пример программы Windows, в которой используют-
        ся обычные кнопки нажатия и командные кнопки по умолчанию.

                      +---------------------------------+-+
                      |#=#XXXXXXXXXHex CalculatorXXXXXXX|v|
                      +---------------------------------+-|
                      |        +-----------------+        |
                      |        |        0        |        |
                      |        +-----------------+        |
                      |                                   |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | ||D||  | E | | F |  | + |  | & |  |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | | A |  | B | | C |  | - |  | | |  |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | | 7 |  | 8 | | 9 |  | * |  | ^ |  |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | | 4 |  | 5 | | 6 |  | / |  | < |  |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | | 1 |  | 2 | | 3 |  | % |  | > |  |
                      | +---+  +---+ +---+  +---+  +---+  |
                      | +---+  +---------+  +----------+  |
                      | | 0 |  |   Back  |  |  Equals  |  |
                      | +---+  +---------+  +----------+  |
                      +-----------------------------------+

             Рис. 12.3 Программа Windows, использующая командные кнопки.


                             Построение командных кнопок
        -----------------------------------------------------------------

             Кроме обычных 6 параметров, конструктор Init объекта TButton
        воспринимает текстовую  строку  типа  PChar,  AText  и  флаг типа
        Boolean IsDefaultButton,  указывающий,  должна ли кнопка быть ис-
        пользуемой по умолчанию или обычной командной кнопкой.  Конструк-
        тор Init объекта TButton описывается следующим образом:

             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));

                             Реакция на командные кнопки
        -----------------------------------------------------------------

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

             Для организации реакции на сообщения кнопок нужно определить
        основанный на  дочернем идентификаторе метод для обработки каждой
        кнопки.  Например, следующий метод IDBut1 обрабатывает реакцию на
        "нажатие" пользователем кнопки. Единственный код уведомления, оп-
        ределенный в Windows для командных кнопок - это bn_Clicked,  поэ-
        тому код уведомления не нужно проверять.

             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;

                   Примечание: Пример использования командных кнопок  по-
              казывает  программа  BtnTest,  которую  вы  можете найти на
              дистрибутивных дисках.

                             Использование блоков выбора
        -----------------------------------------------------------------

             Тип TCheckBox наследует от TButton, а тип TRadioButton - от
        TCheckBox. Кнопки  с  зависимой  и независимой фиксацией мы будем
        иногда кратко называть блоками выбора.

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

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

             Однако, вы  можете для выполнения ими некоторых действий при
        нажатии создать типы,  производные от TCheckBox  и  TRadioButton.
        Если  ваш  тип определяет метод для nf_First + bn_Clicked,  то он
        сначала должен вызывать метод реакции BNClicked,  а уже затем вы-
        полнять любые дополнительные действия.

                Построение кнопок с зависимой и независимой фиксацией
        -----------------------------------------------------------------

             Кроме обычных  6  параметров,  конструктор Init для кнопок с
        зависимой и независимой фиксацией воспринимает текстовую строку и
        указатель на объект группового блока (см. "Групповые блоки"), ко-
        торый логически и визуально выделяет кнопки.  AGroup - это указа-
        тель на объект группового блока.  Если AGroup имеет значение nil,
        то блок выбора не является частью какой-либо  логической  группы.
        Конструкторы описываются следующим образом:

             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));

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

             Если вы переопределяете стили объектов  кнопок  с  зависимой
        или независимой фиксацией как "неавтоматические", то тогда уже вы
        отвечаете за их выбор или не выбор в ответ на произведенные поль-
        зователем нажатия.


                              Модификация блоков выбора
        -----------------------------------------------------------------

             Модификация (выбор или отмена выбора) блоков выбора выглядит
        задачей пользователя программы, а не вашей. Но в некоторых случа-
        ях программе  требуется  явно управлять состоянием блоков выбора.
        Одним из таких случаев является вывод на экран параметров,  кото-
        рые  были  выбраны  и сохранены ранее.  Для модификации состояния
        кнопки с независимой фиксацией TCheckBox определяет 4 метода:

          Методы модификации кнопок с независимой фиксацией  Таблица 12.5
        +---------------------------+-----------------------------------+
        |    Выполняемое действие   |       Вызов метода                |
        +---------------------------+-----------------------------------|
        |   Выбор кнопки            | Check или SetCheck(bf_Chacked)    |
        |   Отмена выбора кнопки    | Uncheck или SetCheck(bf_Unchecked)|
        |   Переключение кнопки     | Toggle                            |
        +---------------------------+-----------------------------------+

             Когда вы  используете  данные  методы с кнопками с зависимой
        фиксацией, ObjectWindows обеспечивает выбор в группе только одной
        кнопки с зависимой фиксацией.

                                 Опрос блоков выбора
        -----------------------------------------------------------------

             Опрос блока выбора - это один из способов выяснения его сос-
        тояния и организации реакции на него.  Кнопки с зависимой и неза-
        висимой  фиксацией имеют два состояния:  выбранные и невыбранные.
        Для получения состояния блока выбора используется метод  GetCheck
        типа TheckBox:

             MyState:=Check1^.GetCheck;

             Для определения состояния блока возвращаемое GetCheck значе-
        ние  можно  сравнить  с   заданными   константами   bf_Unchecked,
        bf_Checked и bf_Grayed.

                   Примечание: Использование  кнопок обоих видов показано
              в примере программы BtnTest на ваших дистрибутивных дисках.

                            Использование групповых блоков
        -----------------------------------------------------------------

             В своей простейшей форме блок группы представляет собой ста-
        тический прямоугольник с меткой, который обычно объединяет другие
        управляющие  элементы.


                             Построение групповых блоков
        -----------------------------------------------------------------

             Конструктор Init группового блока кроме обычных 6 параметров
        воспринимает текстовую строку метки группы.

             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;

             Заметим, что передаваемый блоку выбора параметр группы - это
        указатель на объект блока группы,  а не идентификатор  группового
        управляющего элемента (как в API Windows). Использование указате-
        ля позволяет  вам  строить  объекты   перед   созданием   методом
        SetupWindows порождающего окна экранных элементов.


                              Реакция на групповые блоки
        -----------------------------------------------------------------

             Когда происходит событие, которое может изменить выбор блока
        группы (например,  "нажатие" пользователем кнопки или вызов прог-
        раммой метода Check), порождающее окно блока группы принимает со-
        общение, основанное на дочернем идентификаторе.  Порождающий объ-
        ект воспринимает сообщение,  используя сумму id_First и идентифи-
        катора  группового блока. Это позволяет вам определить методы для
        каждой  группы вместо их задания для каждого блока выбора в груп-
        пе.

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

                              Пример программы: BtnTest
        -----------------------------------------------------------------

             BtnTest -  это полная программа,  которая создает окно с ко-
        мандной кнопкой,  кнопками с зависимой и независимой фиксацией  и
        блоком группы управляющих элементов. После запуска приложения по-
        является основное окно с управляющими элементами. Когда пользова-
        тель  "нажимает" на управляющий элемент,  приложение реагирует на
        это различными способами. См. Рис. 12.4.

                   Примечание: Полный  текст программы содержится в файле
              BTNTEST.PAS на ваших дистрибутивных дискетах.

        +-----------------------------------------------------------+-+-+
        |#=#XXXXXXXXXXXXXXXXXXXButton TesterXXXXXXXXXXXXXXXXXXXXXXXX|^|v|
        +-----------------------------------------------------------+-+-|
        |                                                               |
        |         +---+                                                 |
        |         | X | Текст кнопки с независимой фиксацией            |
        |         +---+                                                 |
        | +----------------------------------------------------------+  |
        | |###########Состояние кнопки с независимой фиксацией#######|  |
        | +----------------------------------------------------------+  |
        |                                                               |
        |             +-Групповой блок-------------------------------+  |
        |             | ( ) Кнопка с зависимой фиксацией 1           |  |
        |             | (*) Кнопка с зависимой фиксацией 2           |  |
        |             +----------------------------------------------+  |
        +---------------------------------------------------------------+

             Рис. 12.4 Окно с различными видами кнопок.

                            Использование полос прокрутки
        -----------------------------------------------------------------

             Полосы прокрутки являются важнейшим механизмом изменения об-
        зора пользователем окна приложения,  блока списка или  комбиниро-
        ванного блока. Однако, может возникнуть ситуация, когда нужна от-
        дельная полоса прокрутки для выполнения  некоторой  специализиро-
        ванной задачи (например, управление температурой в программе тер-
        мостата или цветом в программе рисования).  Когда нужна отдельная
        специализированная полоса    прокрутки,    используются   объекты
        TScrollBar. Рис.  12.5 показывает типичное использование  объекта
        TSсrollBar.

        +-----------------------------------------------------------+-+-+
        |#=#XXXXXXXXXXXXXXXXXXXXXXThermostatXXXXXXXXXXXXXXXXXXXXXXXX|^|v|
        +-----------------------------------------------------------+-+-|
        |                                                               |
        |                     68 градусов                               |
        |                                                               |
        |                                                               |
        |                                                               |
        | +--+----------------------------------------------------+--+  |
        | |<X|#################X##################################|X>|  |
        | +--+----------------------------------------------------+--+  |
        |                                                               |
        +---------------------------------------------------------------+

             Рис. 12.5 Объект полосы прокрутки.

                              Построение полос прокрутки
        -----------------------------------------------------------------

             Кроме обычных 6 параметров управляющего объекта, конструктор
        Init полосы  прокрутки воспринимает флаг типа Boolean,  указываю-
        щий, является ли полоса прокрутки горизонтальной. Приведем описа-
        ние конструктора полосы прокрутки:

             constructor TScrollBarInit(AParent: PWindowsObject;
                                      AnID: Integer; X, Y, W, H: Integer;
                                      IsHScrollBar: Boolean);

             Если вы зададите нулевую ширину вертикальной полосы прокрут-
        ки, Windows присвоит ей стандартную  ширину  (аналогичную  полосе
        прокрутки блока списка). То же самое касается задания нулевой вы-
        соты горизонтальной полосы прокрутки. Вызов:

             ThermScroll := New(PScrollBar, Init(@Self, id_ThermScroll,
                                20, 170, 340, 0, True));

        создает горизонтальную  полосу прокрутки стандартной высоты,  как
        это показано на Рис. 12.5.  Init конструирует полосы прокрутки со
        стилями ws_Child, ws_Visible и sbs_Horz или sbs_Vert для горизон-
        тальной или вертикальной полосы прокрутки соответственно.  Разно-
        образные полосы прокрутки показаны на Рис. 12.6.

        +-----------------------------------------------------------+-+-+
        |#=#XXXXXXXXXXXXXXXXXXXScroll Bar TesterXXXXXXXXXXXXXXXXXXXX|^|v|
        +-----------------------------------------------------------+-+-|
        |          +--+                                     +-+         |
        |    +--+--|/\|---------------------------+--+      |^|         |
        |    |/X|##+--|###########X###############|X\|      +-|         |
        |    |\X|##|##|###########X###############|X/|      |#|         |
        |    +--+--|XX|---------------------------+--+      |X|         |
        |          |##|                                     |#|         |
        |          |##|                                     |#|         |
        |          |##|                                     +-|         |
        |          +--|                                     |v|         |
        |          |\/|                                     +-+         |
        |          +--+                                                 |
        | +--+----------------------------------------------------+--+  |
        | |<X|#################X##################################|X>|  |
        | +--+----------------------------------------------------+--+  |
        |                                                               |
        |                                                               |
        +---------------------------------------------------------------+

             Рис. 12.6 Окно с разнообразными полосами прокрутки.

                        Управление диапазоном полосы прокрутки
        -----------------------------------------------------------------

             Один из атрибутов полосы прокрутки,  инициализируемый при ее
        конструировании,  это  диапазон.  Диапазон полосы прокрутки - это
        набор всевозможных положений указателя (маркера  полосы  прокрут-
        ки). Маркер полосы прокрутки - это подвижный прямоугольник, кото-
        рый пользователь может перемещать по ней.  Каждой  позиции  соот-
        ветствует целое число.  Порождающее окно использует эту целую ве-
        личину,  позицию,  для установки и запроса по  полосе  прокрутки.
        После конструирования объекта полосы прокрутки его диапазон уста-
        навливается от 1 до 100.

             Положению маркера в "самой верхней" позиции (вершина  верти-
        кальной полосы прокрутки или крайнее левое положение горизонталь-
        ной полосы прокрутки) соответствует позиция 1. "Самой нижней" по-
        зиции маркера соответствует позиция 100. Для установки иного диа-
        пазона  нужно  использовать  метод SetRange,  описанный в разделе
        "Модификация полосы прокрутки".


                       Управление параметрами полосы прокрутки
        -----------------------------------------------------------------

             Два других  атрибута объекта полосы прокрутки - это его при-
        ращение по строкам и страницам.  Приращение по строкам,  установ-
        ленное в 1, это расстояние в единицах диапазона, на которое пере-
        местится указатель при нажатии пользователем  стрелок  на  полосе
        прокрутки. Приращение по страницам, установленное в 10, это расс-
        тояние в единицах диапазона,  на которое  переместится  указатель
        при нажатии пользователем в области прокрутки. Эти значения можно
        изменить непосредственной модификацией полей объекта  TScrollBar,
        LineSize и PageSize.

                                Опрос полосы прокрутки
        -----------------------------------------------------------------

             TScrollBar определяет  два  метода  опроса полосы прокрутки:
        GetRange и GetPosition. Метод GetRange - это процедура, использу-
        ющая два  целочисленных переменных аргумента. Процедура заносит в
        эти целые  значения  верхнюю и нижнюю позиции из диапазона полосы
        прокрутки. Этот метод очень удобен, когда нужно, чтобы ваша прог-
        рамма переместила указатель в его верхнюю или нижнюю позицию.

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

                             Модификация полос прокрутки  
        -----------------------------------------------------------------

             Модификация полос прокрутки - это скорее работа для  пользо-
        вателя  вашей программы,  и часто это действительно так.  Однако,
        ваша программа также может модифицировать полосу  прокрутки.  Ис-
        пользуемые для этого методы перечислены в следующей таблице.

                      Методы модификации полос прокрутки    Таблица 12.6
        +--------------------------------------+------------------------+
        |       Выполняемое действие           |    Вызываемый метод    |
        +--------------------------------------+------------------------|
        |    Задание диапазона прокрутки       |   SetRange             |
        |    Установка позиции маркера         |   SetPosition          |
        |    Перемещение позиции маркера       |   DeltaPos             |
        +--------------------------------------+------------------------+

             SetRange - это процедура,  которая воспринимает два целочис-
        ленных аргумента,  наименьшую и наибольшую позицию диапазона.  По
        умолчанию новая полоса прокрутки имеет диапазон от 1 до  100.  Вы
        можете  изменить этот диапазон для наилучшего расположения управ-
        ляющих элементов полос прокрутки.  Например,  полоса прокрутки  в
        приложении  для термостата может иметь диапазон от 32 до 120 гра-
        дусов Фаренгейта:

             ThermScroll^.SetRange(32, 120);


             SetPosition - это процедура, которая воспринимает один цело-
        численый аргумент - позицию,  в которую нужно переместить  указа-
        тель полосы прокрутки.  В рассмотренном ранее приложении для тер-
        мостата, ваша программа может непосредственно установить темпера-
        туру 78 градусов:

             ThermScroll^.SetPosition(78);

             Третий метод  DeltaPos  передвигает позицию указателя полосы
        прокрутки вверх (налево) или вниз (направо) на величину, заданную
        целым аргументом.  Положительная целая величина перемещает указа-
        тель вниз (направо).  Отрицательная целая величина перемещает его
        вверх (налево).  Например,  для уменьшения температуры термостата
        на 5 градусов используется:

             ThermScroll^.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. Наибо-
        лее часто вы будете реагировать на каждое событие проверкой новой
        позиции полосы прокрутки и  организацией  соответствующего  дейс-
        твия.  В  данном  случае вы можете игнорировать уведомляющий код.
        Например:

             procedure TestWindow.HandleThermScrollMsg(var Msg:
                                                       TMessage);
             var
                NewPos: Integer;
             begin
                NewPos:=ThermScroll^.GetPosition;
                { обработка с помощью NewPos }
             end;

             Часто альтернатива  состоит  в том,  чтобы не реагировать на
        перемещение  указателя до тех пор,  пока пользователь не  выберет
        его нового местоположения. В этом случае нужно реагировать на со-
        общение с кодом sb_ThumbTrack.

             procedure TestWindow.HandleThermScrollMsg(var Msg:
                                                       TMessage);
             var
               NewPos: Integer;
             begin
               if Msg.wParam <> sb_ThumbTrack
                then begin
                      NewPos:=ThermScroll^.GetPosition;
                      { некоторая обработка на основе NewPos. }
                     end;
             end;

             Иногда может потребоваться,  чтобы объекты полосы  прокрутки
        сами реагировали на уведомляющие сообщения полосы прокрутки.  При
        этом конкретная реакция поведения должна быть встроена  в  объект
        полосы прокрутки.  Для программирования объекта полосы прокрутки,
        который непосредственно реагировал бы на его информационные сооб-
        щения, нужно определить для его типа метод реакции, основанный на
        информации.  В качестве идентификатора заголовка метода нужно ис-
        пользовать  сумму nf_First и информационного кода полосы прокрут-
        ки. Этот процесс описан в разделе "Уведомляющие сообщения  управ-
        ляющих элементов" Главы 16.

                              Пример программы: SBarTest
        -----------------------------------------------------------------

             Программа SBarTest создает приложение для термостата,  пока-
        занное на Рис.  12.5.  Полный текст программы содержится в  файле
        SBARTEST.PAS на ваших дистрибутивных дискетах.

                  Использование управляющих элементов редактирования
        -----------------------------------------------------------------

             Управляющие элементы редактирования могут быть описаны,  как
        интерактивные статические управляющие элементы. Это прямоугольные
        области (с рамкой или без) на экране, которые пользователь прило-
        жения может заполнять текстом,  изменять или удалять. Управляющий
        элемент редактирования наиболее удобен в качестве поля для  ввода
        данных на экране. Они обеспечивают следующие операции:

             - Ввод текста пользователем.
             - Динамическое отображение текста приложением.
             - Вырезание, копирование и вставка в буфер вырезанного изоб-
               ражения.
             - Многострочное  редактирование (удобно для текстовых редак-
               торов).

             На Рис.  12.7  показано окно с двумя управляющими элементами
        редактирования.

        +-----------------------------------------------------------+-+-+
        |#=#@@@@@@@@@@@@@@@@@Edit Control Tester@@@@@@@@@@@@@@@@@@@@|^|v|
        +-----------------------------------------------------------+-+-|
        |                                                               |
        |   Оригинал:                     Копия:                        |
        |  +----------------------+ +---+ +----------------------+      |
        |  |Default Text          | |#>#| |DEFAULT.TEXT          |      |
        |  +----------------------+ +---+ +----------------------+      |
        |                                                               |
        |                                                               |
        +---------------------------------------------------------------+

             Рис. 12.7 Окно с управляющими элементами редактирования.


                   Построение управляющих элементов редактирования
        -----------------------------------------------------------------

             Конструктор Init управляющего элемента редактирования анало-
        гичен конструктору статического управляющего элемента и восприни-
        мает 6 обычных параметров,  плюс начальная текстовая строка, мак-
        симальная длина строки и флаг Multiline типа Boolean. Конструктор
        TEdit описывается следующим образом:

             constructor TEdit.Init(AParent: PWindowsObject;
                      AnID: Integer; ATitle: PChar;
                      X, Y, W, H, ATextLen: Integer; Multiline: Boolean);

             По умолчанию управляющий элемент редактирования имеет  стили
        ws_Child, ws_Visible,  es_TabStop,  es_Left и es_AutoHScroll. Так
        как управляющий элемент должен включать в себя завершающий  нуле-
        вой символ,  параметр  длины  текста на самом деле на 1 превышает
        максимальное число символов,  допустимых в строке редактирования.

             Если Multiline имеет значение True, то управление редактиро-
        ванием  имеет  стиль es_MultiLine,  es_AutoVScroll,  ws_VScroll и
        ws_HScroll. Приведем типичные конструкторы управляющих  элементов
        редактирования (один  для  однострочного  элемента,  другой - для
        многострочного):

             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
        -----------------------------------------------------------------

             Вы можете передавать текст  непосредственно  между  объектом
        управляющего  элемента редактирования и буфером вырезанного изоб-
        ражения Windows,  используя для этого вызовы методов.  Часто  вам
        бывает  нужно предоставить пользователю доступ к этим методам че-
        рез меню редактирования.  Объект управляющего элемента редактиро-
        вания автоматически отреагирует на выбор из меню таких вариантов,
        как Edit|Copy и Edit|Undo.  TEdit определяет основанные на коман-
        дах методы (например, CMEditCopy и CMEditUndo), которые вызывают-
        ся в ответ на конкретный выбор (команду) меню в порождающем  окне
        управляющего элемента редактирования. CMEditCopy вызывает Copy, а
        CMEditUndo вызывает Undo.


             Следующая таблица содержит список методов, которые вызывают-
        ся в ответ на выбор пункта меню:

           Управляющие элементы редактирования и меню Edit  Таблица 12.7
        +-----------------------+-------------------+-------------------+
        |    Операция           |     Метод TEdt    |    Команда меню   |
        +-----------------------+-------------------+-------------------|
        | Копирование текста в  |  Cut              | cm_EditCut        |
        | буфер вырезанного     |                   |                   |
        | изображения.          |                   |                   |
        +-----------------------+-------------------+-------------------|
        | Вырезание текста в    |  Copy             | cm_EditCopy       |
        | буфер вырезанного     |                   |                   |
        | изображения.          |                   |                   |
        +-----------------------+-------------------+-------------------|
        | Вставка текста из     |  Paste            | cm_EditPaste      |
        | буфера вырезанного    |                   |                   |
        | изображения.          |                   |                   |
        +-----------------------+-------------------+-------------------|
        | Очистка всего элемента|  Clear            | cm_EditClear      |
        | редактирования.       |                   |                   |
        +-----------------------+-------------------+-------------------|
        | Удаление выделенного  |  DeleteSelection  | cm_EditDelete     |
        | текста.               |                   |                   |
        +-----------------------+-------------------+-------------------|
        | Отмена последнего     |  Undo             | cm_EditUndo       |
        | редактирования.       |                   |                   |
        +-----------------------+-------------------+-------------------+

             Чтобы добавить в окно меню редактирования, содержащее управ-
        ляющий элемент редактирования,  определите для окна с помощью ко-
        манд, перечисленных  в Таблице 12.7,  ресурс меню.  Никаких новых
        методов вам писать не нужно.

             Имеется также один дополнительный  метод  в  виде  булевской
        функции CanUndo,  который определяет, можно ли отменить последнюю
        операцию редактирования.


                      Опрос управляющих элементов редактирования
        -----------------------------------------------------------------

             Иногда нужно организовать опрос управляющих элементов редак-
        тирования  для  проверки  допустимости введенного текста,  записи
        ввода для его последующего использования или копирования ввода  в
        другой управляющий элемент.  TEdit поддерживает несколько методов
        опроса.  Многие из опросов управляющих элементов редактирования и
        методов  модификации  возвращают или требуют от вас указать номер
        строки или позицию символа в строке. Все эти индексы начинаются с
        нуля. Другими словами, первая строка - это нулевая строка, а пер-
        вый символ в любой строке это нулевой символ.  Самыми важными ме-
        тодами запроса являются GetText, GetLine, NumLines и LineLength.

          Методы опроса управляющих элементов редактирования  Таблица12.8
        +------------------------------------------+--------------------+
        |    Выполняемое действие                  | Вызываемый метод   |
        +------------------------------------------+--------------------|
        |    Определение изменения текста          | IsModified         |
        |    Считывание всего текста               | GetText            |
        |    Считывание строки                     | GetLine            |
        |    Получение числа строк                 | GetNumLines        |
        |    Получение длины данной строки         | GetLineLength      |
        |    Получение индекса выделенного текста  | GetSelection       |
        |    Получение диапазона символов          | GetSubText         |
        |    Подсчет символов перед строкой        | LineIndex          |
        |    Поиск строки, содержащей индекс       | GetLineFromProc    |
        +------------------------------------------+--------------------+

             Вы можете заметить, что методы запросов TEdit, которые возв-
        ращают  текст из управляющего элемента редактирования,  сохраняют
        форматирование текста.  Это важно только для многострочных управ-
        ляющих элементов редактирования, которые допускают появление нес-
        кольких строк текста.  В этом случае возвращаемый текст,  который
        занимает  несколько  строк  в управляющем элемента редактирования
        содержит в конце каждой строки два дополнительных символа:  возв-
        рат каретки (#13) и смена строки (#10). Если этот текст снова по-
        мещается в управляющий элемент редактирования, вставляется из бу-
        фера  вырезанного изображения,  записывается в файл или выводится
        на принтер, то строки разбиваются так, как это было в управляющем
        элемента редактирования.

             Следовательно, при  использовании метода запроса для получе-
        ния определенного числа символов,  нужно учитывать эти два симво-
        ла,  которые заканчивают строку. GetText ищет текст в управляющем
        элементе редактирования. Он заполняет строку, на которую указыва-
        ет переданный  аргумент  PChar,  содержимым управляющего элемента
        редактирования,  включая перевод строки. Общее число символов за-
        дается вторым параметром.  Он возвращает значение False, если уп-
        равляющий элемент редактирования пуст,  или содержит текста боль-
        ше,  чем помещается в предоставленную строку. Следующая процедура
        считывает из управляющего элемента редактирования строку и  выде-
        ленный текст:

            procedure TTestWindow.ReturnText(RetText: PChar);
            var TheText: array[020] of Char;
            begin
             if EC1^.GetText(@TheText, 20) then
              RetText:=@TheText
             else RetText:=nil;
            end;

            procedure TTestWindow.ReturnText(RetText: PChar);
            var TheText: array[020] 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[020] of Char;
             begin
               with EC1^ do
               begin
                 GetSelection(SelStart, SelEnd);
                 GetSubText(TheText, SelStart, SelEnd);
               end;
                 RetText := TheText;
             end;

                   Модификация управляющих элементов редактирования
        -----------------------------------------------------------------

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

                               Методы модификации
                      управляющих элементов редактирования   Таблица 12.9
        +----------------------------------------+----------------------+
        |    Выполняемое действие                | Вызываемый метод     |
        +----------------------------------------+----------------------|
        |    Удаление всего текста               | Clear                |
        |    Удаление выделенного текста         | DeleteSelection      |
        |    Удаление диапазона символов         | DeleteSubText        |
        |    Удаление строки текста              | DeleteLine           |
        |    Вставка текста                      | Insert               |
        |    Вставка текста из буфера            | Paste                |
        |    вырезанного изображения             |                      |
        |    Замена всего текста                 | SetText              |
        |    Выделение диапазона текста          | SelectRange          |
        |    Прокрутка текста                    | Scroll               |
        +----------------------------------------+----------------------+

                              Пример программы: EditTest
        -----------------------------------------------------------------

             EditTest - это программа, которая помещает на экран основное
        окно,  которое будет порождающим для двух  управляющих  элементов
        редактирования, двух статических управляющих элементов и  кнопки.
        Данное окно показано на Рис. 12.7.

             Когда пользователь щелкает на командной кнопке кнопкой  "мы-
        ши",  текст  из левого управляющего элемента редактирования (EC1)
        копируется в правый управляющий элемент редактирования  (EC2).  В
        EC2 текст преобразуется в буквы верхнего регистра,  поскольку оно
        было построено со стилем es_UpperCase. Если в C1 никакой текст не
        выбран, то в EC2 копируется весь текст. Если в EC1 выбран некото-
        рый текст,  то будет скопирован именно  он.  Меню  редактирования
        обеспечивает  функции редактирования независимо от того,  с каким
        управляющим элементов редактирования  идет  работа.  Полный  файл
        EDITTEST.PAS  и файл ресурса EDITTEST содержатся на ваших дистри-
        бутивных дискетах.

                         Использование комбинированных блоков
        -----------------------------------------------------------------

             Управляющий элемент типа комбинированного блока является со-
        четанием двух других управляющих элементов: блока списка и управ-
        ляющего  элемента редактирования.  Он служит тем же целям,  что и
        блок списка - позволяет пользователю выбрать один элемент  списка
        из  прокручиваемого  списка  элементов текста,  нажимая на кнопку
        "мыши".  Управление редактированием,  вынесенное в верхнюю  часть
        блока списка предоставляет иной механизм выбора, позволяя пользо-
        вателю ввести текст нужного элемента.  Если отображается  область
        списка комбинированного блока, то автоматически выбирается нужный
        элемент.  Тип TComboBox является производным от типа  TListBox  и
        наследует его методы модификации, опроса и выбора элементов спис-
        ка. Кроме того, TComboBox предоставляет методы по манипулированию
        списком, находящемся в комбинированном блоке, который в некоторых
        случаях может раскрываться по запросу.


                           Три типа комбинированных блоков
        -----------------------------------------------------------------

             Имеются три типа комбинированных блоков: простые, раскрываю-
        щиеся  и  раскрывающиеся со списком.  На Рис.  12.8 показан вывод
        трех типов комбинированных блоков с блоком списка.

        +-----------------------------------------------------------+-+-+
        |#=#XXXXXXXXXXXXXXXXXStatic Control TesterXXXXXXXXXXXXXXXXXX|^|v|
        +-----------------------------------------------------------+-+-|
        |                                                               |
        |  Блок списка                 Простой комбинированный блок     |
        |  +----------------+          +--------------------------+     |
        |  |a               |          |                          |     |
        |  |b               |          ++-------------------------|     |
        |  |c               |           |a                        |     |
        |  |d               |           |b                        |     |
        |  |e               |           |c                        |     |
        |  |f               |           |d                        |     |
        |  +----------------+           +-------------------------+     |
        |                                                               |
        |  Раскрывающийся комбинированный Комбинированный блок с        |
        |  блок                           раскрывающимся списком        |
        |  +-----------------------++---+ +----------------------+---+  |
        |  |                       || v | |c#####################| v |  |
        |  +-----------------------++---+ +----------------------+---+  |
        |                                                               |
        |                                                               |
        |                                                               |
        +---------------------------------------------------------------+

             Рис. 12.8 Три типа комбинированных блоков и блок списка.

                    Перечень стилей комбинированного блока  Таблица 12.10
        +---------------------+---------------------+-------------------+
        |    Стиль            |Возможность скрытого |Соответствие текста|
        |                     |     списка          |     списку        |
        +---------------------+---------------------+-------------------|
        |   Простой           |      нет            |      нет          |
        |   Раскрывающийся    |      есть           |      нет          |
        |   Раскрывающийся со |      есть           |      да           |
        |   списком           |                     |                   |
        +---------------------+---------------------+-------------------+

             С точки зрения пользователя между различными стилями  комби-
        нированных блоков существуют следующие различия:

             * Простые комбинированные блоки.

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

             * Раскрывающиеся комбинированные блоки.

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

             * Раскрывающиеся комбинированные блоки списка.

               Область списка  в  раскрывающемся  комбинированном   блоке
               списка  ведет  себя  подобно области списка в спускающемся
               комбинированном блоке - появляется при необходимости и ис-
               чезает,  когда не нужна. Эти два типа комбинированных бло-
               ков отличаются  поведением  их  областей   редактирования.
               Раскрывающиеся  области  редактирования ведут себя подобно
               обычным управляющим элементам редактирования. Раскрывающи-
               еся  области  редактирования  списка ограничиваются только
               отображением одного элемента  списка.  Если  редактируемый
               текст соответcтвует  элементу списка,  то никаких дополни-
               тельных символов ввести нельзя.

                          Выбор типа комбинированного блока
        -----------------------------------------------------------------

             Раскрывающиеся комбинированные блоки списка удобно использо-
        вать тогда,  когда не допускаются никакие другие варианты,  кроме
        перечисленных в области списка. Например, при выборе принтера для
        печати можно выбрать только принтер, к которому есть доступ в ва-
        шей системе.

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

                          Построение комбинированных блоков
        -----------------------------------------------------------------

             Кроме обычных  6  параметров  объектов управляющих элементов
        конструктор Init для TComboBox воспринимает в качестве аргументов
        стиль и максимальную длину текста. Конструктор TComboBox описыва-
        ется следующим образом:

             constructor TComboBox.Init(AParent: PWindowsObject;
                                      AnID: Integer: X, Y, W, H: Integer;
                                      AStyle, ATextLen: Word);

              Все комбинированные блоки, построенные с помощью Init, име-
        ют стили ws_Child,  ws_Visible, cbs_AutoHScroll, cbs_Sort (отсор-
        тированный список),  и VScroll (вертикальная  полоса  прокрутки).
        Параметр  стиля  - это один из стандартных стилей комбинированных
        блоков Windows:  cbs_Simple,  cbs_DropDown или  cbs_DropDownList.
        Параметр длины текста работает подобно соответствующему параметру
        управляющего элемента редактирования, ограничивая число символов,
        которые  можно  ввести  в область редактирования комбинированного
        блока.

             Следующие строки приведут к созданию спускающегося  комбини-
        рованного блока списка с неотсортированным списком:

             CB3: = New(PComboBox, Init(@Self, id_CB3, 190, 160,
                        150, 100, cbs_DropDownList, 40));
             CB3^.Attr.Style:=CB3^.Attr.Style and (not cbs_Sort);

                          Модификация комбинированных блоков
        -----------------------------------------------------------------

             TComboBox определяет  два метода для демонстрации и сокрытия
        области списка в раскрывающихся комбинированных блоках и  раскры-
        вающихся комбинированных блоках списка:  ShowList и HideList. Обе
        эти процедуры не нуждаются в аргументах.  Вызывать эти методы для
        демонстрации или сокрытия  списка,  когда  пользователь  нажимает
        стрелку вниз справа от области редактирования,  не нужно.  В этом
        случае работает автоматический механизм  комбинированных  блоков.
        Эти методы полезны только для принудительного вывода или сокрытия
        списка.

                              Пример программы: CBoxTest
        -----------------------------------------------------------------

             Программа CBoxTest реализует приложение,  показанное на Рис.
        12.8. В нем использованы все три типа комбинированных блоков. CB1
        - это простой комбинированный блок, CB2 это раскрывающийся комби-
        нированный блок,  а CB3 - это раскрывающийся комбинированный блок
        списка. Нажатие кнопок Show и Hide выполняет принудительный вывод
        и сокрытие правого верхнего комбинированного  блока,  CB3,  путем
        вызова методов ShowList и HideList.

                  Примечание: Полный  текст файла CBOXTEST.PAS содержится
              на ваших дистрибутивных дискетах.

                       Установка значений управляющих элементов
        -----------------------------------------------------------------

             Для управления  сложными  блоками  диалога или окнами с мно-
        жеством дочерних окон управляющих элементов вы обычно можете  для
        хранения  и выяснения состояния его управляющих элементов создать
        производный тип объекта. Состояние управляющего элемента включает
        в себя текст управляющего элемента редактирования,  положение по-
        лосы прокрутки и установку кнопки с зависимой фиксацией.

                        Для чего используется буфер передачи?
        -----------------------------------------------------------------

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

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

             Механизм передачи   требует  для  представления  управляющих
        элементов, для которых вы будете передавать данные, использования
        объектов ObjectWindows.  Это означает, что вы должны использовать
        InitResource для связывания объектов с управляющими элементами  в
        блоках и окнах диалога.

                   Примечания: Связь управляющих элементов с управляющими
              объектами описывается в Главе 11 "Объекты  диалоговых  бло-
              ков".

             Чтобы использовать механизм передачи, вы можете сделать сле-
        дующее:

             * Определить буфер передачи.
             * Определить соответствующее окно.
             * Передать данные.

                             Определение буфера передачи
        -----------------------------------------------------------------

             Буфер передачи - это запись с одним полем для каждого управ-
        ляющего элемента,  участвующего в передаче. Окно или диалог могут
        также иметь управляющие элементы,  значения которых не устанавли-
        ваются механизмом передачи. Например, командные кнопки, у которых
        нет  состояния,  не участвуют в передаче.  Это же справедливо для
        групповых блоков.

             Для определения буфера передачи нужно  определить  поле  для
        каждого участвующего управляющего элемента диалога или окна.  Оп-
        ределять поля для каждого управления диалога или окна не требует-
        ся - нужно лишь определить поля для тех из них, которые будут по-
        лучать и принимать значения по вашему желанию. Этот буфер переда-
        чи  хранит один из каждых типов управляющих элементов,  кроме ко-
        мандной кнопки и блока группы:

             type
             TSampleTransferRecord = record
               Stat1: array[0TextLen-1] of Char; { статический текст }
               Edit1: array[0TextLen-1] of Char; { текст управляющего
                                                элемента редактирования }
               List1Strings: PStrCollection;      { строки блока списка }
               List1Selection: Integer; { индекс выбранных строк }
               ComboStrings: PStrCollection; { строки комбинированного
                                                блока }
               ComboSelection: array[0TextLen-1] of Char; { выбранные
                                                строки }
               Check1: Word;                 { проверка состояния блока}
               Radio1: Word; { состояние кнопки с независимой фиксацией }
               Scroll1: ScrollBarTransferRec;  {  диапазон полосы
                                               прокрутки и т.д. }
             end;


             В каждом  типе  управляющего элемента хранится различная ин-
        формация. Буфер передачи для  каждого  стандартного  управляющего
        элемента поясняется в следующей таблице:

                             Поля буфера передачи
                    для каждого типа управляющего элемента  Таблица 12.11
        +-----------------------+---------------------------------------+
        |  Тип управляющего     |            Буфер передачи             |
        |     элемента          |                                       |
        +-----------------------+---------------------------------------|
        |  Статический          | Символьный массив  размером до  макси-|
        |                       | мальной длины текста, плюс завершающий|
        |                       | нулевой символ.                       |
        |                       |                                       |
        +-----------------------+---------------------------------------|
        |  Редактирование       | Текстовый буфер управляющего  элемента|
        |                       | редактирования размером до  длины, оп-|
        |                       | ределенной в текстовом поле TextLen.  |
        |                       |                                       |
        +-----------------------+---------------------------------------|
        |  Блок списка          |                                       |
        |   одиночный выбор     | Набор строк в списке, плюс целочислен-|
        |                       | ный индекс выделенной строки.         |
        |                       |                                       |
        |   множественный выбор | Набор строк в списке, плюс запись, со-|
        |                       | держащая индексы всех выделенных  эле-|
        |                       | ментов.                               |
        |                       |                                       |
        +-----------------------+---------------------------------------|
        |  Комбинированный блок | Набор строк в списке,  плюс  выбранная|
        |                       | строка.                               |
        |                       |                                       |
        +-----------------------+---------------------------------------|
        |  Кнопка с независимой | Значения Word с указывающими состояния|
        |  фиксацией            | bf_Unchecked, bf_Checked и bf_Grayed. |
        |                       |                                       |
        +-----------------------+---------------------------------------|
        |  Кнопка с зависимой   | Значения Word с указывающими состояния|
        |  фиксацией            | bf_Unchecked, bf_Checked и bf_Grayed. |
        |                       |                                       |
        +-----------------------+---------------------------------------|
        |  Полоса прокрутки     | Запись типа TScrollBarTransferRec, со-|
        |                       | храняющая диапазон полосы прокрутки  и|
        |                       | позицию в ней.                        |
        |                       |                                       |
        +-----------------------+---------------------------------------+

             Тип TScrollBarTransferRec имеет вид:

             TScrollBarTransferRec := record
              LowValue : Integer;
              HighValue: Integer;
              Position : Integer;
             end;

                                   Определение окна
        -----------------------------------------------------------------

             Окно или диалоговый блок, которые используют буфер передачи,
        должны  создавать объекты участвующих управляющих элементов в той
        последовательности, в которой определяются их соответствующие по-
        ля буфера передачи.  Для подключения механизма передачи к объекту
        окна или  диалога  нужно  просто  установить  значение  его  поля
        TransferBuffer в указатель на определенный вами буфер передачи.

                  Использование буфера передачи с диалоговым блоком
        -----------------------------------------------------------------

             Для случая  окон с управляющими элементами объекты управляю-
        щих элементов конструируются с использованием Init.  Для диалогов
        и окон диалогов нужно использовать конструктор InitResource. Нап-
        ример (используется определенный ранее тип TSampleRecord):

             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;

             Для управляющих    элементов,    построенных    с    помощью
        InitResource, механизм передачи разрешается автоматически.

                        Использование буфера передачи с окном
        -----------------------------------------------------------------

             Для случая окна с управляющими  элементами  используйте  для
        конструирования  объектов  управления в надлежащей последователь-
        ности Init,  а не InitResource.  Другое отличие между диалогами и
        окнами состоит в том,  что механизм передачи по умолчанию для уп-
        равляющих  элементов окна запрещен.  Для разрешения использования
        механизма вызывается EnableTransfer:

             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;

             Чтобы явно  исключить управляющий элемент из механизма пере-
        дачи, вызовите после его создания метод DisableTransfer.

                                   Передача данных
        -----------------------------------------------------------------

             В большинстве  случаев  передача  данных  в окно выполняется
        автоматически, но в любой момент вы можете явно передать данные.

                                Передача данных в окно 
        -----------------------------------------------------------------

             После создания окна или диалогового блока  данные  автомати-
        чески. Для  создания экранного элемента,  представляющего оконный
        объект, конструктор вызывает SetupWindow. Затем для загрузки дан-
        ных из буфера передачи вызывается TransferData.  Окно SetupWindow
        интерактивно вызывает SetupWindow для каждого из  дочерних  окон,
        так что  дочерние  окна  имеют  возможность передать свои данные.
        Поскольку порождающее окно устанавливает свои дочерние окна в по-
        рядке их построения,  данные в буфере передачи должны следовать в
        том же порядке.

             Если объект  управляющего  элемента  был  построен с помощью
        InitResource или если порождающее окно  явным  образом  разрешило
        межанизм   передачи   путем   вызова  для  управляющего  элемента
        EnableTransfer, то методы управляющего объекта SetupWindow  вызы-
        вают TransferData.

                         Передача данных из диалогового окна
        -----------------------------------------------------------------

             Когда режимное диалоговое окно получает командной  сообщение
        с идентификатором управляющего элемента id_OK,  оно автоматически
        передает данные из управляющего элемента в буфер передачи. Обычно
        ляет свой буфер передачи. Затем, если вы снова выполняете диалог,
        диалоговый блок передает текущие данные в управляющие элементы.

                               Передача данных из окна
        -----------------------------------------------------------------

             Однако, вы можете явно передавать данные в любом направлении
        в  любой момент времени.  Например,  вы можете передать данные из
        управляющих элементов окна или безрежимного диалога. Вы также мо-
        жете  сбросить состояния управляющих элементов,  используя данные
        буфера передачи,  в  ответ  на  щелчок  "мышью"  на  кнопке Reset
        (сброс).  В обоих случаях используется метод TransferData.  Конс-
        танта tf_SetData обозначает передачу данных из буфера в управляю-
        щий элемент, а константа tf_GetData - передачу в другом направле-
        нии.  Например,  вы  можете вызвать TransferData в методе Destroy
        объекта окна:

             procedure TSampleWindow.Destroy;
             begin
              TransferData(tf_GetData);
              TWindow.Destroy;
             end;

         Поддержка передачи для специализированных управляющих элементов
        -----------------------------------------------------------------

             Вы можете изменить способ передачи  данных  для  конкретного
        управляющего элемента или включить новый управляющий элемент, оп-
        ределенный вами в механизме передачи.  В обоих случаях вам просто
        нужно  написать  метод  Transfer для вашего управляющего объекта,
        который если установлен флаг tf_GetData копирует данные из управ-
        ляющего элемента в место,  задаваемое указателем. Если установлен
        флаг tf_SetData,  то просто скопируйте данные по заданному указа-
        телю   в  управляющий  элемент.  Рассмотрим  в  качестве  примера
        TStatic.Transfer:

             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;

             Метод Transfer должен  всегда  возвращать  число  переданных
        байт информации.

                              Пример программы: TranTest
        -----------------------------------------------------------------

             Основное окно программы TranTest воспроизводит режимный диа-
        лог с полями, в которые пользователь вводит данные об имени и ад-
        ресе.  Буфер передачи используется для хранения этой информации и
        отображения ее в управляющих элементах диалога при повторном  его
        выполнении.  Обратите внимание на то, что нам не нужно определять
        новый тип объекта диалога для установки и поиска данных  диалога.
        Также обратите ваше внимание на то,  что мы непосредственно мани-
        пулируем данными буфера передачи,  поэтому статическое управление
        при  первом  выводе  диалога гласит "First Mailing Label" (первая
        почтовая этикетка),  а при всех остальных появлениях  "Subsequent
        Mailing Label" (следующая почтовая этикетка).

                   Примечание: Полный  текст программы содержится в файле
              TRANTEST.PAS на ваших дистрибутивных дискетах.


                Использование специализированных управляющих элементов
        -----------------------------------------------------------------

             Windows обеспечивает  механизм,  позволяющий  вам  создавать
        свои собственные виды управляющих элементов,  а ObjectWindows об-
        легчает создание объектов,  использующих преимущества управляющих
        элементов. В данном разделе обсуждается использование специализи-
        рованных управляющих  элементов Borland,  которые придают своеоб-
        разный вид работающим в Windows приложениям Borland, а затем опи-
        сывается, как  создавать  свои собственные уникальные управляющие
        элементы.

             Специализированные управляющие элементы Borland для Windows
        -----------------------------------------------------------------

             Специализированные управляющие  элементы Borland для Windows
        (BWCC) обеспечивают выразительный внешний вид приложений  Borland
        для Windows. Основными средствами BWCC являются:

             * командные кнопки с графическими изображениями;

             * серый "рельефный" фон диалоговый блоков;

             * трехмерные кнопки с зависимой и независимой фиксацией.

             ObjectWindows дает  вам возможность простого доступа к BWCC,
        так что вы можете  придать  своим  приложениями  стандартный  для
        Borland вид.


                            Использование стандартных BWCC
        -----------------------------------------------------------------

             ObjectWindows позволяет легко добавлять BWCC в ваши приложе-
        ния Windows.  Нужно просто добавить модуль BWCC в  оператор  uses
        программы:

             uses BWCC;

             Использование BWCC автоматически позволяет вам делать следу-
        ющее:

             * использовать загружаемые из ресурсов управляющие  элементы
               BWCC;

             * создавать в вашей программе BWCC.

             Например, с  помощью  пакета  разработчика ресурсов Resource
        WorkShop вы можете создать ресурсы диалоговых блоков,  использую-
        щие специализированные управляющие элементы Borland.  Включение в
        оператор uses программы модуля BWCC обеспечивает для вашей  прог-
        раммы информацию о том, где искать динамически компонуемую библи-
        отеку (BWCC.DLL),  содержащую код,  который  обеспечивает  работу
        BWCC.

             Кроме того, после добавления модуля BWCC любые создаваемые в
        программе объекты управляющих элементов будут иметь вид и  харак-
        теристики управляющих элементов Borland.

                                    Средства BWCC
        -----------------------------------------------------------------

             BWCC добавляет  к  стандартным управляющим элементам в стиле
        Windows некоторые новые стили,  но подчиняется также новым согла-
        шения и предположениям. Если вы создаете все свои новые управляю-
        щие элементы из ресурсов,  то беспокоиться об этом вам не  нужно.
        Однако при  построении  управляющих  элементов в программном коде
        вам может потребоваться использовать некоторые новые стили и сле-
        довать соглашениям.


                                   Расширение BWCC
        -----------------------------------------------------------------

             BWCC обеспечивает кнопки с  графическими  изображениями  для
        всех стандартных командных кнопок Windows.  То есть, имеются гра-
        фические изображения,  предусмотренные для командных кнопок,  для
        которых Windows обеспечивает стандартный идентификатор: id_Abort,
        id_Cancel, id_Ignore, id_No, id_Ok, id_Retry и id_Yes.

                  Создание кнопок с графическими изображениями

             В своих приложениях вы можете обеспечить для командных  кно-
        пок собственные графические образы. Все что нужно предусмотреть -
        это шесть  ресурсов  графических  изображений (битовых массивов),
        пронумерованных относительно идентификатора управляющего элемента
        вашей командной кнопки.  Например,  если вы хотите создать графи-
        ческую командную кнопку с идентификатором id_MyButton, то создае-
        те  ресурсы  битовых  массивов  с идентификаторами ресурса 1000 +
        id_MyButton,  2000 + id_MyButton,  3000  +  id_MyButton,  4000  +
        id_MyButton,  5000  +  id_MyButton  и 6000 + id_MyButton.  Каждый
        представляемый битовый массив показан в следующей таблице:

        Ресурсы битовых массивов для командных кнопок BWCC  Таблица 12.12
        +------------------------+-----------------+--------------------+
        |    Образ               | Идентификатор   | Идентификатор      |
        |                        |  ресурса VGA    |  ресурса VGA       |
        +------------------------+-----------------+--------------------|
        |    Командная кнопка    | 1000 + идент.   |  2000 + идент.     |
        |    в фокусе            |                 |                    |
        |                        |                 |                    |
        +------------------------+-----------------+--------------------|
        |    Нажатая командная   | 3000 + идент.   |  4000 + идент.     |
        |    кнопка              |                 |                    |
        |                        |                 |                    |
        +------------------------+-----------------+--------------------|
        |    Командная кнопка    | 5000 + идент.   |  6000 + идент.     |
        |    не в фокусе         |                 |                    |
        |                        |                 |                    |
        +------------------------+-----------------+--------------------+

             Графические образы  командных кнопок VGA должны иметь ширину
        63 и высоту 39 элементов изображения.  Графические образы команд-
        ных кнопок EGA должны иметь  ширину  63  и  высоту  39  элементов
        изображения.

             Для текста следует использовать шрифт Helvetica  размером  8
        пунктов, а  вокруг образа кнопки,  находящейся в фокусе,  следует
        выводить рамку из точек.  Набор графических изображений  для  ко-
        мандных кнопок  с идентификатором 201 показан на следующем рисун-
        ке:

        +------------------+  +------------------+  +------------------+
        |##################|  |##################|  |##################|
        |###@@######Add####|  |###@@######Add####|  |###@@######Add####|
        |#@@@@@@####Pen####|  |#@@@@@@####Pen####|  |#@@@@@@####Pen####|
        |###@@#############|  |###@@#############|  |###@@#############|
        |##################|  |##################|  |##################|
        +------------------+  +------------------+  +------------------+
                1201                  3201                  5201

        +------------------+  +------------------+  +------------------+
        |                  |# |          .   |  |          .  #|
        |   @@      Add    |# |   @@    : Add :  |  |   @@    : Add : #|
        | @@@@@@    Pen    |# | @@@@@@  : Pen :  |  | @@@@@@  : Pen : #|
        |   @@             |# |   @@     .   |  |   @@     .  #|
        |                  |# |                  |  | #################|
        +------------------+# +------------------+  +------------------+
          ###################
                2201                  4201                  6201

             Рис. 12.9  Графические  ресурсы  для командной кнопки BWCC с
        идентификатором 201.
                              Создание ваших собственных
                    специализированных управляющих элементов
        -----------------------------------------------------------------

             Простейший способ создания специализированного  управляющего
        элемента состоит  в фактическом создании окна,  которое действует
        как управляющий элемент,  но вовсе не является окном. Этот подход
        используется в программе Steps в Части 1 данного руководства. Тот
        же используемый в программе Steps метод применяется для ее объек-
        та палитры,  который можно использовать,  например,  для создания
        объекта инструментальной полосы. Таким "управляющие элементы" яв-
        ляются наследниками TWindow,  а не TControl,  поскольку  TControl
        имеет   дело   только  со  стандартными  управляющими  элементами
        Windows.

             Другим стандартным способом создания специализированного уп-
        равляющего элемента является построение в динамически компонуемой
        библиотеке нового класса окон.  После этого вы  можете  создавать
        объекты ObjectWindows,  использующие этот новый класс. Пакет раз-
        работчика ресурсов также  может  использовать  специализированные
        управляющие элементы,  созданные в DLL. Информацию об использова-
        нии специализированных управляющих элементов в ресурсах  диалого-
        вых  блоках вы можете найти в "Руководстве пользователя по пакету
        разработчика ресурсов".

                   Примечание: О классах окон рассказывается в Главе 10. 
                              Назад | Содержание | Вперед
Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...