Tutorial Object Pascal

Embed Size (px)

Citation preview

Learning Delphi

Page 1 of 15

Delphi TutorialIndiceBasi di Delphi Introduzione Delphi Un primo esempio I componenti L'Object Pascal Object Oriented Programming (OOP) Costanti e Variabili Elementi del linguaggio Eccezioni Eventi Un grande project di esempio Migliorare l'esempio Help Files Approfondimenti Threads Utilizzo delle DLL

Basi di DelphiIntroduzionePer questo tutorial dar per scontato che abbiate familiarit col Pascal. Se non la avete, leggetevi prima uno dei molti tutorials sul Turbo Pascal (cercate "pascal tutorial" in Yahoo). Vi aiuter anche conoscere i concetti della programmazione orientata agli oggetti (OOP), ma la spiegher brevemente. Vi prego di scusare tutti gli errori, sia di stampa che di altra natura. L'inglese non la mia lingua madre.

DelphiDelphi un cos chiamato RAD-Tool (RAD sta per Rapid Application Development). Vi permette di disegnare visualmente (utilizzando il drag-and-drop) le finestre di dialogo e perfino intere applicazioni. Nel toolbar della finestra principale potete trovare un sacco di componenti predefiniti da usare nei vostri progetti. Si tratta di effettuare un doppio click sulle icone per incollare nel form attivo. Nella parte sinistra del vostro schermo c' l'object inspector. Potete settarvi le propriet dei vostri componenti. Non c' bisogno di scriveredel codice per fare questo! Un buon metodo per imparare Delphi di giocherellare con i componenti. torna in alto

Un primo esempio1. Scegliete File - New Application Questo creer un form vuoto a quale potrete aggiungere tutti i componenti che volete. 2. Potete adesso aggiungere componenti dalla component palette facendo doppio click su di essi. Per cambiare la loro grandezza selezionateli, clickate su uno degli angoli e muovete il mouse. Come primo passo aggiungete un button (sesto da sinistra nella palette "standard"). Apparir al centro del form. Muovetelo dove volete. Il button avr scritto "button1" che non troppo utile per il vostro programma. Per camniare il testo del button ( chiamato caption), andate nell'object inspector e cambiate il campo "Caption". 3. Ora l'utente pu clickare sul button nel vostro programma, ma non succeder niente. Per assegnare una qualsiasi azione al button fate doppio click su di esso. Delphi proporr la finestra del codice. Il cursore gi nella posizione corretta. 4. Potete inserire del codice pascal nella procedura. Per questo esempio digitate semplicemente

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 2 of 15

"close;". Questo chiude il form e termina l'applicazione. 5. Il vostro progetto ora pronto per essere compilato. Scegliete File - Save As per salvarlo. Vi raccomando di usare directories differenti per i vostri diversi progetti perch tendono ad avere molti files (almeno 5). 6. Per compilare ed eseguire il progetto clickate sul tasto "play" nel toolbar. 7. Vedrete una finestra che pu essere ridimensionata e spostata per lo schermo come succede in "windows". Potete chiuderla clickando sul vostro button, clickando sul tasto "close"nell'angolo in alto a destra, o selezionando close dal window menu (angolo in alto a sinistra). torna in alto

L'IDEQuando avviate Delphi per la prima volta, vedrete alcune finestre. Noterete anche che non esistono finestre di origine che contengono tutte le altre (figlie) finestre. Invece c' una finestra principale (nella parte alta dello schermo) che ha una barra di menu e le icone. Presenta anche una component palette (che verr trattata pi avanti). Nella parte sinistra dello schermo potete vedere l'object inspector. Esso permette di cambiare le propriet del componente corrente.

I componentiE' possibile trovare i componenti di maggiore utilizzo nelle prime tre tabs nella component palette. Non li tratter tutti qui, fate riferimento al file di help se avete domande specifiche (o scrivetemi se non riuscite a capire qualcosa). Qui c' una veduta generale dei componenti pi importanti: MainMenu Aggiunge un menu bar standard al vostro form. Per cambiare i contenuti fate doppio click sull'icona sul form. Label Mette del testo sul vostro form. Il carattere della caption con davanti una "&" verr sottolineato. Potete linkare alla label un altro componente, tipo TEdit, utilizzando la propriet FocusControl. Quando l'utente preme Alt+CARATTERE quel componente sar selezionato. E' possibile variare l'aspetto del testo con la propriet "font". Edit permette all'utente di inserire del testo. E' possibile anche utilizzare il Copia-Incolla dagli appunti di Windows. Memo Multi-line Edit. Button Propriet efficaci sono "default" e "cancel" (rende il button default o cancel). Checkbox and Radiobutton permette all'utente di posizionarlo su acceso o su spento. In un gruppo di radiobuttons ne pu venire selezionato solo uno. Listbox and Combobox Mostra degli elenchi. L'utente pu selezionare un elemento cliccandolo. Potete permettere selezioni multiple, ordinare la lista, ecc. Image Probabilmente il modo pi semplice di aggiungere un bitmap al vostro form. utilizzate la propriet "picture". Tab- and Pagecontrol Permette di inserire pi componenti su un form di quanti se ne potrebbero mettere normalmente, fornendo diversi "strati" (layers). L'utente pu scegliere tra i layers utilizzando le linguette (tabs) nella parte alta del control. Potete anche utilizzare il page-editor per aggiungere pagine a designtime. Questo control viene spesso utilizzato per gli option dialogs. Per aggiungere un componente al vostro form, fate semplicemente doppio click su di esso. Potete muoverlo col mouse e customizzare le sue propriet nell'object inspector. Per lanciare il vostro programma premete semplicemente il tasto "play" nella finestra principale. torna in alto

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 3 of 15

L'Object PascalL'Object Pascal il linguaggio di programmazione che si utilizza in Delphi. E' molto simile al Turbo Pascal, ma la Borland vi ha aggiunto alcune caratteristiche. Me ne occuper dopo. L'Object Pascal ovviamente un linguaggio object oriented. Per quelli che non sanno che cosa sia, far una breve ricapitolazione nel prossimo paragrafo. Quelli che hanno familiarit con l'OOP possono saltarlo.

Object Oriented Programming (OOP)l'idea dell'OOP di mettere sia i dati che il programma in un contenitore solo. Questo container viene chiamato oggetto. Cosa che dovreste di norma dichiarare come segue:var MyByte: Byte; Name: String; procedure DoSomething; function Whatever: Byte;

Pu essere ricapitolato in un singolo oggetto. Un oggetto si specifica con la direttiva "object":type PMyObject = ^TObject; TMyObject = object MyByte: Byte; Name: String; procedure DoSomething; function Whatever: byte; end;

Notare che questo non dichiara l'oggetto che userete in seguito. Fornisce semplicemente un tipo (immaginatelo come un "formato" (template)). Potete utilizzare questo template per creare oggetti da esso. Per farlo usate:var MyObject: PMyObject; begin MyObject:= TMyObject.Create; //... MyObject.Free; end.

"MyObject" ci con cui potete lavorare. Avete anche bisogno di dire a Delphi di creare l'oggetto (create chiamato constructor). Questo riserver della memoria per esso. Quando avrete finito di utilizzarlo, dovrete liberare la memoria utilizzata, con MyObject.Free; (free il destructor). Quello che rende gli oggetti potenti che essi possono ereditare variabili e metodi (constructors, destructors, funzioni e procedure) da altri oggetti. Se avete bisogno di un oggetto che semplicemente lo stesso MyObject ma che ha una variabile addizionale FirstName: String, potete utilizzare l'ereditariet per ottenere ci:type TMySecondObject = object(TMyObject) FirstName: String; end;

Non c' bisogno di riprogrammare tutto quello che avete gi specificato in TMyObject. Il concetto di oggetto preso dai tempi del Turbo Pascal. I componenti in Delphi sono tutti delle classi. Le classi sono molto simili agli oggetti. La differenza principale nella dichiarazione. Le classi sono sempre Pointers, non c' bisogno di dichiararlo ulteriormente. PMyObject come classe dovrebbe essere simile a questo:type TMyClass = class MyByte: Byte;

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 4 of 15

Name: String; procedure DoSomething; function Whatever: byte; end;

L'ereditariet funziona allo stesso modo degli oggetti. In una classe esistono sezioni differenti: private, protected, public, e published. Esempio:type TMyClass = class private Password: String; procedure ModifyPassword; protected Username: String; public Phonenumber: String; end;

La password non deve essere visibile agli oggetti esterni (questo significa che possono accedervi solo i metodi dell'oggetto). Comunque, un membro private non cos privato come potreste pensare. Nella unit nella quale viene dichiarata la classe, anche accessibile. (E' simile alla direttiva friend del C++.) La direttiva protected piuttosto riduce le restrizioni di private. I membri protected sono visibili a tutti i discendenti della classe. I membri public sono letteralmente pubblici - sono accessibili dovunque (se la classe visibile). I membri published si comportano allo stesso modo dei public. La differenza sta nel fatto che per essi viene generata una informazione di tipo runtime. Questo significa che applicazioni esterne possono ottenere informazioni sui membri (per ulteriori dettagli consultate l'help system online di Delphi dato che non proprio una cosa di cui avete bisogno quando cominciate con Delphi). torna in alto

Dettagli sulla OOPUn oggetto pu ereditare i metodi del suo prototipo - molto bene. Ma cosa si deve fare se si vuole cambiare il comportamento di un oggetto? Mettiamo che state scrivendo un programma con alcuni elementi grafici ed avete questi oggetti:TThing = Object // ... procedure draw; end; TBox = Object(TThing) // ... procedure draw; end; TCircle = Object(TThing) // ... procedure draw; end;

TBox e TCircle sono successori di TThing perch questo facilita il disegno della vostra grafica. Potete semplicemente chiamare AThing.Draw senza sapere se AThing in realt un TBox o un TCircle. Comunque, non dovrete mai chiamare il metodo draw di TThing - cosa dovrebbe disegnare TThing? Poich TThing.Draw si presume che non venga mai chiamato, dovrete dichiararlo come un metodo abstract. Quando viene chiamato un metodo abstract il programma termina con una eccezione. Questo rende facile trovare chiamate di metodi sensa senso. La funzionalit del metodo Draw implementato solo negli oggetti successori. Essi sanno cosa sembrano e perci possono disegnare qualcosa sullo schermo.

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 5 of 15

Come fa Delphi a sapere quale metodo Draw chiamare se scrivete AThing.Draw (e AThing un TBox)? La risposta che voi dovete dichiarare i metodi che volete sovrascrivere come virtual. Semplicemente utilizzate la parola chiave virtual dietro la dichiarazione dei metodi. Pe dire a Delphi di sovrascrivere un metodo in un oggetto successore si utilizza la parola chiave override. I nostri oggetti ora appaiono come questi:TThing = Object // ... procedure draw; virtual; abstract; end; TBox = Object(TThing) // ... procedure draw; override; end; TCircle = Object(TThing) // ... procedure draw; override; end;

Come fa Delphi a trovare il metodo corretto a runtime (quando si esegue il typecasting di un oggetto)? La risposta si trova nel VMT (Virtual Method Table). Come potete indovinare dal nome si tratta di una tabella con tutti i metodi virtual dell'oggetto. Esiste una copia del VMT creata ogni volta che si eredita un oggetto (questo significa che le singole istanze non possiedono le proprie copie del VMT - avrebbe a mala pena senso). Quando chiamate un metodo virtual verr messo nel VMT e verr eseguita la corretta implementazione (nel caso facciate l'override di un metodo virtual da un oggetto progenitore). I metodi dynamic sono simili a quelli virtual. La differenza che il DMT (Dynamic Method Table) non viene copiata tutte le volte che istanziate l'oggetto. Esistono links dietro gli oggetti progenitori. Quando viene chiamato un metodo dinamico viene prima controllato nel DMT dell'oggetto stesso. Se non viene trovato viene cercato il DMT del progenitore. Quindi salva la memoria ulteriore di cui si ha bisogno per copiare tutto il VMT ogni volta che si eredita. Utilizzando i metodi dynamic ha senso solo in qualche caso speciale (oggetti con molti metodi dynamic/vitual (>100) e con molti gradi di ereditariet). In generale ci si dovrebbe attenere ai virtual.

Costanti e VariabiliCostants e Varibili vengono dichiarati allo stesso modo come nel Turbo Pascal:const MyConstant = 100; MyOtherConst: real = 1.0; var MyVar: integer; MySet: set of byte;

Notate che (cos come in Turbo Pascal) le variabili non sono inizializzate. Potete comunque dichiarare il tipo delle costanti (cosaa che non si pu fare nel Pascal standard):procedure DoSomething; const MyLocalConstant: real= 1.0; begin //... end;

Tipi Ordinal nell'Object Pascal: Nome ShortInt Byte Integer Word Range -128..127 0..255 -32768..32768 0..65535 Memoria 1 Byte 1 Byte 4 Byte 2 Byte

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 6 of 15

Cardinal Longint Currency

0..65535 -2147483648..2147483647 +/-922337203685477.5807

4 Byte 4 Byte 4 Byte

Tipi Floating-point nell'Object Pascal: Nome Real Single Double Extended Comp Strings: In Delphi 32bit (2.0, 3.0, 4.0 e ora 5) avete a disposizione le long string al posto delle vecchie string del pascal che erano limitate a 255 caratteri. L'opzione del compilatore "Huge-String" on per default. Potete metterlo su off nel tab Compiler su project options. Molte funzioni Windows utilizzano il tipo PChar. Si tratta di un puntatore ad una string che non ha una lunghezza in bytes all'inizio. Per indicare la fine della stringa si usa il byte #0-byte. Per convertire una string Pascal in un PChar si utilizza PChar(MyString). torna in alto Range 2.9*10^-39..1.7*10^38 1.5*10^-45..3.4*10^38 1.5*10^-324..1.7*10^308 5*10^-4932..1.1*10^4932 -9.2*10^18..9.2*10^18 Precisione 11-12 cifre 7-8 cifre 15-16 cifre 19-20 cifre 19-20 cifre Memoria 6 Byte 4 Byte 8 Byte 10 Byte 8 Byte

Il Typecasting Elementi del linguaggioLa maggior parte degli elementi dell'Object Pascal sono identici al Pascal normale. Vi prego di fare riferimento ad una documentazione Pascal.

Eccezionile eccezioni vengono usate per trattare eventi speciali come gli errori. Quando eseguite un programma in modalit debug (cio all'interno di Delphi), ogni volta che si incontra una eccezione si apre un dialog. Questa non il solo modo in cui il vostro programma pu rispondere alle eccezioni. Per convertire una stringa in un integer potete usare la funzione StrToInt(MyString: String). Se gli passate 'xaslk' come MyString otterrete una eccezione che vi informa che 'xaslk' non un integer. Sarebbe molto noioso se il vostro programma crashasse ogni volta che l'utente passa un valore non valido. Per intrappolare l'eccezione utilizzate:procedure Button1Click(Sender: TObject); begin try strtotint('xaslk'); except showmessage('You did not pass a valid integer value. Please try again.'); exit; finally //... end; end;

Tutto quello dopo except viene eseguito solo se avviene una eccezione. Tutti i comandi dopo finally verranno eseguiti sempre. Qui dovreste liberare le risorse, ecc. torna in alto

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 7 of 15

EventiI programmi di Windows sono event-oriented. Questo significa che il programma attende che l'utente faccia qualcosa e reagisce di conseguenza. Se l'utente preme un tasto, viene eseguito l'evento corrispondente. Molti componenti VCL hanno almento una propriet event. Il suo nome di solito formato da "On" pi una descrizione dell'evento. Cos l'evento che viene eseguito quando l'utente preme un tasto viene chiamato OnClick. E' una propriet della classe TButton. Potete controllare gli eventi dei componenti del vostro form dal tab event dell'object-inspector. Selezionate un button e guardate i suoi eventi. Troverete che ce ne sono sorprendentemente molti. OnClick di gran lunga il pi importante. Per cortesia fate riferimento al file di help di Delphi per una descrizione degli eventi. Per assegnare una azione ad un evento, semplicemente fate doppio click sul campo vuoto alla destra del nome dell'evento. Delphi aprir una procedura al posto vostro con i parametri corretti e le assegner l'evento. Il nome della procedura formato dal nome del componente e da quello dell'evento (senza "on"). Per Button1 e OnClick sar Button1Click. Per assegnare una procedura ad un evento manualmente, semplicemente usate:Component.OnEvent:= MyEventprocedure;

Dove Component.OnEvent una propriet-evento (Button1.OnClick per esempio) e MyEventprocedure la procedura da assegnare all'evento. Siate consapevoli che la procedura ha bisogno di avere gli argomenti corretti, in questo caso sar:procedure MyEventprocedure(Sender: TObject);

Per gli altri eventi potrebbe essere un po' diverso. Il modo pi semplice per trovare l'argomento di cui una procedura-evento ha bisogno di effettuare un doppio click sull'evento e vedere nel template che Delphi far al posto vostro. torna in alto

Un grande project di esempioQuesta una guida passo passo per creare un semplice editor di testo in Delphi. In questo esempio imparerete a conoscere alcuni altri componenti. Per prima cosa, create una uova applicazione scegliendo File - New Application. Vedrete un form vuotoe una finestra del codice sorgente quasi vuota. Come primo passo create il menu principale dell'editor. Per farlo fate doppio click sul componente MainMenu del tab "standard". Ora avete un menu completamente vuoto e inutile. Per aggiungere dei contenuti fate doppio click sulla sua icona. Delphi aprir il menu editor. Tutto quello che vedrete un box blu nell'angolo in alto a sinistra. Questo il primo elemento del menu. Per dargli un nome, andate nell'object inspector e cambiate la propriet "caption" in "&File". Notate che la "&" non un errore di stampa ma indica che il carattere successivo sar sottolineato. Questo carattere pu essere usato come hotkey nel vostro programma. Clickate nel menu editor fuori dal box blu. L'elemento sar rinominato in "File". Ora avete un menu vuoto sotto di esso. Rinominate il primo elemento in "&Exit". Fate doppio click su Exit per aprire il codice che viene eseguito quando l'utente clicca sull'elemento del menu. Mettete "Close;" qui. Premete F9 per compilare il vostro programma. Ora potete aggiungere altri elementi al menu utilizzando la procedura descritta prima. Chiamateli "&New", "&Open", "&Save", "Save &As", e "&Print". Potete inserire dei separatori tra di essi utilizzando "-" come caption. Aggiungete un componente RichEdit (Win32 palette) al vostro form. RichEdit un componente che permette all'utente di inserire del testo su pi linee. Pu anche cambiare gli attributi (tipo bold, italic...) ma non lo useremo. Il vantaggio di RichEdit rispetto a Memo che RichEdit fornisce automaticamente gli scrollbars. Settate la propriet "Align" del RichEdit in alClient. Questo assicurer che sar sempre grande quanto il form. Quindi selezionate la propriet lines. Vedrete un tasto con tre punti.

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 8 of 15

Cliccandolo si aprir l'editor di linea. cancellate "RichEdit1". Per permettere all'utente di selezionare il file da aprire e il nome del file da salvare, aggiungete un OpenDialog e un SaveDialog (Dialogs palette) al vostro form. Aprire un file nel RichEdit abbastanza semplice. Andate nel menu editor (doppio click ull'icona menu del vostro form), quindi fate doppio click su open. Per aprire un file nel RichEdit aggiungete il seguente codice:procedure TForm1.Open1Click(Sender: TObject); begin if opendialog1.execute then RichEdit1.Lines.LoadFromFile(Opendialog1.filename); end;

Eseguite il programma e provate ad aprire un file. Se pi largo dello schermo, vedrete che non appariranno gli scrollbars che vi aspettavate. Uscite dal programma, selezionate il RichEdit, e vedete l'object inspector. Troverete una propriet ScrollBars. E' settata a ssNone per default. Settatela a ssBoth. Lanciate il programma di nuovo. Ora il RichEdit ha semjpre gli scrollbars che non proprio quello che volevamo. Per nascondere gli scrollbars se non ce n' bisogno, settate HideScrollBars a true. Come prossimo passo aggiungeremo una variabile filename e una variabile changed al form. Filename (ovviamente) quella che contiene il nome del file che correntemente editato. Changed settata a true se l'utente ha cambiato il file. Cambiate la procedura open in:procedure TForm1.Open1Click(Sender: TObject); begin if opendialog1.execute then begin RichEdit1.Lines.LoadFromFile(Opendialog1.filename); filename:= OpenDialog1.filename; changed:= false; end; end;

E la classe TForm1 in:TForm1 = class(TForm) {components left out} procedure Exit1Click(Sender: TObject); procedure Open1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } filename: String; changed: boolean; end;

Per segnalare qualsiasi cambiamento al componente RichEdit potete usare il suo evento OnChange. Fate doppio click su di esso per editare il suo codice. Poich la variabile changed viene dichiarata nello stesso oggetto della sua procedura possiamo semplicemente mettere:procedure TForm1.RichEdit1Change(Sender: TObject); begin changed:= true; end;

Questo setter changed a true ogni volta che l'utente cambia qualcosa. Dopo implementeremo la caratteristica save. Andate al menu editor per editare il codice associato all'elemento "&Save" del menu. La propriet lines di TRichEdit una TStrings. Questa classe ha un sacco di propriet, incluso caricare e salvare in e da un file (vedere il file help per maggiori informazioni).procedure TForm1.Save1Click(Sender: TObject); begin if (filename'') and (changed= true) then begin RichEdit1.Lines.SaveToFile(Filename); changed:= false; end; end;

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 9 of 15

Ora l'utente ha la possibilit di salvare i cambiamenti che ha fatto al file. Non pu ancora salvare il file con un nome diverso. Cambiamo il codice:procedure TForm1.SaveAs1Click(Sender: TObject); begin if SaveDialog1.Execute then begin RichEdit1.Lines.SaveToFile(SaveDialog1.Filename); filename:= SaveDialog1.Filename); changed:= false; end; end;

Probabilmente avrete notato che non ci sono tipi di files nel SaveDialog (non ce ne sono neanche nell'OpenDialog). Per cambiare ci, selezionate il dialog e edittate la propriet filter. Implementare la funzione new piuttosto semplice. Tutto quello che dovete fare di chiedere all'utente se vuole salvare (solo se il file stato cambiato) e quindi cancellare il RichEdit.procedure TForm1.New1Click(Sender: TObject); begin if changed= true then begin if MessageDlg('Do you want to save the current file?', mtWarning,[mbYes, mbNo],0)= idYes then Save1Click(self); RichEdit1.Clear; end else RichEdit1.clear; end;

La prossima la procedura per la stampa. Stampare veramente semplice - grazie a RichEdit. Basta chiamare il metodo TRichEdit.Print. Potete perfino passare un titolo per il lavoro di stampa. Per questo scopo useremo il nome del file. Stampiamo il documento sulla stampante standard.procedure TForm1.Print1Click(Sender: TObject); begin Richedit1.print(filename); end;

Adesso forniamo le funzioni di editing standard. Creiamo un nuovo menu top-level chiamato "&Edit" con submenu "Cu&t", "&Copy", "&Paste" e "C&lear". Tutte queste funzioni sono facilissime da implementare perch TRichEdit le fornisce tutte. Tutto quello che dovete fare di collegare le funzioni RichEdit al vostro menu:procedure TForm1.Cut1Click(Sender: TObject); begin RichEdit1.CutToClipboard; end; procedure TForm1.Copy1Click(Sender: TObject); begin RichEdit1.CopyToClipboard; end; procedure TForm1.Paste1Click(Sender: TObject); begin RichEdit1.PasteFromClipboard; end; procedure TForm1.Clear1Click(Sender: TObject); begin RichEdit1.Clear; end;

Ora abbiamo pi o meno il notepad standard di Windows. Non c' voluto molto, eh? Aggiungiamo un paio di caratteristiche addizionali all'editor. Primo un "&Options" menu con un submenu "&Font". Fortunatamente non avremo bisogno di scrivere il dialog per selezionare il font. Delphi/Windows lo fanno per noi. Il componente situato nella palette "dialogs". Il codice per utilizzarlo pi o meno questo:

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 10 of 15

procedure TForm1.Font1Click(Sender: TObject); begin if FontDialog1.Execute then RichEdit1.Font:= FontDialog1.Font; end;

torna in alto

Migliorare l'esempioIn molti programmi Windows le funzioni pi importanti possono essere lanciate non solo attraverso il menu, ma anche tramite hotkeys e un toolbar. Gli hotkeys sono molto semplici. Settate semplicemente la propriet "shortcut" di un elemento del menu in qualsiasi cosa volete. Per ottenere un toolbar nel vostro form avete bisogno di aggiungere un componente ToolBar dalla palette Win32. Con un click del tasto destro del mouse potete aggiungere nuovi tasti. Le immagini sui tasti sono forniti da un componente chiamato ImageList. Potete trovarlo nella palette Win32. Aggiungete un ImageList al vostro form. Per aggiungere immagini all'ImageList fate doppio click su di esso e scegliete add. Prima avete bisogno di creare un paio di immagini (per i tasti: new, open, save, print, font). Utilizzate il picture editor (tools menu in Delphi). Scegliete New - Bitmap e createle 20x20. Salvate i bitmaps nella stessa directory del vostro progetto. Aggiungete tutti i bitmaps nell'ImageList. Settate la propriet "Images" del toolbar nella vostra ImageList (ImageList1). Settate l'ImageIndex di ogni toolbutton nel valore corretto. Per collegare i tasti del toolbar alle funzioni che avete gi scritto, semplicemente fate doppio click sui tasti. Chiamate le vostre funzioni da qui. Per il tasto open sar:procedure TForm1.ToolButton2Click(Sender: TObject); begin Open1Click(self); end;

Self un puntatore all'oggetto del quale self una propriet. Immaginatelo come un loop: punta dietro di s (TForm1 in the example). All'inizio potr sembrare strano, ma risulter veramente utile per i casi come questo. Nelle vere applicazioni gli elementi del menu che al momento non hanno senso sono grigi. Dovremmo farlo per Save. E' facile da ottenere. Ogni volta che il file viene cambiato, avr senso salvarlo. Quindi dobbiamo abilitare Save dopo changed:= true e di disabilitarlo dopo changed:= false. Mettete solo una linea come la seguente:Save1.enabled:= false;

dopo ogni changed:= false. (Save1.enabled:= true dopo changed:= true) e settate enabled a false nell'object inspector. Attualmente la funzione save as semplicemente sovrascrive i files esistenti. Per aggiungere un dialog box che chiede all'utente se voglia o meno sovrascrivere un file esistente, dovete semplicemente controllare se un file con lo stesso nome gi esiste. Per farlo utilizzate FileExists:procedure TForm1.SaveAs1Click(Sender: TObject); begin if SaveDialog1.Execute then if FileExists(SaveDialog1.Filename) then if MessageDlg('Do you want to overwrite the existing file?', mtWarning,[mbYes, mbNo],0)= idYes then begin RichEdit1.Lines.SaveToFile(SaveDialog1.Filename); filename:= SaveDialog1.Filename; changed:= false; end else begin RichEdit1.Lines.SaveToFile(SaveDialog1.Filename); filename:= SaveDialog1.Filename; changed:= false; end; end;

Per prima cosa, viene mostrato il SaveDialog. Se l'utente immette il nome di un file e preme yes, il

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 11 of 15

programma controlla se il file gi esiste. Se esiste, viene chiesto all'utente se vuole sovrascrivere il file. In MessageDlg viene passato il testo nel dialog box, il "tipo" del box (mtWarning in questo caso), e una combinazione di tasti da mostrare. Restituisce l'ID del tasto che stato cliccato (idYes). Non molto utile avere la possibilit di cambiare alcune opzioni del programma se poi l'utente deve rifare le stesse operazioni tutte le volte che riavvia il programma. Quello che ovviamente ci serve un modo per salvare le opzioni. Bill Gates vuole che voi le salviate nel registro di Windows. Se non volete farlo si presume almeno che mettiate il vostro file di configurazionenella directory c:\windows directory. Ora, andate nell'Explorer, nella directory c:\windows e provate a cercare le applicazioni che hanno creato tutti i files che ci sono (io ne ho contate circa 400 anche se provo a ripulirla di tanto in tanto). Il punto : NON scrivete niente nel registro (guardatevelo con regedit.exe, gi enorme) o una directory che debba appartenere al vostro programma a meno di non avere una ragione particolare per farlo. Quale danno pu fare se il vostro programma salva la sua configurazione nella propria directory? Se l'utente vuole cancellare il programma deve semplicemente cancellare la directory per essere sicuro di aver fatto tutto e che non ci saranno effetti collaterali. Delphi fornisce una classe che aiuta ad occuparsi dei fiels di configurazione (chiamati in Windows files *.ini). La classe chiamata TIniFile ed incapsula tutte le funzionalit di cui di solito si ha bisogno per salvare le opzioni in un file. Fornisce lettura e scrittura di string, integer, booleans e organizza anche il vostro file ini in sezioni. Quando il vostro programma termina vogliamo che salvi le opzioni. L'evento TForm.OnClose si ha quando si chiude un form. Agganciatelo e piazzateci il codice seguente:procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); var AIniFile: TIniFile; begin AIniFile:= TIniFile.Create(IniDir+'\'+'editor.ini'); with AIniFile do begin WriteString('Config', 'FontName', RichEdit1.Font.Name); WriteInteger('Config', 'FontSize', RichEdit1.Font.Size); WriteInteger('Config', 'Left', Left); WriteInteger('Config', 'Top', Top); WriteInteger('Config', 'Width', width); WriteInteger('Config', 'Height', height); end; AIniFile.Free; end;

Abbiamo anche bisogno di aggiungere una variabile IniDir: String alla classe TForm1. Viene usata per salvare la directory che era la directory corrente quando il programma stato lanciato (l'utente pu cambiarla).Come potete vedere dal codice, AIniFile ha bisogno di essere inizializzato prima di utilizzare TIniFile.create(PATHNAME);. Quindi le opzioni vengono scritte nel file. Alla fine AIniFile viene rilasciato. Leggere le informazioni qualcosa di pi difficile, perch non si pu solamente agganciare l'evento OnCreate e quindi leggere e settare le opzioni. Quando si presenta TForm1.OnCreate, RichEdit ancora non stato creato. Avete bisogno di ritardare il processo. Aggiungete un componente timer dalla palette "system" al vostro form. Settate la sua propriet interval a 5 ( misurato in millisecondi). Il componente ha soltanto un evento: OnTime (si presenta quando l'intervallo scade). Ponete il seguente codice nella sua procedura:procedure TForm1.Timer1Timer(Sender: TObject); var AIniFile: TIniFile; begin AIniFile:= TIniFile.Create(getcurrentdir+'\'+'editor.ini'); IniDir:= getcurrentDir; with AIniFile do begin RichEdit1.Font.Name:= ReadString('Config', 'FontName', 'Courier New'); RichEdit1.Font.Size:= ReadInteger('Config', 'FontSize', 10); left:= ReadInteger('Config', 'Left', 0); top:= ReadInteger('Config', 'Top', 0); width:= ReadInteger('Config', 'width', 0); if width= 0 then width:= screen.width - 50; height:= ReadInteger('Config', 'Height', 0);

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 12 of 15

if height= 0 then height:= screen.height - 50; end; AIniFile.Free; Timer1.Interval:= 0; Timer1.Free; Timer1:= Nil; end;

Per prima cosa viene inizializzato AIniFile. Il file viene immagazzinato nella directory corrente (determinata tramite GetCurrentDir) e chiamato 'editor.ini'. Quindi la directory corrente viene salvata nella variabile IniDir. Le opzioni vengono lette. Come ultimo passo l'intervallo del timer viene settato a 0 cos non si presenter nessun altro evento OnTimer. Siccome non avremo pi bisogno del timer possiamo liberarlo. Aiuta molto settare gli oggetti da liberare a Nil. Se dopo vogliamo controllare se un Object inizializzato si pu semplicemente controllare che MyObjectNil. torna in alto

Help filesUna vera applicazione di solito include anche un file di help. Se volete crearne uno per il vostro programma fate riferimento all'altra documentazione. Sarebbe off-topic discuterne qui.

ApprofondimentiThreadsI threads sono parti di un programma che possono essere eseguite "simultaneamente". Esistono running time assegnati dal sistema operativo. Di solito un progetto Delphi utilizza solo un thread (viene creato senza che se ne sappia niente). Questo il thread principale. Quando termina l'intero programma si ferma. I threads sono utili se volete effettuare in background dei tasks che consumano tempo, mentre l'utente pu continuare ad usare il programma. Questo era qualcosa di difficile da ottenere in Windows a 16-bit. Windows a 32-bit ora fornisce dei threads che liberano il programmatore dal compito di coordinare il tutto. Non creer un progetto di esempio per i threads ma tratter solo quello fornito con Delphi. Potete trovarlo nella directory Delphi3\Demos\Thread. Caricatelo e eseguitelo per vedere cosa fa. Ora date un'occhiata al codice, specialmente la unit SortThds. Nel type block troverete una classe chiamata TSortThread. Essa eredita da TThread che una classe fornita con Delphi. Essa incapsula l'oggetto Windows Thread, quindi non avete bisogno di fare chiamate a funzioni di Windows.TSortThread = class(TThread) private FBox: TPaintBox; FSortArray: PSortArray; FSize: Integer; FA, FB, FI, FJ: Integer; procedure DoVisualSwap; protected procedure Execute; override; procedure VisualSwap(A, B, I, J: Integer); procedure Sort(var A: array of Integer); virtual; abstract; public constructor Create(Box: TPaintBox; var SortArray: array of Integer); end;

Il metodo pi importante la procedura execute. Viene chiamata quando parte il thread e esegue i calcoli (o chiama le funzioni che eseguono i caloli). Pi in basso ci sono pi thread classificati che definiscono il tipo di sorting da fare. Questi sono quelli che vengono usati dal programma. Lo scopo di TSortThread di fornire una funzionalit condivisa da tutti i differenti threads di sorting. Se avete in esecuzione pi di un thread ( sempre il caso quando create un thread da soli), c' pericolo che tutti i threads vogliano accedere ai dati simultaneamente. Questo avr come risultato un conflitto con risultati imprevedibili. Per evitare ci la classe TThread ha un metodo chiamato synchronize. Esso sincronizza le attivit dei threads. Gli viene passata come parametro una procedura che deve essere

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 13 of 15

sincornizzata. Nel programma di esempio VisualSwap ci sono tutte le procedure critiche. Quindi il threads chiamaSynchronize(DoVisualSwap);

per sincronizzare. I parametri per VisualSwap sono contenuti nell'oggetto perch non si pu passare a Synchronize una procedura con parametri. Ora date un'occhiata all'altra unit: ThSort. La procedura StartBtnClick inizializza Threads:procedure TThreadSortForm.StartBtnClick(Sender: TObject); begin RandomizeArrays; ThreadsRunning := 3; with TBubbleSort.Create(BubbleSortBox, BubbleSortArray) do OnTerminate := ThreadDone; with TSelectionSort.Create(SelectionSortBox, SelectionSortArray) do OnTerminate := ThreadDone; with TQuickSort.Create(QuickSortBox, QuickSortArray) do OnTerminate := ThreadDone; StartBtn.Enabled := False; end;

Non dovete farlo nel modo in cui fatto qui. Potreste anche usare://... var MyThread: TBubbleSort; //... begin MyThread:= TBubbleSort.Create(BubbleSortBox, BubbleSortArray); MyThread.OnTerminate:= ThreadDone; //...

Questo solo utile se avete bisogno del puntatore al thread in seguito. Avete bisogno di questo puntatore per cambiare la priorit del Thread nel corso del programma. Ogni thread ha una propriet priority che potete settare in sei valori (presi dal file help):TThreadPriority = (tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical);

Potete cambiarli ogni volta che volete. torna in alto

Utilizzo delle DLLNota: Questa solo un'introduzione veramente basilare. Se avete bisogno di ulteriori dettagli, fate riferimento al sistema di help di Dephi. Ci troverete una buona serie di articoli. Una DLL - come un eseguibile - un modulo di un programma compilato. Comunque, non pu essere eseguito da solo ma piuttosto una collezione di funzioni che vengono chiamate da programmi esterni. L'abbreviazione DLL significa Dynamic Link Library. Non viene compilata in un file EXE a compiletime ma linkata in esso a run-time. Poich le DLL sono indipendenti dal linguaggio di programmazione che usate (beh, quasi) ci sono un paio di cose che dovreste conoscere: Per chiamare una funzione di una DLL il programma chiamante deve conoscere il nome della funzione. Questo un problema con alcuni compilatori C++ che aggiungono informazioni sul tipo della funzione nel nome della funzione stessa. I tipi dei parametri devono essere identici (o almeno compatibili) in entrambi i linguaggi. Se volete chiamare una funzione di una DLL che utilizza il tipo int del C come Parameter, dovete renderlo un integer nel vostro programma Pascal.

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 14 of 15

Il programma chiamante e la DLL devono utilizzare le stesse convenzioni di chiamata. Questo significa che i parametri devono essere passati nello stesso ordine.

Funzioni di importazione - un semplice esempioEsiste una DLL di Windows chiamata USER32.DLL che include la funzione MessageBox. Per utilizzare questa funzione nel vostro programma dovete dire al compilatore di importare dalla DLL:function MessageBox(HWnd: Integer; Text, Caption: PChar; Flags: Integer): Integer; stdcall; external 'user32.dll' name 'MessageBoxA';

Aprite il file Win32.hlp nella directory Delphi\Help e date un'occhiata alla descrizione della funzione. Vedrete come i parametri sono adattati ai tipi di Delphi. La parola "stdcall" dopo la dichiarazione normale della funzione costringe il compilatore ad usare le convenzioni di chiamata del C. "external" dice al compilatore di non cercare la funzione in una unit, ma piuttosto nel file esterno specificato (una DLL in questo caso). Dopo external passate il nome della DLL. Notate che deve essere nella directory corrente \Windows, o \Windows\System. Se il nome che utilizzate in Pascal diverso dal nome della funzione della DLL dovete specificare il vero nome della funzione. Sappiate che il C case sensitive e che il nome della vostra funzione in Pascal deve essere corretto.

Scrivere DLL in DelphiScrivere le vostre DLL in Delphi veramente semplice. Ci sono solo alcune cose da tenere in considerazione, che vi saranno chiarite con quest'esempio:library Test; uses MyUnit; exports MyFunction name 'MyFunction'; begin end.

Naturalmente questo funziona solo se MyFunction dichiarata in MyUnit. torna in alto

Libri sul DelphiUn libro tedesco veramente buono sul Delphi "Delphi 3" di Elmar Warken (ISBN 3-8273-1238-8).

AlgoritmiPotete trovare informazioni su algoritmi specifici anche in questo sito. cercate nella sezione "texts and articles" in Delphi main page. Inoltre, un buon libro sugli algoritmi "Algorithms" di Robert Sedgewick. Non conosco il numero ISBN per la versione inglese

Per commenti scrivetemi! 17.5.98 Sebastian Boung Home Traduzione: Papero - IDR 1999 Eng?Ita! Team

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010

Learning Delphi

Page 15 of 15

http://gpi.eden.it/idr

file://C:\Documents and Settings\simona.porru\Desktop\delph\tutorial.html

10/12/2010