A Delphi programozási nyelv

Delphi Tutorial

 

Aki először találkozik a Delphivel, vagy még keveset tud róla, talán tanulságosnak találhatja, ha végigcsinálja ezt a tutorialt. Feltételezzük az alapvető programozói tudást, ennek birtokában valószínűleg az új programnyelvvel kapcsolatos kezdeti kérdések közül sokra választ kaphat az olvasó. Nem törekszünk a teljességre, inkább ízelítőt szeretnénk adni a nyelv és a fejlesztői környezet kínálta lehetőségekről.

 

Új alkalmazás létrehozása

Válasszuk ki a File menüből a New Applicationt. A fejlesztői környezet indításakor erre nincs is szükség, alapból egy üres formot tartalmazó projectet kapunk. Ezt akár rögtön le is fordíthatjuk és futtathatjuk: működőképes alkalmazásunk van. Próbaképp rakhatunk komponenseket is a formra, futtatáskor mind meg fog jelenni.

 

Új komponens létrehozása

A Component menüből a New Component pontot választva egy dialógusablak jelenik meg, itt állítsuk be az alábbiakat: Ancestor: TButton, Name: TButtonKa, Palette page: Samples, Unit file: ButtonKa.pas. Ezután installáljuk az alapértelmezésben felkínált helyre, tipikusan a C:\Program Files\Borland\Delphi5\Lib\dclusr50.dpk-ba. Ha mindent jól csináltunk, a komponenspalettán a Samples fülön megjelent a ButtonKa. Tegyünk egyet a formunkra!

A frissen létrehozott komponensünk forráskódját nyissuk meg. (Tipikusan: C:\Program Files\Borland\Delphi5\Lib\ButtonKa.pas.) Adjunk a komponensünkhöz két új tulajdonságot, egy szám és egy szöveg típusút; nevük legyen szam ill. szoveg.

  published     { Published declarations }     property szam : integer read GetSzam write SetSzam;     property szoveg : string read GetSzoveg write SetSzoveg;

A hozzájuk tartozó változókat ill. eljárásokat és függvényeket deklaráljuk...

  protected     { Protected declarations }         sza: integer;         szo: string;         function GetSzam: integer;         procedure SetSzam(ujszam: integer);         function GetSzoveg: string;         procedure SetSzoveg(ujszoveg: string);

majd implementáljuk.

implementation   procedure Register; begin   RegisterComponents('Samples', [TButtonKa]); end;   function TButtonKa.GetSzam: integer; begin         GetSzam := sza; end;   procedure TButtonKa.SetSzam(ujszam: integer); begin         sza := ujszam;         Text := szoveg + ' ' +  inttostr(szam); end;   function TButtonKa.GetSzoveg: string; begin         GetSzoveg := szo; end;   procedure TButtonKa.SetSzoveg(ujszoveg: string); begin         szo := ujszoveg;         Text := inttostr(szam) + ' ' +  szoveg; end;

Próbaképp fordítsuk le a programot, hogy mindent jól csináltunk-e. Valami ilyesmit fogunk látni:

 

Eseménykezelés és kommunikáció a main formon belül

Most az object inspectorban a Form1 events fülét nyissuk meg és az OnCreate-hez rendeljünk egy Kezdet nevű eljárást, és írjuk a törzsébe:

procedure TForm1.Kezdet(Sender: TObject); begin ButtonKa1.szam := 42; ButtonKa1.szoveg := 'hello'; end;

Ha a "ButtonKa1." kiírása után várunk egy kicsit, megjelenik egy lista, amiről kiválaszthatjuk többek között a szam és a szoveg tulajdonságokat. Ebből is látszik, hogy a fejlesztői környezet már felismerte ezeket, és - mivel published-ként deklaráltuk őket - fejlesztési időben már a rendelkezésünkre bocsátotta.

Ha most újra lefordítjuk a programot, ezt látjuk:

Most adjunk a formunkhoz egy soreditort a standard komponens fülről, majd az Object Inspectorban rendeljünk hozzá az editor OnChange eventjéhez egy UjSzoveg nevű eljárást:

procedure TForm1.UjSzoveg(Sender: TObject); begin ButtonKa1.szoveg := Edit1.Text; end;

Ha most lefordítjuk a programot, már szerkeszthetjük is a gombunk szövegét az editorból. Gyakorlásképp az olvasó megpróbálhatja egyénileg megvalósítani, hogy a gombra klikkelve növekedjen a számláló, a formra klikkelve pedig csökkenjen. Egy egyszerű megoldás, hogy a ButtonKa1 OnClick eseményéhez rendeljük az alábbi eljárást:

procedure TForm1.Klikk(Sender: TObject); begin ButtonKa1.szam := ButtonKa1.szam + 1; end;

A Form1 OnClick eseménye pedig legyen:

procedure TForm1.KiKlikk(Sender: TObject); begin ButtonKa1.szam := ButtonKa1.szam - 1; end;

Ezen a ponton már ilyet is láthatunk:

Megjegyzés: A form csak akkor kapja meg a klikkelés eseményét, ha az nem a gombon vagy az editoron történt.

Figyeljük meg, hogy pl. az inc eljárást nem tudjuk használni a fenti esetben - ebben pl. különböznek a propertyk a tagváltozóktól. Nyilván nem lenne elvi akadálya, hogy pl. érték szerinti paraméternek átadjunk egy propertyt, de az inc eljárásnál nem is erről lenne szó... Mindenki tudja, milyen paraméterátadások vannak Pascalban?

 

Példa az osztályreferencia típusok használatára

Tegyünk fel két radio buttont a formunkra, az elsőnek "Button" legyen a Caption-je, a másodiknak "Edit". Rendeljünk hozzájuk OnClick üzenetkezelőket, az elsőhöz a SelBut-ot, a másodikhoz a SelEdit-et. Írjunk az eljárások törzsébe egy-egy pontosvesszőt, ugyanis automatikusan törlődnek, ha üresen hagyjuk őket. A formhoz rendeljünk egy Lenyom nevű eljárást az OnMouseDown eseményhez. (Az OnMouseDown eseményt egy egérgomb lenyomása váltja ki, ellentétben a már ismert OnClickkel, amely a bal egérgombbal történt klikkelést jelenti. Előbbi megkapja paraméterként az egér helyét, utóbbi nem.)

Tegyünk be egy AC: TControlClass típusú private tagot...

private { Private declarations } AC: TControlClass;

...majd inicializáljuk a Kezdet-ben:

procedure TForm1.Kezdet(Sender: TObject); begin ButtonKa1.szam := 42; ButtonKa1.szoveg := 'hello'; AC := TButton; end;

Ha nagyon ráérünk, akkor állítsuk a RadioButton1 Checked propertyjét True-ra.

(Egyébként a TControlClass definíciója: type TControlClass = class of TControl; ezt be is írhatjuk, de fölösleges.)

Módosítsuk az UjSzoveg eljárást, majd a SelBut-ot és a SelEdit-et, valamint a Lenyom-ot, hogy a végeredmény az alábbi legyen:

unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ButtonKa; type TControlClass = class of TControl; type TForm1 = class(TForm) ButtonKa1: TButtonKa; Edit1: TEdit; RadioButton1: TRadioButton; RadioButton2: TRadioButton; procedure Kezdet(Sender: TObject); procedure UjSzoveg(Sender: TObject); procedure Klikk(Sender: TObject); procedure KiKlikk(Sender: TObject); procedure SelBut(Sender: TObject); procedure SelEdit(Sender: TObject); procedure Lenyom(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private AC: TControlClass; { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Kezdet(Sender: TObject); begin ButtonKa1.szam := 42; ButtonKa1.szoveg := 'hello'; AC := TButton; end; procedure TForm1.UjSzoveg(Sender: TObject); begin if Sender is TEdit then ButtonKa1.szoveg := TEdit(Sender).Text else ButtonKa1.szoveg := Edit1.Text; end; procedure TForm1.Klikk(Sender: TObject); begin ButtonKa1.szam := ButtonKa1.szam + 1; end; procedure TForm1.KiKlikk(Sender: TObject); begin ButtonKa1.szam := ButtonKa1.szam - 1; end; procedure TForm1.SelBut(Sender: TObject); begin AC := TButton; end; procedure TForm1.SelEdit(Sender: TObject); begin AC := TEdit; end; procedure TForm1.Lenyom(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var uc: TControl; begin uc := AC.Create(self); with uc do begin Left := x; Width := 100; Top := y; Height := 50; Parent := self; Caption := '# ' + Edit1.Text + ' #'; end; if uc is TButton then begin TButton(uc).OnClick := Klikk; TButton(uc).Caption := 'Button'; end; if uc is TEdit then begin TEdit(uc).OnChange := UjSzoveg; TButton(uc).Caption := 'Edit'; end; end; end.

A Lenyom eljárásban érdekesség, hogy bár az "uc" új kontrollnak mindenképp van Caption propertyje, mégis a főablak Captionje változik, ugyanis a TControlnak önmagában nincs. Nem kapunk hibaüzenetet, hisz látszik a Caption tag, csak nem azt látjuk, amelyiket szeretnénk. Kiváló példa arra, hogy hogyan okozhat nehezen felderíthető programozási hibát a with utasítás használata.

Így néz ki a program:

Menü használata

A formunkhoz adjunk egy MainMenu standard komponenst. Mindegy, hogy hova helyezzük az ikont, a menü mindenképp a form tetején fog megjelenni. Az ikonra jobb gombbal kattintva válasszuk a menu designert. Itt szerkeszthetjük a menüt, adjunk hozzá pl. egy "a" és egy "b" menüt, alájuk pedig tetszőlegesen elosztva pl. "aa", "ab", "ac", "ba" menüpontokat. Válasszuk ki az "aa"-t az object inspectorban (pl. helyben klikkeljünk rá) és rendeljük hozzá az OnClick eseményéhez:

procedure TForm1.NegyvenKetto(Sender: TObject); begin ButtonKa1.szam := 42; end;

Futtassuk a programot és próbáljuk ki.

 

Új form használata

A File menüből válasszuk ki a New Form menüpontot. Az új formra tegyünk rá egy editort. Menjünk vissza a Form1-hez (pl. használjuk a View menüt), majd a file menü use unit pontját kiválasztva adjuk hozzá a unit2-t. Így a főform látni fogja a második form minden public tagját és eljárását. Hogy megjelenítsük, az "ab" menüponthoz rendeljük az alábbi eljárást:

procedure TForm1.Masik(Sender: TObject); begin Form2.Edit1.Text := '...'; Form2.ShowModal; ButtonKa1.szoveg := Form2.Edit1.Text; end;

Így máris kommunikáltunk vele. A ShowModal akkor ér véget, amikor lezárul a Form2. Ha nem modálisan akarjuk megjeleníteni, akkor használjuk a Show-t. Kétirányú kommunikációra példa:

Cseréljük le ez előbbi eljárás törzsét az alábbira:

procedure TForm1.Masik(Sender: TObject); begin Form2.Edit1.Text := '...'; Form2.Show; end;

Tegyünk egy gombot a Form2-re, az OnClick-je legyen:

procedure TForm2.Klikk(Sender: TObject); begin Form1.ButtonKa1.szoveg := 'klikk volt mashol'; end;

Ha itt megfeledkezünk a use unit-ról, akkor sincs baj, a Delphi fordításkor rögtön felajánlja, hogy megcsinálja helyettünk.

Kivételkezelés

Tegyünk a Form2-re még két editort, egy címkét és egy gombot, majd a gomb üzenetkezelője legyen az alábbi:

procedure TForm2.Szamol(Sender: TObject); var a, b: integer; begin try a := strtoint(Edit2.Text); b := strtoint(Edit3.Text); Label1.Caption := inttostr(a div b); except on e: EDivByZero do raise EDivByZero.Create('nullaval osztas volt'); else MessageDlg('szamot, ha lehet', mtWarning, [mbOK], 0); end; end;

Ha a programot a szerkesztőből indítjuk, akkor alaphelyzetben minden kivétel megállítja a futást és elindítja a debuggert. Ha csak a kész .exe-t futtatjuk, akkor a feldolgozatlan hibák csak üzenetablakot dobnak (ld. osztás nullával), alapértelmezésben a program nem áll le.

Kapcsolódás adatbázishoz

Hozzunk létre pl. egy Paradox 7 adatbázist a Database Desktoppal, adjunk hozzá néhány mezőt... lehet próbálkozni. Pl. a mezőnevek legyenek A, B és C, A típusa legyen long int és ez legyen kulcs, B típusa legyen Alpha és hossza 42, C típusa legyen number. Ha kész vagyunk vele, mentsük el és a Delphiben nyissuk meg a form wizardot, és generáltassunk hozzá egy formot. Ilyen egyszerű az egész. Pl. eddigi projectünkhöz hozzáadhatjuk, ha nem engedjük neki, hogy main formot generáljon (az az alapértelmezett); generáljunk formot és data module-t is (ezt mind az utolsó oldalon lehet beállítani a wizard-ban).

A Unit1-be tegyük bele a use unit4-et, majd az "ac" menüponthoz rendeljük hozzá:

procedure TForm1.Adatok(Sender: TObject); begin Form4.Show; end;

Végül a "ba" menüponthoz:

procedure TForm1.ElegEnnyi(Sender: TObject); begin ButtonKa1.szoveg := Form4.EditB.Text; ButtonKa1.szam := strtoint(Form4.EditA.Text); end;

Az új form editoraihoz közvetlenül hozzáférünk; azonban az adatokat inkább a data module-on keresztül érjük el, ha a use unit3-at beraktuk - a DataModule3 ill. annak Table1 tagja rendelkeznek a megfelelő eljárásokkal.

Grafikus komponens készítése

Bevezetés

A Delphi-ben talán kissé szokatlan módon, kódolással fogunk elkészíteni egy saját komponenst, mely később a VCL szerves részét képezi, és az alkalmazások formjára felpakolható, azokon látható, használható.
A komponens egy hétszegmenses kijelző lesz, mely egyetlen számjegyet képes ábrázolni, de több ilyen komponens egymás mellé pakolásával előállítható egy például egy digitális óra.

A komponens alapjai

Vágjunk bele. A New menüpontban nyissunk egy új unitot. A komponensünk ebből az egyetlen forrásból fog állni. Legyen a neve LEDSSD (LED Seven Segment Display). Hozzunk létre benne egy osztályt, mely a TLEDSSD nevet viseli és a TGraphicControl osztályból származik (mivel grafikus komponenst kreálunk). Ahhoz, hogy ebből az osztályból származtathassunk fel kell tüntetnünk a Controls unitot a uses kulcsszó után. A TGraphicControl osztály tartalmaz egy Canvas tagot, amire rajzolni fogunk. Valamint van neki Paint metódusa, aminek felüldefiniálásával megjeleníthetjük a saját komponensünket jellemző grafikát.
Az osztály deklarációja alá az interface részbe kell még egy procedure Register; szignatúrát rakni. Ezt ki is fejthetjük az implementation rész legelején. A RegisterComponent végzi el a komponensünk regisztrációját a komponenspalettán. Ennek használatához be kell írni a Classes unitot is a uses részbe. Első paraméter a paletta neve, legyen most "Sajat", második a Típus - amit regisztrálni szeretnénk - szögletes zárójelek között megadott megnevezése.
Írjuk meg az osztályunkhoz a Create konstruktort és a Destroy destruktort is. Az előbbi kapjon egy TComponent típusú COwner paramétert, ez lesz a komponensünk szülőobjektuma, ami adott esetben pl egy Form. A konstruktorban már elérhetjük a TGraphicControl-ban deklarált adattagokat. Hogy milyen mezők vannak, nézzük meg a help-ben. Inicializáljuk komponensünket a szülő konstruktorával, majd állítsunk be a Width és Height mezőknek egy alapértelmezett értéket. Az így elkészített komponens már életképes. Mentsük el a fájlt, majd a Component menü Install Component menüpontjában a forrásfájlunkat kiválasztva telepíthetjük.

unit LEDSSD; interface uses Classes, Controls; type TLEDSSD = class(TGraphicControl) public constructor Create(COwner: TComponent); override; destructor Destroy; override; end; procedure Register; implementation procedure Register; begin RegisterComponents('PLS', [TLEDSSD]); end; constructor TLEDSSD.Create(COwner: TComponent); begin inherited Create(COwner); Width := 100; Height := 140; end; destructor TLEDSSD.Destroy; begin inherited Destroy; end; end.

Grafika 1.

Miután installáltuk, nyithatunk egy új Form-ot, és arra fel is rakhatjuk, bár sokat még nem látunk belőle...
Jöjjön az érdemi munka. Tervezzük meg konkrétabban a komponens képességeit. Az előzőekben leírtak egy általános grafikus komponens elkészítésénél is járható út a kezdeteknél. Nyilván előtte át kell gondolni mi az ami már meg van valósítva egy létező komponensben, amit szülőként használhatunk. Nekünk most a nyers grafikus komponens felelt meg a legjobban, mivel csak egy Canvassal bővíti a TComponentet.

Nézzük mit várunk el a kijelzőtől.

Nyilvánvaló, hogy a kijelezni kívánt számjegyet el kell tárolni egy belső adattagban. Vegyük fel a Value: Byte mezőt, és deklaráljuk a setter metódust. Ezután először a színezéseket valósítsuk meg. Ehhez vegyünk fel újabb TColor típusú adattagokat CASegment, CISegment, CBackground néven. Ezekhez deklaráljuk a setter eljárásokat is, valamint published propertyket is létre kell hozni hozzájuk, melyben megadjuk, hogy olvasásnál a mező értékét adja vissza, írásnál pedig a settert hívja meg. A konstruktorban adjunk ezeknek a mezőknek egy alapértelmezett színt: CASegment = clLime; CISegment = clGreen; CBackground = clBlack;. Valamint definiáljuk felül az ősosztály Paint metódusát, ahol egyelőre csak a komponens hátterét rajzoljuk meg.

... private Value: Byte; CASegment: TColor; CISegment: TColor; CBackground: TColor; procedure SetValue(const SDigit: Byte); procedure SetBackgroundColor(const Value: TColor); procedure SetActiveColor(const Value: TColor); procedure SetInactiveColor(const Value: TColor); protected procedure Paint; override; public .... published property Digit: Byte read Value write SetValue; property ColorBackground: TColor read CBackground write SetBackgroundColor; property ColorActiveSegment: TColor read CASegment write SetActiveColor; property ColorInactiveSegment: TColor read CISegment write SetInactiveColor; .... procedure TLEDSSD.SetValue(const SDigit: Byte); begin if (Value <> SDigit) and (SDigit <= 9) then begin Value := SDigit; Invalidate; end; end; ... procedure TLEDSSD.Paint(); begin inherited; with Canvas do begin Brush.Color := CBackGround; Pen.Color := CBackground; Rectangle(0, 0, Width, Height); end; end;

Természetesen a többi setter-t is meg kell írni a SetValue mintájára. Ha elmentjük majd újra installáljuk a komponenst akkor az ObjectInspectorban megjelennek az új tulajdonságok, valamint fekete hátteret kap a komponensünk.

Grafika 2.

Lépjünk tovább. A könnyebb programozhatóság kedvéért definiálnunk kell, hogy mely számjegyek megjelenítése esetén mely szegmensek "világítanak". Valamint a könnyebb/egyszerűbb Paint metódus érdekében nyilvántartjuk a szegmensek sarokpontjainak koordinátáit is, ekkor majd minden szegmensen végig kell iterálni és megnézni (a későbbiekben definiált) mátrixban, hogy a szegmens „világít”-e és annak megfelelő színnel meghívni a Canvas Polygon metódusát, ami kirajzolja a kitöltött poligont. Mindezekhez le kell rögzíteni a szegmensek sorrendjét. Legyen például:
--a--
|    |
f    b
|    |
--g--
|    |
e    c
|    |
--d--

Így már létrehozhatjuk a számjegy-szegmens aktivitási mátrixot. Például a tömb első (nulladik) eleme a 0-ás számjegy úgy jeleníthető meg, ha g szegmens kivételével az összes "világít". Ezt definiáljuk az osztályunkon kívül.

const DigitAsSegment: array[0..9, 0..6] of boolean = ( (true, true, true, true, true, true, false), (false, true, true, false, false, false, false), (true, true, false, true, true, false, true ), (true, true, true, true, false, false, true ), (false, true, true, false, false, true, true ), (true, false, true, true, false, true, true ), (true, false, true, true, true, true, true ), (true, true, true, false, false, false, false), (true, true, true, true, true, true, true ), (true, true, true, true, false, true, true ) ); ... procedure TLEDSSD.Paint(); var i: Byte; begin inherited; with Canvas do begin Brush.Color := CBackGround; Pen.Color := CBackground; Rectangle(0, 0, Width, Height); if Visible then begin for i := 0 to 6 do begin if Enabled then begin if DigitAsSegment[Digit, i] then Brush.Color := CASegment else Brush.Color := CISegment; end else Brush.Color := CISegment; Polygon(SegmentPoints[i]); end; end; end; end;

A szegmensek sarokpontjai legyenek az óramutató járásával megegyező sorrendben :
   0
 /   \
5     1
|     |
|     |
4     2
 \   /
   3
Definiáljunk egy adattagot mely az összes szegmens minden pontjának koordinátáját tartalmazza SegmentPoints: array[0..6,0..5] of TPoint;. A TPoint típus használatához a Windows unitot is fel kell venni a uses listába. Ezeket a pontokat majd egy privát Geometry nevű tagfüggvény fogja karbantartani/kiszámítani amit minden méretezés után, valamint minden setter függvény végén meghívunk.
Vegyük fel a belső adattagokat és a published propertiket a szegmens vastagsághoz, szegmensköz szélességhez, valamint a szegély vastagsághoz. Írjuk meg a hozzájuk tartozó settereket is.

... SegWidth: Byte; Padding: Byte; Spacing: Byte; ... property WidthSegment: Byte read SegWidth write SetSegWidth; property WidthPadding: Byte read Padding write SetPadding; property WidthSpacing: Byte read Spacing write SetSpacing; ...

Most pedig írjuk meg a Geometry eljárást amely minden szegmensre kiszámítja annak pontjait a komponens adattagjai értékének függvényében.

procedure TLEDSSD.Geometry; var X: Integer; Y: Integer; SLength: Integer; SHeight: Integer; begin SLength := Width - Padding*2 - Spacing * 2 - SegWidth; SHeight := ((Height - Padding*2) div 2) - Spacing * 2 - SegWidth; //Szegmens a X := Padding + (SegWidth div 2) + Spacing; Y := Padding + (SegWidth div 2); SegmentPoints[0,0] := Point(X,Y); SegmentPoints[0,1] := Point(X + (SegWidth div 2),Y - (SegWidth div 2)); SegmentPoints[0,2] := Point(X + SLength - (SegWidth div 2),Y - (SegWidth div 2)); SegmentPoints[0,3] := Point(X + SLength, Y); SegmentPoints[0,4] := Point(X + SLength - (SegWidth div 2),Y + (SegWidth div 2)); SegmentPoints[0,5] := Point(X + (SegWidth div 2),Y + (SegWidth div 2)); //Szegmens b X := Width - (Padding + (SegWidth div 2)); Y := Padding + (SegWidth div 2) + Spacing; SegmentPoints[1,0] := Point(X,Y); SegmentPoints[1,1] := Point(X + (SegWidth div 2),Y + (SegWidth div 2)); SegmentPoints[1,2] := Point(X + (SegWidth div 2),Y + SHeight); SegmentPoints[1,3] := Point(X, Y + SHeight + (SegWidth div 2)); SegmentPoints[1,4] := Point(X - (SegWidth div 2),Y + SHeight); SegmentPoints[1,5] := Point(X - (SegWidth div 2),Y + (SegWidth div 2)); //Szegmens c X := Width - (Padding + (SegWidth div 2)); Y := (Height div 2) + Spacing; SegmentPoints[2,0] := Point(X,Y); SegmentPoints[2,1] := Point(X + (SegWidth div 2),Y + (SegWidth div 2)); SegmentPoints[2,2] := Point(X + (SegWidth div 2),Y + SHeight); SegmentPoints[2,3] := Point(X, Y + SHeight + (SegWidth div 2)); SegmentPoints[2,4] := Point(X - (SegWidth div 2),Y + SHeight); SegmentPoints[2,5] := Point(X - (SegWidth div 2),Y + (SegWidth div 2)); //Szegmens d X := Padding + (SegWidth div 2) + Spacing; Y := Height- (Padding + (SegWidth div 2)); SegmentPoints[3,0] := Point(X,Y); SegmentPoints[3,1] := Point(X + (SegWidth div 2),Y - (SegWidth div 2)); SegmentPoints[3,2] := Point(X + SLength - (SegWidth div 2),Y - (SegWidth div 2)); SegmentPoints[3,3] := Point(X + SLength, Y); SegmentPoints[3,4] := Point(X + SLength - (SegWidth div 2),Y + (SegWidth div 2)); SegmentPoints[3,5] := Point(X + (SegWidth div 2),Y + (SegWidth div 2)); //Szegmens e X := Padding + (SegWidth div 2); Y := (Height div 2) + Spacing; SegmentPoints[4,0] := Point(X,Y); SegmentPoints[4,1] := Point(X + (SegWidth div 2),Y + (SegWidth div 2)); SegmentPoints[4,2] := Point(X + (SegWidth div 2),Y + SHeight); SegmentPoints[4,3] := Point(X, Y + SHeight + (SegWidth div 2)); SegmentPoints[4,4] := Point(X - (SegWidth div 2),Y + SHeight); SegmentPoints[4,5] := Point(X - (SegWidth div 2),Y + (SegWidth div 2)); //Szegmens f X := Padding + (SegWidth div 2); Y := Padding + (SegWidth div 2) + Spacing; SegmentPoints[5,0] := Point(X,Y); SegmentPoints[5,1] := Point(X + (SegWidth div 2),Y + (SegWidth div 2)); SegmentPoints[5,2] := Point(X + (SegWidth div 2),Y + SHeight); SegmentPoints[5,3] := Point(X, Y + SHeight + (SegWidth div 2)); SegmentPoints[5,4] := Point(X - (SegWidth div 2),Y + SHeight); SegmentPoints[5,5] := Point(X - (SegWidth div 2),Y + (SegWidth div 2)); //Szegmens g X := Padding + (SegWidth div 2) + Spacing; Y := (Height div 2); SegmentPoints[6,0] := Point(X,Y); SegmentPoints[6,1] := Point(X + (SegWidth div 2),Y - (SegWidth div 2)); SegmentPoints[6,2] := Point(Width - X - (SegWidth div 2),Y - (SegWidth div 2)); SegmentPoints[6,3] := Point(Width - X, Y); SegmentPoints[6,4] := Point(Width - X - (SegWidth div 2),Y + (SegWidth div 2)); SegmentPoints[6,5] := Point(X + (SegWidth div 2),Y + (SegWidth div 2)); end;

A komponens forráskódja: LEDSSD.zip
Egy demo program forráskódja: LEDSSDDemo.zip