Procedurální typ
Jelikož je Object Pascal přísně typovým jazykem existuje také typ procedura. Ve skutečnosti je to v podstatě ukazatel na proceduru nebo funkci. Tím, že zadefinujeme tento typ, získáme možnost bezpečně přiřazovat nebo předávat odkaz a kompilátor nikdy neztratí kontrolu nad parametry, čímž minimalizujeme možnost předání špatného typu (nebo počtu) parametru.
type TMyProc = function (x,y:Integer):Integer; TMyMethod = function (x,y:Integer):Integer of Object;
První deklarace definuje funkci s dvěma parametry a návratovým typem Integer. Druhá deklarace definuje metodu se stejnou syntaxí.
function Test(a,b:Integer):Integer; begin Result:=a+b end; var mp:TMyProc; begin mp:=Test; writeln(mp(1,2)); end;
Dědičnost rozhraní
Object Pascal umí jen vícenásobnou dědičnost rozhraní, anglicky Interface (česky někdy jako meziksicht).
První předchůdce musí být následníkem TObject. Vhodným objektem je
TInterfacedObject, který má implementované metody pro počítání referencí. Následně je uveden seznam rozhraní, které je nutno implementovat.
type IRozhrani1=Interface procedure Metoda; end; TMyObject=class(TInterfacedObject, IRozhrani1) procedure Metoda; end; implementation procedure TMyObject.Metoda; begin end;
Portace zdrojových kódů
Nejprve bych rád uvedl, že následující informace platí hlavně pro aplikace psané v Delphi s VCL, jelikož aplikace napsaná čistě v CLX pro Delphi 6 je přeložitelná bez jakékoliv úpravy.
Úspěch celé operace velmi závisí na použitých komponentách. Předem upozorňuji, že pokud aplikace používá BDE (Borland Database Engine) budou nutné úpravy, jejichž rozsah závisí na způsobu použití komponent. BDE není dále vyvíjeno ani na platformě Windows.
Některé informace o přenosu aplikací pod Linux lze nalézt v helpu pod heslem Porting Windows applications to Linux.
Znovu bych rád upozornil na rozdílnost verzí. V Open Edition mnoho komponent chybí.
Obecně se dá říci, že pokud máte v programu komponenty třetí strany, bude vlastní konverze obtížnější. Základem je, aby jste od všech komponent měli zdrojové kódy, nebo aby existovaly příslušné komponenty ve verzi pro Kylix.
Nejméně problémů je s nevizuálními komponentami a třídami. Naopak prakticky bez úpravy nepřenositelné jsou třeba komponenty zapouzdřující COM objekty.
Pokud vaše aplikace používá proměnné typu variant, tak nemusíte zoufat, jelikož tento ryze COM typ proměnné byl úplně nově implementován a je umístěn v jednotce Variants (překvapivě).
Poznámka: proměnná typu Variant se vyznačuje tím, že je kompatibilní prakticky se všemi typy (vyjímky jsou uvedeny v helpu). Já sice raději používám třídu nebo záznam (pro lepší typovou kontrolu a efektivnější kód), ale někomu to může vyhovovat.
Příklad na varianty
var Test:Variant; i:Integer; begin Test:='string'; Test:=1.23; Test:=1; I:=Test; Test:=True; Test:='1'; // string I:=Test ; // konverze string > Integer end;
Postup vlastní portace
Nejprve překopírujeme projekt z Delphi do nového adresáře a popřípadě mu změníme atributy (chmod -x *).
Pokud máme projekt staršího data tak je možné, že formuláře budou uloženy v binární a nikoli textové formě.
Tuto skutečnost zjistíme jednoduše zobrazením obsahu. Pokud je obsah srozumitelný, tak je to textový formát (to by jeden nevěřil). V opačném případě použijeme program convert z instalace Kylixu, který umí převádět mezi oběma formáty a zároveň si v nabídce Tools/Enviroment Options/Preferences (pokud to již nemáme) zvolíme New forms as text. Touto volbou IDE řekneme, že nové formuláře mají být ukládány jako čistý text.
Smažeme všechny automaticky generované soubory, ponecháme jen .dpr, *. dfm, *.pas a ty soubory, které jsme sami vytvořili (.inc, *.rc atd.).
Přejmenujeme všechny soubory dfm na xfm.
Ve formulářích přepíšeme {$ *.DFM} na {$ *.xfm} – pozor na velikost písmen. Tento příkaz udává linkeru, že do výsledného binárního souboru má přilinkovat převedené formuláře.
V klauzulích uses přepíšeme Form, Menus, Graphics, Controls, Dialogs, StdCtrls na na QForm, QMenus, QGraphics, QControls, QDialogs, QStdCtrls.
Z uses smažeme Windows a Messages.
Předchozí dva odstavce platí pokud nechceme mít jeden zdrojový kód pro obě platformy. V opačném případě máme prakticky jedinou možnost:
Podmíněná kompilace
Uvedu rovnou příklad zápisu:
uses {$IFDEF LINUX} QForm, QMenus, QGraphics ..., {$ELSE} Form, Menus, Graphics ..., {$ENDIF} Classes, SysUtils ...
Kylix definuje symbol LINUX, naproti tomu Delphi symbol MSWINDOWS definován není. Dále je definován symbol VERxxx, kde xxx je verze kompilatoru. Kylix, Delphi 6 a kupodivu i Kylix 2 mají
VER140.
Poznámka: zajímavé (aspoň pro mne) je, že dcc alias Delphi Command Compiler se hlásí jako 14.1, ale symbol VER141 definován není.
Zpět ke konverzi
Další možností je vložení části kódu pomocí direktivy {$I filename }. Pokud někoho napadlo, že tímto způsobem vloží celou klauzuli uses tak bych mu rád sdělil, že to nejde.
Prakticky by tímto krokem zmátnul IDE, které při přidání komponenty na formulář automaticky vygeneruje potřebnou jednotku do klauzule uses (pokud tam již není uvedena). No a pokud tam máme pouze příkaz pro vložení externího souboru, tak nám vznikne pěkný zmatek (nehledě na to, že to asi nepůjde přeložit).
Tento způsob se především používá pro vložení nějaké sekvence, např. pro určení kompilátoru a jeho verze.
{$INCLUDE detect.inc}
Zkontrolujeme zda jména unitů odpovídají: např. Classes x classes.
Překonvertujeme všechny zdrojáky, kde se vyskytují česká slova (buďto manuálně nebo např. pomocí iconv). Delphi 6 a Kylix už používají unicode, takže u konverze z Delphi 6 tento bod odpadá.
Nyní nastává okamžik pravdy (věřící se pomodlí, ostatní odplivnou na všechny světové strany). Otevřeme projekt v Kylixu a zkusíme ho překompilovat.
V ideálním případě mi pošlete děkovný mail nebo aspoň necháte zahrát pěknou písničku.
Pokud vám Kylix sdělí, že nějaká komponenta není nainstalovaná, tak nevěšte hlavu. Pořád je možné, že ji a nebo jinou se stejnou funkcí naleznete třeba na http://www.torry.net/ nebo přes http://www.google.com/.
Poznámka: zde bych se rád zeptal, zda se někomu povedlo smysluplně nainstalovat balík komponent SynEdit. Jedná se o Mozilla PL komponenty, které jsou snad v každém druhém programátorském editoru pod Windows (doplňování kódu, zvýrazňování syntaxe pro snad všechny známé jazyky atd.).
První spuštění
Pokud se vám podařilo projekt přeložit, tak neváhejte a klávesou F9 provedeme spuštění.
Pokud na obrazovce vidíme škaredé fonty, je problém ve špatně nastaveném fontu. Přepneme se na formulář a po stisku pravého tlačítka vybereme z nabídky View as Text. Tímto zobrazíme formulář textově (je to ekvivalentní zobrazení a editaci dfm nebo xfm). Zde buď jména fontů upravíme nebo řádky smažeme. V druhém případě se budou brát standardní fonty, popřípadě si je můžeme následně zvolit v Object Inspectoru.
Zobrazení vrátíme zpět volbou View as form.
Příklad konvertované aplikace
Napsal jsem v Delphi 5 malou aplikaci, kterou jsem následně portoval na Linux. Jedná se o nejjednodušší možný textový editor, který umí pouze načíst a uložit text. Mimochodem, já sám jsem tam napsal jen 6 řádků, zbytek jsem naklikal. Dále je uveden postup jak tento editor naprogramovat v Kylixu. Vytvoření této aplikace by mělo osvětlit koncepci práce v Kylixu.
Editor od nuly
Vytvoříme novou aplikaci. Hned poté si projekt uložíme do svého adresáře volbou z menu File/Save project as… Formulář uložíme do souboru fMain.pas a projekt pod výsledným jménem aplikace Test1.dpr. Klikneme na formulář a v Object Inspectoru (to okno vlevo) vybereme položku
Name a vložíme místo Form1 jméno frmMain. Tímto krokem jsme přejmenovali komponentu (v tomto případě hlavní formulář).
Na formulář umístíme z palety Standard komponentu TMainMenu. Dvojitým poklepáním se dostaneme do editoru menu, kde přidáme hlavní položky menu: &File a &Help. Znak & značí hotkey (česky teplou klapku). Položky v Object Inspectoru přejmenujeme na miFile a miHelp (mi jako menu item).
Do menu File přidáme &Open, &Save a &Exit. Pokud chceme mezi Save a Exit vložit oddělovač tak napíšeme „-“ (bez těch uvozovek). Položky opět přejmenujeme na miOpen, miSave, miExit (není to nutné, ale tak si udržujeme pořádek v proměnných).
Do menu Help přidáme &About a přejmenujeme ho na miAbout. Tím jsme s menu pro tento okamžik hotovi.
Na formulář přidáme nevizuální komponenty TOpenDialog a TSaveDialog. Nevizuální, protože nejsou za běhu vidět. Přejmenujeme je na dlgOpen a dlgSave.
Nyní na formulář přidáme nevizuální komponentu TActionList. ActionList je velmi užitečná věcička. Opět modelová situace: pro otevření souboru můžeme použít jak menu, nějaké tlačítko nebo třeba lokální menu vyvolané po stisku pravého (resp. levého pro leváky) tlačítka myši. Psát pro každou akci obsluhu je nudné. Proto Kylix umožňuje přiřadit všem těmto akcím jednu obsluhu.
To už je lepší. Ale pokud použijeme ActionList, tak tam můžeme vytvořit pro všechny tyto činnosti jednu akci, tu pojmenovat, vytvořit její obsluhu, přiřadit ji Hint (plovoucí nápovědu) a třeba přiřadit i ikonu.
Dvojitým poklepáním na ActionList se dostaneme do editoru akcí. Zde vytvoříme akce actOpen, actSave, actExit a actAbout. V Object Inspectoru jim nastavíme požadované vlastnosti a zavřeme editor akcí.
Teď musíme přiřadit akci odpovídající položce menu. Otevřeme editor menu a v Object Inspectoru vybereme pro každou položku menu pro vlastnost Action některou z námi definovaných akcí.
Na formulář vložíme komponentu TMemo, přejmenujeme ji na Editor a nastavíme její vlastnost Align na alClient. Tímto jsme oznámili komponentě, že si přejeme aby se při změně velikosti formuláře automaticky přizpůsobovala.
V tento okamžik máme návrh grafického rozhraní zdárně za sebou. Všechno co jsme provedli je poznačeno buďto v fMain.pas nebo v fMain.xfm. V druhém souboru je hlavně popis formuláře a to jako hierarchie objektů. Pokud se některá hodnota neliší od defaultní tak uvedena není.
Do tohoto okamžiku jsme nenapsali ani řádek kódu. Zkušený programátor v Kylixu toto zvládne za deset minut.
Oživení aplikace
Máme sice krásné uživatelské rozhraní, ale bohužel bez sebemenší špetky života. Programování v Kylixu znamená obsluhovat události. Samozřejmě jsou aplikace, které fungují klasickým způsobem (hlavní smyčka), ale převážná většina programů tak psána není.
Jakmile uživatel stiskne tlačítko, pro nějž máme vlastní obsluhu, je tato zavolána. Pokud vlastní obsluhu nemáme, je zavolána standardní obsluha.
V této aplikaci musíme obsloužit čtyři akce: actOpen, actSave, actExit, actAbout.
Začneme ukončením :-). V editoru akcí vybereme actExit a v Object Inspectoru záložku Events a poklepeme na OnExecute. Tato událost je vyvolána při provedení akce (například u tlačítka při kliknutí na tlačítko, u menu při zvolení položky atd.). Otevře se nám editor kódu s předgenerovanou obsluhou:
procedure TfrmMain.actExitExecute(Sender: TObject); begin Close; //tento řádek doplníme end;
Metoda Close je metodou TForm a způsobí zavření formuláře. Pokud je to poslední formulář, tak se aplikace ukončí. Parametr Sender obsahuje objekt, který obsluhu zavolal. Pokud by tato obsluha byla společná například pro několik různých objektů, tak můžeme podle tohoto parametru zjistit, kdo si žadá naši pozornost.
Stejným způsobem vytvoříme obsluhy ostatních akcí.
procedure TfrmMain.actOpenExecute(Sender: TObject); begin if dlgOpen.Execute then Editor.Lines.LoadFromFile(dlgOpen.FileName); end; procedure TfrmMain.actSaveExecute(Sender: TObject); begin if dlgSave.Execute then Editor.Lines.SaveToFile(dlgSave.FileName); end; procedure TfrmMain.actAboutExecute(Sender: TObject); begin ShowMessage('Editor 1.0'); end;
U dialogů metoda Execute provede zobrazení dialogu a vrátí True pokud byl dialog úspěšný (např. byl vybrán soubor).
Editor má vlastnost Lines, která je typu TStrings (viz help) a vlastní seznam řetezců. Mezi metodami, které publikuje je i načtení a uložení do/ze souboru.
ShowMessage je procedura, která zobrazí zprávu a tlačítko OK.
Tímto krokem je aplikace dokončena.
Abych předešel různým připomínkám: ano v Kylixu se dá vytvořit aplikace bez řádku kódu, ale taky aplikace, kde není ani jedna vizuální komponenta, ale pouze mraky kódu. Většina aplikací je někde napůl cesty.
Zdrojové kódy původní aplikace naleznete zde a zde je varianta pod Linux.
Komponenty – ZeosDB
Opensource knihovna DB komponent pro připojení k Firebirdu, Interbasi, MS SQL (Win), MySQL, Postgresql, IBM DB2 a Oracle.
Lze provozovat i pod Open Edition, v instalaci pomůže HOW-TO na adrese http://www.zeoslib.org/how_to.php
Podporovány jsou Delphi a Kylix.
Licence: GPL (někde zase LGPL)
Zdrojové kódy: ANO
Homepage:
Užitečné klávesové zkratky
- CTRL+K, I – odskočení bloku textu vpravo
- CTRL+K, U – a vlevo
- CTRL+kliknutí myši na identifikátor v editoru způsobí vyhledání deklarace
- CRTL+Shift+šipka nahoru – pokud je kurzor v implementaci, tak skočí do definice
- CRTL+Shift+šipka dolů – naopak
- CTRL+Shift+C – ve vyšších edicích způsobí, že pokud kurzor stojí v definici, doplní hlavičky implementace pro metody konkrétní třídy (toto mi v Open Edition moc chybí)
- CTRL+Space – nabídne doplnění kódu (Code Completion) – je zajímavé, že nabízí jen korektní nabídky, tj. IDE provádí na pozadí parsování kódu
- Shift+CTRL+Space – zobrazí u procedury očekávané parametry (automaticky se zobrazuje při napsání otevírací závorky)
- Během ladění zastavení kurzorem nad proměnnou (objektem) zobrazí její hodnotu
- CTRL+J – šablony kódu (code templates), lze definovat
A co příště?
Příště si dáme knihovny, vlákna a ukážeme si dynamické linkování (princip plug-inu ala XMMS).