[ Pobierz całość w formacie PDF ]
.Jak zapewne pamiętasz, właścicielem komponentu może być tylko inny komponent, czyli obiekt wywodzący się z klasy TComponent; ani kolekcja, ani jej elementy nie spełniają tego warunku, nie mogą być więc właścicielami przycisków TddgRunButton.Pojawia się tu jednak pewien problem.Właścicielem przycisku jest co prawda komponent nadrzędny (TddgLaunchPad), lecz tworzenie jego egzemplarza odbywa się w konstruktorze elementu kolekcji — TRunBtnItem.Podczas zapisu formularza w strumieniu, zostaną w nim zapisane również przyciski TddgRunButton; podczas odczytu formularza nastąpi ich podwojenie — oprócz zestawu odczytanego ze strumienia powstanie drugi ich zestaw, utworzony przez konstruktory elementów kolekcji.Stąd wniosek, iż należy zapobiec zapisywaniu przycisków w strumieniu; należy w tym celu przedefiniować metodę GetChildren() paska narzędziowego tak, by zawłaszczone przez niego komponenty klasy TddgRunButton nie były brane pod uwagę:procedure TddgLaunchPad.GetChildren(Proc: TGetChildProc; Root: TComponent);varI: Integer;beginfor I := 0 to ControlCount - 1 doif not (Controls[i] is TddgRunButton)thenProc(TComponent(Controls[I]));end;Takie przedefiniowanie automatycznie zapobiega jeszcze jednej niepożądanej rzeczy — mianowicie zwalnianiu przycisków przez pasek narzędziowy podczas jego destrukcji; przyciski są zwalniane w destruktorach elementów kolekcji i nie można zwalniać ich powtórnie.Druga z prezentowanych instrukcji konstruktora czyni pasek narzędziowy kontrolką rodzicielską w stosunku do przycisków, co zapewnia utrzymanie ich właściwej reprezentacji graficznej.Znaczenie pozostałych metod, będących w większości metodami dostępowymi właściwości, wyjaśnione jest w komentarzach towarzyszących kodowi źródłowemu.Implementacja kolekcji TRunButtonsKonstruktor Create() po utworzeniu kolekcji przypisuje wskazanie na komponent nadrzędny (którym jest pasek narzędziowy) polu FLaunchPad; jest ono wielokrotnie wykorzystywane w treści modułu.Metoda Update()wywoływana jest wówczas, gdy którykolwiek element kolekcji zasygnalizuje zmianę.Powoduje ona wywołanie metody UpdateRunButton()paska narzędziowego, ustawiającej pewne jego „geometryczne” właściwości, w efekcie czego następuje ponowne rozmieszczenie przycisków na panelu paska.Pozostałe metody są metodami dostępowymi właściwości kolekcji; znaczenie ważniejszych z nich zostało wyjaśnione za pomocą komentarzy.Implementacja paska narzędziowego TddgLaunchPadKonstruktor i destruktor paska to procedury nieskomplikowane; utworzeniu (zwolnieniu) egzemplarza paska towarzyszy jednoczesne utworzenie (zwolnienie) kolekcji.Przedefiniowanie metody GetChildren() ma związek z niepożądanymi konsekwencjami faktu, iż pasek narzędziowy jest właścicielem przycisków TddgRunButton; o konsekwencjach tych pisaliśmy omawiając implementację obiektów TRunBtnItem.Metoda UpdateRunButton() — a raczej jej iteracyjne wywołanie — powoduje odświeżenie wyglądu paska.Treść metody wyklucza „chowanie się” przycisków poza pionowymi krawędziami komponentu; możliwe jest natomiast jego pionowe przewijanie, jako że wywodzi się on z klasy TScrollBox.Edycja kolekcji i jej elementów w dialogowym edytorze właściwościPo szczegółowym opisie komponentu TddgLaunchPad, kolekcji TRunButtons oraz jej elementów TRunBtnItem, zaprezentujemy teraz edytor umożliwiający manipulowanie zawartością tej kolekcji, czyli dodawanie do niej i usuwanie z niej przycisków TddgRunButton.Ten edytor jest dialogowym edytorem właściwości RunButtons paska narzędziowego; bezpośrednio manipuluje elementami kolekcji TRunButtons — w oknie dialogowym wyświetlane są etykiety poszczególnych przycisków, ukrywające się pod właściwością CommandLine poszczególnych elementów.Obecne w oknie dialogowym przyciski umożliwiają dodawanie i usuwanie poleceń, zatwierdzanie i odrzucanie zmian, jak również testowanie skutków wybranego polecenia.Implementację wspomnianego edytora przedstawiamy na wydruku 12.11.Wydruk 12.11.Implementacja edytora kolekcji przyciskówunit LPadPE;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, Buttons, RunBtn, StdCtrls, LnchPad, DesignIntf, DesignEditors,ExtCtrls, TypInfo;type{ formularz okna dialogowego }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);privateTestRunBtn: TddgRunButton;FLaunchPad: TddgLaunchPad; // kopia zapasowa paska narzędziowegoFRunButtons: TRunButtons; // wskazanie na kolekcjęModified: Boolean;procedure UpdatePathListBox;end;{ Klasa edytora właściwości }TRunButtonsProperty = class(TPropertyEditor)function GetAttributes: TPropertyAttributes; override;function GetValue: string; override;procedure Edit; override;end;{ Funkcja wywoływana przez edytor właściwości.}function EditRunButtons(RunButtons: TRunButtons): Boolean;implementation{$R *.DFM}function EditRunButtons(RunButtons: TRunButtons): Boolean;{Tworzy egzemplarz klasy TLaunchPadEditor bezpośredniomodyfikujący kolekcję}beginwith TLaunchPadEditor.Create(Application) dotryFRunButtons := RunButtons;{ Tworzenie kopii zapasowej kolekcji na wypadekanulowania edycji}FLaunchPad.RunButtons.Assign(RunButtons);{ Narysuj okno z przyciskami TRunBtnItems.}UpdatePathListBox;ShowModal; // wyświetl formularz dialogowyResult := Modified;finallyFree;end;end;{ TLaunchPadEditor }procedure TLaunchPadEditor.FormCreate(Sender: TObject);begin{ Tworzenie kopii zapasowej paska narzędziowego na wypadekanulowania edycji}FLaunchPad := TddgLaunchPad.Create(Self);// Create the TddgRunButton instance and align it to the// enclosing panel.TestRunBtn := TddgRunButton.Create(Self);TestRunBtn.Parent := pnlRBtn;// Utwórz egzemplarz TddgRunButton i wyrównaj go do paneluTestRunBtn.Width := pnlRBtn.Width;TestRunBtn.Height := pnlRBtn.Height;end;procedure TLaunchPadEditor.FormDestroy(Sender: TObject);beginTestRunBtn.Free;FLaunchPad.Free; // zwolnij kopię zapasową paska narzędziowegoend;procedure TLaunchPadEditor
[ Pobierz całość w formacie PDF ]