SNK Software
Web Studio Монополия Metaproducts Утилиты Игры
Монополию Web Studio Библиотека
Вебмастер Дельфи Работа на ПК Самоучитель
Для PHP Для Delphi
Веб-дизайн Программирование Компьютеры Девайсы Заметки
SNK Software Индустрия hardware Индустрия software
О студии Портфолио Сопровождение сайтов

Новые материалы

Девайсы:
Сравнительный обзор Nokia Lumia 920 и HTC 8X
Девайсы:
Обзор Nokia Lumia 820 – смартфона на WP8
Вебмастеру:
Настройка Apache, PHP и MySQL для Linux-VPS
Вебмастеру:
VPS на домашнем ПК: настройка сети в VM VirtualBox и Debian
Вебмастеру:
VPS на домашнем ПК: устанавливаем Linux Debian 6
Вебмастеру:
VPS на домашнем ПК: установка VM VirtualBox
Работа на компьютере:
Иные возможности текстового процессора Word
Работа на компьютере:
Вставка объектов
Работа на компьютере:
Таблицы в Word
Работа на компьютере:
Печать и сохранение документов
Работа на компьютере:
Сноски, колонтитулы, оглавление и указатели в Word

Визуальные компоненты VCL и ООП

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

Библиотека VCL

Библиотека визуальных компонентов содержит множество классов, которые вы можете использовать в своих приложениях. Она написана на языке Object Pascal и непосредственно связана с интегрированной средой разработки Delphi. В частности, все кнопки, расположенные на палитре компонент являются ни чем иным, как представлением визуальных компонент VCL.

Вместе с тем, многие классы VCL не являются визуальными компонентами. Например, существует специальный класс TStringList, используемый для работы с группами строк, или же класс TRegistry, предназначенный для работы с реестром Windows. Но все классы в Delphi, как мы знаем, происходят от общего предка - класса TObject, а прочие классы являются его наследниками в том или ином поколении, образуя иерархию классов.

Следующим классом в иерархии классов VCL, после TObject, является класс TPersistent. В дополнение к методам TObject он имеет так же методы для присвоения данных свойствам и для обмена объектов данными между собой (метод Assign). Параллельно классу TPersistent существуют так же классы TException и TIniFile. Первый из них предназначен для работы с исключительными ситуациями (т.е. обеспечивает обработку ошибок времени выполнения), а второй инкапсулирует методы для работы с INI-файлами.

Если же говорить именно о компонентах, а не о каких-то абстрактных классах, то их прародителем является класс TComponent, являющийся прямым потомком класса TPersistent. Именно происходящие от TComponent классы являются компонентами Delphi, в том числе теми, что отображаются на палитре компонент. Помимо класса TComponent, у TPersistent имеются еще 2 потомка - класс TClipboard, предназначенный для работы с буфером обмена Windows и класс TStrings, являющийся основой для уже упоминавшегося класса TStringList.

При всем этом компоненты, происходящие от класса TComponent, не обязательно являются визуальными. Если же говорить именно о визуальных компонентах, то нам следует продвинуться еще дальше, к классу TControl, являющимся общим предком для всех элементов графического интерфейса в созданных при помощи Delphi приложениях Windows. Но реальные компоненты, как правило, происходят не от самого класса TControl, а от 2 его разновидностей, представленных, в случае для Windows, классами TWinControl и TGraphicControl. Отметим, что полноценными оконными элементами управления (с поддержкой ввода с клавиатуры, визуальной реакцией на действия пользователя и т.д.) являются только наследники класса TWinControl. Что касается компонент, происходящих от TGraphicControl, то они являются облегченным вариантом элементов интерфейса, не требующими поддержки всех функциональных возможностей управления со стороны операционной системы. Такими элементами являются, например, статические картинки, используемые в оформлении программ (вроде логотипа в окне About) и т.п.

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

Таким образом, если представить все рассмотренные здесь классы в виде некой древовидной структуры, выстроив ее по направлению от TObject до TWinControl, то мы получим фрагмент иерархии классов VCL, относящийся к визуальным компонентам и захватывающий некоторые ближайшие ответвления (рис. 8.1).

Фрагмент иерархии классов VCL от TObject до TWinControl
Рис. 8.1. Фрагмент иерархии классов VCL от TObject до TWinControl

Еще одним важным подспорьем в изучении VCL, помимо иерархии классов, является исходный код самой библиотеки VCL, поставляемый вместе с Delphi. Обычно они располагаются в каталоге Source, вложенном в тот каталог, в который вы установили саму Delphi, например, C:\Program Files\Borland\Delphi\Source.

Класс TComponent

Теперь настало время более подробно ознакомиться с классами, на которых основываются компоненты VCL. Начнем с основы - класса TComponent. В дополнение к методам своего родителя - класса TPersistent, он имеет ряд собственных методов, а также здесь впервые появляются свойства. Именно благодаря свойствам, определенным в этом классе, одни компоненты могут владеть другими. На практике это означает, что когда на такой компонент, как форма (окно), вы помещаете другой компонент, скажем, кнопку, то кнопка становится составной частью формы. Благодаря этой особенности при создании основного компонента, все принадлежащие ему компоненты будут созданы автоматически. Равно как и при удалении такого компонента, все принадлежащие ему компоненты так же удаляются автоматически.

Рассмотрим свойства класса TComponent более подробно, для чего обратимся к таблице 8.1

Таблица 8.1. Основные свойства TComponent
СвойствоТипОписание
ComponentCountIntegerЧисло принадлежащих (дочерних) компонентов
ComponentIndexIntegerНомер компонента в списке родительского компонента-владельца
Componentsarray of TComponentСписок всех принадлежащих компонентов
ComponentStateTComponentStateУказывает на текущее состояние компонента, может принимать значения csLoading, csReading, csWriting, csDestroying, csDesigning, csAncestor, csUpdating, csFixups, csFreeNotification, csInline, csDesignInstance
NameStringОпределяет имя компонента, по которому к нему следует обращаться из кода программы
OwnerTComponentСсылается на компонент, являющийся владельцем данного компонента
TagIntegerХранит число, которое можно использовать в произвольных целях

Важно отметить, что многие из этих свойств доступны только для чтения, т.е. их нельзя изменить явно, присвоив им то или иное значение. Плный доступ допустим только для свойств Name, Tag и ComponentIndex. Кроме того, свойства Name и Tag являются опубликованными, и, соответственно, они будут видны в инспекторе объекта уже на этапе разработки программы.

Что касается методов, то их для класса TComponent определено предостаточно, однако подавляющее большинство из них используется либо для реализации каких-либо внутренних механизмов взаимодействия в VCL, либо имеет весьма специфическое предназначение. Что касается более приземленных методов, то среди них можно выделить группу из 4 методов, предназначенных для манипулирования принадлежащими компонентами:

В качестве своего непосредственного родителя класс TComponent имеют такие компоненты, как таймер (TTimer), невизуальные компоненты для доступа к данным (TDataSet, TDataSource), компоненты для взаимодействия через DDE и другие. От него же ведут свою "родословную" многие основополагающие классы, на основе которых строятся другие компоненты. Самым интересным среди них, безусловно, является класс TControl, на основе которого построены все визуальные компоненты в Delphi. Именно на основе класса TControl можно изучить общие свойства всех элементов интерфейса (окон, кнопок, текстовых надписей, окон редактирования и т.д.), которые только можно создать в приложении.

Свойства визуальных компонент

Как уже было отмечено, все визуальные компоненты происходят от класса TControl. Всего для этого класса определено около 100 методов и свыше 50 свойств, и это - помимо свойств и методов, унаследованных от TComponent. Причем многие из них, особенно если рассматривать свойства, довольно часто используются при практической разработке приложений в контексте того или иного визуального компонента, начиная от окна-формы, и заканчивая текстовыми подписями.

Рассмотрим такие свойства, обратившись к таблице 8.2.

Таблица 8.2. Основные свойства класса TControl
СвойствоТипОписание
ActionTBasicActionОпределяет действие, связанное с данным элементом
AlignTAlignОпределяет выравнивание элемента относительно родительского элемента. Допустимые значения: alNone, alTop, alBottom, alLeft, alRight, alClient, alCustom
AnchorsTAnchorsОпределяет, по каким краям данный элемент привязывается к родительскому. Допустимые значения akTop, akLeft, akRight, akBottom
AutoSizeBooleanОпределяет, может ли размер элемента изменяться автоматически, в зависимости от содержимого
CaptionSttringОпределяет текстовую строку, идентифицирующую элемент длЯ пользователя
ClientHeightIntegerОпределяет высоту внутреннего пространства элемента, доступную для размещения других элементов в пикселях
ClientWidthIntegerОпределяет ширину внутреннего пространства элемента, доступную для размещения других элементов в пикселях
ColorTColorОпределяет цвет фона элемента. Цвет задается при помощи ключевых слов (clNone, clAqua и т.д.) или числовым значением в диапазоне -$7FFFFFFF-1..$7FFFFFFF
ConstraintsTSizeConstraintsОпределяет минимальные и максимальные размеры элемента, задаваемые четырьмя целыми
CursorTCursorОпределяет тип курсора. Например, crDefault, crNone и т.д.
DragCursorTCursorОпределяет тип курсора в момент перетаскивания. Например, crDefault, crNone и т.д.
DragKindTDragKindОпределяет, будет ли элемент при перетаскивании просто перемещаться или должен быть пристыкован, может принимать значения dkDrag, dkDock
DragModeTDragModeОпределяет, как должны инициироваться операции drag-and-drop и drag-and-dock. Допустимые значения dmManual, dmAutomatic
EnabledBooleanОпределяет, должне ли элемент реагировать на событиЯ клавиатуры, мыши и таймера
FontTFontОпределяет атрибуты шрифта длЯ текстового наполнения элемента.
HeightIntegerОпределяет высоту элемента в пикселях
HelpContextIntegerОпределяет индекс раздела в файле справки, относящегося к этому элементу
HelpKeywordStringОпределяет ключевое слово в файле справки, относящегося к этому элементу
HelpTypeTHelpTypeОпределяет, по какому критерию должно производиться обращение к файлу справки, по слову (htKeyword), или по номеру (htContext)
HintStringОпределяет текст всплывающей подсказки
LeftIntegerОпределяет горизонтальную координату левой стороны элемента в пикселях по отношению к родительскому
NameStringОпределяет имя элемента
ParentTWinControlОпределяет родительский элемент, в целом аналогична свойству Owner, но всегда ссылается на элемент типа TWinControl
ParentColorBooleanОпределяет, должен ли элемент унаследовать фоновый цвет у содержащего объекта
ParentFontBooleanОпределяет, должен ли элемент унаследовать оформление шрифта у содержащего объекта
ParentShowHintBooleanОпределяет, должен ли элемент унаследовать показ подсказки у содержащего объекта
PopupMenuTPopupMenuОпределяет всплывающее (контекстное) меню, связанное с данным элементом
ShowHintBooleanОпределяет, показывать или нет всплывающую подсказку для данного элемента
TextStringОпределяет текст, который должен быть отображен элементом. В зависимости от типа элемента, используется либо свойство Text, либо Caption
TopIntegerОпределяет вертикальную координату верхней стороны элемента в пикселях по отношению к родительскому
VisibleBooleanОпределяет, должен ли компонент быть видимым
WidthIntegerОпределяет ширину элемента в пикселях

Достаточно создать новый проект в Delphi (File > New > Application), и щелкнуть по окну первой формы, созданной для приложения (Form1), чтобы увидеть многие из перечисленных в таблице свойств в окне инспектора объекта. Разумеется, учитывая то, что класс TForm, на основе которого создаются формы, является наследником рассматриваемого класса TControl далеко не в первом поколении, а на каждом этапе добавляются все новые и новые свойства, то список доступных свойств будет большим, нежели в таблице.

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

С теми или иными исключениями и дополнениями данные свойства имеются и для других визуальных компонент - будь то кнопки, поля редактирования текста, списки, рамки, переключатели и т.д. Причем общее их количество довольно сильно варьируется в зависимости от конкретного компонента. Свою долю вносит и версия Delphi, поскольку от версии к версии могут добавляться какие-либо новые свойства. В результате для Delphi 7 мы имеем 60 свойств для формы, 33 - для кнопки и 47 - для поля редактирования текста (рис. 8.2).

Инспектор объекта Delphi со свойствами формы, кнопки и текстового поля
Рис. 8.2. Инспектор объекта со свойствами формы, кнопки и текстового поля

Из тех свойств, что всегда доступны для любого объекта в VCL, можно выделить такие, как Tag и Name. Если же брать визуальные компоненты, то для них всегда актуальны так же свойства, отвечающие за размеры (Height, Width и т.д.), вид курсора, шрифт, связь со справочной системой и т.д.

СОВЕТ
Всегда можно получить подсказку по любому интересующему вас свойству, выбрав его в инспекторе объекта и нажав на клавишу F1.

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

События

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

К счастью, Delphi большую часть работы по обработке событий берет на себя. Фактически, при разработке приложений, использующему Delphi разработчику необходимо всего лишь установить собственные обработчики на те события, которые ему действительно необходимо обработать. Типичный пример - нажатие на клавишу мышки. Причем, опять-таки, благодаря Delphi, не понадобиться отслеживать различные фазы нажатия (кнопка опущена - кнопка отжата - кнопка отпущена), как и следить за тем, от какого источника пришел сигнал (т.е. был ли это щелчок мышкой, или нажатие Enter, или было использовано сочетание горячих клавиш).

Отметим, что события, как часть класса VCL, впервые появляются, начиная как раз с класса TControl. Таким образом, в дополнение к полутора сотням свойств и методов этого класса, мы получим еще некоторое количество событий. Собственно говоря, событие представляет собой ничто иное, как свойство процедурного типа, предназначением которого является обеспечение реакции на те или иные действия. Когда такому свойству присваивают значение, то фактически указывается метод, вызываемый при наступлении данного события. Подобные методы называют обработчиками событий (event handlers).

События в Delphi подразделяются на несколько типов, в зависимости от того, что представляет собой то или иное событие. Простейшим и одним из наиболее распространенных является тип TNotifyEvent, характерный для обычных уведомляющих событий. В VCL этот тип описан следующим образом:

type TNotifyEvent = procedure(Sender: TObject) of object;

Единственный параметр Sender здесь обозначает объект, являющийся источником возникшего события.

Инспектор объекта со списком событий для формы, кнопки и текстового поля
Рис. 8.3. Инспектор объекта со списком событий для формы, кнопки и текстового поля

Переходя от общих слов к делу, вновь обратим свое внимание на инспектор объекта. Можно заметить, что помимо закладки свойств (properties), он содержит еще и вторую закладку - события (events). На ней приводится список событий, которые могут быть обработаны данным объектом (рис. 8.3).

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

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

procedure TForm1.FormClick(Sender: TObject); begin end;

Кроме того, если теперь посмотреть объявление самой формы, то можно будет увидеть, что в часть объявлений класса TForm1 добавилось объявление этой процедуры:

procedure FormClick(Sender: TObject);

Таким образом, нам остается лишь добавить свой код в тело процедуры, созданной для обработчика события щелчка мышкой по форме. Пусть это будет смена заголовка окна с предлагаемого по умолчанию значения (Form1) на все ту же фразу "Hello, World!". Для этого достаточно обратиться к свойству Caption объекта Form1, и назначить ему новое значение. В итоге, вся процедура примет следующий вид:

procedure TForm1.FormClick(Sender: TObject); begin Form1.Caption:='Hello, World!'; end;

Теперь, если запустить такое приложение на выполнение (нажав F9), и щелкнуть в любом месте его окна мышкой, то текст заголовка окна изменится с "Form1" на "Hello, World!".

Методы визуальных компонент

Итак, события представляют собой свойства, для которых определяются методы. Таким образом, от событий мы вновь возвращаемся к теме методов, в аспекте их работы с визуальными компонентами.

ПРИМЕЧАНИЕ
Отметим, что в отличие от обычных свойств, или от событий, для методов в инспекторе объектов места не нашлось. Поэтому чтобы получить справочную информацию о методах, следует сперва обратиться к справке по самому компоненту, а уже из самого окна справки щелкнуть по ссылке "Methods".

Прежде всего, методы предоставляют иной путь управления компонентами. Поскольку компоненты - это все те же объекты, они могут иметь процедуры и функции. Таким образом, по аналогии с любыми другими классами, метод визуального компонента представляет собой процедуру или функцию, объявленную в общедоступной части класса, и которую можно вызвать при работе с данным компонентом. Например, когда мы изменяли заголовок окна, то использовали свойство Caption. А вот если бы мы хотели, скажем, скрыть форму (сделать ее невидимой), то следовало бы обратиться к методу Hide:

Form1.Hide;

Помимо метода Hide, а так же определенных еще для родительских классов методов вроде Create и Free, класс TControl имеет ряд других часто применяемых методов, которые наследуются визуальными компонентами-потомками этого класса. Некоторые из наиболее часто употребляемых методов приведены в таблице 8.3.

Таблица 8.3. Некоторые методы класса TControl
МетодОписание
BringToFrontДелает форму видимой или переносит элемент, скрытый на форме под другими элементами, на передний план
PerformПересылает элементу указанное Windows-сообщение
RefreshИнициирует обновление (перерисовку) объекта на экране
RepaintСиноним для Refresh
SendToBackПереносит элемент на задний план
ShowДелает элемент видимым
UpdateИнициирует немедленное выполнение всех сообщений, связанных с ожиданием обновления (перерисовки) элемента

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

var Form1: TForm1; But: TButton; ... But:=TButton.Create(Form1); But.Parent:=Form1;

К счастью, при создании экземпляров компонент визуальными методами (т.е. в графической среде Delphi) вся необходимая работа выполняется автоматически.

Типы методов

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

Для примера переопределяемого определим некий класс TFigure с методом Draw, а так же создадим его потомков - классы TCircle и TSquare с одноименными методами, которые и переопределим:

type TFigure = class procedure Draw; virtual; end; TCircle = class(TFigure) procedure Draw; override; end; TSquare = class(TFigure) procedure Draw; override; end;

Если теперь создать переменную типа TFigure, и использовать конструктор класса TSquare, а затем вызвать метод Draw, то вызван будет метод класса TSquare. Если же для переменной использовать конструктор класса TCircle, то метод уже этого класса будет вызван:

var Fig: TFigure; begin Fig := TSquare.Create; Fig.Draw; // вызов TSquare.Draw Fig.Destroy; Fig := TCircle.Create; Fig.Draw; // вызов TCircle.Draw Fig.Destroy; end;

В то же время, если бы, скажем, класс TCircle не имел собственного определения метода Draw, то был бы вызван метод, унаследованный от класса TFigure. Что касается перегружаемых методов, то суть их использования сводится к тому, что на разных уровнях наследования в родственных классах можно использовать одноименные методы, различающиеся лишь количеством и (или) типом параметров. Например, если взять те же классы TFigure и TSquare, то можно было бы использовать не переопределяемые, а перегружаемые методы:

type TFigure = class procedure Draw(left, top: integer); end; TCircle = class(TFigure) procedure Draw(left, top, radius: integer); overload; end; TSquare = class(TFigure) procedure Draw(left, top, width, height: integer); overload; end;

Таким образом, в зависимости от того, с какими параметры будет вызван метод Draw, будет произведено обращение к той или иной процедуре:

var Fig: TFigure; begin Fig := TSquare.Create; Fig.Draw(10,10,30,40); // вызов TSquare.Draw Fig.Draw(5,50); // вызов TFigure.Draw Fig.Destroy; end;

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

Избранное

SNK GSCP
SNK GSCP - новая библиотека для PHP 5!
Web Studio
Web Studio и Visual Workshop
Библиотека:
Стандарты на web-технологии
Монополия
Монополия Android
Загрузки:
скачать программы
Продукция:
программы и книги
Техподдержка / Связаться с нами
Copyright © 1999-2020 SNK. Все права защищены.
При использовании материалов с сайта ссылка на источник обязательна.
Рейтинг@Mail.ru