Difference between revisions of "Lazarus For Delphi Users/sk"

From Lazarus wiki
Jump to navigationJump to search
m (úprava formátovania)
m (Fixed syntax highlighting)
 
(16 intermediate revisions by 6 users not shown)
Line 7: Line 7:
  
 
===Najväčšie rozdiely===
 
===Najväčšie rozdiely===
Lazarus je úplný open source, je napísaný bez závislosti na platforme a používa silný prekladač FreePascal (FPC). FPC beží na viac ako 15 platformách, ale nie všetky balíčky a knižnice sú prenesené, tak Lazarus práve beží pod Linux, Free/Open/NetBSD, MacOSX a win32.
+
Lazarus je úplný open source, je napísaný bez závislosti na platforme a používa silný prekladač FreePascal (FPC). FPC beží na viac ako 15 platformách, ale nie všetky balíčky a knižnice sú prenesené, tak Lazarus práve beží pod Linux, Free/Open/NetBSD, Mac OS X a win32.
  
 
Lazarus zatiaľ nie je kompletný, ako aj tento text. Stále hľadáme nových vývojárov, porterov, pisateľov dokumentácie, ... .
 
Lazarus zatiaľ nie je kompletný, ako aj tento text. Stále hľadáme nových vývojárov, porterov, pisateľov dokumentácie, ... .
 +
 +
 +
=== Prvá vec pri pokuse o konverziu projektu z Delphi ===
 +
Spustite Lazarus, choďte do '''Tools''' a potom '''Convert Delphi Project to Lazarus Project'''. Toto síce nespraví úplne všetko, je to však najlepší spôsob ako začať. Všimnite si, že pomôcky na konverziu sú v Lazaruse jednosmerné, a neobsahujú spätnú konverziu do Delphi. Na tento účel môžete použiť [http://wiki.lazarus.freepascal.org/XDev_Toolkit XDev Toolkit].
 +
 +
 +
=== Podpora Unicode ===
 +
Delphi až do verzie 2007 nepodporovalo Unicode, a používalo štandardné ANSI kódovanie Windows. Od verzie 2008 Delphi podporuje Unicode prostredníctvom stringov UTF-16.
 +
 +
Lazarus však na druhej strane od začiatku podporuje Unicode, a to prostredníctvom stringov UTF-8. Viac informácií: [[LCL Unicode Support]].
  
 
==Delphi IDE -> Lazarus IDE==
 
==Delphi IDE -> Lazarus IDE==
 
===Projekty===
 
===Projekty===
 
Základným súborom aplikácie Delphi je súbor .dpr. Základným súborom projektu Lazarus je súbor .lpi (Lazarus Project Information). Súbor .dpr je základný zdrojový kód programu a Delphi IDE v ňom uchováva niektoré informácie o direktívach prekladača a jednotkách. Aplikácia Lazarus má tiež súbor .lpr, ktorý je súborom so základným zdrojovým kódom, ale všetky ostatné informácie sú uchovávané v súbore .lpi. Teda, dôležitým súborom je súbor .lpi.
 
Základným súborom aplikácie Delphi je súbor .dpr. Základným súborom projektu Lazarus je súbor .lpi (Lazarus Project Information). Súbor .dpr je základný zdrojový kód programu a Delphi IDE v ňom uchováva niektoré informácie o direktívach prekladača a jednotkách. Aplikácia Lazarus má tiež súbor .lpr, ktorý je súborom so základným zdrojovým kódom, ale všetky ostatné informácie sú uchovávané v súbore .lpi. Teda, dôležitým súborom je súbor .lpi.
 +
 +
Napríklad:
 +
 +
Delphi ukladá cesty k unitám do súboru .dpr. Napr.: unit1 in 'path/Unit1.pas'. Tieto 'in' cesty sú špecifické pre Delphi a Lazarus IDE ich ignoruje. Nepoužívajte ich - namiesto nich použite nastavenie kompilátora.
 +
 +
Delphi ukladá nastavenie kompilátora do súbora .dpr., napr. {$APPTYPE CONSOLE}. Tieto nastavenia sú tiež ignorované Lazarus IDE. Nepoužívajte ich - namiesto nich použite nastavenie kompilátora (Compiler Options).
  
 
Jedno dôležité pravidlo: '''Vždy existuje projekt!!!'''
 
Jedno dôležité pravidlo: '''Vždy existuje projekt!!!'''
 
 
Jediný spôsob ako zatvoriť projekt je skončiť Lazarus alebo otvoriť iný projekt. To je preto, že projekt Lazarus je tiež "session". To znamená, že aktuálne nastavenia editora sú uchovávané v súbore .lpi a sú obnovené, keď otvoríte projekt. Napríklad: ladíte aplikáciu, nastavíte veľa ladiacich bodov a záložiek. Môžete projekt uložiť a zatvoriť Lazarus alebo otvoriť iný, ale keď znova otvoríte pôvodný, dokonca i na inom počítači, všetky vaše ladiace body, záložky, otvorené súbory, pozície kurzora, histórie skokov, ... sú obnovené.
 
Jediný spôsob ako zatvoriť projekt je skončiť Lazarus alebo otvoriť iný projekt. To je preto, že projekt Lazarus je tiež "session". To znamená, že aktuálne nastavenia editora sú uchovávané v súbore .lpi a sú obnovené, keď otvoríte projekt. Napríklad: ladíte aplikáciu, nastavíte veľa ladiacich bodov a záložiek. Môžete projekt uložiť a zatvoriť Lazarus alebo otvoriť iný, ale keď znova otvoríte pôvodný, dokonca i na inom počítači, všetky vaše ladiace body, záložky, otvorené súbory, pozície kurzora, histórie skokov, ... sú obnovené.
  
 
===Editor zdrojového kódu===
 
===Editor zdrojového kódu===
 
(Source Editor)
 
(Source Editor)
Takmer všetky klávesy a klávesové skratky môžu byť nastavené v Environment->Editor options->Key mappings
+
Takmer všetky klávesy a klávesové skratky môžu byť nastavené v Tools -> Options -> Editor -> Key Mappings
  
 
IDE Lazarus má veľa nástrojov pre zdrojový kód. Mnohé z nich sú veľmi podobné tým v Delphi. Ale je tu jeden veľký rozdiel: Lazarus nepoužíva prekladač na získanie informácií o kóde, ale analyzuje priamo zdrojový kód, čo má veľa výhod:
 
IDE Lazarus má veľa nástrojov pre zdrojový kód. Mnohé z nich sú veľmi podobné tým v Delphi. Ale je tu jeden veľký rozdiel: Lazarus nepoužíva prekladač na získanie informácií o kóde, ale analyzuje priamo zdrojový kód, čo má veľa výhod:
Line 32: Line 47:
 
(Local Variable Completion)
 
(Local Variable Completion)
 
Predstavte si, že ste práve vytvorili novú metódu a napísali príkaz "i:=3;"
 
Predstavte si, že ste práve vytvorili novú metódu a napísali príkaz "i:=3;"
<pascal>procedure
+
<syntaxhighlight lang=pascal>procedure
 
  TForm1.DoSomething;  
 
  TForm1.DoSomething;  
 
  begin
 
  begin
 
   i := 3;  
 
   i := 3;  
  end;</pascal>
+
  end;</syntaxhighlight>
  
 
Umiestnite kurzor nad identifikátor "i" a stlačte Ctrl+Shift+C, čím získate:
 
Umiestnite kurzor nad identifikátor "i" a stlačte Ctrl+Shift+C, čím získate:
<pascal>procedure
+
<syntaxhighlight lang=pascal>procedure
 
  TForm1.DoSomething;  
 
  TForm1.DoSomething;  
 
  var
 
  var
Line 45: Line 60:
 
  begin
 
  begin
 
   i:= 3;  
 
   i:= 3;  
  end;</pascal>
+
  end;</syntaxhighlight>
  
 
====Dokončovanie priradenia udalostí====
 
====Dokončovanie priradenia udalostí====
Line 53: Line 68:
 
: Button1.OnClick:=
 
: Button1.OnClick:=
 
Umiestnite kurzor za operátor priradenia ":=" a stlačte Ctrl+Shift+C.
 
Umiestnite kurzor za operátor priradenia ":=" a stlačte Ctrl+Shift+C.
    
+
 
 +
====Príklad doplňovania volaných procedúr ====
 +
Predstavte si, že ste práve napísali príkaz 'DoSomething(Width);'<syntaxhighlight lang=pascal>
 +
procedure SomeProcedure;
 +
var
 +
   Width: integer;
 +
begin
 +
  Width:=3;
 +
  DoSomething(Width);
 +
end;
 +
</syntaxhighlight>
 +
 
 +
Umiestnite kurzor na identifikátor DoSomething a stlačte Ctrl-Shift-C. Dostanete:
 +
 
 +
<syntaxhighlight lang=pascal>
 +
procedure DoSomething(aWidth: LongInt);
 +
begin
 +
 
 +
end;
 +
 
 +
procedure SomeProcedure;
 +
var
 +
  Width: integer;
 +
begin
 +
  Width:=3;
 +
  DoSomething(Width);
 +
end;
 +
</syntaxhighlight>
 +
 
 
====Dokončovanie slov====
 
====Dokončovanie slov====
 
(Word Completion Ctrl+W)
 
(Word Completion Ctrl+W)
Line 97: Line 140:
 
Ak je napríklad potrebný Label s fontom bold/special color, musíte použiť TStaticText, keďže TLabel je špecifický prvok rozhrania a všetky rozhrania sú poskytnuté v pôvodnej verzii a mnoho z nich bude mať predvolené nastavenia, ktoré budú použité.
 
Ak je napríklad potrebný Label s fontom bold/special color, musíte použiť TStaticText, keďže TLabel je špecifický prvok rozhrania a všetky rozhrania sú poskytnuté v pôvodnej verzii a mnoho z nich bude mať predvolené nastavenia, ktoré budú použité.
  
====Control Dragging/Docking====
+
==== Riadenie Dragging/Docking ====
 
Vo VCL väčšina (Win) prvkov implementuje metódy a spätné funkcie pre obsluhovanie preťahovania a dokovania prvkov, napríklad preťahovanie prvku z jedného panela a jeho dokovanie do iného panely v dobe behu programu.
 
Vo VCL väčšina (Win) prvkov implementuje metódy a spätné funkcie pre obsluhovanie preťahovania a dokovania prvkov, napríklad preťahovanie prvku z jedného panela a jeho dokovanie do iného panely v dobe behu programu.
  
Line 103: Line 146:
  
 
Toto aktuálne znamená, že prvky nemôžu dediť/používať nasledujúce funkcie, procedúry, vlastnosti a udalosti TControl:
 
Toto aktuálne znamená, že prvky nemôžu dediť/používať nasledujúce funkcie, procedúry, vlastnosti a udalosti TControl:
{| class="code"
+
 
|- class="code"
+
<syntaxhighlight lang=pascal>protected
| class="code" |<div class="key">Protected</div>
+
   function GetDockEdge(MousePos: TPoint): TAlign;  
   <div class="key">function</div> GetDockEdge(MousePos: TPoint): TAlign;
+
   function GetDragImages: TDragImageList;  
   <div class="key">function</div> GetDragImages: TDragImageList;
+
   function GetFloating: Boolean;  
   <div class="key">function</div> GetFloating: Boolean;
+
   function GetFloatingDockSiteClass: TWinControlClass;  
   <div class="key">function</div> GetFloatingDockSiteClass: TWinControlClass;
+
   procedure DoEndDrag(Target:TObject); X, Y: Integer);  
   <div class="key">procedure</div> DoEndDrag(Target:TObject); X, Y: Integer);
+
   procedure DockTrackNoTarget(Source: TDragDockObject; X, Y: Integer);  
   <div class="key">procedure</div> DockTrackNoTarget(Source: TDragDockObject; X, Y: Integer);
+
   procedure DoEndDock(Target: TObject; X, Y: Integer);  
   <div class="key">procedure</div> DoEndDock(Target: TObject; X, Y: Integer);
+
   procedure DoDock(NewDockSite: TWinControl; var ARect: TRect);  
   <div class="key">procedure</div> DoDock(NewDockSite: TWinControl; <div class="key">var</div> ARect: TRect);
+
   procedure DoStartDock(var DragObject: TDragObject);  
   <div class="key">procedure</div> DoStartDock(<div class="key">var</div> DragObject: TDragObject);
+
   procedure DragCanceled;  
   <div class="key">procedure</div> DragCanceled;
+
   procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;  
   <div class="key">procedure</div> DragOver(Source: TObject; X, Y: Integer; State: TDragState;
+
                    var Accept: Boolean);  
                    <div class="key">var</div> Accept: Boolean);
+
   procedure DoEndDrag(Target: TObject; X, Y: Integer);  
   <div class="key">procedure</div> DoEndDrag(Target: TObject; X, Y: Integer);
+
   procedure DoStartDrag(var DragObject: TDragObject);  
   <div class="key">procedure</div> DoStartDrag(<div class="key">var</div> DragObject: TDragObject);
+
   procedure DrawDragDockImage(DragDockObject: TDragDockObject);  
   <div class="key">procedure</div> DrawDragDockImage(DragDockObject: TDragDockObject);
+
   procedure EraseDragDockImage(DragDockObject: TDragDockObject);  
   <div class="key">procedure</div> EraseDragDockImage(DragDockObject: TDragDockObject);
+
   procedure PositionDockRect(DragDockObject: TDragDockObject);  
   <div class="key">procedure</div> PositionDockRect(DragDockObject: TDragDockObject);
+
   procedure SetDragMode(Value: TDragMode);  
   <div class="key">procedure</div> SetDragMode(Value: TDragMode);
+
   property DragKind: TDragKind;  
   <div class="key">property</div> DragKind: TDragKind;
+
   property DragCursor: TCursor;  
   <div class="key">property</div> DragCursor: TCursor;
+
   property DragMode: TDragMode;  
   <div class="key">property</div> DragMode: TDragMode;
+
   property OnDragDrop: TDragDropEvent;  
   <div class="key">property</div> OnDragDrop: TDragDropEvent;
+
   property OnDragOver: TDragOverEvent;  
   <div class="key">property</div> OnDragOver: TDragOverEvent;
+
   property OnEndDock: TEndDragEvent;  
   <div class="key">property</div> OnEndDock: TEndDragEvent;
+
   property OnEndDrag: TEndDragEvent;  
   <div class="key">property</div> OnEndDrag: TEndDragEvent;
+
   property OnStartDock: TStartDockEvent;  
   <div class="key">property</div> OnStartDock: TStartDockEvent;
+
   property OnStartDrag: TStartDragEvent;  
   <div class="key">property</div> OnStartDrag: TStartDragEvent;
+
public  
<div class="key">public</div>
+
   function Dragging: Boolean;  
   <div class="key">function</div> Dragging: Boolean;
+
   function ManualDock(NewDockSite: TWinControl; DropControl: TControl;  
   <div class="key">function</div> ManualDock(NewDockSite: TWinControl; DropControl: TControl;
+
                      ControlSide: TAlign): Boolean;  
                    <div class="key"> </div>ControlSide: TAlign): Boolean;
+
   function ManualFloat(ScreenPos: TRect): Boolean;  
   <div class="key">function</div> ManualFloat(ScreenPos: TRect): Boolean;
+
   function ReplaceDockedControl(Control: TControl; NewDockSite: TWinControl;  
   <div class="key">function</div> ReplaceDockedControl(Control: TControl; NewDockSite: TWinControl;
+
                                DropControl: TControl; ControlSide: TAlign): Boolean;  
                    <div class="key"> </div>DropControl: TControl; ControlSide: TAlign): Boolean;
+
   procedure BeginDrag(Immediate: Boolean; Threshold: Integer);  
   <div class="key">procedure</div> BeginDrag(Immediate: Boolean; Threshold: Integer);
+
   procedure Dock(NewDockSite: TWinControl; ARect: TRect);  
   <div class="key">procedure</div> Dock(NewDockSite: TWinControl; ARect: TRect);
+
   procedure DragDrop(Source: TObject; X, Y: Integer);  
   <div class="key">procedure</div> DragDrop(Source: TObject; X, Y: Integer);
+
   procedure EndDrag(Drop: Boolean);  
   <div class="key">procedure</div> EndDrag(Drop: Boolean);
+
   property DockOrientation: TDockOrientation;  
   <div class="key">property</div> DockOrientation: TDockOrientation;
+
   property Floating: Boolean;  
   <div class="key">property</div> Floating: Boolean;
+
   property FloatingDockSiteClass: TWinControlClass;  
   <div class="key">property</div> FloatingDockSiteClass: TWinControlClass;
+
   property HostDockSite: TWinControl;  
   <div class="key">property</div> HostDockSite: TWinControl;
+
   property LRDockWidth: Integer;  
   <div class="key">property</div> LRDockWidth: Integer;
+
   property TBDockHeight: Integer;  
   <div class="key">property</div> TBDockHeight: Integer;
+
   property UndockHeight: Integer;  
   <div class="key">property</div> UndockHeight: Integer;
+
   property UndockWidth: Integer;</syntaxhighlight>
   <div class="key">property</div> UndockWidth: Integer;  
 
|}
 
  
 
a že nasledujúce triedy neexistujú alebo sú nepoužiteľné:
 
a že nasledujúce triedy neexistujú alebo sú nepoužiteľné:
{| class="code"
+
 
|- class="code"
+
<syntaxhighlight lang=pascal>TDragImageList = class (TCustomImageList)  
| class="code" | TDragImageList = <div class="key">class</div>(TCustomImageList)
+
TDockZone = class
TDockZone = <div class="key">class</div>
+
TDockTree = class (TInterfacedObject, IDockManager)  
TDockTree = <div class="key">class</div>(TInterfacedObject, IDockManager)
+
TDragObject = class (TObject)  
TDragObject = <div class="key">class</div>(TObject)
+
TBaseDragControlObject = class (TDragObject)  
TBaseDragControlObject = <div class="key">class</div>(TDragObject)
+
TDragControlObject = class (TBaseDragControlObject)  
TDragControlObject = <div class="key">class</div>(TBaseDragControlObject)
+
TDragDockObject = class (TBaseDragControlObject)</syntaxhighlight>
TDragDockObject = <div class="key">class</div>(TBaseDragControlObject)
+
 
|}
 
 
a že nasledujúce funkcie sú tiež neexistujúce/nepoužiteľné:
 
a že nasledujúce funkcie sú tiež neexistujúce/nepoužiteľné:
{| class="code"
+
 
|- class="code"
+
<syntaxhighlight lang=pascal>function FindDragTarget(const Pos: TPoint; AllowDisabled: Boolean) : TControl;  
| class="code" | <div class="key">function</div> FindDragTarget(<div class="key">const</div> Pos: TPoint;
+
procedure CancelDrag;  
                        <div class="key"> </div>AllowDisabled: Boolean) : TControl;
+
function IsDragObject(sender: TObject): Boolean;</syntaxhighlight>
<div class="key">procedure</div> CancelDrag;
 
<div class="key">function</div> IsDragObject(sender: TObject): Boolean;
 
|}
 
  
 
====TEdit/TCustomEdit====
 
====TEdit/TCustomEdit====
Prvky Edit, kým základné funkcie sú rovnaké ako vo VCL, nemajú niektoré výstupy v konverzii:
+
Prvky Edit, kým základné funkcie sú v LCL rovnaké ako vo VCL, iné treba pri konverzii robiť opatrne:
 
# kvôli obmedzeniam rozhraní, TEdit.PasswordChar zatiaľ nepracuje vo všetkých rozhraniach (neskôr možno), namiesto toho použite TCustomEdit.EchoMode emPassword v udalosti na skrytie textu.  
 
# kvôli obmedzeniam rozhraní, TEdit.PasswordChar zatiaľ nepracuje vo všetkých rozhraniach (neskôr možno), namiesto toho použite TCustomEdit.EchoMode emPassword v udalosti na skrytie textu.  
# Udalosti OnDrag/Dock zatiaľ nie sú implementované. Viz [LazarusForDelphiUsers#Control Dragging/Docking|Control Dragging/Docking].
+
# Udalosti OnDrag/Dock zatiaľ nie sú implementované. Viz [[#Riadenie Dragging/Docking|Riadenie Dragging/Docking]].
# Vlastnosti Font sú zvy訠 ajne ignorované kvôli správaniu rozhrania. Viz [[#TControl.Font/TControl.ParentFont | TControl.Font/TControl.ParentFont]]
+
# Vlastnosti Font sú, kvôli správaniu rozhrania, zvyčajne ignorované. Viz [[#TControl.Font/TControl.ParentFont|TControl.Font/TControl.ParentFont]]
  
 
===TSplitter -> TPairSplitter===
 
===TSplitter -> TPairSplitter===
Line 204: Line 241:
 
;Teda ako môžem konvertovať existujúci kód používajúci TSplitter na TPairSplitter?
 
;Teda ako môžem konvertovať existujúci kód používajúci TSplitter na TPairSplitter?
 
Ak sú splitter a prvky vytvorené vo vnútri aktuálnej funkcie (ako OnCreate formulára), konverzia nebude zložitá, najprv zreorganizujeme kód na vytvorenie prvkov v poradí novej hierarchie a nastavíme rodičov podriadených prvkov pre rozdelenie na ľavý/horný a pravý/dolný podiel prvku PairSplitter. Napríklad:
 
Ak sú splitter a prvky vytvorené vo vnútri aktuálnej funkcie (ako OnCreate formulára), konverzia nebude zložitá, najprv zreorganizujeme kód na vytvorenie prvkov v poradí novej hierarchie a nastavíme rodičov podriadených prvkov pre rozdelenie na ľavý/horný a pravý/dolný podiel prvku PairSplitter. Napríklad:
 +
 
{| class="code"
 
{| class="code"
 
|-  
 
|-  
| class="header" | VCL || class="header" | LCL
+
| class="header" | '''VCL''' || class="header" | '''LCL'''
 
|- class="code"
 
|- class="code"
| class="code" |<div class="key">var</div>
+
| class="code" |
  BottomPanel: TPanel<div class="symbol">;</div>
+
<syntaxhighlight lang=pascal>var  
<div></div>
+
  BottomPanel: TPanel;
  VerticalSplitter: TSplitter<div class="symbol">;</div>
+
  VerticalSplitter: TSplitter;
  LeftPanel: TPanel<div class="symbol">;</div>
+
  LeftPanel: TPanel;
  HorizontalSplitter: TSplitter<div class="symbol">;</div>
+
  HorizontalSplitter: TSplitter;
<div></div>
+
  MainPanel: TPanel;
  MainPanel: TPanel<div class="symbol">;</div>
+
 
  <div class="key">begin</div>
+
begin
  BottomPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  BottomPanel:= TPanel.Create(Self);
  <div class="key">with</div> (BottomPanel) <div class="key">do</div>
+
  with (BottomPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Height:= <div class="int">75</div><div class="symbol">;</div>
+
    Height:= 75;
    Align:= alBottom<div class="symbol">;</div>
+
    Align:= alBottom;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  VerticalSplitter:= TSplitter.Create(Self)<div class="symbol">;</div>
+
  VerticalSplitter:= TSplitter.Create(Self);
  <div class="key">with</div> (VerticalSplitter) <div class="key">do</div>
+
  with (VerticalSplitter) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Align:= alBottom<div class="symbol">;</div>
+
    Align:= alBottom;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  HorizontalSplitter:= TSplitter.Create(Self)<div class="symbol">;</div>
+
  HorizontalSplitter:= TSplitter.Create(Self);
  <div class="key">with</div> (HorizontalSplitter) <div class="key">do</div>
+
  with (HorizontalSplitter) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    align:= alLeft<div class="symbol">;</div>
+
    align:= alLeft;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  LeftPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  LeftPanel:= TPanel.Create(Self);
  <div class="key">with</div> (LeftPanel) <div class="key">do</div>
+
  with (LeftPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Width:= <div class="int">125</div><div class="symbol">;</div>
+
    Width:= 125;
    Align:= alLeft<div class="symbol">;</div>
+
    Align:= alLeft;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  MainPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  MainPanel:= TPanel.Create(Self);
  <div class="key">with</div> (MainPanel) <div class="key">do</div>
+
  with (MainPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
    Caption:= <div class="str">'Hello'</div><div class="symbol">;</div>
+
    Caption:= 'Hello';
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div class="key">end</div>;
+
end;</syntaxhighlight>
| class="code" | <div class="key">var</div>
+
| class="code" |  
  BottomPanel: TPanel<div class="symbol">;</div>
+
<syntaxhighlight lang=pascal>var
<div></div>
+
  BottomPanel: TPanel;
  VerticalSplitter: TPairSplitter<div class="symbol">;</div>
+
  VerticalSplitter: TPairSplitter;
  LeftPanel: TPanel<div class="symbol">;</div>
+
  LeftPanel: TPanel;
  HorizontalSplitter: TPairSplitter<div class="symbol">;</div>
+
  HorizontalSplitter: TPairSplitter;
<div></div>
+
  MainPanel: TPanel;
  MainPanel: TPanel<div class="symbol">;</div>
+
 
<div class="key">begin</div>
+
begin
  VerticalSplitter:= TPairSplitter.Create(Self)<div class="symbol">;</div>
+
  VerticalSplitter:= TPairSplitter.Create(Self);
  <div class="key">with</div> (VerticalSplitter) <div class="key">do</div>
+
  with (VerticalSplitter) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
    Width:= Self.Width<div class="symbol">;</div>
+
    Width:= Self.Width;
    Height:= Self.Height<div class="symbol">;</div>
+
    Height:= Self.Height;
    SplitterType:= pstVertical<div class="symbol">;</div>
+
    SplitterType:= pstVertical;
    Position:= Height - <div class="int">75</div><div class="symbol">;</div>
+
    Position:= Height - 75;
    Sides[<div class="int">0</div>].Width:= Width<div class="symbol">;</div>
+
    Sides[0].Width:= Width;
    Sides[<div class="int">0</div>].Height:= Position<div class="symbol">;</div>
+
    Sides[0].Height:= Position;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  HorizontalSplitter:= TPairSplitter.Create(Self)<div class="symbol">;</div>
+
  HorizontalSplitter:= TPairSplitter.Create(Self);
  <div class="key">with</div> (HorizontalSplitter) <div class="key">do</div>
+
  with (HorizontalSplitter) do
  <div class="key">begin</div>
+
  begin
    Parent:= VerticalSplitter.Sides[<div class="int">0</div>]<div class="symbol">;</div>
+
    Parent:= VerticalSplitter.Sides[0];
    Width:= Self.Width<div class="symbol">;</div>
+
    Width:= Self.Width;
    Height:= VerticalSplitter.Position<div class="symbol">;</div>
+
    Height:= VerticalSplitter.Position;
    align:= alClient<div class="symbol">;</div>
+
    align:= alClient;
    SplitterType:= pstHorizontal<div class="symbol">;</div>
+
    SplitterType:= pstHorizontal;
    Position:= <div class="int">125</div><div class="symbol">;</div>
+
    Position:= 125;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  LeftPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  LeftPanel:= TPanel.Create(Self);
  <div class="key">with</div> (LeftPanel) <div class="key">do</div>
+
  with (LeftPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= HorizontalSplitter.Sides[<div class="int">0</div>]<div class="symbol">;</div>
+
    Parent:= HorizontalSplitter.Sides[0];
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  MainPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  MainPanel:= TPanel.Create(Self);
  <div class="key">with</div> (MainPanel) <div class="key">do</div>
+
  with (MainPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= HorizontalSplitter.Sides[<div class="int">1</div>]<div class="symbol">;</div>
+
    Parent:= HorizontalSplitter.Sides[1];
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
    Caption:= <div class="str">'Hello'</div><div class="symbol">;</div>
+
    Caption:= 'Hello';
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  BottomPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  BottomPanel:= TPanel.Create(Self);
  <div class="key">with</div> (BottomPanel) <div class="key">do</div>
+
  with (BottomPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= VerticalSplitter.Sides[<div class="int">1</div>]<div class="symbol">;</div>
+
    Parent:= VerticalSplitter.Sides[1];
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div class="key">end</div><div class="symbol">;</div>
+
end;</syntaxhighlight>
 
|}
 
|}
  
 
Ako môžete vidieť, zmena pozostáva väčšinou z hierarchie. Ak vám lepšie vyhovuje práca s DFM, zmeny potrebné pre konverziu DFM->LFM sú podobné zmenám vyššie, ide o rovnaký typ zmien v Parent/Owner atď.
 
Ako môžete vidieť, zmena pozostáva väčšinou z hierarchie. Ak vám lepšie vyhovuje práca s DFM, zmeny potrebné pre konverziu DFM->LFM sú podobné zmenám vyššie, ide o rovnaký typ zmien v Parent/Owner atď.
 
Potom bude vyššie spomínaný príklad vyzerať takto nejako:
 
Potom bude vyššie spomínaný príklad vyzerať takto nejako:
 +
 
{| class="code"
 
{| class="code"
 
|-  
 
|-  
| class="header" | Delphi DFM <div style="font-weight: normal">(exteranous values removed)</div>
+
| class="header" | '''Delphi DFM''' <div style="font-weight: normal">'''(extraneous values removed)'''
| class="header" | Lazarus LFM <div style="font-weight: normal">(most width, height etc removed)</div>
+
| class="header" | '''Lazarus LFM''' <div style="font-weight: normal">'''(most width, height, etc. removed)'''
 
|- class="code"
 
|- class="code"
| class="code" |<div class="key">object</div>VerticalSplitter: TSplitter
+
| class="code" |
   Height <div class="symbol">=</div> <div class="int">3</div>
+
<syntaxhighlight lang=pascal>
   Cursor <div class="symbol">=</div> crVSplit
+
object VerticalSplitter: TSplitter
   Align <div class="symbol">=</div> alBottom
+
   Height = 3
<div class="key">end</div>
+
   Cursor = crVSplit
<div class="key">object</div> HorizontalSplitter: TSplitter
+
   Align = alBottom
   Width <div class="symbol">=</div> <div class="int">3</div>
+
end
   Align <div class="symbol">=</div> alLeft
+
object HorizontalSplitter: TSplitter
<div class="key">end</div>
+
   Width = 3
<div class="key">object</div> BottomPanel: TPanel
+
   Align = alLeft
   Height <div class="symbol">=</div> <div class="int">75</div>
+
end
   Align <div class="symbol">=</div> alBottom
+
object BottomPanel: TPanel
<div class="key">end</div>
+
   Height = 75
<div class="key">object</div> LeftPanel: TPanel
+
   Align = alBottom
   Width <div class="symbol">=</div> <div class="int">125</div>
+
end
   Align <div class="symbol">=</div> alLeft
+
object LeftPanel: TPanel
<div class="key">end</div>
+
   Width = 125
<div class="key">object</div> MainPanel: TPanel
+
   Align = alLeft
   Align <div class="symbol">=</div> alClient
+
end
<div class="key">end</div>  
+
object MainPanel: TPanel
| class="code" |<div class="key">object</div> VerticalSplitter: TPairSplitter
+
   Align = alClient
   Align <div class="symbol">=</div> alClient
+
end  
   SplitterType <div class="symbol">=</div> pstVertical
+
</syntaxhighlight>
   Position <div class="symbol">=</div> <div class="int">225</div>
+
| class="code" |
   Height <div class="symbol">=</div> <div class="int">300</div>
+
<syntaxhighlight lang=pascal>
   Width <div class="symbol">=</div> <div class="int">400</div>
+
object VerticalSplitter: TPairSplitter
   <div class="key">object</div> Pairsplitterside1: TPairSplitterIde
+
   Align = alClient
     <div class="key">object</div> HorizontalSplitter: TPairSplitter
+
   SplitterType = pstVertical
       Align <div class="symbol">=</div> alClient
+
   Position = 225
       Position <div class="symbol">=</div> <div class="int">125</div>
+
   Height = 300
       <div class="key">object</div> Pairsplitterside3: TPairSplitterIde
+
   Width = 400
         Width <div class="symbol">=</div> <div class="int">125</div>
+
   object Pairsplitterside1: TPairSplitterIde
         <div class="key">object</div> LeftPanel: TPanel
+
     object HorizontalSplitter: TPairSplitter
           Align <div class="symbol">=</div> alClient
+
       Align = alClient
           Width <div class="symbol">=</div> <div class="int">125</div>
+
       Position = 125
         <div class="key">end</div>
+
       object Pairsplitterside3: TPairSplitterIde
       <div class="key">end</div>
+
         Width = 125
       <div class="key">object</div> Pairsplitterside4: TPairSplitterIde
+
         object LeftPanel: TPanel
         <div class="key">object</div> MainPanel: TPanel
+
           Align = alClient
           Align <div class="symbol">=</div> alClient
+
           Width = 125
         <div class="key">end</div>
+
         end
       <div class="key">end</div>
+
       end
     <div class="key">end</div>
+
       object Pairsplitterside4: TPairSplitterIde
   <div class="key">end</div>
+
         object MainPanel: TPanel
   <div class="key">object</div> Pairsplitterside2: TPairSplitterIde
+
           Align = alClient
     <div class="key">object</div> BottomPanel: TPanel
+
         end
       Align <div class="symbol">=</div> alClient
+
       end
       Height <div class="symbol">=</div> <div class="int">75</div>;
+
     end
     <div class="key">end</div>
+
   end
   <div class="key">end</div>
+
   object Pairsplitterside2: TPairSplitterIde
<div class="key">end</div>
+
     object BottomPanel: TPanel
 +
       Align = alClient
 +
       Height = 75
 +
     end
 +
   end
 +
end
 +
</syntaxhighlight>
 
|}
 
|}
  
Line 392: Line 437:
 
#* tvoShowSeparators- zobrazuje oddeľovače  
 
#* tvoShowSeparators- zobrazuje oddeľovače  
 
#* tvoToolTips- zobrazuje samostatné tooltips pre uzly  
 
#* tvoToolTips- zobrazuje samostatné tooltips pre uzly  
 
 
# LCL poskytuje dodatočné vlastnosti:
 
# LCL poskytuje dodatočné vlastnosti:
 
#* udalosť TCustomTreeView.OnSelectionChange  
 
#* udalosť TCustomTreeView.OnSelectionChange  
 
#* TCustomTreeView.DefaultItems, pre predvolené číslo položiek  
 
#* TCustomTreeView.DefaultItems, pre predvolené číslo položiek  
#* TCustomTreeView.ExpandSignType na určenie znamienka použitého na rozbaliteľných/zbaliteľných uzloch  
+
#* TCustomTreeView.ExpandSignType na určenie znamienka použitého na rozbaliteľných/zbaliteľných uzloch
 +
# Síce väčšina udalostí OnDrag/OnDock je k dispozícii v LCL, nefungujú však! Pre viac informácii si prosím prečítajte predchádzajúcu sekciu.
 +
 
 +
 
 +
=== Správy / Udalosti ===
 +
 
 +
(Messages / Events) Poradie a množstvo správ a udalostí (OnShow, OnActivate, OnEnter, ...) sa líši od VCL a závisí od použitého widgeset.
 +
LCL síce poskytuje podmnožinu správ podobných WinAPI (aby bolo portovanie komponentov z Delphi jednoduchšie), avšak takmer všetky LCL správy sa od WinAPI mierne líšia. Niektoré časti Delphi kódy používajú WinAPI správy preto, že vo VCL chýbajú alebo kvôli rýchlosti. Niektoré veci občas samé fungujú, ale je nutné ich skontrolovať ručne. To je dôvod, prečo sa LCL správy nazývajú napr. LM_SIZE namiesto WM_SIZE (unit lmessages).
 +
 
 +
'''Poznámka ku spracovávaniu vlastných správ!'''
 +
Od verzie 0.9.26 (December 2008) sa zmenil spôsob spracovávania vlastných WinAPI správ (ako napr. WM_HOTKEY, WM_SYSCOMMAND); a líši sa od spôsobu používanom v Delphi. V tomto momente nie je možné odchytávať správy prostredníctvom direktívy ''message'' alebo pomocou prekrytia metódy ''WndProc'' formulára. Jediný spôsob, ako odchytávať metódy vo formulári je nahradiť metódy ''windowproc''. Viac tu: [[Win32/64_Interface#Processing_non-user_messages_in_your_window | Processing non-user messages in your window]]
  
 
==Original Contributors and changes==
 
==Original Contributors and changes==
Line 411: Line 465:
 
* Fixed Typo [[User:Kirkpatc]] 20 May 2004
 
* Fixed Typo [[User:Kirkpatc]] 20 May 2004
 
* Prvotný preklad z origánalu - [[User:Slavko|Slavko]] 01:18, 2 Apr 2005 (PST)
 
* Prvotný preklad z origánalu - [[User:Slavko|Slavko]] 01:18, 2 Apr 2005 (PST)
 +
* Aktualizácia prekladu --[[User:Adamm|Adamm]] 14:45, 29 December 2008 (CET)

Latest revision as of 23:55, 18 February 2020

Deutsch (de) English (en) español (es) français (fr) 日本語 (ja) 한국어 (ko) português (pt) русский (ru) slovenčina (sk)

Tento článok je pre tých, ktorí sú zainteresovaní v Lazarus a už poznajú Delphi. Popisuje rozdiely medzi týmito dvomi prostrediami.

Delphi -> Lazarus

Lazarus je Rapid Application Development (RAD) nástroj ako Delphi. To znamená, že prichádza s knižnicou vizuálnych komponentov a IDE. Knižnica komponentov Lazarus (LCL) sa veľmi podobá Delphi VCL. Väčšina jednotiek, tried a vlastností má rovnaké meno a funkciu, čím je prechod jednoduchý. Ale Lazarus nie je 'open source Delphi klon', tak neočakávajte 100% kompatibilitu.

Najväčšie rozdiely

Lazarus je úplný open source, je napísaný bez závislosti na platforme a používa silný prekladač FreePascal (FPC). FPC beží na viac ako 15 platformách, ale nie všetky balíčky a knižnice sú prenesené, tak Lazarus práve beží pod Linux, Free/Open/NetBSD, Mac OS X a win32.

Lazarus zatiaľ nie je kompletný, ako aj tento text. Stále hľadáme nových vývojárov, porterov, pisateľov dokumentácie, ... .


Prvá vec pri pokuse o konverziu projektu z Delphi

Spustite Lazarus, choďte do Tools a potom Convert Delphi Project to Lazarus Project. Toto síce nespraví úplne všetko, je to však najlepší spôsob ako začať. Všimnite si, že pomôcky na konverziu sú v Lazaruse jednosmerné, a neobsahujú spätnú konverziu do Delphi. Na tento účel môžete použiť XDev Toolkit.


Podpora Unicode

Delphi až do verzie 2007 nepodporovalo Unicode, a používalo štandardné ANSI kódovanie Windows. Od verzie 2008 Delphi podporuje Unicode prostredníctvom stringov UTF-16.

Lazarus však na druhej strane od začiatku podporuje Unicode, a to prostredníctvom stringov UTF-8. Viac informácií: LCL Unicode Support.

Delphi IDE -> Lazarus IDE

Projekty

Základným súborom aplikácie Delphi je súbor .dpr. Základným súborom projektu Lazarus je súbor .lpi (Lazarus Project Information). Súbor .dpr je základný zdrojový kód programu a Delphi IDE v ňom uchováva niektoré informácie o direktívach prekladača a jednotkách. Aplikácia Lazarus má tiež súbor .lpr, ktorý je súborom so základným zdrojovým kódom, ale všetky ostatné informácie sú uchovávané v súbore .lpi. Teda, dôležitým súborom je súbor .lpi.

Napríklad:

Delphi ukladá cesty k unitám do súboru .dpr. Napr.: unit1 in 'path/Unit1.pas'. Tieto 'in' cesty sú špecifické pre Delphi a Lazarus IDE ich ignoruje. Nepoužívajte ich - namiesto nich použite nastavenie kompilátora.

Delphi ukladá nastavenie kompilátora do súbora .dpr., napr. {$APPTYPE CONSOLE}. Tieto nastavenia sú tiež ignorované Lazarus IDE. Nepoužívajte ich - namiesto nich použite nastavenie kompilátora (Compiler Options).

Jedno dôležité pravidlo: Vždy existuje projekt!!! Jediný spôsob ako zatvoriť projekt je skončiť Lazarus alebo otvoriť iný projekt. To je preto, že projekt Lazarus je tiež "session". To znamená, že aktuálne nastavenia editora sú uchovávané v súbore .lpi a sú obnovené, keď otvoríte projekt. Napríklad: ladíte aplikáciu, nastavíte veľa ladiacich bodov a záložiek. Môžete projekt uložiť a zatvoriť Lazarus alebo otvoriť iný, ale keď znova otvoríte pôvodný, dokonca i na inom počítači, všetky vaše ladiace body, záložky, otvorené súbory, pozície kurzora, histórie skokov, ... sú obnovené.

Editor zdrojového kódu

(Source Editor) Takmer všetky klávesy a klávesové skratky môžu byť nastavené v Tools -> Options -> Editor -> Key Mappings

IDE Lazarus má veľa nástrojov pre zdrojový kód. Mnohé z nich sú veľmi podobné tým v Delphi. Ale je tu jeden veľký rozdiel: Lazarus nepoužíva prekladač na získanie informácií o kóde, ale analyzuje priamo zdrojový kód, čo má veľa výhod:

Editor zdrojového kódu pracuje s komentármi. V Delphi sú komentáre len medzerou v kóde, funkcie kódu tu nepracujú a pri automatickom vložení kódu, sú vaše komentáre posunuté. Pod Lazarus môžete hľadať deklarácie dokonca v kóde komentára. Aj keď toto nie je úplne spoľahlivé, často to pracuje. A keď vložíte nový kód, používa IDE nejakú heuristiku na uchovanie komentára a kódu spolu. Napríklad: nebude rozdelený riadok "c: char; // comment".

Dokončovanie kódu Delphi (Ctrl+Space) je pod Lazarus nazvané Identifier Completion. Termín Lazarus Code Completion je funkcia, ktorá kombinuje Automatic Class Completion (rovnaká ako v Delphi), Local Variable Completion a Event Assignment Completion. Tieto všetky sú vyvolané pomocou Ctrl+Shift+C a IDE určuje podľa pozície kurzora, ktorá funkcia bude použitá.

Dokončovanie lokálnych premenných

(Local Variable Completion) Predstavte si, že ste práve vytvorili novú metódu a napísali príkaz "i:=3;"

procedure
 TForm1.DoSomething; 
 begin
   i := 3; 
 end;

Umiestnite kurzor nad identifikátor "i" a stlačte Ctrl+Shift+C, čím získate:

procedure
 TForm1.DoSomething; 
 var
   i: Integer; 
 begin
   i:= 3; 
 end;

Dokončovanie priradenia udalostí

(Event Assignment Completion) Príjemná funkcia Inšpektora objektov je automatické vytváranie metód. To isté môžete urobiť v editore zdrojového kódu. Napríklad:

Button1.OnClick:=

Umiestnite kurzor za operátor priradenia ":=" a stlačte Ctrl+Shift+C.

Príklad doplňovania volaných procedúr

Predstavte si, že ste práve napísali príkaz 'DoSomething(Width);'

procedure SomeProcedure;
var
  Width: integer;
begin
  Width:=3;
  DoSomething(Width);
end;

Umiestnite kurzor na identifikátor DoSomething a stlačte Ctrl-Shift-C. Dostanete:

procedure DoSomething(aWidth: LongInt);
begin

end;

procedure SomeProcedure;
var
  Width: integer;
begin
  Width:=3;
  DoSomething(Width);
end;

Dokončovanie slov

(Word Completion Ctrl+W) Táto funkcia je odstupná po stlačení Ctrl+W. Pracuje podobne ako "Identifier Completion", ale nepracuje len s identifikátormi Pascalu, ale so všetkými slovami. Dovolí vám vybrať zo všetkých slov zo všetkých otvorených súborov začínajúcich rovnakými písmenami.

Include súborov

Delphi túto podporu nemá a tak ste pravdepodobne veľa takýchto súborov nevytvorili. Ale include súbory majú veľkú výhodu: Dovoľujú písanie na platforme (ne)závislý kód bez komplikovanosti vášho kódu s direktívami IFDEF.

Napríklad: Method jumping, Class Completion, Find declaration, .. všetky pracujú s include súbormi.

Pre nastavenie dokončovania kódu je k dispozícii veľa nastavení.

Designer

- Guidelines

Object Inspector

Ako v IDE Delphi aj v IDE Lazarus je Inšpektor objektov použitý na úpravu vlastností komponentov, priradenie udalostí atď. Nasledujú niektoré malé rozdiely, na ktoré treba pri použití pamätať:

  1. Počnúc Delphi 5, je Object Treeview, ktorý môže byť použitý na navigáciu a výber objektov podľa ich hierarchie, ako doplnok tradičného rozbaľovacieho zoznamu v Inšpektore objektov. V Lazarus je toto súčasťou Inšpektora objektov a jeho použitím namiesto predvoleného rozbaľovacieho zoznamu môžete vybrať jeho ne/použitie pomocou kontextového menu "Show Component Tree"
  2. V Delphi dvojité kliknutie na prázdnu udalosť ju automaticky vytvorí a otvorí Editor zdrojového kódu na jej pozícii, v Lazarus je tlačítko napravo od rozbaľovacieho zoznamu, ktoré vykoná to isté.
  3. V Delphi musíte ručne zmazať meno udalosti v políčku, aby ste odstránili priradenie, v Lazarus zvoľte v zozname "(None)".
  4. Podobne ako pri udalostiach, dvojitým kliknutím na regulárne vlastnosti (napr. Boolean) nezmení ich hodnotu, ale musíte ju zvoliť zo zoznamu a na otvorenie ich predvoleného editora, musíte kliknúť na tlačítko vpravo od rozbaľovacieho zoznamu.

Balíčky

V Lazarus nemôžete inštalovať balíčky Delphi, pretože potrebujú čary prekladača Delphi. Preto pre Lazarus potrebujete špeciálne vytvorené balíčky.

Vytvorte nový balíček, uložte ho v zdrojovom adresári balíčkov (bežne rovnaký adresár súboru .dpk), pridajte LCL ako vyžadovaný balíček a nakoniec pridajte súbory .pas. Teraz ho môžete nainštalovať alebo použiť vo svojom projekte. Medzi balíčkami Lazarus a Delphi sú rozdiely, prečítajte si prosím docs/Packages.txt v zdrojovom kóde Lazarus. - viď docs/Packages.txt v zdrojovom kóde Lazarus.

VCL -> LCL

Hoci obe, VCL aj LCL, slúžia rovnakému cieľu - Objektovo orientovanej hierarchii komponentov hlavnému motoru pre rýchly vývoj aplikácií (RAD), nie sú identické. Napríklad, kým VCL poskytuje veľa nevizuálnych komponentov, LCL sa pokúša poskytovať len vizuálne, kým väčšina nevizuálnych komponentov (ako db access) sú poskytované pomocou FCL, zahrnutej vo FreePascal.

Takže veľa prvkov VCL nemusí existovať v LCL, alebo naopak, alebo dokonca keď prvky existujú v oboch, nie sú to klony a musíte urobiť pri prenose zmeny v aplikácii, komponentoch a prvkoch.

Nasledujúci text sa pokúša poskytnúť čo najúplnejší popis hlavných rozdielov a nekompatibility medzi nimi, pre užívateľov Delphi. Popisuje najmä rozdiely VCL v D4, ale i D5, D6 alebo D7; s aktuálnou LCL, ako je v CVS. Takže nemusí byť vždy presne k verzii, ktorú používate alebo úplne súhlasiť s aktuálnym LCL, ktorý máte. Ak uvidíte rozdiely medzi nasledujúcim textom a LCL ako je v CVS, alebo svojim Delphi kľudne sa pripojte a zmeňte to tak, aby ste prispeli k úplnosti pre všetkých ľudí.

TControl.Font/TControl.ParentFont

Vo VCL je pre prvky úplne bežné použiť presné meno fontu a vlastností fontu ako bold a italics a očakávanie tejto hodnoty bude vždy nasledovať. Ďalej je poskytnutá vlastnosť TControl.ParentFont, ktorá zaisťuje, že prvok sa bude vždy riadiť svojim rodičovským fontom. Opäť, implicitná domnienka je, že tieto hodnoty budú vždy nasledované, dokonca nedbajúc nastavenia Windows Apearance.

Toto nie je vždy pravda v LCL, ani byť nemôže. LCL je cross-platform/cross-interface od začiatku preferuje vyvážené nastavenie a bude sa vždy pokúšať nastaviť Desktop/Toolkit Apearance alebo nastavenú Tému na všetkých nástrojoch. Napríklad, ak používate rozhranie GTK a téma GTK poskytuje konkrétny font pre tlačítka, potom sa tlačítka LCL budú vždy pokúšať použiť tento font.

To znamená, že väčšina prvkov LCL nemá rovnakú úroveň návrhu prvku, ktorá je často predpokladaná vo VCL, skôr len tie vlastné prvky, ktoré sú kreslené Canvas miesto pridelené rozhraním môžu byť modifikované týmto spôsobom, nedbajúcim na použité rozhranie.

Ak je napríklad potrebný Label s fontom bold/special color, musíte použiť TStaticText, keďže TLabel je špecifický prvok rozhrania a všetky rozhrania sú poskytnuté v pôvodnej verzii a mnoho z nich bude mať predvolené nastavenia, ktoré budú použité.

Riadenie Dragging/Docking

Vo VCL väčšina (Win) prvkov implementuje metódy a spätné funkcie pre obsluhovanie preťahovania a dokovania prvkov, napríklad preťahovanie prvku z jedného panela a jeho dokovanie do iného panely v dobe behu programu.

Táto funkcia nie je teraz implementovaná/dokončená v LCL, hoci teraz je v počiatočnom štádiu plánovania a bude eventuálne podporovať nejakú úroveň kompatibility tohto typu správania, ak nie dokonca presne rovnaké.

Toto aktuálne znamená, že prvky nemôžu dediť/používať nasledujúce funkcie, procedúry, vlastnosti a udalosti TControl:

protected
  function GetDockEdge(MousePos: TPoint): TAlign; 
  function GetDragImages: TDragImageList; 
  function GetFloating: Boolean; 
  function GetFloatingDockSiteClass: TWinControlClass; 
  procedure DoEndDrag(Target:TObject); X, Y: Integer); 
  procedure DockTrackNoTarget(Source: TDragDockObject; X, Y: Integer); 
  procedure DoEndDock(Target: TObject; X, Y: Integer); 
  procedure DoDock(NewDockSite: TWinControl; var ARect: TRect); 
  procedure DoStartDock(var DragObject: TDragObject); 
  procedure DragCanceled; 
  procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; 
                     var Accept: Boolean); 
  procedure DoEndDrag(Target: TObject; X, Y: Integer); 
  procedure DoStartDrag(var DragObject: TDragObject); 
  procedure DrawDragDockImage(DragDockObject: TDragDockObject); 
  procedure EraseDragDockImage(DragDockObject: TDragDockObject); 
  procedure PositionDockRect(DragDockObject: TDragDockObject); 
  procedure SetDragMode(Value: TDragMode); 
  property DragKind: TDragKind; 
  property DragCursor: TCursor; 
  property DragMode: TDragMode; 
  property OnDragDrop: TDragDropEvent; 
  property OnDragOver: TDragOverEvent; 
  property OnEndDock: TEndDragEvent; 
  property OnEndDrag: TEndDragEvent; 
  property OnStartDock: TStartDockEvent; 
  property OnStartDrag: TStartDragEvent; 
public 
  function Dragging: Boolean; 
  function ManualDock(NewDockSite: TWinControl; DropControl: TControl; 
                      ControlSide: TAlign): Boolean; 
  function ManualFloat(ScreenPos: TRect): Boolean; 
  function ReplaceDockedControl(Control: TControl; NewDockSite: TWinControl; 
                                DropControl: TControl; ControlSide: TAlign): Boolean; 
  procedure BeginDrag(Immediate: Boolean; Threshold: Integer); 
  procedure Dock(NewDockSite: TWinControl; ARect: TRect); 
  procedure DragDrop(Source: TObject; X, Y: Integer); 
  procedure EndDrag(Drop: Boolean); 
  property DockOrientation: TDockOrientation; 
  property Floating: Boolean; 
  property FloatingDockSiteClass: TWinControlClass; 
  property HostDockSite: TWinControl; 
  property LRDockWidth: Integer; 
  property TBDockHeight: Integer; 
  property UndockHeight: Integer; 
  property UndockWidth: Integer;

a že nasledujúce triedy neexistujú alebo sú nepoužiteľné:

TDragImageList = class (TCustomImageList) 
TDockZone = class
TDockTree = class (TInterfacedObject, IDockManager) 
TDragObject = class (TObject) 
TBaseDragControlObject = class (TDragObject) 
TDragControlObject = class (TBaseDragControlObject) 
TDragDockObject = class (TBaseDragControlObject)

a že nasledujúce funkcie sú tiež neexistujúce/nepoužiteľné:

function FindDragTarget(const Pos: TPoint; AllowDisabled: Boolean) : TControl; 
procedure CancelDrag; 
function IsDragObject(sender: TObject): Boolean;

TEdit/TCustomEdit

Prvky Edit, kým základné funkcie sú v LCL rovnaké ako vo VCL, iné treba pri konverzii robiť opatrne:

  1. kvôli obmedzeniam rozhraní, TEdit.PasswordChar zatiaľ nepracuje vo všetkých rozhraniach (neskôr možno), namiesto toho použite TCustomEdit.EchoMode emPassword v udalosti na skrytie textu.
  2. Udalosti OnDrag/Dock zatiaľ nie sú implementované. Viz Riadenie Dragging/Docking.
  3. Vlastnosti Font sú, kvôli správaniu rozhrania, zvyčajne ignorované. Viz TControl.Font/TControl.ParentFont

TSplitter -> TPairSplitter

Please Improve Me

V LCL existuje prvok TSplitter, tak ho netreba konvertovať, napriek tomu ho chcem trochu vysvetliť:

Vo VCL, "Splitting" prvkov, čo je ošetrením, ktoré umožňuje preťahovanie medzi dvomi komponentmi na získanie viac/menej miesta pre jeden na úkor ostatných, je urobený pomocou TSplitter. Často to môžete vidieť, napríklad v IDE Delphi medzi dokovaným Code Explorer a Source Viewer.

LCL poskytuje svoj vlastný prvok, nazvaný TPairSplitter, ktorý obsluhuje rovnakú úlohu, avšak nie je kompatibilný, tak "skúšanie" preruší VCL kód alebo bude potrebný Delphi DFM pri prenose kódu.

V čom presne sú rozdiely?

Najväčšie rozdiely sú, že VCL TSplitter nemá potomkov, namiesto toho ho umiestňujete medzi dva prvky, ktoré sú správne usporiadané a dovoľuje meniť ich veľkosť za behu programu, nedbajúc na vlastnú veľkosť. Prvky musia byť správne usporiadané, napríklad Panel a Splitter s Aligned Left a druhý Panel Aligned Client. Za behu programu môžete zmeniť rozloženie panelov pomocou preťahovania ošetreného pomocou prvku Splitter.

V LCL je však TPairSplitter špeciálnym typom prvku s dvomi panelmi a môže byť užitočný len ak prvky na presúvanie sú na týchto paneloch, ale posúvanie bude jednako vykonané medzi týmito panelmi, i keď na nich nebude nič. Ako v predchádzajúcom príklade, potrebujete formulár s TPairSplitter Aligned Client a Panel Aligned Client na jeho ľavej strane a Panel Aligned Client na jeho pravej strane.

Iným dôležitým rozdielom je, že vo VCL, keďže TSplitter je svoj vlastný TControl, tak jeho pozícia pri zmene veľkosti je uchovávaná relatívne k ostatným prvkom, tak napríklad klientský panel sa bude zväčšovať, kým ostatné panely nie, tým je pozícia rozdelenia relatívna k zarovnaniu rozdeľovaných prvkov.

V LCL sú bočné panely samostatné, potom TPairSplitter má vlastnosť Position, ktorá je absolútne relatívna k vrcholu Top alebo Left. Tak pri zmene veľkosti aktuálna sa pozícia nemení podľa obsahu, tak musí byť nastavené spätné volanie na zaistenie uchovania pomeru, ak je to dôležité.

Napríklad, ak pravá strana vertikálneho rozdelenia musí mať správanie ako alClient, potrebujete zmeniť spätným volaním veľkosť formulára, napríklad takto:

PairSplitter.Position := PairSplitter.Width - PairSplitter.Position; 
Teda ako môžem konvertovať existujúci kód používajúci TSplitter na TPairSplitter?

Ak sú splitter a prvky vytvorené vo vnútri aktuálnej funkcie (ako OnCreate formulára), konverzia nebude zložitá, najprv zreorganizujeme kód na vytvorenie prvkov v poradí novej hierarchie a nastavíme rodičov podriadených prvkov pre rozdelenie na ľavý/horný a pravý/dolný podiel prvku PairSplitter. Napríklad:

VCL LCL
var 
  BottomPanel: TPanel;
  VerticalSplitter: TSplitter;
  LeftPanel: TPanel;
  HorizontalSplitter: TSplitter;
  MainPanel: TPanel;

begin
  BottomPanel:= TPanel.Create(Self);
  with (BottomPanel) do
  begin
    Parent:= Self;
    Height:= 75;
    Align:= alBottom;
  end;

  VerticalSplitter:= TSplitter.Create(Self);
  with (VerticalSplitter) do
  begin
    Parent:= Self;
    Align:= alBottom;
  end;

  HorizontalSplitter:= TSplitter.Create(Self);
  with (HorizontalSplitter) do
  begin
    Parent:= Self;
    align:= alLeft;
  end;

  LeftPanel:= TPanel.Create(Self);
  with (LeftPanel) do
  begin
    Parent:= Self;
    Width:= 125;
    Align:= alLeft;
  end;

  MainPanel:= TPanel.Create(Self);
  with (MainPanel) do
  begin
    Parent:= Self;
    Align:= alClient;
    Caption:= 'Hello';
  end;
end;
var
  BottomPanel: TPanel;
  VerticalSplitter: TPairSplitter;
  LeftPanel: TPanel;
  HorizontalSplitter: TPairSplitter;
  MainPanel: TPanel;

begin
  VerticalSplitter:= TPairSplitter.Create(Self);
  with (VerticalSplitter) do
  begin
    Parent:= Self;
    Align:= alClient;
    Width:= Self.Width;
    Height:= Self.Height;
    SplitterType:= pstVertical;
    Position:= Height - 75;
    Sides[0].Width:= Width;
    Sides[0].Height:= Position;
  end;

  HorizontalSplitter:= TPairSplitter.Create(Self);
  with (HorizontalSplitter) do
  begin
    Parent:= VerticalSplitter.Sides[0];
    Width:= Self.Width;
    Height:= VerticalSplitter.Position;
    align:= alClient;
    SplitterType:= pstHorizontal;
    Position:= 125;
  end;

  LeftPanel:= TPanel.Create(Self);
  with (LeftPanel) do
  begin
    Parent:= HorizontalSplitter.Sides[0];
    Align:= alClient;
  end;

  MainPanel:= TPanel.Create(Self);
  with (MainPanel) do
  begin
    Parent:= HorizontalSplitter.Sides[1];
    Align:= alClient;
    Caption:= 'Hello';
  end;

  BottomPanel:= TPanel.Create(Self);
  with (BottomPanel) do
  begin
    Parent:= VerticalSplitter.Sides[1];
    Align:= alClient;
  end;
end;

Ako môžete vidieť, zmena pozostáva väčšinou z hierarchie. Ak vám lepšie vyhovuje práca s DFM, zmeny potrebné pre konverziu DFM->LFM sú podobné zmenám vyššie, ide o rovnaký typ zmien v Parent/Owner atď. Potom bude vyššie spomínaný príklad vyzerať takto nejako:

Delphi DFM
(extraneous values removed)
Lazarus LFM
(most width, height, etc. removed)
object VerticalSplitter: TSplitter
  Height = 3
  Cursor = crVSplit
  Align = alBottom
end
object HorizontalSplitter: TSplitter
  Width = 3
  Align = alLeft
end
object BottomPanel: TPanel
  Height = 75
  Align = alBottom
end
object LeftPanel: TPanel
  Width = 125
  Align = alLeft
end
object MainPanel: TPanel
  Align = alClient
end
object VerticalSplitter: TPairSplitter
  Align = alClient
  SplitterType = pstVertical
  Position = 225
  Height = 300
  Width = 400
  object Pairsplitterside1: TPairSplitterIde
    object HorizontalSplitter: TPairSplitter
      Align = alClient
      Position = 125
      object Pairsplitterside3: TPairSplitterIde
        Width = 125
        object LeftPanel: TPanel
          Align = alClient
          Width = 125
        end
      end
      object Pairsplitterside4: TPairSplitterIde
        object MainPanel: TPanel
          Align = alClient
        end
      end
    end
  end
  object Pairsplitterside2: TPairSplitterIde
    object BottomPanel: TPanel
      Align = alClient
      Height = 75
    end
  end
end

TCustomTreeView/TTreeView

Oboje, VCL aj LCL, poskytujú komponent TCustomTreeView/TTreeView, používaný pre výpisy stromovej štruktúry dát s viacnásobnými uzlami, rozšíreným výberom a ImageList, a hoci skutočná funkčnosť je porovnateľná, nie všetky vlastnosti sú úplne kompatibilné. Hlavné rozdiely sú: Incomplete list, also update to include TCustomTreeView Mark functions and protected methods

  1. LCL poskytuje TCustomTreeView.Options, množinu volieb, ktoré môžu byť nastavené na zmenu správania a vzhľadu prvku:
    • tvoAllowMultiselect- nastavuje mód viacnásobného výberu uzlov, ekvivalent k TCustomTreeView.MultiSelect vo VCL VCL
    • tvoAutoExpand- automatické rozbalenie uzlov, ekvivalent k TCustomTreeView.AutoExpand
    • tvoAutoInsertMark- aktualizácia prípravy Drag pri prechode myšou.
    • tvoAutoItemHeight- automatické prispôsobenie výšky prvku.
    • tvoHideSelection- neoznačovať vybranú položku.
    • tvoHotTrack- použitie HotTracking, ekvivalent k TCustomTreeview.HotTrack
    • tvoKeepCollapsedNodes- pri zbalení uzla, uchováva podriadené uzly
    • tvoReadOnly- ekvivalent k TCustomTreeview.ReadOnly
    • tvoRightClickSelect- dovoľuje použiť pravé tlačítko myši na výber uzla, ekvivalent k TCustomTreeView.RightClickSelect
    • tvoRowSelect- dovoľuje výber riadkov, ekvivalent k TCustomTreeView.RowSelect
    • tvoShowButtons- zobrazuje tlačítka, ekvivalent k TCustomTreeView.ShowButtons
    • tvoShowLines- zobrazuje čiary uzlov, ekvivalent k TCustomTreeView.ShowLines
    • tvoShowRoot- zobrazuje root, ekvivalent k TCustomTreeView.ShowRoot
    • tvoShowSeparators- zobrazuje oddeľovače
    • tvoToolTips- zobrazuje samostatné tooltips pre uzly
  2. LCL poskytuje dodatočné vlastnosti:
    • udalosť TCustomTreeView.OnSelectionChange
    • TCustomTreeView.DefaultItems, pre predvolené číslo položiek
    • TCustomTreeView.ExpandSignType na určenie znamienka použitého na rozbaliteľných/zbaliteľných uzloch
  3. Síce väčšina udalostí OnDrag/OnDock je k dispozícii v LCL, nefungujú však! Pre viac informácii si prosím prečítajte predchádzajúcu sekciu.


Správy / Udalosti

(Messages / Events) Poradie a množstvo správ a udalostí (OnShow, OnActivate, OnEnter, ...) sa líši od VCL a závisí od použitého widgeset. LCL síce poskytuje podmnožinu správ podobných WinAPI (aby bolo portovanie komponentov z Delphi jednoduchšie), avšak takmer všetky LCL správy sa od WinAPI mierne líšia. Niektoré časti Delphi kódy používajú WinAPI správy preto, že vo VCL chýbajú alebo kvôli rýchlosti. Niektoré veci občas samé fungujú, ale je nutné ich skontrolovať ručne. To je dôvod, prečo sa LCL správy nazývajú napr. LM_SIZE namiesto WM_SIZE (unit lmessages).

Poznámka ku spracovávaniu vlastných správ! Od verzie 0.9.26 (December 2008) sa zmenil spôsob spracovávania vlastných WinAPI správ (ako napr. WM_HOTKEY, WM_SYSCOMMAND); a líši sa od spôsobu používanom v Delphi. V tomto momente nie je možné odchytávať správy prostredníctvom direktívy message alebo pomocou prekrytia metódy WndProc formulára. Jediný spôsob, ako odchytávať metódy vo formulári je nahradiť metódy windowproc. Viac tu: Processing non-user messages in your window

Original Contributors and changes

This page has been converted from the epikwiki version.

  • Initial import and formatting - VlxAdmin 9/26/2003
  • Begin VCL -> LCL with a section on TSplitter -> TPairSplitter - Andrew Johnson 9/30/2003
  • Add TControl.Font/TControl.ParentFont to VCL -> LCL - Andrew Johnson 9/30/2003
  • Update TEdit/TCustomEdit section in VCL -> LCL - Andrew Johnson 10/1/2003
  • Add Control Dragging/Docking to VCL -> LCL - Andrew Johnson 10/1/2003
  • Added "Object Inspector" to Delphi IDE -> Lazarus IDE - Andrew Johnson 10/1/2003
  • Added initial "TCustomTreeView/TTreeView" to VCL -> LCL - Andrew Johnson 10/1/2003
  • Added introduction to VCL -> LCL - Andrew Johnson 10/1/2003
  • Fixed some typos - Vincent 10/2/2003
  • Fixed Typo User:Kirkpatc 20 May 2004
  • Prvotný preklad z origánalu - Slavko 01:18, 2 Apr 2005 (PST)
  • Aktualizácia prekladu --Adamm 14:45, 29 December 2008 (CET)