SlideShare une entreprise Scribd logo
1  sur  12
Télécharger pour lire hors ligne
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
1
Лекция 11 (ч.5)
Синтаксис и программные конструкции Visual C
4. Библиотека визуальных компонент С++Builder
4.2. Иерархия классов VCL
Все компоненты VCL находятся в иерархии классов, основу которой составляют базовые
классы. Каждый базовый класс имеет некоторый набор методов, событий и свойств и
специальное назначение. От этих базовых классов затем наследуются уже реальные классы
компонентов и их поведение определено базовыми классами-предками, находящимися выше них
в иерархии. Базовые классы библиотеки VCL иногда называют абстрактными, однако они не
являются абстрактными классами с точки зрения языка С++. Эти классы не имеют чистых
виртуальных функций и для них могут быть созданы экземпляры классов. Однако для этих
классов нельзя создать полноценно работающие объекты, поскольку в них содержатся лишь
общие характеристики, которые затем должны уточняться и переопределяться в классах-
потомках. Тем не менее, эти классы полезны в качестве базовых при создании пользовательских
компонент, так как содержат общие характеристики, присущие всем классам данного семейства.
Кроме того, указателю на базовый класс может быть присвоен адрес любого объекта
производного класса. Полная иерархия базовых классов библиотеки VCL представлена на
рисунке.
Рис. 4.1. Фрагмент схемы иерархии классов библиотеки VCL
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
2
Основой иерархий являются классы TObject, TPersistent, TComponent, TControl,
TGraphicControl, TWinControl. TObject является базовым классом для всех порождаемых классов
библиотеки VCL, TComponent является базовым классом для всех порождаемых компонент.
Невидимые компоненты произведены от класса TComponent. Отображаемые компоненты имеют
общего предка TControl, при этом графические компоненты произведены от класса
TGraphicControl, а оконные от класса TWinControl. Причем компоненты, инкапсулирующие
стандартные органы управления Windows, произведены непосредственно от класса TWinControl,
а оригинальные компоненты от класса TCustomControl. Рассмотрим основные базовые классы
более подробно.
Класс TObject инкапсулирует общее функциональное поведение для всех классов
системы С++Builder, а именно:
- возможность создания, управления и уничтожения экземпляров объекта;
- поддержка информации RTTI об имени и типе объекта;
- поддержка механизма обработки сообщений.
Большинство этих методов предназначены для внутреннего использования системой
С++Builder. Часть методов TObject объявлены как статические (с ключевым словом static). Таким
образом, к ним можно обращаться, не создавая экземпляр класса, используя лишь имя класса или
метакласс. Рассмотрим некоторые часто используемые методы объекта TObject.
ShortString TObject::ClassName(void) - статический метод, который возвращает строку с
именем класса.
TMetaClass * TObject::ClassType(void) - статический метод, который возвращает указатель
на метакласс.
TMetaClass * TObject::ClassParent(void) - статический метод, который возвращает
указатель на метакласс предка (для TObject возвращает NULL).
bool TObject::InheritsFrom(TMetaClass *) возвращает true, если объект является
экземпляром указанного в качестве параметра класса или класса потомка. Например:
if (Sender->InheritsFrom(__classid(TWinControl)))
ShowMessage(«Экземпляр потомка TWinControl»);
void TObject::Dispatch (void* Message) - виртуальный метод, посылает сообщение на
обработку, вызывая необходимый обработчик. Обработчик ищется по идентификатору
сообщения, расположенному в 2-х первых байтах по адресу, переданному в качестве параметра.
В классах потомках в качестве параметра передается указатель на структуру TMessage. Сначала
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
3
просматриваются обработчики в текущем классе, затем, если обработчик не был найден, - в
классах предках. Если обработчик так и не был найден, вызывается DefaultHandler.
void TObject::DefaultHandler(void* Message) - виртуальный метод, обработчик сообщения
по умолчанию. Для TObject не выполняет никаких действий (для TWinControl вызывает
стандартную API-функцию DefWndProc, которая выполняет обработку сообщений Windows по
умолчанию).
int TObject::Free(void) вызывает деструктор для уничтожения объекта. Аналогичные
действия могут быть выполнены с помощью оператора delete.
Ниже приведен пример, позволяющий вывести диалоговое окно, содержащее иерархию
для объекта переданного в качестве параметра Sender.
void __fastcall TForm1::ControlClick(TObject *Sender)
{AnsiString Str;
TClass tcl;
tcl=Sender->ClassType();
while (tcl)
{ Str+=AnsiString(tcl->ClassName())+"n";
tcl=tcl->ClassParent();
}
ShowMessage(Str);}
Кроме рассмотренных выше методов существуют еще несколько сервисных методов,
использующихся в основном при разработке компонентов. Например, FieldAddress,
MethodAddress, MethodName, InitInstance, FreeInstance, InstanceSize и т.д. От TObject наследуются
в основном простые объекты, которые не являются компонентами и не нуждаются в поточности
и присваивании.
Класс TPersistent является предком всех классов, поддерживающих работу со
свойствами. Являясь потомками TPersistent, производные классы приобретают способность
поточности и присваивания, а именно:
- возможность сохранения и чтения из потока неопубликованных свойств;
- возможность присвоения значений свойствам;
- возможность присвоения данных одного объекта другому.
Запись и чтение из потока производится в формате dfm. Таким образом, под
записью/чтением в поток подразумевается возможность сохранения/загрузки значений свойств в
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
4
файл формы. В общем случае поточность предоставляет классам возможность помещения в
память и загрузки из памяти, например, при переносе компонентов через буфер обмена.
Несмотря на то, что поточность появляется, начиная с класса TPersistent, используют эту
возможность в основном компоненты, т.е. классы, наследованные от TComponent. Большинство
методов TPersistent перегружаются в потомках. Рассмотрим методы этого класса.
void TPersistent::Assign(TPersistent *Source) позволяет данному объекту присвоить
значения свойств и атрибутов другого объекта, заданного в качестве параметра. Например,
Destination->Assign(Source);
void TPersistent::AssignTo (TPersistent* Destination) позволяет присваивать значения
свойств и атрибутов текущего объекта другому объекту, указанному в качестве параметра. У
TPersistent этот метод является виртуальным и защищенным. Этот метод необходим при
разработке новых классов для обеспечения возможности присваивания их стандартным классам.
Если метод Assign объекта A не знает как выполнить присваивание параметров объекта B, то его
метод Assign автоматически вызывает метод AssignTo объекта B. Т.е. если A->Assign(B) не
может выполниться для типа объекта B, то внутри метода Assign вызывается B->AssignTo(A).
void TPersistent::DefineProperties(TFiler *Filer) позволяет определить процедуру загрузки и
сохранения в потоке неопубликованных свойств. По умолчанию сохраняются только
опубликованные свойства, т.е. объявленные в секции __published. У TPersistent этот метод
является виртуальным и защищенным.
От TPersistent наследуются классы, которые не являются компонентами, но нуждаются в
поточности и присваивании.
Класс TComponent является предком всех компонент. TComponent определяет общее
функциональное поведение для всех компонент системы С++Builder, а именно:
-возможность помещения на форму из палитры компонент и манипуляции в окне
редактора форм;
-способность владения и обслуживания других компонент;
-специальные характеристики поточности, с которыми может манипулировать инспектор
объектов на этапе проектирования.
На уровне TСomponent проявляется отношение "основной - вспомогательный". Это
отношение распространяется на все компоненты системы С++Builder. Конструктор TСomponent,
в отличие от конструкторов предыдущих классов, имеет параметр AOwner типа TComponent *,
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
5
указывающий основной компонент для создаваемого компонента. Кроме того, TСomponent
содержит ряд свойств, характеризующих отношение "основной - вспомогательный".
Свойство TComponent* TComponent::Owner - указатель на основной компонент. Доступно
только для чтения и только во время выполнения приложения (ReadOnly, RunTime). Форма
является основной для всех помещенных на нее компонент, приложение Application является
основным для всех форм.
int TComponent::ComponentCount содержит количество вспомогательных компонент для
данного компонента (ReadOnly, RunTime).
int TComponent::ComponentIndex содержит индекс данного компонента в списке
основного компонента (ReadOnly, RunTime). Нумерация начинается с 0. При отображении
компоненты с меньшим индексом прорисовываются раньше. Изменить порядок для
отображаемых компонент можно с помощью пунктов главного меню Edit | Bring to Front и Edit |
Send to Back, изменяющих также Z-порядок. Для неотображаемых компонент с помощью пункта
главного меню Edit | Creation Order.
TComponent* TComponent::Components[int Index] содержит массив указателей
вспомогательных компонент для данного компонента (ReadOnly, RunTime). Нумерация
начинается с 0. При вызове конструктора компонент помещается в список Components
компонента, указанного в качестве параметра. При вызове деструктора удаляется из этого
списка. Кроме того, можно добавить и удалить компонент из списка с помощью методов void
TComponent::InsertComponent (TComponent* AComponent) и void
TComponent::RemoveComponent (TComponent* AComponent) соответственно. Внутренняя
реализация этого массива представляет собой два отдельных списка TList для отображаемых и
неотображаемых компонент.
Отношение "основной - вспомогательный" отвечает за владение и удаление компонентов.
При удалении компонента сначала вызываются деструкторы всех вспомогательных компонент.
При этом для всех компонент, помещенных на формы в процессе проектирования, при
освобождении обнуляются указатели на соответствующие компоненты.
Свойство AnsiString TComponent::Name содержит имя компонента. При помещении на
форму имя компонента назначается автоматически на основе имени класса. Например, Button1,
Button2 и т.д. для класса TButton, это же имя будет присвоено переменной, содержащей
указатель на компонент. Рекомендуется задавать осмысленные имена для более удобного чтения
кода. Например, btnStart, btnStop и т.д. Для динамически создаваемых во время выполнения
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
6
компонент имя может отличаться от имени переменной, допустимо значение NULL. Следует
также отметить, что для отображаемых компонент обычно существуют также свойства Caption
или Text. Они содержат текстовые строки, отображаемые на самом компоненте (название
кнопки, содержимое поля ввода и т.д.). При добавлении компонента на форму эти свойства
содержат значения, совпадающие с Name. Однако они имеют принципиально другое назначение
и используются лишь для отображения компонента. Например, для нашего примера Caption
может быть «Старт» и «Стоп» для кнопок btnStart и btnStop.
TComponent* TComponent::FindComponent (const AnsiString AName) возвращает указатель
экземпляра компонента с именем, указанным в качестве параметра. Например:
void_fastcall TForm1::ButtonlClick(TObject *Sender)
{TEdit* EditInstance;
EditInstance = dynamic_cast<TEdit *>(FindComponent("Edit1"));
if (EditInstance) EditInstance->Text="new";}
TComponentState TComponent::ComponentState - текущее состояние компонента. Список
возможных значений: (csAncestor, csDesigning, csDestroying, csFixups, csLoading, csReading,
csUpdating,csWriting).
TComponentStyle TComponent::ComponentStyle - стиль, определяющий поведение
компонента (csInheritable, csCheckPropAvail).
int TComponent::Tag - свойство целого типа, которое не имеет предопределенного
значения и может содержать любые данные или указатели, по усмотрению программиста.
TComponent используется в качестве базового класса при создании невидимых компонент.
Класс TControl является предком всех видимых компонент. Поскольку элементы TControl
обладают способностью отображать себя, некоторые свойства этого класса оперируют с
положением, размером и видом объекта (Top, Left, Width, Height, BoundsRect, Cursor, Hint), а
другие свойства относятся к параметрам клиентской области (ClientRect, ClientWidth и
ClientHeight). TControl также вводит свойства, устанавливающие видимость, доступность, цвет и
шрифт элементов управления (Visible, Enabled, Color и Font). Свойства Text и Caption
обеспечивают установку редактируемых текстов и названий. Свойство ControlState задает
состояние органа управления (csLButtonDown, csClicked, csPalette, csReadingState,
csAlignmentNeeded, csFocusing, csCreating, csPaintCopy, csCustomPaint, csDestroyingHandle,
csDocking). Свойство ControlStyle определяет характеристики органа управления
(csAcceptsControls, csCaptureMouse, csDesignInteractive, csClickEvents, csFramed, csSetCaption,
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
7
csOpaque, csDoubleClicks, csFixedWidth, csFixedHeight, csNoDesignVisible, csReplicatable,
csNoStdEvents, csDisplayDragImage, csReflector, csActionClient, csMenuEvents). Свойство Align
задает выравнивание компонента относительно родительского компонента (alNone, alTop,
alBottom, alLeft, alRight, alClient), а свойство Anchor задает привязку к размерам родительского
компонента (множество из akLeft, akTop, akRight, akBottom). Свойство Constraints позволяет
задать максимальные и минимальные размеры компонента. Метод SetBounds(int ALeft, int ATop,
int AWidth, int AHeight) позволяет изменить положение и размер компонента.
Все визуальные компоненты кроме отношения "основной-вспомогательный" находятся
также в отношении "старший-младший" или "родитель-ребенок". В аналогичном отношении
находятся все органы управления Windows. Поэтому уже у TСontrol появляются некоторые
свойства характеризующие это отношение.
Свойство TWinControl* TСontrol::Parent содержит указатель на родительский компонент.
Родительскими могут быть только оконные элементы управления, и поэтому они должны быть
производным от TWinControl. Сам компонент TControl не может быть родителем, а может быть
только дочерним компонентом. Для формы значение свойства Parent задается как NULL.
Кроме того, имеются свойства ParentColor, ParentFont и ParentShowHint типа bool которые
определяют, будут ли в качестве значений свойств Color, Font и ShowHint использоваться
значения соответствующих свойств родительского компонента.
Все координаты компонента задаются относительно родительского компонента, при этом
начало координат это левый верхний угол этого компонента (так называемые локальные
координаты). Существуют еще и глобальные координаты с началом координат в верхнем левом
углу экрана. Для пересчета локальных координат в глобальные и наоборот используются
функции TPoint TControl::ClientToScreen(const TPoint &Point) и TPoint
TControl::ScreenToClient(const TPoint &Point) соответственно.
TControl содержит также методы ответственные за отображение органа управления.
void TControl::Hide(void) делает текущий элемент управления невидимым, т.е.
устанавливает свойство Visible в false. При этом компонент всего лишь не отображается на
экране, он не удаляется из динамической памяти и из списка вспомогательного компонента, и все
его методы и свойства остаются доступными.
void TControl::Show(void) отображает текущий элемент управления, т.е. устанавливает
свойство Visible в true.
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
8
void TControl::Repaint(void) перерисовывает текущий элемент управления. Перерисовка
происходит немедленно. При этом, если свойство ControlStyle содержит значение csOpaque,
компонент перерисовывает себя самостоятельно, в противном случае вызывается метод
Invalidate, а затем Update для перерисовки некоторой видимой части компонента.
void TControl::Refresh(void) вызывает метод Repaint.
void TControl::Invalidate(void) сообщает системе о том, что некоторая область органа
управления должна быть перерисована. Перерисовка произойдет при обработке сообщения о
перерисовке после обработки всех сообщений находящихся в очереди. Причем Invalidate может
быть вызван несколько раз, до того момента как произойдет непосредственно перерисовка.
void TControl::Update(void) позволяет немедленно обработать сообщение о перерисовке.
Таким образом, если для компонента до этого был вызван метод Invalidate, это приведет к
перерисовке.
Методы void TControl::BringToFront(void) и void TControl::SendToBack(void) управляют Z-
порядком компонента, помещая его на передний или задний план соответственно.
Метод TControl::WndProc(TMessage &Message) обрабатывает поступившие органу
управления сообщения Message класса TMessage. Адрес этого метода хранится в свойстве
WindowProc, описанном в секции public. Это позволяет подменять стандартный обработчик и
производить самостоятельную обработку каких-либо сообщений.
Таким образом, возможность обработки сообщений операционной системы появляется
уже в классе TControl. Этот класс обрабатывает только сообщения от мыши, но его потомки
способны обрабатывать и другие сообщения операционной системы Windows. В результате
обработки сообщений от мыши у класса TControl появляются следующие события: OnClick,
OnDblClick, OnMouseDown, OnMouseMove, OnMouseUp. Задав обработчики этих событий,
можно определить реакцию компонента на манипуляции мышью.
Кроме того, в классе TСontrol появляются также свойства, методы и события,
реализующие механизм Drag-and-Drop.
Класс TControl редко используется непосредственно, большинство компонент являются
производными от TWinControl или TGraphicControl.
Класс TWinControl является предком всех оконных элементов управления. С каждым
таким элементом управления связано окно («window») операционной системы Windows.
Производные от TWinControl компоненты обладают тремя основными характеристиками: они
имеют оконные дескрипторы (HWND), способны принимать фокус ввода и могут являться
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
9
родителями других элементов управления. В классе TWinControl полностью определяется
отношение "старший-младший", для этого добавляются следующие свойства.
int TWinControl::ControlCount содержит количество младших элементов управления для
данного компонента (ReadOnly, RunTime).
TControl* TWinControl::Controls[int Index] содержит массив указателей младших
элементов управления для данного компонента (ReadOnly, RunTime). Нумерация начинается с 0.
Компонент добавляется и удаляется из соответствующих массивов при изменении свойства
Parent. Кроме того, для добавления и удаления компонента в список младших компонентов
можно использовать методы void TWinControl::InsertControl(TControl *AControl) и void
TWinControl::RemoveControl (TControl *AControl).
Метод bool TWinControl::ContainsControl(TControl* Control) определяет, может ли данный
компонент управлять компонентом Control, т.е. является ли Control младшим для данного
компонента непосредственно или косвенно.
TControl* TWinControl::ControlAtPos(TPoint &Pos, bool AllowDisabled) возвращает
указатель на младший компонент расположенный в заданных координатах клиентской области
данного компонента.
Таким образом, все компоненты С++Builder находятся в отношении "основной-
вспомогательный". Как уже говорилось, это отношение отвечает за владение компонентами.
Когда уничтожается основная компонента, уничтожаются и все вспомогательные компоненты.
Для всех компонент, помещенных на форму, основной является форма, для всех форм основным
является приложение Application, экземпляр класса TApplication. Таким образом, если
приложение завершается, то закрываются и все формы, и, соответственно, уничтожаются все
принадлежащие им компоненты. Причем для форм и приложения есть и обратное воздействие.
Среди всех форм одна должна быть главной, ссылка на нее содержится в свойстве MainForm
объекта Application. Обычно главной формой становится первая созданная форма. Изменить
главную форму можно в опциях проекта на закладке Forms в поле MainForm. Закрытие главной
формы приводит к завершению приложения, что в свою очередь приводит к закрытию и всех
остальных форм. Следует особо отметить, что при запуске приложения главная форма
отображается независимо от значения свойства Visible. Затем это форма может быть скрыта
обычными способами. Однако программист в случае скрытия главной формы должен
предусмотреть какие-либо варианты завершения приложения, поскольку закрытие
пользователем всех остальных форм не приведет к завершению приложения. Если все-таки
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
10
необходимо скрыть главную форму при запуске приложения, то можно использовать свойство
ShowMainForm объекта TApplication. Все отображаемые компоненты связаны еще отношением
"старший-младший". Старшим компонентом может быть как сама форма, так и какой-либо
группирующий компонент, например TGroupBox. В общем случае старшим может быть любой
производный от TWinControl компонент, например TButton. Отношение "старший-младший"
отвечает за отображение компонентов. Таким образом, если старший компонент перемещается,
то перемещаются и все младшие, если он скрывается, то скрываются и все младшие, если он
становится недоступным, то недоступны и все младшие. Все координаты компонента также
задаются относительно старшего компонента. Формы не имеют старшего компонента, и
значение свойства Parent у них равно NULL.
В классе TWinControl также появляются дополнительные характеристики, отвечающие за
отображение компонента.
Свойство bool TWinControl::Showing определяет, может ли компонент быть видимым, т.е.
равно ли свойство Visible этого компонента и всех старших компонент true.
Свойство bool TWinControl::CanFocus определяет, может ли компонент принять фокус
ввода, т.е. равны ли свойства Visible и Enabled этого компонента и всех старших компонент true.
Свойство bool TWinControl::Focused возвращает значение true, если компонент находится
в фокусе ввода.
Метод void TWinControl::SetFocus(void) активизирует компонент, т.е. передает ему фокус
ввода.
Свойство bool TWinControl::TabStop – определяет, находится ли данный компонент в
TAB-порядке старшего компонента и может ли быть активизирован при помощи клавиши TAB.
Свойство int TWinControl::TabOrder определяет положение в TAB-порядке старшего
компонента.
Свойство HWND TWinControl::Handle содержит оконный дескриптор объекта Windows,
который инкапсулирует компонент TWinControl. Этот дескриптор может использоваться в Win32
API функциях для работы с компонентом как с обычным окном системы Windows.
Кроме метода WndProc класс TWinControl имеет еще невиртуальный метод void
TWinControl::MainWndProc(TMessage &Message), который сообщается системе Windows как
функция окна. Внутри этого метода происходит попытка вызвать метод, адрес которого хранится
в свойстве WindowProc (по умолчанию WndProc), и в случае неудачи вызывается Appliction-
>HandleException. В отличие от TControl, класс TWinControl позволяет обрабатывать любые
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
11
сообщения Windows. В частности происходит обработка сообщений от клавиатуры и сообщения
связанные с фокусом ввода, в результате чего у класса TWinControl появляются следующие
события: OnKeyDown, OnKeyPress, OnKeyUp, OnEnter и OnExit.
Метод void TWinControl::Broadcast(void *Message) используется для рассылки сообщения
Message всем младшим элементам управления. Благодаря этому методу компоненты,
наследованные от TControl, получают возможность обработки некоторых сообщений, например,
сообщений от мыши, сообщений, связанных с перерисовкой и т.д.
Большинство компонент не наследуются непосредственно от TWinControl. Для
стандартных органов управления существуют специализированные классы TButtonControl,
TCustomComboBox, TCustomEdit, TCustomListBox и т.д. Дополнительные органы управления
наследуются обычно от класса TCustomControl.
Компоненты, производные от класса TGraphicControl, в отличие от TWinControl, не
имеют оконного дескриптора, не имеют функции окна, не могут принять фокус ввода и не могут
являться родителями других элементов управления. Производные TGraphicControl используются
в тех ситуациях, когда необходимо изобразить на форме текст или графику, не обращаясь к
функциональным возможностям обычных оконных элементов управления. Отметим следующие
достоинства такого подхода. Во-первых, TGraphicControl не пользуется системными ресурсами
Windows, так как не требует оконного дескриптора. Во-вторых, метод рисования TGraphicControl
исполняется немного быстрее за счет того, что перерисовка компоненты не связана с
диспетчеризацией сообщений Windows, а реализуется процессом рисования, заложенным в
родителе данного компонента.
Свойство TCanvas * TGraphicControl::Canvas возвращает указатель на класс TCanvas,
предоставляющий холст для рисования. Класс TCanvas инкапсулирует GDI возможности,
предоставляемые операционной системой Windows. Он содержит различные свойства и методы,
позволяющие производить различные графические операции. Свойство HDC TCanvas::Handle
позволяет получить доступ к контексту отображения, связанному с клиентской областью
компонента. Этот дескриптор может быть передан Win32 API GDI функциям для работы с
контекстом отображения непосредственно.
Метод void TGraphicControl::Paint(void) вызывается в ответ на сообщение WM_PAINT,
принимаемое родительским элементом управления. В классе TGraphicControl этот метод
является защищенным. Метод Paint переопределяется в потомках и рисует изображение
графического элемента управления.
Лекция №11 для дисциплин: «Прикладное программирование» и «Языки
программирования»
12
Основными потомками являются TСustomLabel, TShape, TImage.
Класс TCustomControl, является непосредственным потомком TWinControl. Однако
подобно TGraphicControl в этом классе добавляются свойство Canvas и метод Paint. Благодаря
этому упрощается процедура рисования изображения компонента.
Остальные компоненты в иерархии содержат специфичные свойства, методы и события
для различных групп компонентов (например, TButtonControl для кнопок) и их рассмотрение
выходит за рамки данного учебного пособия.
Вывод
Система С++Builder содержит большой набор различных компонент, основная
функциональность которых определена базовыми классами. Компоненты являются дальнейшим
развитием классов, могут существовать как во время выполнения приложения, так и на этапе
проектирования. В дополнении к данным и функциям класса, компоненты имеют также свойства
и события. Все действия, доступные на этапе проектирования (например, изменение значений
свойств и назначение обработчиков событий), программист может исполнять и на этапе
выполнения. Все компоненты находятся в отношении "основной-вспомогательный", все
отображаемые компоненты находятся в отношении "старший-младший". Компоненты
TWinControl позволяют обрабатывать любые сообщения Windows. Любые функциональные
возможности, предоставляемые системой и не реализованные в тех или иных компонентах, могут
быть реализованы с помощью WIN32 API функций.

Contenu connexe

Tendances

Работа с БД в Java
Работа с БД в JavaРабота с БД в Java
Работа с БД в Javametaform
 
C++ осень 2012 лекция 6
C++ осень 2012 лекция 6C++ осень 2012 лекция 6
C++ осень 2012 лекция 6Technopark
 
VAMR ACADEMY Второе занятие
VAMR ACADEMY Второе занятиеVAMR ACADEMY Второе занятие
VAMR ACADEMY Второе занятиеmixARConference
 
C# Desktop. Занятие 04.
C# Desktop. Занятие 04.C# Desktop. Занятие 04.
C# Desktop. Занятие 04.Igor Shkulipa
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.Igor Shkulipa
 
работа с потоками ввода вывода
работа с потоками ввода выводаработа с потоками ввода вывода
работа с потоками ввода выводаmetaform
 
апкс 2011 05_verilog
апкс 2011 05_verilogапкс 2011 05_verilog
апкс 2011 05_verilogIrina Hahanova
 
Java. Работа с файловой системой. Потоки ввода-вывода.
Java. Работа с файловой системой. Потоки ввода-вывода.Java. Работа с файловой системой. Потоки ввода-вывода.
Java. Работа с файловой системой. Потоки ввода-вывода.Unguryan Vitaliy
 
C++ осень 2013 лекция 6
C++ осень 2013 лекция 6C++ осень 2013 лекция 6
C++ осень 2013 лекция 6Technopark
 
C++ осень 2013 лекция 3
C++ осень 2013 лекция 3C++ осень 2013 лекция 3
C++ осень 2013 лекция 3Technopark
 
Vba программы
Vba программыVba программы
Vba программыLidiKashka
 

Tendances (14)

Работа с БД в Java
Работа с БД в JavaРабота с БД в Java
Работа с БД в Java
 
C++ осень 2012 лекция 6
C++ осень 2012 лекция 6C++ осень 2012 лекция 6
C++ осень 2012 лекция 6
 
лек11 4
лек11 4лек11 4
лек11 4
 
VAMR ACADEMY Второе занятие
VAMR ACADEMY Второе занятиеVAMR ACADEMY Второе занятие
VAMR ACADEMY Второе занятие
 
C# Desktop. Занятие 04.
C# Desktop. Занятие 04.C# Desktop. Занятие 04.
C# Desktop. Занятие 04.
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.
 
работа с потоками ввода вывода
работа с потоками ввода выводаработа с потоками ввода вывода
работа с потоками ввода вывода
 
апкс 2011 05_verilog
апкс 2011 05_verilogапкс 2011 05_verilog
апкс 2011 05_verilog
 
Java. Работа с файловой системой. Потоки ввода-вывода.
Java. Работа с файловой системой. Потоки ввода-вывода.Java. Работа с файловой системой. Потоки ввода-вывода.
Java. Работа с файловой системой. Потоки ввода-вывода.
 
Stream API
Stream APIStream API
Stream API
 
C++ осень 2013 лекция 6
C++ осень 2013 лекция 6C++ осень 2013 лекция 6
C++ осень 2013 лекция 6
 
Step 3.2
Step 3.2Step 3.2
Step 3.2
 
C++ осень 2013 лекция 3
C++ осень 2013 лекция 3C++ осень 2013 лекция 3
C++ осень 2013 лекция 3
 
Vba программы
Vba программыVba программы
Vba программы
 

Similaire à лек11 5

паттерны программирования
паттерны программированияпаттерны программирования
паттерны программированияguestfc8ae0
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++mcroitor
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5Technopark
 
C++ осень 2013 лекция 7
C++ осень 2013 лекция 7C++ осень 2013 лекция 7
C++ осень 2013 лекция 7Technopark
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9Technopark
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Yandex
 
C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.Igor Shkulipa
 
вспомогательные алгоритмы
вспомогательные алгоритмывспомогательные алгоритмы
вспомогательные алгоритмыЕлена Ключева
 
Уменьшение влияния человеческого фактора при разработке бизнес приложений
Уменьшение влияния человеческого фактора при разработке бизнес приложенийУменьшение влияния человеческого фактора при разработке бизнес приложений
Уменьшение влияния человеческого фактора при разработке бизнес приложенийngrebnev
 
C++ теория
C++ теорияC++ теория
C++ теорияtank1975
 
C++ теория
C++ теорияC++ теория
C++ теорияtank1975
 
C++ теория
C++ теорияC++ теория
C++ теорияtank1975
 
язык програмирования
язык програмированияязык програмирования
язык програмированияOlegmingalev1997
 
C++ осень 2012 лекция 3
C++ осень 2012 лекция 3C++ осень 2012 лекция 3
C++ осень 2012 лекция 3Technopark
 
Ado.net module 6 entity framework
Ado.net module 6 entity frameworkAdo.net module 6 entity framework
Ado.net module 6 entity frameworkAndrii Hladkyi
 

Similaire à лек11 5 (20)

лек13 3
лек13 3лек13 3
лек13 3
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
 
лр8
лр8лр8
лр8
 
особенности программирования на с++
особенности программирования на с++особенности программирования на с++
особенности программирования на с++
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
 
C++ осень 2013 лекция 7
C++ осень 2013 лекция 7C++ осень 2013 лекция 7
C++ осень 2013 лекция 7
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
 
C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.C++ Базовый. Занятие 03.
C++ Базовый. Занятие 03.
 
вспомогательные алгоритмы
вспомогательные алгоритмывспомогательные алгоритмы
вспомогательные алгоритмы
 
Уменьшение влияния человеческого фактора при разработке бизнес приложений
Уменьшение влияния человеческого фактора при разработке бизнес приложенийУменьшение влияния человеческого фактора при разработке бизнес приложений
Уменьшение влияния человеческого фактора при разработке бизнес приложений
 
C++ теория
C++ теорияC++ теория
C++ теория
 
C++ теория
C++ теорияC++ теория
C++ теория
 
C++ теория
C++ теорияC++ теория
C++ теория
 
Modul №2. OOP C++
Modul  №2. OOP C++Modul  №2. OOP C++
Modul №2. OOP C++
 
язык програмирования
язык програмированияязык програмирования
язык програмирования
 
C++ осень 2012 лекция 3
C++ осень 2012 лекция 3C++ осень 2012 лекция 3
C++ осень 2012 лекция 3
 
лек11 2
лек11 2лек11 2
лек11 2
 
лекция №1
лекция №1лекция №1
лекция №1
 
Ado.net module 6 entity framework
Ado.net module 6 entity frameworkAdo.net module 6 entity framework
Ado.net module 6 entity framework
 

Plus de Anastasia Snegina

птп по ппп 2013 2014
птп по ппп 2013 2014 птп по ппп 2013 2014
птп по ппп 2013 2014 Anastasia Snegina
 
прикл.прогр птп 13 14
прикл.прогр птп 13 14прикл.прогр птп 13 14
прикл.прогр птп 13 14Anastasia Snegina
 
2012 2013 пм спп провидошина
2012 2013  пм спп провидошина2012 2013  пм спп провидошина
2012 2013 пм спп провидошинаAnastasia Snegina
 
2012 2013 пм спп провидошина
2012 2013  пм спп провидошина2012 2013  пм спп провидошина
2012 2013 пм спп провидошинаAnastasia Snegina
 
рп по у пп практике в
рп по у пп практике врп по у пп практике в
рп по у пп практике вAnastasia Snegina
 
рп по пр практике в
рп по пр практике врп по пр практике в
рп по пр практике вAnastasia Snegina
 
рп по у сп практике в
рп по у сп практике врп по у сп практике в
рп по у сп практике вAnastasia Snegina
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике втAnastasia Snegina
 
рп по пр практике вт
рп по пр практике втрп по пр практике вт
рп по пр практике втAnastasia Snegina
 
рп по у сп практике вт
рп по у сп практике втрп по у сп практике вт
рп по у сп практике втAnastasia Snegina
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике втAnastasia Snegina
 
рп по пр практике вт
рп по пр практике втрп по пр практике вт
рп по пр практике втAnastasia Snegina
 
рп по у сп практике вт
рп по у сп практике втрп по у сп практике вт
рп по у сп практике втAnastasia Snegina
 

Plus de Anastasia Snegina (20)

птп по ппп 2013 2014
птп по ппп 2013 2014 птп по ппп 2013 2014
птп по ппп 2013 2014
 
прикл.прогр птп 13 14
прикл.прогр птп 13 14прикл.прогр птп 13 14
прикл.прогр птп 13 14
 
я.прогр птп
я.прогр птпя.прогр птп
я.прогр птп
 
пп кос вт
пп кос втпп кос вт
пп кос вт
 
пп кос в
пп кос впп кос в
пп кос в
 
пп кос в
пп кос впп кос в
пп кос в
 
2012 2013 пм спп провидошина
2012 2013  пм спп провидошина2012 2013  пм спп провидошина
2012 2013 пм спп провидошина
 
2012 2013 пм спп провидошина
2012 2013  пм спп провидошина2012 2013  пм спп провидошина
2012 2013 пм спп провидошина
 
пп кос вт
пп кос втпп кос вт
пп кос вт
 
рп по у пп практике в
рп по у пп практике врп по у пп практике в
рп по у пп практике в
 
рп по пр практике в
рп по пр практике врп по пр практике в
рп по пр практике в
 
рп по у сп практике в
рп по у сп практике врп по у сп практике в
рп по у сп практике в
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике вт
 
рп по пр практике вт
рп по пр практике втрп по пр практике вт
рп по пр практике вт
 
рп по у сп практике вт
рп по у сп практике втрп по у сп практике вт
рп по у сп практике вт
 
рп по у пп практике вт
рп по у пп практике втрп по у пп практике вт
рп по у пп практике вт
 
рп по пр практике вт
рп по пр практике втрп по пр практике вт
рп по пр практике вт
 
рп по у сп практике вт
рп по у сп практике втрп по у сп практике вт
рп по у сп практике вт
 
лр18
лр18лр18
лр18
 
лр15
лр15лр15
лр15
 

лек11 5

  • 1. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 1 Лекция 11 (ч.5) Синтаксис и программные конструкции Visual C 4. Библиотека визуальных компонент С++Builder 4.2. Иерархия классов VCL Все компоненты VCL находятся в иерархии классов, основу которой составляют базовые классы. Каждый базовый класс имеет некоторый набор методов, событий и свойств и специальное назначение. От этих базовых классов затем наследуются уже реальные классы компонентов и их поведение определено базовыми классами-предками, находящимися выше них в иерархии. Базовые классы библиотеки VCL иногда называют абстрактными, однако они не являются абстрактными классами с точки зрения языка С++. Эти классы не имеют чистых виртуальных функций и для них могут быть созданы экземпляры классов. Однако для этих классов нельзя создать полноценно работающие объекты, поскольку в них содержатся лишь общие характеристики, которые затем должны уточняться и переопределяться в классах- потомках. Тем не менее, эти классы полезны в качестве базовых при создании пользовательских компонент, так как содержат общие характеристики, присущие всем классам данного семейства. Кроме того, указателю на базовый класс может быть присвоен адрес любого объекта производного класса. Полная иерархия базовых классов библиотеки VCL представлена на рисунке. Рис. 4.1. Фрагмент схемы иерархии классов библиотеки VCL
  • 2. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 2 Основой иерархий являются классы TObject, TPersistent, TComponent, TControl, TGraphicControl, TWinControl. TObject является базовым классом для всех порождаемых классов библиотеки VCL, TComponent является базовым классом для всех порождаемых компонент. Невидимые компоненты произведены от класса TComponent. Отображаемые компоненты имеют общего предка TControl, при этом графические компоненты произведены от класса TGraphicControl, а оконные от класса TWinControl. Причем компоненты, инкапсулирующие стандартные органы управления Windows, произведены непосредственно от класса TWinControl, а оригинальные компоненты от класса TCustomControl. Рассмотрим основные базовые классы более подробно. Класс TObject инкапсулирует общее функциональное поведение для всех классов системы С++Builder, а именно: - возможность создания, управления и уничтожения экземпляров объекта; - поддержка информации RTTI об имени и типе объекта; - поддержка механизма обработки сообщений. Большинство этих методов предназначены для внутреннего использования системой С++Builder. Часть методов TObject объявлены как статические (с ключевым словом static). Таким образом, к ним можно обращаться, не создавая экземпляр класса, используя лишь имя класса или метакласс. Рассмотрим некоторые часто используемые методы объекта TObject. ShortString TObject::ClassName(void) - статический метод, который возвращает строку с именем класса. TMetaClass * TObject::ClassType(void) - статический метод, который возвращает указатель на метакласс. TMetaClass * TObject::ClassParent(void) - статический метод, который возвращает указатель на метакласс предка (для TObject возвращает NULL). bool TObject::InheritsFrom(TMetaClass *) возвращает true, если объект является экземпляром указанного в качестве параметра класса или класса потомка. Например: if (Sender->InheritsFrom(__classid(TWinControl))) ShowMessage(«Экземпляр потомка TWinControl»); void TObject::Dispatch (void* Message) - виртуальный метод, посылает сообщение на обработку, вызывая необходимый обработчик. Обработчик ищется по идентификатору сообщения, расположенному в 2-х первых байтах по адресу, переданному в качестве параметра. В классах потомках в качестве параметра передается указатель на структуру TMessage. Сначала
  • 3. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 3 просматриваются обработчики в текущем классе, затем, если обработчик не был найден, - в классах предках. Если обработчик так и не был найден, вызывается DefaultHandler. void TObject::DefaultHandler(void* Message) - виртуальный метод, обработчик сообщения по умолчанию. Для TObject не выполняет никаких действий (для TWinControl вызывает стандартную API-функцию DefWndProc, которая выполняет обработку сообщений Windows по умолчанию). int TObject::Free(void) вызывает деструктор для уничтожения объекта. Аналогичные действия могут быть выполнены с помощью оператора delete. Ниже приведен пример, позволяющий вывести диалоговое окно, содержащее иерархию для объекта переданного в качестве параметра Sender. void __fastcall TForm1::ControlClick(TObject *Sender) {AnsiString Str; TClass tcl; tcl=Sender->ClassType(); while (tcl) { Str+=AnsiString(tcl->ClassName())+"n"; tcl=tcl->ClassParent(); } ShowMessage(Str);} Кроме рассмотренных выше методов существуют еще несколько сервисных методов, использующихся в основном при разработке компонентов. Например, FieldAddress, MethodAddress, MethodName, InitInstance, FreeInstance, InstanceSize и т.д. От TObject наследуются в основном простые объекты, которые не являются компонентами и не нуждаются в поточности и присваивании. Класс TPersistent является предком всех классов, поддерживающих работу со свойствами. Являясь потомками TPersistent, производные классы приобретают способность поточности и присваивания, а именно: - возможность сохранения и чтения из потока неопубликованных свойств; - возможность присвоения значений свойствам; - возможность присвоения данных одного объекта другому. Запись и чтение из потока производится в формате dfm. Таким образом, под записью/чтением в поток подразумевается возможность сохранения/загрузки значений свойств в
  • 4. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 4 файл формы. В общем случае поточность предоставляет классам возможность помещения в память и загрузки из памяти, например, при переносе компонентов через буфер обмена. Несмотря на то, что поточность появляется, начиная с класса TPersistent, используют эту возможность в основном компоненты, т.е. классы, наследованные от TComponent. Большинство методов TPersistent перегружаются в потомках. Рассмотрим методы этого класса. void TPersistent::Assign(TPersistent *Source) позволяет данному объекту присвоить значения свойств и атрибутов другого объекта, заданного в качестве параметра. Например, Destination->Assign(Source); void TPersistent::AssignTo (TPersistent* Destination) позволяет присваивать значения свойств и атрибутов текущего объекта другому объекту, указанному в качестве параметра. У TPersistent этот метод является виртуальным и защищенным. Этот метод необходим при разработке новых классов для обеспечения возможности присваивания их стандартным классам. Если метод Assign объекта A не знает как выполнить присваивание параметров объекта B, то его метод Assign автоматически вызывает метод AssignTo объекта B. Т.е. если A->Assign(B) не может выполниться для типа объекта B, то внутри метода Assign вызывается B->AssignTo(A). void TPersistent::DefineProperties(TFiler *Filer) позволяет определить процедуру загрузки и сохранения в потоке неопубликованных свойств. По умолчанию сохраняются только опубликованные свойства, т.е. объявленные в секции __published. У TPersistent этот метод является виртуальным и защищенным. От TPersistent наследуются классы, которые не являются компонентами, но нуждаются в поточности и присваивании. Класс TComponent является предком всех компонент. TComponent определяет общее функциональное поведение для всех компонент системы С++Builder, а именно: -возможность помещения на форму из палитры компонент и манипуляции в окне редактора форм; -способность владения и обслуживания других компонент; -специальные характеристики поточности, с которыми может манипулировать инспектор объектов на этапе проектирования. На уровне TСomponent проявляется отношение "основной - вспомогательный". Это отношение распространяется на все компоненты системы С++Builder. Конструктор TСomponent, в отличие от конструкторов предыдущих классов, имеет параметр AOwner типа TComponent *,
  • 5. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 5 указывающий основной компонент для создаваемого компонента. Кроме того, TСomponent содержит ряд свойств, характеризующих отношение "основной - вспомогательный". Свойство TComponent* TComponent::Owner - указатель на основной компонент. Доступно только для чтения и только во время выполнения приложения (ReadOnly, RunTime). Форма является основной для всех помещенных на нее компонент, приложение Application является основным для всех форм. int TComponent::ComponentCount содержит количество вспомогательных компонент для данного компонента (ReadOnly, RunTime). int TComponent::ComponentIndex содержит индекс данного компонента в списке основного компонента (ReadOnly, RunTime). Нумерация начинается с 0. При отображении компоненты с меньшим индексом прорисовываются раньше. Изменить порядок для отображаемых компонент можно с помощью пунктов главного меню Edit | Bring to Front и Edit | Send to Back, изменяющих также Z-порядок. Для неотображаемых компонент с помощью пункта главного меню Edit | Creation Order. TComponent* TComponent::Components[int Index] содержит массив указателей вспомогательных компонент для данного компонента (ReadOnly, RunTime). Нумерация начинается с 0. При вызове конструктора компонент помещается в список Components компонента, указанного в качестве параметра. При вызове деструктора удаляется из этого списка. Кроме того, можно добавить и удалить компонент из списка с помощью методов void TComponent::InsertComponent (TComponent* AComponent) и void TComponent::RemoveComponent (TComponent* AComponent) соответственно. Внутренняя реализация этого массива представляет собой два отдельных списка TList для отображаемых и неотображаемых компонент. Отношение "основной - вспомогательный" отвечает за владение и удаление компонентов. При удалении компонента сначала вызываются деструкторы всех вспомогательных компонент. При этом для всех компонент, помещенных на формы в процессе проектирования, при освобождении обнуляются указатели на соответствующие компоненты. Свойство AnsiString TComponent::Name содержит имя компонента. При помещении на форму имя компонента назначается автоматически на основе имени класса. Например, Button1, Button2 и т.д. для класса TButton, это же имя будет присвоено переменной, содержащей указатель на компонент. Рекомендуется задавать осмысленные имена для более удобного чтения кода. Например, btnStart, btnStop и т.д. Для динамически создаваемых во время выполнения
  • 6. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 6 компонент имя может отличаться от имени переменной, допустимо значение NULL. Следует также отметить, что для отображаемых компонент обычно существуют также свойства Caption или Text. Они содержат текстовые строки, отображаемые на самом компоненте (название кнопки, содержимое поля ввода и т.д.). При добавлении компонента на форму эти свойства содержат значения, совпадающие с Name. Однако они имеют принципиально другое назначение и используются лишь для отображения компонента. Например, для нашего примера Caption может быть «Старт» и «Стоп» для кнопок btnStart и btnStop. TComponent* TComponent::FindComponent (const AnsiString AName) возвращает указатель экземпляра компонента с именем, указанным в качестве параметра. Например: void_fastcall TForm1::ButtonlClick(TObject *Sender) {TEdit* EditInstance; EditInstance = dynamic_cast<TEdit *>(FindComponent("Edit1")); if (EditInstance) EditInstance->Text="new";} TComponentState TComponent::ComponentState - текущее состояние компонента. Список возможных значений: (csAncestor, csDesigning, csDestroying, csFixups, csLoading, csReading, csUpdating,csWriting). TComponentStyle TComponent::ComponentStyle - стиль, определяющий поведение компонента (csInheritable, csCheckPropAvail). int TComponent::Tag - свойство целого типа, которое не имеет предопределенного значения и может содержать любые данные или указатели, по усмотрению программиста. TComponent используется в качестве базового класса при создании невидимых компонент. Класс TControl является предком всех видимых компонент. Поскольку элементы TControl обладают способностью отображать себя, некоторые свойства этого класса оперируют с положением, размером и видом объекта (Top, Left, Width, Height, BoundsRect, Cursor, Hint), а другие свойства относятся к параметрам клиентской области (ClientRect, ClientWidth и ClientHeight). TControl также вводит свойства, устанавливающие видимость, доступность, цвет и шрифт элементов управления (Visible, Enabled, Color и Font). Свойства Text и Caption обеспечивают установку редактируемых текстов и названий. Свойство ControlState задает состояние органа управления (csLButtonDown, csClicked, csPalette, csReadingState, csAlignmentNeeded, csFocusing, csCreating, csPaintCopy, csCustomPaint, csDestroyingHandle, csDocking). Свойство ControlStyle определяет характеристики органа управления (csAcceptsControls, csCaptureMouse, csDesignInteractive, csClickEvents, csFramed, csSetCaption,
  • 7. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 7 csOpaque, csDoubleClicks, csFixedWidth, csFixedHeight, csNoDesignVisible, csReplicatable, csNoStdEvents, csDisplayDragImage, csReflector, csActionClient, csMenuEvents). Свойство Align задает выравнивание компонента относительно родительского компонента (alNone, alTop, alBottom, alLeft, alRight, alClient), а свойство Anchor задает привязку к размерам родительского компонента (множество из akLeft, akTop, akRight, akBottom). Свойство Constraints позволяет задать максимальные и минимальные размеры компонента. Метод SetBounds(int ALeft, int ATop, int AWidth, int AHeight) позволяет изменить положение и размер компонента. Все визуальные компоненты кроме отношения "основной-вспомогательный" находятся также в отношении "старший-младший" или "родитель-ребенок". В аналогичном отношении находятся все органы управления Windows. Поэтому уже у TСontrol появляются некоторые свойства характеризующие это отношение. Свойство TWinControl* TСontrol::Parent содержит указатель на родительский компонент. Родительскими могут быть только оконные элементы управления, и поэтому они должны быть производным от TWinControl. Сам компонент TControl не может быть родителем, а может быть только дочерним компонентом. Для формы значение свойства Parent задается как NULL. Кроме того, имеются свойства ParentColor, ParentFont и ParentShowHint типа bool которые определяют, будут ли в качестве значений свойств Color, Font и ShowHint использоваться значения соответствующих свойств родительского компонента. Все координаты компонента задаются относительно родительского компонента, при этом начало координат это левый верхний угол этого компонента (так называемые локальные координаты). Существуют еще и глобальные координаты с началом координат в верхнем левом углу экрана. Для пересчета локальных координат в глобальные и наоборот используются функции TPoint TControl::ClientToScreen(const TPoint &Point) и TPoint TControl::ScreenToClient(const TPoint &Point) соответственно. TControl содержит также методы ответственные за отображение органа управления. void TControl::Hide(void) делает текущий элемент управления невидимым, т.е. устанавливает свойство Visible в false. При этом компонент всего лишь не отображается на экране, он не удаляется из динамической памяти и из списка вспомогательного компонента, и все его методы и свойства остаются доступными. void TControl::Show(void) отображает текущий элемент управления, т.е. устанавливает свойство Visible в true.
  • 8. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 8 void TControl::Repaint(void) перерисовывает текущий элемент управления. Перерисовка происходит немедленно. При этом, если свойство ControlStyle содержит значение csOpaque, компонент перерисовывает себя самостоятельно, в противном случае вызывается метод Invalidate, а затем Update для перерисовки некоторой видимой части компонента. void TControl::Refresh(void) вызывает метод Repaint. void TControl::Invalidate(void) сообщает системе о том, что некоторая область органа управления должна быть перерисована. Перерисовка произойдет при обработке сообщения о перерисовке после обработки всех сообщений находящихся в очереди. Причем Invalidate может быть вызван несколько раз, до того момента как произойдет непосредственно перерисовка. void TControl::Update(void) позволяет немедленно обработать сообщение о перерисовке. Таким образом, если для компонента до этого был вызван метод Invalidate, это приведет к перерисовке. Методы void TControl::BringToFront(void) и void TControl::SendToBack(void) управляют Z- порядком компонента, помещая его на передний или задний план соответственно. Метод TControl::WndProc(TMessage &Message) обрабатывает поступившие органу управления сообщения Message класса TMessage. Адрес этого метода хранится в свойстве WindowProc, описанном в секции public. Это позволяет подменять стандартный обработчик и производить самостоятельную обработку каких-либо сообщений. Таким образом, возможность обработки сообщений операционной системы появляется уже в классе TControl. Этот класс обрабатывает только сообщения от мыши, но его потомки способны обрабатывать и другие сообщения операционной системы Windows. В результате обработки сообщений от мыши у класса TControl появляются следующие события: OnClick, OnDblClick, OnMouseDown, OnMouseMove, OnMouseUp. Задав обработчики этих событий, можно определить реакцию компонента на манипуляции мышью. Кроме того, в классе TСontrol появляются также свойства, методы и события, реализующие механизм Drag-and-Drop. Класс TControl редко используется непосредственно, большинство компонент являются производными от TWinControl или TGraphicControl. Класс TWinControl является предком всех оконных элементов управления. С каждым таким элементом управления связано окно («window») операционной системы Windows. Производные от TWinControl компоненты обладают тремя основными характеристиками: они имеют оконные дескрипторы (HWND), способны принимать фокус ввода и могут являться
  • 9. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 9 родителями других элементов управления. В классе TWinControl полностью определяется отношение "старший-младший", для этого добавляются следующие свойства. int TWinControl::ControlCount содержит количество младших элементов управления для данного компонента (ReadOnly, RunTime). TControl* TWinControl::Controls[int Index] содержит массив указателей младших элементов управления для данного компонента (ReadOnly, RunTime). Нумерация начинается с 0. Компонент добавляется и удаляется из соответствующих массивов при изменении свойства Parent. Кроме того, для добавления и удаления компонента в список младших компонентов можно использовать методы void TWinControl::InsertControl(TControl *AControl) и void TWinControl::RemoveControl (TControl *AControl). Метод bool TWinControl::ContainsControl(TControl* Control) определяет, может ли данный компонент управлять компонентом Control, т.е. является ли Control младшим для данного компонента непосредственно или косвенно. TControl* TWinControl::ControlAtPos(TPoint &Pos, bool AllowDisabled) возвращает указатель на младший компонент расположенный в заданных координатах клиентской области данного компонента. Таким образом, все компоненты С++Builder находятся в отношении "основной- вспомогательный". Как уже говорилось, это отношение отвечает за владение компонентами. Когда уничтожается основная компонента, уничтожаются и все вспомогательные компоненты. Для всех компонент, помещенных на форму, основной является форма, для всех форм основным является приложение Application, экземпляр класса TApplication. Таким образом, если приложение завершается, то закрываются и все формы, и, соответственно, уничтожаются все принадлежащие им компоненты. Причем для форм и приложения есть и обратное воздействие. Среди всех форм одна должна быть главной, ссылка на нее содержится в свойстве MainForm объекта Application. Обычно главной формой становится первая созданная форма. Изменить главную форму можно в опциях проекта на закладке Forms в поле MainForm. Закрытие главной формы приводит к завершению приложения, что в свою очередь приводит к закрытию и всех остальных форм. Следует особо отметить, что при запуске приложения главная форма отображается независимо от значения свойства Visible. Затем это форма может быть скрыта обычными способами. Однако программист в случае скрытия главной формы должен предусмотреть какие-либо варианты завершения приложения, поскольку закрытие пользователем всех остальных форм не приведет к завершению приложения. Если все-таки
  • 10. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 10 необходимо скрыть главную форму при запуске приложения, то можно использовать свойство ShowMainForm объекта TApplication. Все отображаемые компоненты связаны еще отношением "старший-младший". Старшим компонентом может быть как сама форма, так и какой-либо группирующий компонент, например TGroupBox. В общем случае старшим может быть любой производный от TWinControl компонент, например TButton. Отношение "старший-младший" отвечает за отображение компонентов. Таким образом, если старший компонент перемещается, то перемещаются и все младшие, если он скрывается, то скрываются и все младшие, если он становится недоступным, то недоступны и все младшие. Все координаты компонента также задаются относительно старшего компонента. Формы не имеют старшего компонента, и значение свойства Parent у них равно NULL. В классе TWinControl также появляются дополнительные характеристики, отвечающие за отображение компонента. Свойство bool TWinControl::Showing определяет, может ли компонент быть видимым, т.е. равно ли свойство Visible этого компонента и всех старших компонент true. Свойство bool TWinControl::CanFocus определяет, может ли компонент принять фокус ввода, т.е. равны ли свойства Visible и Enabled этого компонента и всех старших компонент true. Свойство bool TWinControl::Focused возвращает значение true, если компонент находится в фокусе ввода. Метод void TWinControl::SetFocus(void) активизирует компонент, т.е. передает ему фокус ввода. Свойство bool TWinControl::TabStop – определяет, находится ли данный компонент в TAB-порядке старшего компонента и может ли быть активизирован при помощи клавиши TAB. Свойство int TWinControl::TabOrder определяет положение в TAB-порядке старшего компонента. Свойство HWND TWinControl::Handle содержит оконный дескриптор объекта Windows, который инкапсулирует компонент TWinControl. Этот дескриптор может использоваться в Win32 API функциях для работы с компонентом как с обычным окном системы Windows. Кроме метода WndProc класс TWinControl имеет еще невиртуальный метод void TWinControl::MainWndProc(TMessage &Message), который сообщается системе Windows как функция окна. Внутри этого метода происходит попытка вызвать метод, адрес которого хранится в свойстве WindowProc (по умолчанию WndProc), и в случае неудачи вызывается Appliction- >HandleException. В отличие от TControl, класс TWinControl позволяет обрабатывать любые
  • 11. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 11 сообщения Windows. В частности происходит обработка сообщений от клавиатуры и сообщения связанные с фокусом ввода, в результате чего у класса TWinControl появляются следующие события: OnKeyDown, OnKeyPress, OnKeyUp, OnEnter и OnExit. Метод void TWinControl::Broadcast(void *Message) используется для рассылки сообщения Message всем младшим элементам управления. Благодаря этому методу компоненты, наследованные от TControl, получают возможность обработки некоторых сообщений, например, сообщений от мыши, сообщений, связанных с перерисовкой и т.д. Большинство компонент не наследуются непосредственно от TWinControl. Для стандартных органов управления существуют специализированные классы TButtonControl, TCustomComboBox, TCustomEdit, TCustomListBox и т.д. Дополнительные органы управления наследуются обычно от класса TCustomControl. Компоненты, производные от класса TGraphicControl, в отличие от TWinControl, не имеют оконного дескриптора, не имеют функции окна, не могут принять фокус ввода и не могут являться родителями других элементов управления. Производные TGraphicControl используются в тех ситуациях, когда необходимо изобразить на форме текст или графику, не обращаясь к функциональным возможностям обычных оконных элементов управления. Отметим следующие достоинства такого подхода. Во-первых, TGraphicControl не пользуется системными ресурсами Windows, так как не требует оконного дескриптора. Во-вторых, метод рисования TGraphicControl исполняется немного быстрее за счет того, что перерисовка компоненты не связана с диспетчеризацией сообщений Windows, а реализуется процессом рисования, заложенным в родителе данного компонента. Свойство TCanvas * TGraphicControl::Canvas возвращает указатель на класс TCanvas, предоставляющий холст для рисования. Класс TCanvas инкапсулирует GDI возможности, предоставляемые операционной системой Windows. Он содержит различные свойства и методы, позволяющие производить различные графические операции. Свойство HDC TCanvas::Handle позволяет получить доступ к контексту отображения, связанному с клиентской областью компонента. Этот дескриптор может быть передан Win32 API GDI функциям для работы с контекстом отображения непосредственно. Метод void TGraphicControl::Paint(void) вызывается в ответ на сообщение WM_PAINT, принимаемое родительским элементом управления. В классе TGraphicControl этот метод является защищенным. Метод Paint переопределяется в потомках и рисует изображение графического элемента управления.
  • 12. Лекция №11 для дисциплин: «Прикладное программирование» и «Языки программирования» 12 Основными потомками являются TСustomLabel, TShape, TImage. Класс TCustomControl, является непосредственным потомком TWinControl. Однако подобно TGraphicControl в этом классе добавляются свойство Canvas и метод Paint. Благодаря этому упрощается процедура рисования изображения компонента. Остальные компоненты в иерархии содержат специфичные свойства, методы и события для различных групп компонентов (например, TButtonControl для кнопок) и их рассмотрение выходит за рамки данного учебного пособия. Вывод Система С++Builder содержит большой набор различных компонент, основная функциональность которых определена базовыми классами. Компоненты являются дальнейшим развитием классов, могут существовать как во время выполнения приложения, так и на этапе проектирования. В дополнении к данным и функциям класса, компоненты имеют также свойства и события. Все действия, доступные на этапе проектирования (например, изменение значений свойств и назначение обработчиков событий), программист может исполнять и на этапе выполнения. Все компоненты находятся в отношении "основной-вспомогательный", все отображаемые компоненты находятся в отношении "старший-младший". Компоненты TWinControl позволяют обрабатывать любые сообщения Windows. Любые функциональные возможности, предоставляемые системой и не реализованные в тех или иных компонентах, могут быть реализованы с помощью WIN32 API функций.