Živě.cz o počítačích a internetu

Umíme to s Delphi, 47. díl – vytvořte si vlastní komponentu, dokončení

Václav Kadlec - 25.2.2002
Kapitoly článku:
  1. Definování a testování
  2. Ukázková komponenta a vytvoření ikony pro komponentu

Ukázková komponenta – běžící text

Na úplný závěr kapitoly „vytváření komponent“ si společně vytvoříme velmi jednoduchou komponentu, která však prakticky demonstruje většinu popsaných činností – bude to komponenta typu „běžící text“. Dejme tomu, že nestojíme o některé vlastnosti komponenty Label, proto ji odvodíme od třídy TCustomLabel a nazveme ji TRunText. Komponenta bude mít navíc (oproti komponentě Label) vlastnosti Speed (nastavující rychlost posuvu textu) a Active (zapne/vypne posuv). Ještě jednou si připomeneme celý postup vytvoření a instalace komponenty.

Poznámka: ani po dlouhém uvažování se mi bohužel nepodařilo vymyslet žádnou dostatečně názornou komponentu, která by měla smysluplné použití a zároveň by její vývoj bylo možné popsat na omezeném prostoru tohoto dílu seriálu…:) Zachránila mě nakonec komponenta Běžící text, kterou jsem převzal z knihy Slavoje Píska Začínáme programovat v Delphi, Grada 2000.

V prostředí Delphi pozavírejte veškerá otevřená okna (File – Close All). Vytvořte novou komponentu (Component – New Component). Pole v zobrazeném dialogu vyplňte podle následujícího obrázku:

Klepněte na OK a zapište zdrojový kód podle následujícího výpisu:

unit RunText;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, StdCtrls, ExtCtrls;

type
  TRunText = class(TCustomLabel)
  private
    FTimer: TTimer;
    procedure PosunText(Sender: TObject);
    function GetActive: Boolean;
    procedure SetActive(Start: Boolean);
    function GetSpeed: Integer;
    procedure SetSpeed(MSec: Integer);

    { Private declarations }
  protected
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
    { Public declarations }
  published
    // zverejnime jen nektere vlastnosti TCustomLabel
    property AutoSize;
    property Alignment;
    property Transparent;
    property WordWrap;
    property Caption;
    // a vytvorime sve vlastni vlastnosti
    property Active: Boolean read GetActive write SetActive;
    property Speed: Integer read GetSpeed write SetSpeed;
    { Published declarations }
  end;

procedure Register;

implementation

constructor TRunText.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FTimer := TTimer.Create(Self);
  FTimer.OnTimer := PosunText;
  FTimer.Interval := 500;
  FTimer.Enabled := True;
end;    // constructor

procedure TRunText.PosunText(Sender: TObject);
var S, Pom: String;
begin
  Pom := Caption;
  S := Copy(Pom, 1, 1);
  Delete(Pom, 1, 1);
  Pom := Pom + S;
  Caption := Pom;
end;    // TRun.PosunText

function TRunText.GetActive: Boolean;
begin
  Result := FTimer.Enabled;
end;    // TRunText.GetActive

procedure TRunText.SetActive(Start: Boolean);
begin
  FTimer.Enabled := Start;
end;    // TRunText.SetActive

function TRunText.GetSpeed: Integer;
begin
  Result := FTimer.Interval;
end;    // TRunText.GetSpeed

procedure TRunText.SetSpeed(MSec: Integer);
begin
  FTimer.Interval := MSec;
end;    // TRunText.SetSpeed


procedure Register;
begin
  RegisterComponents(`Nase`, [TRunText]);
end;

end.

Dovolím si upozornit na několik maličkostí souvisejících s tímto zdrojovým kódem:

Nyní komponentu instalujeme do palety:

Nejprve zdrojový kód uložte. Pak vyberte Component – Install Component. V otevřeném dialogu buď vyberte existující balík nebo vytvořte nový (podle toho vyberte záložku v horní části). My vytvoříme nový balík jmenující se ZiveComponents:

Klepněte na OK a na následující dotaz odpovězte kladně (zajímá-li vás to, Delphi se ptá, má-li balík sestavit a následně instalovat do palety komponent):

Objeví se informační hláška říkající, že balíček s názvem ZiveComponents byl úspěšně instalován a že byla registrována komponenta RunText třídy TRunText:

Potvrďte a je hotovo. Nyní společně komponentu otestujeme uvedeným postupem (v testovací aplikaci, bez IDE). Uložte a pozavírejte veškerá okna (File – Save All, File – Close All) a vytvořte novou aplikaci. Na formulář umístěte tři tlačítka: btnVytvor, btnNastav, btnZrus. Nezapomeňte také modul s naší komponentou (tedy soubor RunText) uvést v sekci uses a definovat proměnnou typu TRunText (viz tučné fragmenty). Zdrojový kód této aplikace je zde:

unit hlavni;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    btnVytvor: TButton;
    btnNastav: TButton;
    btnZrus: TButton;
    procedure btnVytvorClick(Sender: TObject);
    procedure btnNastavClick(Sender: TObject);
    procedure btnZrusClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
uses RunText;
var RunTextComponent: TRunText;

{$R *.dfm}

procedure TForm1.btnVytvorClick(Sender: TObject);
begin
  // vytvoreni instance komponenty
  RunTextComponent := TRunText.Create(Self);
  with RunTextComponent do
  begin
    Parent := Self;
    Left := 20;
    Top := 20;
    Height := 40;
    Width := 100;
    Caption := `Toto je text naší slavné ukázkové komponenty  `;
  end;  // with

end;

procedure TForm1.btnNastavClick(Sender: TObject);
begin
  if Assigned(RunTextComponent) then
  begin
    RunTextComponent.Caption := `Ukázka změny nastavení vlastnosti Caption  `;
    RunTextComponent.Speed := 200;
  end;  // if
end;

procedure TForm1.btnZrusClick(Sender: TObject);
begin
  RunTextComponent.Free;
end;

end.

Aplikaci si přeložte a spusťte. Klepnutím na tlačítko btnVytvor dojde k vytvoření a zobrazení běžícího textu. Po klepnutí na btnNastav se změní titulek a rychlost běhu komponenty. Po klepnutí na btnZrus se komponenta zruší a z formuláře zmizí.

Na úplný závěr si ukážeme, co si počít v případě, že bychom uvedeným postupem našli chybu a chtěli ji ve zdrojovém kódu komponenty opravit. V našem případě se třeba rozhodneme, že publikujeme jednu událost třídy TCustomLabel (zatím jsme tak neučinili, proto by se v Object Inspectoru žádné události komponenty TRunText nezobrazily). Bude nutné znovu otevřít balík ZiveComponents obsahující naši komponentu TRunText (např. File – Close All, File – Open Project, změnit filtr přípon souborů na Delphi packages <.dpk) a najít podadresář Lib adresáře, v němž se nachází Delphi – viz následující obrázek).

Otevře se balík, viz obrázek:

Nyní poklepejte na soubor RunText.pas a soubor se otevře v Code Editoru. Proveďte potřebné modifikace (viz zdrojový kód obhahující změněnou deklaraci třídy), pak soubor uložte (File – Save). Nyní je velmi důležité klepnout na tlačítko Compile v dialogu zobrazujícím balík (tedy v tom z předchozího obrázku). Klepněte na Compile, balík se zkompiluje, vy vše pozavírejte a můžete otevřít opět testovací aplikaci, případně vytvořit novou aplikaci a vyzkoušet komponentu i v době návrhu.

type
  TRunText = class(TCustomLabel)
  private
    FTimer: TTimer;
    procedure PosunText(Sender: TObject);
    function GetActive: Boolean;
    procedure SetActive(Start: Boolean);
    function GetSpeed: Integer;
    procedure SetSpeed(MSec: Integer);

    { Private declarations }
  protected
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
    { Public declarations }
  published
    // zverejnime jen nektere vlastnosti TCustomLabel
    property AutoSize;
    property Alignment;
    property Transparent;
    property WordWrap;
    property Caption;
    // dale zverejnime jednu udalost
    property OnMouseEnter;
    // a vytvorime sve vlastni vlastnosti
    property Active: Boolean read GetActive write SetActive;
    property Speed: Integer read GetSpeed write SetSpeed;
    { Published declarations }
  end;

Elegantnějším řešením tohoto testování komponent je vytvoření tzv. skupiny projektů. V tom případě můžete mít zároveň otevřený balíček i testovací aplikaci (aplikace). Nutno dodat, že koneckonců můžete mít balík i aplikaci otevřenou i bez skupiny projektů.

Vytvoření ikony pro komponentu

Úplně poslední „maličkostí“, kterou jsme zatím nezmínili, je vytvoření vlastní ikony nové komponenty. Pokud přidáme komponentu do palety komponent, vyhledá Delphi automaticky ikonu v souboru *.DCR (Delphi Component Resource) stejného jména, jako je zdrojový soubor komponenty. Soubor *.DCR je jednoduše přejmenovaným souborem se zdroji <.RES). Pokud tento soubor není nalezen, bude komponenta reprezentována pomocí implicitní ikony (nebo pomocí ikony svého předka, pokud předkem byla komponenta mající svou ikonu).

Jak tedy vytvořit vlastní ikonu? Uvnitř souboru *.DCR musíme vytvořit bitmapu o velikosti 24 x 24 pixelů ze 16 nebo 256 barev. Jméno bitmapy musí být stejné jako jméno třídy komponenty, jen převedené na velká písmena. ukážeme si, jak vytvořit ikonu pro komponentu TRunText, kterou jsme vytvořili v předchozím příkladu:

Na závěr

Tolik tedy k popisu vytváření nových komponent. Je samozřejmé, že jsme se nemohli dokonale věnovat všemu, co by se v této souvislosti nabízelo – nicméně i tak mám pocit, že jsme tyto díly „nafoukli“ na samou hranici únosnosti. Proto prozatím téma „vytváření nových komponent“ uzavíráme s tím, že bude-li v budoucnu dostatek času, můžeme se k němu později vrátit a popsat ostatní, složitější, koncepty.