Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка DELPHI.DOC
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.73 Mб
Скачать

Пример 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

if Assigned(ToDestroy) then begin

SelectNext(ToDestroy,false,true);

ToDestroy.Free;

ToDestroy:=nil;

end ;

Caption:=Format('Кнопок %d',[TMyButton.GetCount]);

end;

end.

Вариант решения получим таким же, как на рис. 35. Однако в данном варианте, нажимая неоднократно на клавишу BackSpace, можно удалить все кнопки, построенные на форме.

Все переменные типа класс (например, ToDestroy) по сути являются указателями, поэтому для проверки, существует ли тот или иной объект, применяется функция Assigned (обработчик Timer1Timer) которая проверяет, равна ли переменная значению “пустой указатель” (т.е. nil) или нет.