Библиотека визуальных компонентов VCL и ее базовые классы


Все классы библиотеки визуальных компонентов произошли от группы базовых классов, которые лежат в основе иерархии VCL. Самый общий предок компонентов — это класс TObject, инкапсулирующий простейший объект. Как известно, каждый объект наследует свойства и методы родительского класса. К объекту можно добавить новые свойства и методы, но нельзя удалить унаследованные. Объект-наследник в свою очередь может стать родительским для нового класса, который унаследует возможности всех своих предков.
Поэтому иерархия базовых классов VCL продумана чрезвычайно тщательно — ведь на их основе создано все множество компонентов, используемых в Delphi. Особое место среди базовых классов, помимо TObject, занимают TComponent (от него происходят все компоненты) и TControl (от него происходят все элементы управления).
В этой главе рассматривается иерархия базовых классов и их возможности. Представленные здесь сведения помогут разобраться с основными механизмами функционирования компонентов. Настоящая глава послужит справочным материалом для тех, кто создает собственные объекты и элементы управления.
 
Иерархия базовых классов
В основе всего многообразия классов и компонентов, используемых в Delphi, лежат всего лишь пять базовых классов. Они обеспечивают выполнение основных функций любого объекта — будь это стандартный компонент VCL или специализированный объект, выполняющий некоторые операции в приложении.
Благодаря механизму наследования свойств и методов, потомки базовых классов умеют "общаться" друг с другом; работают в среде разработки, взаимодействуя с Палитрой компонентов и Инспектором объектов; распознаются операционной системой как элементы управления и окна.
В основе иерархии классов лежит класс TObject. Он обеспечивает выполнение важнейших функций "жизнедеятельности" любого объекта. Благодаря ему, каждый класс получает в наследство механизмы создания экземпляра объекта и его уничтожения.
Обычно разработчик даже не задумывается о том, как объект будет создан и что необходимо сделать для его корректного уничтожения. Компоненты VCL создаются и освобождают занимаемые ресурсы автоматически. Иногда разработчику приходится создавать и удалять объекты самостоятельно. Но даже в этом случае ему достаточно вызвать соответствующие конструктор и деструктор:
var SomeList: TStrings;
...
 SomeList := TStrings.Create; 
...
SomeList.Free;
За кажущейся простотой этих операций скрывается довольно сложная реализация указанных процессов. Практически весь исходный код класса TObject написан на ассемблере для обеспечения наибольшей эффективности операций, которые будут выполняться в каждом его потомке.
Кроме этого, класс TObject обеспечивает создание и хранение информации об экземпляре объекта и обслуживание очереди сообщений.
Класс TPersistent происходит непосредственно от класса TObject. Он обеспечивает своих потомков возможностью взаимодействовать с другими объектами и процессами на уровне данных. Его методы позволяют передавать данные в потоки, а также обеспечивают взаимодействие объекта с Инспектором объектов.
Класс TComponent является важнейшим для всех компонентов. Непосредственно от него можно создавать любые невизуальные компоненты. Механизмы, реализованные в классе TComponent, обеспечивают взаимодействие компонента со средой разработки, главным образом с Палитрой компонентов и Инспектором объектов. Благодаря возможностям этого класса, компоненты начинают работать на форме проекта уже на этапе разработки.
Класс TControl происходит от класса TComponent. Его основное назначение — обеспечить функционирование визуальных компонентов. Каждый визуальный компонент, произошедший от TControl, наделяется основными признаками элемента управления. Благодаря этому, каждый визуальный компонент умеет работать с GUI (Graphic User Interface — графический интерфейс пользователя ОС) и отображать себя на экране.
Класс TWinControl расширяет возможности разработчиков по созданию элементов управления. Он наследуется от класса TControl и обеспечивает создание оконных элементов управления.
На основе класса TWinControl создан еще один дополнительный класс — TCustomControl. Он обеспечивает создаваемые на его основе компоненты возможностями по использованию канвы — специального объекта, предназначенного для отображения графики (подробнее о канве см. гл. Л).
Класс TCustomControl является общим предком для целой группы классов, обеспечивающих создание различных нестандартных типов оконных (получающих фокус) элементов управления Windows: редакторов, списков и т. д.
Для создания неоконных (не получающих фокус) элементов управления используется класс TGraphicControl, являющийся потомком класса TControli.
В целом иерархия базовых классов обеспечивает полноценную работу разработчиков в Delphi, позволяя проектировать любые типы приложений.
Ниже мы остановимся на основных свойствах и методах базовых классов, выделяя только те, которые могут пригодиться в реальной работе. Часть из них доступна в Инспекторе объектов, часть может быть использована в программном коде.
 
Класс TObject
Класс TObject является родоначальником всей иерархии использующихся в Delphi классов VCL. Он реализует функции, которые обязательно будет выполнять любой объект, который может быть создан в среде разработки. Учитывая гигантское разнообразие возможных областей применения объектов в процессе создания приложений, можно сказать, что круг общих для всех классов операций весьма невелик.
В первую очередь — это создание экземпляра объекта и его уничтожение. Любой объект выполняет эти две операции в обязательном порядке. Процесс создания объекта включает выделение области адресного пространства, установку указателя на экземпляр объекта, задание начальных значений свойств и выполнение установочных действий, связанных с назначением объекта. В общем случае две последние операции могут не выполняться.
Указатель на экземпляр объекта передается в переменную объектного типа, которая в дальнейшем будет идентифицировать объект в программном коде приложения. В приведенном выше фрагменте кода переменная объектного типа someList объявлена как экземпляр типа TStrings. При создании экземпляра этого типа конструктор Create возвращает в переменную SomeList указатель на выделенную для нового объекта область памяти. Для этого применяется метод Newinstance, который вызывается в конструкторе автоматически:
class function Newinstance: TObject; virtual;
Объект класса TObject обеспечивает выполнение этого процесса для любого порожденного от него объекта. А уже внутри конструктора, который унаследован от класса TObject, можно предусмотреть инициализацию переменных и выполнение дополнительных операций. Объявление конструктора выглядит следующим образом:
 constructor Create;
В конструкторах потомков это объявление может перекрываться, но при необходимости вызвать конструктор предка используется оператор inherited:
constructor TSomeObject.Create; 
begin 
inherited Create;
...
end;
Для уничтожения экземпляра объекта в классе TObject предназначены методы Destroy и Free:
destructor Destroy; virtual; 
procedure Free;
Как видно из объявления, настоящим деструктором является метод Destroy. Он обеспечивает освобождение всех занимаемых экземпляром объекта ресурсов. Обычно при создании новых классов деструктор всегда перекрывается для того, чтобы корректно завершить работу с данными.
Примечание
Обратите внимание, что обычно унаследованный конструктор вызывается в первую очередь. Это необходимо для того, чтобы выполнить все нужные операции при создании объекта до инициализации его собственных свойств. При уничтожении объекта обычно сначала выполняются завершающие операции и только в самом конце вызывается унаследованный деструктор, чтобы выполнить собственно уничтожение объекта.
При уничтожении объектов рекомендуется вместо деструктора использовать метод Free, который просто вызывает деструктор, но перед этим проверяет, чтобы указатель на экземпляр объекта был не пустым (не был равен Nil). Это позволяет избежать серьезных ошибок.
Если объект является владельцем других объектов (например, форма владеет всеми размещенными на ней компонентами), то его метод Free автоматически вызовет эти же методы для всех объектов. Поэтому при закрытии формы разработчик избавлен от необходимости заботиться об уничтожении всех компонентов.
Для освобождения занимаемой объектом памяти деструктор автоматически Вызывает метод Freelnstance:
procedure Freelnstance; virtual;
Каждый объект должен содержать некоторую информацию о себе, которая используется приложением и средой разработки. Поэтому класс TObject содержит ряд методов, обеспечивающих представление этой информации в потомках.
Метод
class function Classlnfo: Pointer;
возвращает указатель на таблицу информации времени выполнения (RTTI). Эта информация используется в среде разработки и в приложении.
Функция
class function ClassName: ShortString;
возвращает имя типа объекта, которое может быть использовано для идентификации. Например, один метод-обработчик щелчка на кнопке может работать с несколькими типами компонентов кнопок:
procedure TForml.BitBtnlClick(Sender: TObject);
 begin 
if Sender is TBitBtn
then TBitBtn(Sender).Enabled := False;
 if Sender is TSpeedButton
then TSpeedButton(Sender).Down := True;
  end;
Метод
class function ClassNamels(const Name: string): Boolean;
позволяет определить, является ли данный объект того типа, имя которого передано в параметре Name. В случае положительного ответа функция возвращает True.
Как известно, программирование для Windows основано на событиях. Каждое приложение и каждый программный объект должны уметь реагировать на сообщение о событиях и, в свою очередь, рассылать сообщения. В выполнении этих операций заключается третья общая для всех объектов функция.
Метод
procedure Dispatch(var Message); virtual;
осуществляет обработку сообщений, поступающих объекту. Он определяет, сможет ли объект обработать сообщение при помощи собственных обработчиков событий. В случае отсутствия таких методов сообщение передается аналогичному методу Dispatch класса-предка (если он есть).
Класс TObject имеет предопределенный обработчик событий:
procedure DefaultHandler(var Message); virtual;
Кроме рассмотренных здесь методов, класс TObject имеет еще несколько методов, которые в основном применяются для взаимодействия объекта со средой разработки.
В целом класс TObject может служить для создания на его основе некоторых простых классов для использования в приложениях.
 
Класс TPersistent
"Persistent" в переводе с английского означает "устойчивый", "постоянный". Что же такого постоянного в одноименном классе? Ответ таков: виртуальный метод
procedure Assign(Source: TPersistent);
Этот важнейший метод осуществляет копирование содержимого одного объекта (source) в другой (self, т. е. в объект, вызвавший метод Assign). При этом объект-получатель остается самим собой, чего нельзя достигнуть, используя простое присваивание переменных объектного типа:
FirstObject := SecondObject;
Ведь в этом случае указатель на одну область адресного пространства, содержащую экземпляр класса (объект), замещается указателем на другую область адресного пространства, содержащую другой объект.
Метод Assign позволяет продублировать объект — присвоить одному объекту значения всех свойств другого. При этом объекты не обязательно должны быть одного и того же класса; более того, они не обязательно должны находиться в отношениях "родитель-потомок". Данный метод тем и хорош, что позволяет полиморфное присвоение. Конструкция
Clipboard.Assign(Picture);
позволяет скопировать содержимое картинки Picture в папку обмена Windows (объект clipboard). Какова здесь логика? Известно, что в папку обмена можно поместить растровую картинку, текст, метафайл, мультимедийные данные и т. п. Метод Assign класса TClipboard переписан таким образом, чтобы обеспечить присвоение (т. е. реальное перемещение в папку обмена) всех этих данных.
procedure TCiipboard.Assign(Source: TPersistent);
 begin
if Source is TPicture
then AssignPicture(TPicture(Source)) 
else
if Source is TGraphic
then AssignGraphic(TGraphic(Source))
 else  inherited Assign(Source);
  end;
Для обеспечения взаимодействия потомков класса TPersistent со средой разработки предназначен метод
function GetNamePath: string; dynamic;
Он возвращает имя объекта для передачи его в Инспектор объектов.
Для взаимодействия с потоками при загрузке и сохранении компонентов предназначен следующий метод:
procedure DefineProperties(Filer: TFiler); virtual;
Класс TPersistent никогда не используется напрямую, от него порождаются потомки, которые должны уметь передавать другим объектам значения своих свойств, но не являться при этом компонентами.
 
Класс TComponent
Класс TComponent является предком всех компонентов VCL. Он используется в качестве основы для создания невизуальных компонентов и реализует основные механизмы, которые обеспечивают функционирование любого компонента. В нем появляются первые свойства, которые отображаются в Инспекторе объектов. Это свойство
property Name: TComponentName;
Оно содержит имя экземпляра компонента, которое используется для идентификации компонента в приложении.
Примечание 
Тип TComponentName представляет собой обычную строку:
type TComponentName = type string;
Свойство
property Tag: Longint;
является вспомогательным и не влияет на работу компонента. Оно отдано на откуп разработчику, который может присваивать ему значения по своему усмотрению. Например, это свойство можно использовать для дополнительной, более удобной идентификации компонентов.
Для компонентов существует своя иерархия, поэтому в классе введен механизм учета и управления компонентами, для которых данный компонент является владельцем. Свойства и методы, которые отвечают за управление, приведены в табл. 2.1.

Таблица 2.1. Свойства и методы для управления списком компонентов


Свойство (метод)

Описание

property Components [Index: Integer]: TComponent ;

Содержит индексированный список указателей всех компонентов, для которых данный компонент является владельцем (owner)

property ComponentCount : Integer;

Число подчиненных компонентов

property Owner: TComponent;

Указывается, какой компонент является владельцем данного

property Componentlndex: Integer;

Индекс данного компонента в списке владельца

procedure InsertComponent (AComponent : TComponent) ;

Вставляет компонент AComponent в список

procedure RemoveComponent (AComponent : TComponent};

Удаляет компонент AComponent из списка

procedure FindComponent (AName: string): TComponent;

Осуществляет поиск компонента по имени AName

procedure DestroyComponents;

Предназначен для уничтожения всех компонентов, подчиненных данному

Очень важное свойство
type TComponentState = set of (csLoading, csReading, csWriting, csDestroying, csDesigning, csAncestor, csllpdating, csFixups, csFreeNotification, cslnline, csDesignlnstance); property ComponentState: TComponentState;
дает представление о текущем состоянии компонента. В табл. 2.2 описаны возможные состояния компонента. Состояние может измениться в результате получения компонентом некоторого сообщения, действий разработчика, выполнения акции и т. д. Это свойство активно используется средой разработки.
Таблица 2.2. Возможные состояния компонента


Состояние

Описание

csLoading

Устанавливается при загрузке компонента из потока

csReading

Устанавливается при чтении значений свойств из потока

csWriting

Устанавливается при записи значений свойств в поток

csDestroying

Устанавливается при уничтожении компонента

csDesigning

Состояние разработки. Устанавливается при работе с формой во время разработки

csAncestor

Устанавливается при переносе компонента на форму. Для перехода в это состояние должно быть уже установлено состояние csDesigning

csUpdating

Устанавливается при изменении значений свойств и отображения результата на форме-владельце. Для перехода в это состояние должно быть уже установлено состояние csAncestor

CsFixups

Устанавливается, если компонент связан с компонентом другой формы, которая еще не загружена в среду разработки

csFreeNotification

Если это состояние устанавливается, другие компоненты, связанные с данным, уведомляются о его уничтожении

cslnline

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

csDesignlnstance

Определяет корневой компонент на этапе разработки

Для обеспечения работы механизма действий (см. гл. 8) предназначен
метод
function ExecuteAction(Action: TBasicAction): Boolean; dynamic;
Он вызывается автоматически при необходимости выполнить акцию, предназначенную для данного компонента.
На уровне класса TComponent обеспечена поддержка СОМ-интерфейсов IUnknown и IDispatch.
Через свойство
property ComObject: IUnknown;
вы можете обеспечить применение методов этих интерфейсов.
Таким образом, класс TComponent имеет все для использования в качестве предка, для создания собственных невизуальных компонентов.
 
Базовые классы элементов управления
Вслед за классом TComponent в иерархии базовых классов (см. 1) располагается группа из трех классов, которые обеспечивают создание различных визуальных компонентов. Визуальные компоненты — это разнообразные стандартные для Windows и специальные (созданные разработчиками Inprise) элементы управления.
Понятно, что визуальные компоненты должны уметь отобразить себя на экране монитора и реагировать на целый ряд новых событий (реакция на мышь и клавиатуру, движение курсора и т. д.). Для этого в них встроен специальный механизм, обеспечивающий взаимодействие компонентов с графической подсистемой ОС (GUI).
Существует несколько типов элементов управления, которые существенно отличаются по своим возможностям и поведению. Каждому типу соответствует собственный класс иерархии.
Класс TWinControl обеспечивает использование в Delphi оконных элементов управления. Главное отличие оконного элемента управления от любых других — наличие дескриптора окна hwnd. Дескриптор окна — это специальный идентификатор, который операционная система присваивает всем объектам, которые должны обладать свойствами окна. Если элемент управления имеет дескриптор окна, то он должен уметь выполнять следующие операции:

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

Оконными элементами управления являются не только формы, но и практически все стандартные элементы управления Windows: и списки, и редакторы имеют дескриптор окна.
Итак, все визуальные компоненты происходят от класса TWinControl. Однако нестандартные элементы управления имеют еще одного общего предка. Это класс TCustomContrl. Он существенно облегчает использование элементов управления, т. к. позволяет управлять отрисовкой компонента путем использования специального класса TCanvas — так называемой канвы (см. гл. 11) вместо обращения к системным функциям GUI.
Для обеспечения создания обычных (не оконных) элементов управления непосредственно от класса TControl порожден класс TGraphicControl. Его потомки не могут получать фокус, но используют для визуализации канву.
 
Класс TControl
Класс TControi является базовым для всех визуальных компонентов и инкапсулирует механизмы отображения компонента на экране. В нем используется множество новых свойств и методов. Недаром в Delphi в Инспекторе объектов появилась категоризация методов и свойств (2). Большинство из них вводятся как раз в классах TControl и TWinControl.
Рассмотрим только важнейшие свойства и методы по категориям.
Группа свойств Visual. Местоположение и размер элемента управления
Для определения местоположения и размеров визуального компонента введены два опубликованных свойства для задания координат левого верхнего угла:
Для представления их в таком виде нужно отметить флажок By Category в пункте меню Arrange всплывающего меню Инспектора объектов
property Top: Integer; 
property Left: Integer;
и два опубликованных свойства для определения размеров:
property Height: Integer; 
property Width: Integer;
Значения свойств задаются в пикселах. Для определения местоположения используется система координат рабочей области владельца данного компонента. Начало отсчета находится в левом верхнем углу. Оси направлены вправо и вниз. Под рабочей областью понимается та часть площади владельца (формы, панели), которая предназначена для размещения дочерних элементов. Эти свойства можно использовать как на этапе разработки, так и во время выполнения.
Свойство
property ClientOrigin: TPoint;
содержит координаты левого верхнего угла элемента управления в системе координат экрана. Координаты любой точки можно пересчитать в экранные при помощи метода
function ClientToScreen(const Point: TPoint): TPoint;
и наоборот:
function ScreenToClient(const Point: TPoint): TPoint;
Для приведения компонента в соответствие текущим значениям указанных выше свойств используется метод
procedure AdjustSize; dynamic;
Параметры рабочей области компонента определяются следующими свойствами:

  •  property ClientHeight: Integer;

определяет высоту рабочей области в пикселах.

  •  property ClientWidth: Integer;

определяет ширину рабочей области в пикселах.

  •  property ClientRect: TRect;

значение которого есть не что иное, как (0, 0, .clientwidth, ClientHeight). Кому-то будет удобнее пользоваться этим свойством.
Если разработчику неизвестны текущие параметры рабочей области, то он может воспользоваться следующими методами.
Функция
function GetClientOrigin: TPoint; virtual;
возвращает координаты левого верхнего угла рабочей области. Функция
function GetClientRect: TRect; virtual;
возвращает размеры прямоугольника рабочей области.
 
Выравнивание элемента управления
Для выравнивания компонента в рабочей области его владельца (обычно это форма) применяется свойство
property Align: TAlign;
Тип TAlign объявлен следующим образом:
type TAlign = (alNone, alTop, alBottom, alLeft, alRight, alClient);
При значении alNone выравнивание отсутствует. При следующих четырех значениях выравнивание осуществляется по соответствующей стороне. Значение alclient приводит к тому, что элемент управления изменяет свои размеры до размеров рабочей области владельца.
Свойство
property Anchors: TAnchors;
type TAnchors = set of TAnchorKind;
type TAnchorKind = (akTop, akLeft, akRight, akBottom);
обеспечивает фиксацию элемента управления по сторонам владельца. "Якорь" можно установить по одной, двум, трем или четырем сторонам. При задании якоря по любой стороне расстояние между стороной и элементом управления сохраняется неизменным. Комбинируя якоря для сторон, можно добиться различных вариантов поведения компонента при изменении размеров владельца.
Если по вертикали или горизонтали якорь не установлен вообще, то при изменении размеров владельца компонент остается на том же месте с учетом изменившегося размера.
Если по вертикали или горизонтали установлены оба якоря, то при изменении размеров владельца размер элемента управления изменяется таким образом, чтобы расстояния до сторон владельца остатись неизменными.
Свойство
property AutoSize: Boolean;
обеспечивает изменение размеров компонента в соответствии с размерами его содержимого (текста, изображения, списка, иерархического дерева и т. д.).
 
Внешний вид элемента управления
Для определения цвета компонента используется свойство
property Color: TColor;
При нахождении указателя мыши над компонентом его изображение может изменяться в соответствии со значением свойства
property Cursor: TCursor;
Для текста компонента шрифт обычно задается свойством
property Font: TFont;
Сложный класс TFont, задающий все характеристики шрифта, подробно рассматривается в гл. 10.
Свойство
property DesktopFont: Boolean;
определяет возможность использования шрифта для отображения, который применяется ОС для представления текста в значках.
Сам текст задается свойством
type TCaption = string; property Text: TCaption;
Длину текста можно определить при помощи функции
function GetTextLen: Integer;
Она возвращает число символов в тексте.
Элемент управления можно сделать видимым или невидимым. Для этого применяется свойство
property Visible: Boolean;
Этих же результатов можно достичь методами show (компонент видим) и Hide (компонент невидим).
Опубликованное свойство
property Hint: string;
содержит текст ярлыка — однострочной подсказки, которая появляется в маленькой рамке при остановке мыши на элементе управления.
Для управления ярлыком используется свойство
property ShowHint: Boolean;
При значении True ярлык начинает работать, при значении False ярлык выключается.
Для каждого элемента управления можно создать собственное всплывающее меню. Ссылка на экземпляр класса TPopupMenu, инкапсулирующего такое меню, хранится в свойстве
property PopupMenu: TPopupMenu;
Текущее состояние элемента управления определяется свойством Controistate:
type TControlState = set of (csLButtonDown, csClicked, csPalette, csReadingState, csAlignmentNeeded, csFocusing, csCreating, csPaintCopy, csCustomPaint, csDestroyingHandle, csDocking,); property Controistate: TControlState;
Описание возможных состояний элемента управления представлено в табл. 2.3. 
Таблица 2.3. Возможные состояния элемента управления


Состояние

Описание

csLButtonDown

Левая кнопка мыши нажата, но еще не отпущена. Используется для реализации события OnMouseDown

csClicked

Левая кнопка мыши нажата, но еще не отпущена. Используется для реализации события OnClick

csPalette

Состояние соответствует режиму изменения палитры. Это реакция на сообщение WM_ PALETTCHANGED

csReadingState

Осуществляется чтение значений свойств из потока (см. табл. 5.1)

csAlignmentNeeded

Осуществляется выравнивание компонента

csFocusing

Элемент управления получает фокус

csCreating

Элемент управления и его дочерние элементы создаются

csPaintCopy

Отрисовывается копия элемента управления

csCustomPaint

Элемент управления выполняет нестандартные операции отрисовки, заданные разработчиком

csDestroyingHandle

Указатель на объект элемента управления уничтожается

csDocking

Элемент управления находится в режиме присоединения

В зависимости от совокупности установленных свойств, элемент управления может соответствовать одному из возможных стилей, который задается свойством
type TControlStyle = set of (csAcceptsControls, csCaptureMouse, csDesignlnteractive, csClickEvents, csFramed, csSetCaption, csOpaque, csDoubleClicks, csFixedWidth, csFixedHeight, csNoDesignVisible, csReplicatable, csNoStdEvents, csDisplayDraglmage, csReflector, csActionClient, csMenuEvents); property ControlStyle: TControlStyle;
Доступность элемента управления в целом определяется свойством
property Enabled: Boolean;
При значении True элемент управления полностью работоспособен. При значении False элемент управления неактивен и отображается серым цветом.
Для получения контекста устройства нос элемента управления используется метод
function GetDeviceContext(var WindowHandle: HWnd): HDC; virtual;
Набор свойств и методов класса TwinControl обеспечивает функционирование механизма перетаскивания (Drag-and-Drop) и механизма присоединения (Drag-and-Dock).
 
Связь с родительским элементом управления
Механизм связывания визуального компонента с родительским компонентом (владельцем) позволяет автоматически задавать для нового элемента управления некоторые свойства, отвечающие за его внешний вид (см. выше). В результате все дочерние элементы управления для одного родительского (формы, панели) будут выглядеть одинаково оформленными.
Родительский компонент задается свойством
property Parent: TWinControl;
Для каждого дочернего элемента управления можно задать значения нескольких свойств:
property ParentBiDiMode: Boolean; property ParentColor: Boolean; property ParentFont: Boolean; property ParentShowHint: Boolean;
Каждое из них управляет одной характеристикой визуализации элемента. Метод
function HasParent: Boolean; override;
используется для того, чтобы определить, имеется ли у компонента владелец вообще.
В классе TControl впервые появляются методы-обработчики событий, которые обеспечивают передачу в элемент действия мыши, присоединение и перетаскивание.
 
Класс TWinControl
Класс TWinControl обеспечивает создание и использование оконных элементов управления (см. выше). Напомним, что оконный элемент управления имеет системный дескриптор окна hwnd. Однако оконными элементами являются не только формы и диалоги, но и большинство стандартных элементов управления.
Новые механизмы, инкапсулированные в классе, обеспечивают выполнение характерных для оконных элементов функций: прием и передачу фокуса, отклик на действия мышью и ввод с клавиатуры и т. д. Рассмотрим основные свойства и методы класса.
Дескриптор окна содержится в свойстве
property Handle: HWND;
При создании оконного элемента управления вызывается метод
procedure CreateParams(var Params: TCreateParams); virtual;
который заполняет структуру TCreateParams необходимыми значениями:
type
TCreateParams = record 
Caption: PChar;
 Style: DWORD;
ExStyle: DWORD;
X, Y: Integer;
Width, Height: Integer;
WndParent: HWND;
Param: Pointer
WindowClass: TWndClass;
WinClassName: array[0..63] of Char;
end;
Для создания дескриптора окна для элемента управления используется метод
procedure CreateHandle; virtual;
Операционная система создает дескриптор окна только вместе с самим окном. Поэтому метод CreateHandle только создает окно, а для присваивания свойству Handle значения дескриптора окна вызывает метод createwnd.
Для передачи фокуса между элементами управления на одной форме часто используется клавиша <Таb>. Порядок перемещения фокуса между элементами определяется свойством
type TTabOrder = -1..32767; 
property TabOrder: TTabOrder;
В первую очередь фокус передается компоненту с минимальным значением свойства. Далее — по возрастанию значения. При переносе компонента на форму это значение задается автоматически в соответствии с числом компонентов на форме.
Компонент можно заставить не откликаться на клавишу <Таb>. Для этого свойству
property TabStop: Boolean;
необходимо присвоить значение False.
Для передачи фокуса прямо элементу управления применяется метод
procedure SetFocus; virtual;
Чтобы узнать, имеет ли элемент управления фокус, в настоящее время используется метод
function Focused: Boolean; dynamic;
Все оконные элементы имеют рамку по контуру (впрочем, она может быть не видна). Ее параметры задаются группой свойств:

  •  property BevelEdges: TBevelEdges; 

задает, какие стороны входят в рамку;

  •  property Bevellnner: TBevelCut; property BevelOuter: TBevelCut;

задают внешний вид рамки;

  •  property BevelKind: TBevelKind;

определяет стиль рамки;

  •  property BevelWidth: TBevelWidth;

задает размер рамки.
 Свойство
property Brush: TBrush;
определяет параметры кисти (цвет и заполнение), которой рисуется фон элемента.
Оконный элемент может содержать другие компоненты. Для управления ими применяется индексированный список указателей, представляющих свойство
property Controls[Index: Integer]: TControl;
Общее число дочерних элементов управления содержится в свойстве
property ControlCount: Integer;
Внешний вид оконного элемента определяется свойством
property Ctl3D: Boolean
При значении True элемент управления имеет трехмерный вид. Иначе элемент выглядит плоским.
Для вызова темы контекстной помощи для конкретного элемента управления предназначено свойство
type THelpContext = -MaxLonglnt..MaxLonglnt;
property HelpContext: THelpContext;
Значение свойства должно соответствовать номеру темы в файле помощи.
В классе TwinControl добавлена возможность использования редакторов способа ввода (Input Method Editor, IME). Такие редакторы позволяют приспособить стандартную раскладку клавиатуры для символьных языков для ввода нестандартных символов (иероглифов и т. д.). Редакторы IMЕ представляют собой специально устанавливаемое в операционной системе программное обеспечение (ПО). Имя такого редактора задается в свойстве ImeName. Режим работы редактора определяется свойством ImeMode.
В классе TwinControl добавлено еще несколько методов-обработчиков событий, обеспечивающих реакцию на ввод с клавиатуры, получение и потерю фокуса.
 
Класс TCustomControl
Класс TCustomControl предназначен для создания на его основе нестандартных оконных элементов управления. Процесс визуализации в нем упрощен за счет использования специального класса TCanvas, инкапсулирующего канву (см. гл. 11).
Доступ к канве осуществляется через свойство
property Canvas: TCanvas;
Отрисовка элемента управления осуществляется методом
procedure PaintWindowfDC: HDC); override;
после получения сообщения WM_PAINT.
Возможности этого класса унаследовали классы TPanel, TGroupBox, TStringGrid и т. д.
 
Класс TGraphicControl
Класс TGraphicControl предназначен для создания на его основе визуальных компонентов, не получающих фокус в процессе выполнения приложения. Так как непосредственным предком класса является класс TControl, то потомки TGraphicControl умеют реагировать на управляющие воздействия мышью.
Наглядный пример элемента управления, которому не нужно получать фокус, — это компонент TLabel, предназначенный для отображения текста, или компонент Timage, предназначенный для визуализации изображений.
Для визуализации элементов управления на основе этого класса используется канва, инкапсулированная в классе TCanvas.
Доступ к канве осуществляется через свойство
property Canvas: TCanvas;
Отрисовка элемента управления осуществляется методом
procedure PaintWindow(DC: HDC); override;
после получения сообщения WM_PAINT.
Резюме
В настоящей главе рассмотрены важнейшие свойства и методы базовых классов, лежащих в основе VCL. Зная возможности этих классов, вы тем самым будете знать назначение многих свойств и методов в компонентах VCL. Поэтому материал данной главы будет полезен при изучении любых вопросов, рассматриваемых в этой книге в дальнейшем.

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г. Яндекс.Метрика