Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого...
Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...
Топ:
Выпускная квалификационная работа: Основная часть ВКР, как правило, состоит из двух-трех глав, каждая из которых, в свою очередь...
Основы обеспечения единства измерений: Обеспечение единства измерений - деятельность метрологических служб, направленная на достижение...
Оценка эффективности инструментов коммуникационной политики: Внешние коммуникации - обмен информацией между организацией и её внешней средой...
Интересное:
Отражение на счетах бухгалтерского учета процесса приобретения: Процесс заготовления представляет систему экономических событий, включающих приобретение организацией у поставщиков сырья...
Средства для ингаляционного наркоза: Наркоз наступает в результате вдыхания (ингаляции) средств, которое осуществляют или с помощью маски...
Принципы управления денежными потоками: одним из методов контроля за состоянием денежной наличности является...
Дисциплины:
2017-06-02 | 245 |
5.00
из
|
Заказать работу |
|
|
Parent:=self;
Left:=x;
Top:=y;
Width:=Width+60;
Caption:=Format('%d кнопка x,y= %d,%d',
[GetCount,x,y]);
end;
Класс-функция GetCount может вызываться, в отличие от обычных методов, как из объекта (в обработчике FormMouseDown), так и из класса. Например, добавим таймер (компонент TTimer) на форму и обеспечим при срабатывании таймера изменение заголовка формы с помощью следующего обработчика события OnTimer:
procedure TForm1.Timer1Timer(Sender: TObject);
Begin
Caption:=Format('Кнопок на форме %d',
[TMyButton.GetCount]);
end;
В результате решения получим, например, следующий вариант (рис. 35).
Рис. 35 Форма со вторым вариантом расчета примера 14.
ОТСЛЕЖИВАНИЕ РАЗРУШЕНИЯ ОБЪЕКТОВ
Проследим за разрушением объектов на форме. Очевидно, это можно увидеть в секциях initialization и finalization, т.е. после того, как форма начнет разрушаться.
Initialization
MessageBox(0,PChar(Format('На форме %d кнопок',
[TMyButton.GetCount])),'Инициализация',mb_ok);
Finalization
MessageBox(0,PChar(Format('На форме %d кнопок',
[TMyButton.GetCount])),'Финиш',mb_ok);
В данном случае использовалась функция Windows API MessageBox, так как при разрушении формы доступ в секции finalization ко многим функциям Delphi невозможен. Запуская данную программу на выполнение, получим два сообщения до построения и после разрушения формы.
СОБЫТИЯ
В приложениях и компонентах событие возникает как результат послания операционной системой сообщения, что произошло некоторое действие, которое контролирует метод послания уведомления о событии. Этот метод проверяет, назначил ли пользователь соответствующий обработчик событий. Если событие произошло и обработчик назначен, то метод послания уведомления о событии вызывает соответствующий обработчик. Методы послания уведомления о событии можно переопределять, используя стандартные методы, или создавать свои собственные.
|
Рассмотрим вариант переопределения методов послания уведомления о событии. Такие методы реализуются в разделе Protected. Поэтому потомки тех встроенных классов, в которых реализуются такие методы, могут делать доступными их для пользователя. Например, рассмотрим, как переопределяется метод послания уведомления о событии Click для кнопки, одновременно изменяя её заголовок строку с текущим временем.
TtimeButton=class(Tbutton)
Protected
Procedure Click; override;
End;
....
Procedure TtimeButton.Click;
Inherited Click;
Caption:=DateTimeToStr(Now);
End;
Методы послания уведомления о событии являются указателями на метод, которые вызываются в случае, когда компонент получает сообщение от Windows о том, что произошло некоторое событие, воздействующее на данный компонент. Обработчики событий представляют собой свойства, которые выполняют чтение и запись в указатели на метод. Например, рассмотрим фрагмент, взятый из класса TControl, содержащегося в исходном коде VCL. Имена обработчиков событий по соглашению содержат префикс On. Вначале объявляется событие:
TNotifyEvent=procedure(Sender:TObject) of object;
Далее объявляется класс, содержащий поля данного типа и обработчики событий, работающие с этими полями.
Tcontrol=class(TComponent)
Private
FOnClick: TNotifyEvent;
..
Ptotected
Property OnClick: TnotifyEvent read FonClick
write FOnClick;
...
end;
При создании собственных обработчиков необходимо научиться строить методы посылки уведомления о событии. Эти методы должны уметь получать и обрабатывать сообщения Windows, что возможно сделать с помощью методов вида Message.
УКАЗАТЕЛИ НА МЕТОДЫ
Этот тип данных представляет собой ссылку (указатель) на метод. У казатель на метод содержит два адреса: одна ссылка на адрес кода метода, другая – на адрес экземпляра объекта – представляет собой скрытый параметр self. Адрес self представляет собой в данном случае адрес расположения данных, принадлежащих конкретному объекту.
Указатели на методы реализуют один из принципов компонентной технологии – делегирование. Если кто-то написал класс, у которого есть поля в виде указателей на методы, например,
|
Type
TNotifyEvent=procedure(Sender:Tobject) of object;
TMyButton=class
OnClick: TNotifyEvent;
End;,
то можно менять поведение построенных (даже скомпилированных) этого типа объектов, просто присваивая этим указателям новые методы. Например,
Type
TForm1=class(TForm)
Procedure OnButton1Click(Sender:Tobject);
Button1:MyButton;
End;
Теперь при построении компонента на форме можно делегировать обработчик OnButton1Click из TForm1 в MyButton путем следующего присваивания:
MyButton.OnClick:=Form1.OnButton1Click;
ПРИМЕР 15
Продолжим рассмотрение примера 14. Попытаемся не только динамически создавать новые объекты, но и разрушать их также динамически. Выберем, что уничтожение очередного объекта будет наступать, как только пользователь нажмет на клавишу BackSpace (#8). Для реализации этой идеи понадобятся указатели на методы.
В данном случае динамически созданный объект для своего уничтожения должен отслеживать нажатие клавиши #8. Для этих целей может служить событие OnKeyPress. Этому событию надо делегировать собственное событие. Прежде всего необходимо убедиться, что оно объявлено как указатель на метод, иначе делегирование невозможно. В справочной системе Delphi можно найти следующее объявление:
TKeyPressEvent=procedure(Sender:Tobject;var key:char)
of object;
Property OnKeyPress: TKeyPressEvent;
Таким образом, для делегирования необходимо создать свою процедуру. В классе TForm1 добавим собственный обработчик: Procedure MyButtonKeyPress(Sender:Tobject;
var key:Char);
Кроме того, в класс TForm1 необходимо добавить переменную для записи того динамически построенного метода, который подлежит удалению, так как может удаляться не только текущий объект, но и предыдущий (если новых объектов не создается). Добавим такое объявление в секции Private:
ToDestroy:TMyButton;
Теперь определим новую процедуру обработки события OnKeyPress:
procedure TForm1.MyButtonKeyPress(Sender: TObject; var Key: Char);
Begin
if key=#8 then ToDestroy:=Sender as TButton;
end;
Эта процедура не уничтожает, а запоминает подлежащий уничтожению объект. Чтобы она работала, необходимо при создании кнопки делегировать наш обработчик, записывая
OnKeyPress:=MyButtonKeyPress;
Допишем еще одну строку для установки фокуса на текущий объект SetFocus;, т.е. после удаления очередного объекта необходимо переместить фокус ввода на предыдущий объект.
|
Удаление кнопки реализуем в обработчике OnTimer. Полный текст программы приводится ниже.
unit prim15;
Interface
uses Windows, Messages, SysUtils,Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
Type
TMyButton=class(TButton)
Public
Constructor Create(AOwner:TComponent); override;
Destructor Destroy; override;
class function GetCount:integer;
end;
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Timer1Timer(Sender: TObject);
Private
ToDestroy:TMyButton;
Procedure MyButtonKeyPress(Sender:Tobject;
var key:Char);
end;
var Form1: TForm1;
Implementation
var CountBtns: integer = 0;
{$R *.dfm}
Constructor TMyButton.Create (AOwner: TComponent);
begin
inherited;
Inc(CountBtns);
end;
Destructor TMyButton.Destroy;
begin
dec(CountBtns);
inherited;
end;
class function TMyButton.GetCount: integer;
begin
Result:=CountBtns;
end;
procedure TForm1.MyButtonKeyPress(Sender: TObject;
var Key: Char);
Begin
if key=#8 then ToDestroy:=Sender as TMyButton;
end;
procedure TForm1.FormMouseDown (Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
with TMyButton.Create(self) do begin
Parent:=self;
Left:=x;
Top:=y;
Width:=Width+60;
Caption:=Format('%d кнопка x,y= %d,%d',
[GetCount,x,y]);
OnKeyPress:=MyButtonKeyPress;
SetFocus;
end;
end;
procedure TForm1.Timer1Timer (Sender: TObject);
begin
|
|
История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...
История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...
Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...
Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!