Главная » Delphi » Реализация классов TddgLaunchPad, TRunBtnItem и TRunButtons

0

Компонент TddgLaunchPad имеет  свойство типа  TRunButtons. Его реализация, как и реализация компонентов TRunBtnItem и TRunButtons, приведена в листин ге 12.11.

Листинг 12.11. LnchPad.pas — иллюстрация реализации компонента

TddgLaunchPad

unit LnchPad;

interface uses

Windows, Messages, SysUtils, Classes, Graphics, Controls,

Forms, Dialogs, RunBtn, ExtCtrls;

type

TddgLaunchPad = class;

TRunBtnItem = class(TCollectionItem)

private

FCommandLine: string;

//

Хранит командную строку

FLeft: Integer;

//

Хранит позиционные свойства

FTop: Integer;

//

для компонента TRunButton

FRunButton: TddgRunButton;

//

Указатель на TddgRunButton

FWidth: Integer;

//

Хранит размеры

FHeight: Integer;

procedure SetCommandLine(const Value: string);

procedure SetLeft(Value: Integer);

procedure SetTop(Value: Integer);

public

constructor Create(Collection: TCollection); override;

destructor Destroy; override;

procedure Assign(Source: TPersistent); override;

property Width: Integer read FWidth;

property Height: Integer read FHeight;

published

{ Публикуемые свойства для работы с потоками. }

property CommandLine: String read FCommandLine

write SetCommandLine;

property Left: Integer read FLeft write SetLeft;

property Top: Integer read FTop write SetTop;

end;

TRunButtons = class(TCollection)

private

// Хранит указатель на TddgLaunchPad

FLaunchPad: TddgLaunchPad;

function GetItem(Index: Integer): TRunBtnItem;

procedure SetItem(Index: Integer; Value: TRunBtnItem);

protected

procedure Update(Item: TCollectionItem); override;

public

constructor Create(LaunchPad: TddgLaunchPad);

function Add: TRunBtnItem;

procedure UpdateRunButtons;

property Items[Index: Integer]: TRunBtnItem read GetItem

write SetItem; default;

end;

TddgLaunchPad = class(TScrollBox)

private

FRunButtons: TRunButtons;

TopAlign: Integer;

LeftAlign: Integer;

procedure SetRunButtons(Value: TRunButtons);

procedure UpdateRunButton(Index: Integer);

publicconstructor Create(AOwner: TComponent); override;

destructor Destroy; override;

procedure GetChildren(Proc: TGetChildProc;

Root: TComponent); override;

published

property RunButtons: TRunButtons read FRunButtons

write SetRunButtons;

end;

implementation

{ TRunBtnItem }

constructor TRunBtnItem.Create(Collection: TCollection);

{ Конструктор принимает в качестве параметра коллекцию

типа TCollection, которая владеет этим элементом TRunBtnItem. }

begin

inherited Create(Collection);

{ Создает экземпляр компонента FRunButton. Делает объект панели

загрузки владельцем и родителем. Затем инициализирует его

различные свойства. }

FRunButton := TddgRunButton.Create(

TRunButtons(Collection).FLaunchPad);

FRunButton.Parent := TRunButtons(Collection).FLaunchPad;

FWidth := FRunButton.Width;       // Хранит размер по горизонтали

FHeight := FRunButton.Height; // и вертикали.

end;

destructor TRunBtnItem.Destroy;

begin

FRunButton.Free;       // Удалить экземпляр TddgRunButton.

inherited Destroy; // Вызов унаследованного деструктора Destroy.

end;

procedure TRunBtnItem.Assign(Source: TPersistent);

{ Необходимо переопределить метод TCollectionItem.Assign таким

образом, чтобы он знал, как копировать данные из одного экземпляра

TRunBtnItem в другой. Если это так, то вызывать унаследованный

метод Assign() не нужно. }

begin

if Source is TRunBtnItem then begin

{ Вместо присвоения командной строки полю FCommandLine

выполнить присвоение значения соответствующему свойству с

помощью вызова метода доступа. Метод доступа осуществляет

все необходимые сопутствующие действия. }

CommandLine := TRunBtnItem(Source).CommandLine;

{ Копировать значения в остальные поля и выйти из процедуры. }

FLeft := TRunBtnItem(Source).Left;

FTop := TRunBtnItem(Source).Top;

Exit;

end;

inherited Assign(Source);

end;procedure TRunBtnItem.SetCommandLine(const Value: string);

{ Это метод записи для свойства TRunBtnItem.CommandLine. Он

гарантирует, что экземпляру FRunButton компонента TddgRunButton

будет присвоено заданное значение строки из параметра Value. }

begin

if FRunButton <> nil then begin

FCommandLine := Value;

FRunButton.CommandLine := FCommandLine;

{ Это приводит к вызову метода TRunButtons.Update для

каждого элемента TRunBtnItem. }

Changed(False);

end;

end;

procedure TRunBtnItem.SetLeft(Value: Integer);

{ Метод доступа к свойству TRunBtnItem.Left. }

begin

if FRunButton <> nil then begin

FLeft := Value;

FRunButton.Left := FLeft;

end;

end;

procedure TRunBtnItem.SetTop(Value: Integer);

{ Метод доступа к свойству TRunBtnItem.Top. }

begin

if FRunButton <> nil then begin

FTop := Value;

FRunButton.Top := FTop;

end;

end;

{ TRunButtons }

constructor TRunButtons.Create(LaunchPad: TddgLaunchPad);

{ Конструктор заставляет FLaunchPad ссылаться на параметр типа

TddgLaunchPad. LaunchPad является владельцем этой коллекции, и для

доступа к ней необходимо иметь соответствующий указатель. }

begin

inherited Create(TRunBtnItem);

FLaunchPad := LaunchPad;

end;

function TRunButtons.GetItem(Index: Integer): TRunBtnItem;

{ Метод доступа для TRunButtons.Items, возвращающий экземпляр

компонента TRunBtnItem. }

begin

Result := TRunBtnItem(inherited GetItem(Index));

end;

procedure TRunButtons.SetItem(Index: Integer; Value: TRunBtnItem);

{ Метод доступа к свойству TRunButton.Items, позволяющий выполнить

присвоение элементу с заданным индексом. }

begininherited SetItem(Index, Value)

end;

procedure TRunButtons.Update(Item: TCollectionItem);

{ Метод TCollection.Update вызывается объектами

типа TCollectionItem при изменении одного из элементов коллекции.

Изначально этот метод является абстрактным. Он должен быть

переопределен для включения необходимой логики обработки

изменения элемента TCollectionItem. Используем его для перерисовки

элемента при вызове метода TddgLaunchPad.UpdateRunButton. }

begin

if Item <> nil then

FLaunchPad.UpdateRunButton(Item.Index);

end;

procedure TRunButtons.UpdateRunButtons;

{ Открытая процедура UpdateRunButtons предоставляет пользователю

компонентов TRunButtons возможность принудительной перерисовки всех

кнопок. Этот метод вызывает метод TddgLaunchPad.UpdateRunButton для

каждого экземпляра TRunBtnItem. }

var

i: integer;

begin

for i := 0 to Count – 1 do

FLaunchPad.UpdateRunButton(i);

end;

function TRunButtons.Add: TRunBtnItem;

{ Этот метод должен быть переопределен таким образом, чтобы

возвращать экземпляр TRunBtnItem при вызове унаследованного метода

Add. Для этого осуществляется приведение типа результата

унаследованного метода. }

begin

Result := TRunBtnItem(inherited Add);

end;

{ TddgLaunchPad }

constructor TddgLaunchPad.Create(AOwner: TComponent);

{ Инициализация экземпляра TRunButtons и внутренних переменных,

используемых для позиционирования элемента TRunBtnItem при его

отображении. }

begin

inherited Create(AOwner);

FRunButtons := TRunButtons.Create(Self);

TopAlign := 0;

LeftAlign := 0;

end;

destructor TddgLaunchPad.Destroy;

begin

FRunButtons.Free;      // Освобождение экземпляра TRunButtons.

inherited Destroy; // Вызов унаследованного деструктора.

end;procedure TddgLaunchPad.GetChildren(Proc: TGetChildProc; Root: TComponent);

{ Переопределить метод GetChildren, чтобы компонент TddgLaunchpad игнорировал любые принадлежащие ему элементы TRunButtons, поскольку они не нуждаются в потоковой обработке в контексте компонента TddgLaunchPad. Вся информация, необходимая для создания экземпляров TRunButton, уже записана в поток в виде публикуемых свойств класса TRunBtnItem, являющегося потомка класса TCollectionItem. Этот метод предотвращает двойную запись в поток компонента TRunButton. }

var

I: Integer;

begin

for I := 0 to ControlCount – 1 do

{ Игнорирует кнопки запуска и поле прокрутки. }

if not (Controls[i] is TddgRunButton) then

Proc(TComponent(Controls[I]));

end;

procedure TddgLaunchPad.SetRunButtons(Value: TRunButtons);

{ Метод доступа для свойства RunButtons. }

begin

FRunButtons.Assign(Value);

end;

procedure TddgLaunchPad.UpdateRunButton(Index: Integer);

{ Этот метод отвечает за отображение экземпляров TRunBtnItem. Он

гарантирует, что элементы TRunBtnItem не будут выходить за пределы

панели TddgLaunchPad, а при необходимости будут созданы новые

строки таких элементов. Это происходит только при

добавлении/удалении элементов TRunBtnItems. Пользователь имеет

возможность так изменить размеры панели TddgLaunchPad, что она

будет меньше ширины строки с элементами TRunBtnItem. }

begin

{ Вначале рисуется первый элемент, обе его позиции обнуляются. }

if Index = 0 then begin

TopAlign := 0;

LeftAlign := 0;

end;

{ Если ширина текущей строки элементов TRunBtnItem больше

ширины панели TddgLaunchPad, то создается новая строка

элементов TRunBtnItem. }

if (LeftAlign + FRunButtons[Index].Width) > Width then begin

TopAlign := TopAlign + FRunButtons[Index].Height;

LeftAlign := 0;

end;

FRunButtons[Index].Left := LeftAlign;

FRunButtons[Index].Top := TopAlign;

LeftAlign := LeftAlign + FRunButtons[Index].Width;

end;

end.

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии