Главная » Delphi » Редактирование списка компонентов TCollectionItem в диалоговом окне редактора свойств

0

Теперь, когда уже определен компонент TddgLaunchPad, класс коллекции TRun- Buttons и класс коллекции TRunBtnItem, необходимо обеспечить пользователя спо собом  добавления компонентов TddgRunButton в коллекцию TRunButtons. Лучше всего для этого  подходит редактор свойств списка,  обслуживаемого коллекцией TRunButtons.

Такое  диалоговое окно  предназначено для проведения непосредственных манипуля ций   компонентами  TRunBtnItem,  содержащимися  в   коллекции  RunButtons типа TddgLaunchPad. В списке  PathListBox отображаются различные строки CommandLine для каждого  элемента TddgRunButton, “вложенного” в компонент TRunBtnItem. В ком поненте TddgRunButton отображается текущий  выбранный элемент списка.  Диалоговоеокно  также  содержит кнопки, позволяющие пользователю добавлять и удалять элемент, принимать изменения и отменять операции. По мере того как пользователь вносит изме нения в диалоговое окно, они отображаются в компоненте TddgLaunchPad.

CОВЕТ

Для редакторов свойств используется соглашение о включении в них кнопки Apply для подтверждения  изменения  формы.  Здесь  не  рассматривается  добавление  кнопки Apply, но читатель может самостоятельно сделать это в качестве упражнения. Чтобы посмотреть, как работает кнопка Apply, обратитесь к исходному коду редактора свой- ства  Panels компонента TStatusBar,  расположенного во  вкладке Win32  палитры компонентов.

В листинге 12.12 представлен исходный код редактора свойства RunButtons.Tddg- LaunchPad и его диалогового окна.

Листинг 12.12. LPadPE.pas — редактор свойств TRunButtons

unit LPadPE; interface uses

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

Dialogs, Buttons, RunBtn, StdCtrls, LnchPad, DesignIntf,

DesignEditors, ExtCtrls, TypInfo;

type

{ Вначале объявить диалоговое окно редактора. }

TLaunchPadEditor = class(TForm)

PathListBox: TListBox;

AddBtn: TButton;

RemoveBtn: TButton;

CancelBtn: TButton;

OkBtn: TButton;

Label1: TLabel;

pnlRBtn: TPanel;

procedure PathListBoxClick(Sender: TObject);

procedure AddBtnClick(Sender: TObject);

procedure RemoveBtnClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure CancelBtnClick(Sender: TObject);

private

TestRunBtn: TddgRunButton;

FLaunchPad: TddgLaunchPad;// Используется как резервная копия

FRunButtons: TRunButtons; // Ссылается на реальный TRunButtons

Modified: Boolean;

procedure UpdatePathListBox;

end;

{ Объявление потомка TPropertyEditor и переопределениенеобходимых методов. }

TRunButtonsProperty = class(TPropertyEditor)

function GetAttributes: TPropertyAttributes; override;

function GetValue: string; override;

procedure Edit; override;

end;

{ Эта функция будет вызываться редактором свойств. }

function EditRunButtons(RunButtons: TRunButtons): Boolean;

implementation

{$R *.DFM}

function EditRunButtons(RunButtons: TRunButtons): Boolean;

{ Создает экземпляр диалогового окна TLaunchPadEditor для

непосредственной модификации коллекции TRunButtons. }

begin

with TLaunchPadEditor.Create(Application) do

try

// Указывает на действительный TRunButtons

FRunButtons := RunButtons;

{ Копирование компонентов TRunBtnItems в резервный экземпляр

FLaunchPad, который будет использован, если пользователь

отменит операцию редактирования. }

FLaunchPad.RunButtons.Assign(RunButtons);

{ Отображение в окне списка компонентов TRunBtnItem. }

UpdatePathListBox;

ShowModal; // Отобразить форму.

Result := Modified;

finally

Free;

end;

end;

{ TLaunchPadEditor }

procedure TLaunchPadEditor.FormCreate(Sender: TObject);

begin

{ Создает резервные экземпляры компонента TLaunchPad для

использования в том случае, если пользователь отменит

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

FLaunchPad := TddgLaunchPad.Create(Self);

// Создает экземпляр компонента TddgRunButton и выравнивает его

// относительно содержащей его панели.

TestRunBtn := TddgRunButton.Create(Self);

TestRunBtn.Parent := pnlRBtn;

TestRunBtn.Width       := pnlRBtn.Width; TestRunBtn.Height := pnlRBtn.Height;

end;procedure TLaunchPadEditor.FormDestroy(Sender: TObject);

begin

TestRunBtn.Free;

FLaunchPad.Free; // Освобождает экземпляр TLaunchPad.

end;

procedure TLaunchPadEditor.PathListBoxClick(Sender: TObject);

{ Если пользователь щелкает на элементе списка TRunBtnItem,

проверить компонент TRunButton, соответствующий выбранному

элементу. }

begin

if PathListBox.ItemIndex > -1 then

TestRunBtn.CommandLine :=

PathListBox.Items[PathListBox.ItemIndex];

end;

procedure TLaunchPadEditor.UpdatePathListBox;

{ Повторная инициализация компонента PathListBox для обновления

списка элементов TRunBtnItem. }

var

i: integer;

begin

PathListBox.Clear; // Вначале очистить окно списка.

for i := 0 to FRunButtons.Count – 1 do

PathListBox.Items.Add(FRunButtons[i].CommandLine);

end;

procedure TLaunchPadEditor.AddBtnClick(Sender: TObject);

{ Если был щелчок на кнопке Add, вызывается диалог TOpenDialog для

получения имени и пути выполняемого файла (этот файл добавляется в

PathListBox), а также добавляется новый элемент FRunBtnItem. }

var

OpenDialog: TOpenDialog;

begin

OpenDialog := TOpenDialog.Create(Application);

try

OpenDialog.Filter := ‘Executable Files|*.EXE';

if OpenDialog.Execute then begin

{ Добавить в PathListBox. }

PathListBox.Items.Add(OpenDialog.FileName);

FRunButtons.Add; // Создать новый экземпляра TRunBtnItem.

{ Установить фокус на новый элемент в списке PathListBox }

PathListBox.ItemIndex := FRunButtons.Count – 1;

{ Установка командной строки для нового элемента TRunBtnItem

равной имени файла, заданного

значением PathListBox.ItemIndex. }

FRunButtons[PathListBox.ItemIndex].CommandLine :=

PathListBox.Items[PathListBox.ItemIndex];

{ Вызов обработчика события PathListBoxClick для проверки

компонента TRunButton, соответствующего вновь добавленному

элементу. }

PathListBoxClick(nil);

Modified := True;end;

finally

OpenDialog.Free

end;

end;

procedure TLaunchPadEditor.RemoveBtnClick(Sender: TObject);

{ Удаление выбранного пути/имени файла из PathListBox одновременно

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

коллекции FRunButtons. }

var

i: integer;

begin

i := PathListBox.ItemIndex;

if i >= 0 then begin

PathListBox.Items.Delete(i); // Удаление элемента из списка

FRunButtons[i].Free;               // Удаление элемента из коллекции

TestRunBtn.CommandLine := ”;// Удаление кнопки проверки

Modified := True;

end;

end;

procedure TLaunchPadEditor.CancelBtnClick(Sender: TObject);

{ Если пользователь отменяет операцию, элементы TRunBtnItem

резервного экземпляра LaunchPad копируются в исходный экземпляр

TLaunchPad, а затем, после установки для ModalResult значения

mrCancel, форма закрывается. }

begin

FRunButtons.Assign(FLaunchPad.RunButtons);

Modified := False;

ModalResult := mrCancel;

end;

{ TRunButtonsProperty }

function TRunButtonsProperty.GetAttributes: TPropertyAttributes;

{ Сообщает инспектору объектов о том, что данный редактор свойства

будет использовать диалоговое окно. По щелчку на кнопке с

многоточием в окне Object Inspector будет вызываться метод Edit. }

begin

Result := [paDialog];

end;

procedure TRunButtonsProperty.Edit;

{ Вызов метода EditRunButton() и передача ему указателя на

редактируемый экземпляр компонента TRunButton. Этот указатель

получен с помощью метода GetOrdValue. Затем следует перерисовка

диалогового окна LaunchDialog с использованием вызова

метода TRunButtons.UpdateRunButtons. }

begin

if EditRunButtons(TRunButtons(GetOrdValue)) then

Modified;

TRunButtons(GetOrdValue).UpdateRunButtons;end;

function TRunButtonsProperty.GetValue: string;

{ Переопределение метода GetValue таким образом, чтобы тип класса

редактируемого свойства отображался в окне инспектора объектов. }

begin

Result := Format(‘(%s)’, [GetPropType^.Name]);

end;

end.В  приведенном  модуле   сначала    определяется   диалоговое  окно   TLaunchPad Editor, а затем —  редактор свойства TRunButtonsProperty. Рассмотрим сначала редактор свойства, так как он и вызывает это диалоговое окно.

Редактор свойства TRunButtonsProperty мало отличается от редактора свойства с диалоговым окном,  описанного выше.  В нем  переопределяются методы  GetAttrib- utes(), Edit() и GetValue().

Метод  GetAttributes() просто возвращает значение типа  TPropertyAttrib- utes, определяющее, что данный редактор вызывает диалоговое окно,  а также  поме щает кнопку с многоточием в окно инспектора объектов.

Метод GetValue() использует функцию GetPropType() для получения указателя на информацию о типах  времени выполнения редактируемого свойства. Он  возвра щает  поле  имени этой  информации, представляющее строку  типа  данного свойства. Данная строка отображается внутри  скобок  в окне инспектора объектов, как это при нято в Delphi.

Наконец, метод  Edit() вызывает функцию EditRunButtons(), определенную в данном  модуле. Ей в качестве параметра передается указатель  на свойство TRunBut- tons (с помощью функции GetOrdValue). При  возврате из функции вызывается ме тод  UpdateRunButtons() для  перерисовки  изображения коллекции RunButtons, отражающий все произошедшие в ней изменения.

Функция  EditRunButtons() создает  экземпляр компонента TLaunchPadEditor и помещает в его поле  FRunButtons указатель  на TRunButtons, переданный в нее в качестве параметра. Этот  указатель  используется  для внесения изменений в коллек цию  TRunButtons. Затем   функция  копирует  коллекцию  свойств  TRunButtons во внутренний экземпляр компонента TddgLaunchPad по имени FLaunchPad. Функция использует этот  экземпляр как резервный на тот  случай,  если  пользователь отменит операцию редактирования.

Выше упоминалась возможность добавления кнопки Apply в диалоговое окно.  Для этого  вместо  непосредственной модификации реальной коллекции можно  отредак тировать экземпляр коллекции RunButtons компонента FLaunchPad. Тогда,  если пользователь отменит операцию редактирования, ничего не произойдет; если  же он нажмет  кнопку Apply или OK, то внесенные изменения подтвердятся.

Конструктор   формы   Create() создает    внутренний   экземпляр   компонента

TddgLaunchPad. Деструктор Destroy() освобождает его перед уничтожением формы.

Метод  PathListBoxClick() представляет собой  обработчик события OnClick

компонента PathListBox. Этот  метод  заставляет компонент TestRunBtn (тестовый

компонент TddgRunButton) отображать элемент, выбранный в данный момент в спи ске  PathListBox, а также  путь к выполняемому файлу.  Пользователь может  нажать кнопку такого экземпляра TddgRunButton для запуска приложения.

Метод  UpdatePathListBox() инициализирует  список  PathListBox элементами коллекции.

Метод   AddButtonClick() представляет  собой   обработчик  события  OnClick кнопки Add. Данный обработчик события вызывает диалоговое окно File Open, чтобы принять от пользователя имя выполняемого файла. При  этом в список  PathListBox добавляется путь к этому файлу.  Метод  AddButtonClick() также  создает  экземпляр компонента TRunBtnItem в  коллекции и  присваивает командную   строку  свойству TRunBtnItems.CommandLine. Это  значение тут же  передается в компонент TddgRunButton, заключенный в данный компонент TRunBtnItems.

Метод   RemoveBtnClick() представляет  собой   обработчик  события  OnClick

кнопки Remove. Он удаляет выбранный элемент из списка  PathListBox и экземпляр

TRunBtnItem из коллекции.

Метод   CancelBtnClick() представляет  собой   обработчик  события  OnClick

кнопки Cancel. Он копирует резервную коллекцию из экземпляра FLaunchPad в дей

ствительную коллекцию TRunButtons и закрывает форму.

Объекты TCollection и TCollectionItem могут оказаться весьма полезными во

многих  отношениях. Внимательно их  изучите, а как  только  потребуется сохранить

список компонентов, можно будет применить уже готовое решение.

Резюме

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

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

По теме:

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