CORSO DI PROGRAMMAZIONE DELPHI

Pagina creata da Greta Nigro
 
CONTINUA A LEGGERE
CORSO DI PROGRAMMAZIONE DELPHI
Benvenuti nel mio interessantissimo corso dedicato a tutti coloro che non hanno MAI avuto a che
fare con variabili, cicli o linguaggi. Chi già possiede diverse basi nella programmazione troverà
questi primi capitoli superflui, tuttavia invito ad attendere i futuri sviluppi, o di leggere la parte
relativa ai Tips & Tricks! Qualsiasi suggerimento per il miglioramento di questo corso è ben
accetto... Al fine della completa trattazione è necessario:

   •   Una copia di Delphi (possibilmente versione 2 o successiva)
   •   File Help di Delphi

Introduzione
Questo testo nasce come risposta ad una delle più frequenti domande poste nell’ambito informatico:
come si costruisce un programma. Molti sono affascinati dall’intrigante arte della codifica ma, o per
mancanza di tempo, o per scarsità di volontà, non affrontano il grande passo della stesura di un
programma. Molti si chiedono, giustamente, l’utilità di saper scrivere codice in un’era in cui ci
troviamo di fronte a prodotti già pronti e in cui ogni tipo di software immaginabile è già stato scritto
da qualcuno; la risposta non è così semplice, la programmazione è un’arte, per alcuni è considerata
alla stregua di un hobby, e per altri è un lavoro, chi non ha mai provato l’ebbrezza della stesura di
una utility innovativa non può in ogni caso capire... Ma questo testo nasce appunto per questo, il
poter apprendere la programmazione da zero.
Si deve innanzi tutto notare che il linguaggio scelto è stato il Pascal, perché è forse quello che offre
miglior rapporto tra prestazioni e difficoltà, tuttavia anche il Visual Basic, specie con l’avvento
delle nuove versioni potrebbe divenire un ottimo strumento, ma ora come ora, il Pascal si colloca
ancora un gradino sopra di detto tool, specie con l’avvento del Delphi; non è comunque da
escludere anche il C++ Builder, il “cugino” di Delphi.

Disclaimer
Questo corso è stato creato interamente da Vanni Brutto (asytnt@tin.it). Potete trovarne una
versione online all'indirizzo http://www.geocities.com/SiliconValley/Lab/6806/. I files che troverete
nello zippato 'corso.zip' sono protetti dal diritto d'autore e sono liberamente riproducibili a
condizione di non farne uso commerciale o economico o per fine di lucro senza la preventiva
autorizzazione dell'autore. In ogni caso deve sempre essere indicato il nome dell'autore e il suo
indirizzo. Ogni altra modalità di utilizzo deve considerarsi contraria alla volontà dell'Autore.
Inoltre, l'Autore non si riterrà responsabile per danni di qualsiasi genere, diretti o indiretti, causati
dall'utilizzo dei suddetti files. LI USATE A VOSTRO RISCHIO.

Nota dell'impaginatore :) (idr@mail.xoom.it)
Ciao! Sono Francesco e questa che state leggendo è la versione riveduta e corretta (nella forma, non
nei contenuti) del corso sul Delphi di Vanni Brutto. Per farla ho chiesto e ottenuto l'autorizzazione
di Vanni. Se volete mettere questi files sul vostro sito, gradirei che me lo comunicaste e che
metteste anche un link al mio sito e a quello di Vanni, dato che ci è costato tempo e fatica ;).
L'indirizzo del mio sito è http://gpi.eden.it/idr (The Italian Delphi Repository), mentre quello di
Vanni lo trovate un po' più su. Ciao e grazie per la collaborazione!

                                                                                                       1
Prima parte: breve introduzione al Turbo Pascal (sintassi e strutture)
Capitolo 1
Un po’ di storia
Il Pascal è un linguaggio ad alto livello, che tenta in pratica di avvicinarsi per quanto possibile al
ragionamento umano. Esempi di linguaggi ad alto livello sono C, C++, Basic, Basic strutturato,
Cobol e Fortran; una delle caratteristiche che differenzia il Pascal da alcuni dei suddetti linguaggi è
la possibilità di scrivere codice a basso livello, in altre parole righe di programmazione che vengono
scritte nel linguaggio della CPU. Il Pascal nasce per merito di N. Wirth che per primo introdusse la
sintassi Pascal, in seguito nel 1970 l’uso del Pascal si estese nell’ambito universitario e scientifico,
ma si deve scorrere all’incirca fino agli anni ‘80 per arrivare al primo compilatore1 di Turbo Pascal
scritto da Anders Hejlsberg. I programmatori Pascal hanno apprezzato attraverso gli anni
l’eleganza, nonché la velocità e la stabilità offerta da questo compilatore. Il Turbo Pascal
rappresentò per l’epoca la giusta via di mezzo tra l’efficiente ma complesso Assembly2 e altri
linguaggi ad alto livello (basic soprattutto), ma non con tali prestazioni. Negli anni il T.P. si evolse,
di versione in versione, fino all’eccezionale versione 7.0 (includente anche Turbo Vision 2.0),
completamente orientato agli oggetti, e tutt’oggi uno dei migliori pacchetti per la scrittura di
software gestionali per DOS. Con l’avvento del Windows, la Borland rilasciò la prima versione di
Borland Pascal, un pacchetto basato sul linguaggio Object Pascal, naturale evoluzione del Turbo
Pascal; tuttavia la stesura di applicazioni Windows in Object Pascal era alquanto lenta e complessa,
il programmatore doveva avere ottime conoscenze di T.P., nonché delle OWL3 e le immancabili
API4 del Windows. Per questo la Borland rilasciò nel mercato Delphi e successivamente Delphi
2.0, la versione riveduta e corretta a 32-bit del primo. Delphi introdusse il concetto di
programmazione Visuale e orientata agli eventi tipica del Visual Basic, ma senza trascurare i
vantaggi della compilazione Pascal. Nel corso del ‘97 la Borland ha creato pure un ambiente di tipo
R.A.D. per il C++ (C++ Builder) molto simile al Delphi; attualmente siamo giunti alla versione 3.0
di Delphi, e sicuramente il futuro riserverà altre sorprese, tuttavia voglio fare notare che il codice
scritto in Delphi è conferme all’Object Pascal, di cui ha ereditato pure il numero delle versione, la
versione 8.0 fu, infatti, del Delphi 1.0 e la successiva 9.0 del Delphi 2.0.

Il primo programma in Turbo Pascal.
Si noti che in questo corso si inizierà usando la programmazione tipica del Turbo Pascal per
passare, poi, a quella Delphi. Questo è fatto volutamente per dare la possibilità anche a coloro che
non conoscono nulla di programmazione a capire il funzionamento di detto compilatore.
Da quando Brian Kernighan e Dennis Richie hanno realizzato nel 1978 il linguaggio di
programmazione C, il tradizionale primo programma è stato quello di visualizzare Hello World!
(Ciao gente!) sullo schermo. Chi se la sente di interrompere questa tradizione?

   1.   Avviare Delphi
   2.   Scegliere close all dal menu file e chiudere tutti i files eventualmente aperti
   3.   Dal menu file scegliere new e quindi Text
   4.   Salvare il file come Hello.dpr (Delphi Project (*.dpr))
   5.   Scrivere il programma in turbo pascal facendolo precedere dalla seguente riga: {$APPTYPE
        CONSOLE}

                                                                                                       2
{$APPTYPE CONSOLE}

{Hello World! App, tutto quello che è tra parentesi graffe non viene letto dal
compilatore}

Program    Hello;    {Program     va   seguito     dal   nome    del    file    del   programma}

Uses
  Forms;
Begin {Inizio del programma}
  WriteLn(‘Hello World’); {WriteLn si usa per scrivere sul video}
  ReadLn;{ReadLn si usa per leggere da tastiera}
End. {Fine del programma}

Se vi siete ripresi dal trauma causato dall’avvio di una finestra DOS possiamo continuare con
qualcosa di più... semplice...

Creare un programma come segue:

{$APPTYPE CONSOLE}

Program Prova;
Uses
  Forms;
Begin
End.

Il file andrà poi salvato con il nome prova ed estensione dpr. La parola riservata Begin indica
l’inizio del programma e deve corrispondere con un seguente End; si dovrà ricordare fin dora che in
Pascal i blocchi di codice andranno definiti sempre tramite un Begin e un End.
Si provi ora ad eseguire il programma tramite la voce Run del menu Run... Passata la compilazione
non accadrà un bel niente, questo perché questo programma non fa assolutamente nulla!
L’importante è osservare che ogni programma deve iniziare con la riga Program contente il nome
del file da salvare e si dovrà SEMPRE aggiungere la riga iniziale {$APPTYPE CONSOLE} per
indicare a Delphi che si sta lavorando in modalità DOS, inoltre si dovrà sempre aggiungere la riga
Uses Forms, è inutile al file dell’esecuzione, ma serve per caricare il file.

Miglioramenti del primo programma
Si modificherà ora il primo programma creato in precedenza come segue:

{$APPTYPE CONSOLE}
{Questo è il secondo programma, tutto quello che è tra parentesi graffe non
viene
letto dal compilatore}
Program P2; {Program va seguito dal nome del file del programma}
Begin {Inizio del programma}
  WriteLn(‘PROGRAMMA P2’); {WriteLn si usa per scrivere sul video}
  WriteLn(‘Questo è semplicemente il mio secondo programma’);
  WriteLn;
  WriteLn(‘Premere INVIO per terminare il programma’);
  ReadLn;{ReadLn si usa per leggere da tastiera}
End. {Fine del programma}

                                                                                                 3
Questo programma è visivamente più complesso del primo, ma nella realtà non è nulla di
particolarmente difficile, ogni programma per Turbo Pascal dovrebbe cominciare con Program
seguito dal nome del file, il carattere di punto e virgola finale non è messo a caso, ogni riga di
Turbo Pascal dovrebbe finire con un carattere tale, tranne poche eccezioni (tra le quali Begin e
End); l’istruzione WriteLn scrive la stringa1 contenuta tra gli apici, WriteLn è un metodo e va
quindi seguito dall’apertura e la chiusura di parentesi rotonde. Provate ora a modificare il
programma aggiungendo altre frasi o ricopiando più volte alcune istruzioni per vedere l’effetto
creato.

       TIP
       Nota per gli utilizzatori di Delphi: è possibile eseguire programmi scritti per Turbo Pascal
       anche in Delphi, si dovrà però seguire la seguente procedura

       1.   Avviare Delphi
       2.   Scegliere close all dal menu file e chiudere tutti i files eventualmente aperti
       3.   Dal menu file scegliere new e quindi Text
       4.   Salvare il file come Delphi Project (*.dpr)
       5.   Scrivere il programma in turbo pascal facendolo precedere dalla seguente riga:
            {$APPTYPE CONSOLE}

Si esamini ora il seguente programma:

{$APPTYPE CONSOLE}

Program P3;
Begin
  WriteLn(‘PROGRAMMA P2’); {WriteLn si usa per scrivere sul video}
  Begin
     WriteLn(‘Questo è semplicemente il mio secondo programma’);
     WriteLn(‘’);
  End;
  WriteLn(‘Premere INVIO per terminare il programma’);
  ReadLn;
End.

Il programma P3 svolge le stesse funzioni di P2, l’unica differenza risiede nel fatto che il secondo
WriteLn è preceduto da un Begin, questo perché si è voluto creare un nuovo blocco di programma.
Si osservi inoltre che il terzo WriteLn è stato sostituito da WriteLn(‘’), nella realtà le due righe di
codice sono equivalenti(!).

                                                                                                     4
Capitolo 2
Le variabili e i calcoli matematici
Presentazione
Per determinare il volume di una barra cilindrica, dobbiamo conoscere la superficie della sezione, e
moltiplicarla per la lunghezza. Osservate il disegno:
superficie della sezione = 3,14159xRxR
volume della barra=superficie della sezione x L = 3,14159xRxRxL

Vediamo come il volume di una barra dipenda in generale da due grandezze: il raggio R e la
lunghezza L. Il programma seguente calcola il volume di una area cilindrica ma questa volta con i
valori:

L=5
R=7

Il programma:

{$APPTYPE CONSOLE}
Program Volume;
Const
Pgreco = 3.1415926535897932385;
Var
R,
L,
Sup : Real;
V : Integer;

begin
  L:= 5;
  R:= 7;
  Sup:= PGreco*R*R;
  V:= Round(Sup*L);
  WriteLn(V);
  ReadLn;
end.

Andiamo ad osservare riga per riga. Nella prima riga si legge: Program Volume; Questa riga serve
ad indicare al compilatore che il programma risiede nel file Volume.dpr
Successivamente si trova la parola riservata Const, questa è seguita dal nome di una costante che
viene inizializzata per un certo valore e cioè il numero corrispondente al Pi. La parola riservata Var
serve invece ad indicare la dichiarazione di variabili, questa serve ad indicare al compilatore di
assegnare un "pezzettino" di memoria per l’inserimento di tre variabili numeriche con la virgola
(Real) ed una variabile numerica intera (Integer). Successivamente nel blocco Begin End troviamo
l’assegnazione di 5 per la variabile L e di 7 per la variabile R, l’assegnazione di un valore ad una
variabile avviene sempre tramite l’operatore :=
Con Sup:= PGreco*R*R si indica al compilatore di moltiplicare Pgreco per il quadrato del raggio e
assegnare il valore alla variabile Sup. Infine con V:= Round(Sup*L) si indica di moltiplicare la
superficie per l’altezza, arrotondare il risultato, e assegnarlo alla variabile V che viene
successivamente passata alla funzione WriteLn dove verrà scritta sullo schermo.

Ora si vedrà lo stesso programma riprodotto in maniera leggermente diversa:

                                                                                                    5
{$APPTYPE CONSOLE}
Program Area;
Const
  Pgreco = 3.1415926535897932385;
Var
  R,
  L,
  V: Real;

begin
  L:= 5;
  R:= 7;
  V:= PGreco*R*R*L;
  WriteLn(V:0:0);
  ReadLn;
end.

Come si può notare il programma è stato reso leggermente meno leggibile, tuttavia il risultato sarà
uguale, l’unica sostanziale differenza sta nel fatto che la variabile V è divenuta di tipo real e che per
essere scritta tramite WriteLn in maniera decimale si è dovuto ricorrere al suffisso :0:0, non è
importante capire cosa serva tale suffisso, l’importante è capire che per scrivere un numero Real
tramite WriteLn si dovrà ricorrere ad esso! Non preoccupativi per la difficoltà di programmazione
in DOS, appena conoscerete queste semplici basi la programmazione in Windows sarà uno scherzo!

                                                                                                       6
Capitolo 3
WriteLn, Write e ReadLn: questi sconosciuti

WriteLn e Write
La prima istruzione che descriveremo sarà l’istruzione WriteLn, questa istruzione scrive sul video e
riporta il cursore a capo, la differenza tra Write è abbastanza evidente, Write non riporta il cursore a
inizio riga.

ReadLn
ReadLn legge un valore dalla periferica standard, di solito dalla tastiera, così l’istruzione
ReadLn(Prova), dove prova è una variabile dichiarata stringa, leggerà una frase da tastiera.

Con questi piccoli apprendimenti si potrà migliorare il programma del secondo capitolo in modo
sostanziale:

{$APPTYPE CONSOLE}
Program Area;

Const
  Pgreco = 3.1415926535897932385;

Var R,
    L,
    V : Real;

begin
  WriteLn;
  WriteLn;
  WriteLn;
  WriteLn;
  WriteLn;
  WriteLn;
  WriteLn;
  WriteLn ('CALCOLO DEL VOLUME DI UN CILINDRO);
  WriteLn;
  Write('Inserire la lunghezza del cilindro ->');
  ReadLn(L);
  Write('Inserire il raggio del cilindro ->');
  ReadLn(R);
  V:= PGreco*R*R*L;
  WriteLn;
  WriteLn;
  WriteLn('Il volume del cilindro è: ', V:0:0);
  WriteLn;
  WriteLn('premere INVIO per continuare');
  ReadLn;
end.

Il programma in questione è un notevole passo avanti, si può infatti calcolare il volume di un
qualsiasi cilindro!

                                                                                                      7
Capitolo 4
Tipi di variabili
Nella programmazione Pascal si dovrà imparare le sottili differenze che esistono tra le variabili
numeriche, qui di seguito riporto un estratto della guida ufficiale di Delphi:

Qui di seguito vengono elencati i tipi interi, che non accettano cioè la virgola.
Type      Range                         Format
Integer -32768..32767                   Signed 16-bit
Cardinal 0..2147483647                  Unsigned 32-bit
Shortint -128..127                      Signed 8-bit
Smallint -32768..32767                  Signed 16-bit
Longint -2147483648..2147483647 Signed 32-bit
Byte    0..255                  Unsigned 8-bit
Word    0..65535                Unsigned 16-bit

Qui di seguito vengono elencati i tipi reali, che ovviamente possono essere utilizzati come interi,
tuttavia sono molto più lenti (non più di tanto tuttavia).
Type       Range                                              Significant digits Size in bytes
Real       2.9 x 10-39 .. 1.7 x 1038                          11-12              6
Single     1.5 x 10-45 .. 3.4 x 1038                          7-8                4
Double 5.0 x 10-324 .. 1.7 x 10308                            15-16              8
Extended 3.4 x 10-4932 .. 1.1 x 104932                        19-20              10
Comp       -263+1 .. 263 -1                                   19-20              8
Currency -922337203685477.5808.. 922337203685477.5807 19-20                      8

Per dichiarare una variabile ricordo che si deve utilizzare la dicitura Var nome_variabile: tipo; ad
esempio

Var Var1,Var2,
    Var3 : Integer;
    R1,
    R2,
    R3   : Real;

Le Stringhe: giochiamo con le lettere
Un tipo particolare che merita una trattazione a parte sono le stringhe: dovete pensare ad una stringa
come una linea di un quaderno nella quale potete immettere testo, numeri nonché caratteri come
linee apostrofi etc. Il compilatore considererà stringa tutto ciò che trova tra due apici, ad esempio

                                                                                                    8
quando è stato mostrata la sintassi di WriteLn si è detto che il testo andava immesso tra due apici,
questo perché altro non era che una stringa!
L'esempio che segue chiarisce l'utilizzo delle stringhe.

{$APPTYPE CONSOLE}
Program Stringhe;

Uses
  Forms;

Var Nome: String;

Begin
  Write('Inserisci il tuo nome: ');
  ReadLn(Nome);
  WriteLn;
  WriteLn;
  Write('Benvenuto ');
  Write(Nome);
  WriteLn(' nel fantastico mondo della programmazione Pascal');
  Nome:= Nome + ' premi invio per continuare';
  WriteLn(Nome);
  ReadLn;
End.

Il programma non è poi niente di così complesso: si limita a chiedere una stringa e rivisualizzarla
successivamente, appare più interessante l'uso di Nome:= Nome + ' premi invio per continuare',
questa istruzione altro non fa che accodare al nome precedentemente immesso un altro pezzo di
stringa. Si descriveranno qui di seguito alcuni metodi usati frequentemente con le stringhe:

AnsiUpperCase
AnsiUpperCase serve per rendere maiuscola una stringa, l'esempio che segue chiarirà meglio
l'utilizzo:

{$APPTYPE CONSOLE}
Program Stringhe;

Uses
  SysUtils;

Var S: String;

Begin
  Write('Inserisci una stringa: ');
  ReadLn(S);
  WriteLn;
  WriteLn;
  WriteLn(AnsiUpperCase(S) + ' questa stringa è stata passata a maiuscola');
  WriteLn('premi invio');
  ReadLn;
End.

La prima volta che si guarda il listato si potrebbe essere messi in crisi dalla sostituzione di Uses
Forms con Uses SysUtils, nella realtà questo avviene in quanto la funzione AnsiUpperCase è
dichiarata nella unit SysUtils, ad ogni modo verrà chiarito questo concetto nel Capitolo 7, questo
non deve assolutamente spaventarvi!

                                                                                                  9
INTtoSTR e STRtoINT
Questi due metodi servono per passare da stringhe a interi e viceversa: ad esempio avendo una
variabile I contenente un dato numero che deve essere trasferito nella stringa S si dovrà eseguire la
seguente riga di codice:

S:= INTtoSTR(I);

Il che tradotto in linguaggio parlato starebbe né più né meno a: -trasforma l'intero I in stringa e
memorizza il risultato nella variabile S.
Viceversa STRtoINT provvede all'operazione inversa, volete magari un esempio? Questo è compito
vostro! Non preoccupativi a capire tutto quanto esposto in questo capitolo in special modo le tabelle
ad inizio capitolo, vi basti sapere che se volete fare una divisione dovrete utilizzare un Real, se
lavorate su operazioni intere l'integer è d'obbligo. Inoltre si noti che le istruzioni INTtoSTR e
STRtoINT non lavorano con i numeri con la virgola. Ora rilassatevi, rileggete i capitoli precedenti e
soprattutto provate a creare piccoli programmi VOSTRI utilizzando magari le stringhe, d'ora in
avanti la strada sarà in salita.

                                                                                                  10
Capitolo 5
Le istruzioni di controllo

IF ... THEN

La più semplice formulazione IF...THEN è la seguente:

if condizione then
  begin //Se la condizione è vera allora...
   istruzione; //Esegui istruzioni...
   istruzione;
   istruzione;
  End
Else
  Begin //Se la condizione precedentemente esposta era falsa allora
   istruzione; //Esegui istruzioni
   istruzione;
   istruzione;
  end;

Quanto appena esposto va imparato come la tabellina del 2!

La maniera migliore per capire il costrutto IF...THEN è con un esempio:

{$APPTYPE CONSOLE}
Program Tre;
Uses Forms;
Var K: Integer;

Begin
  Write('Inserisci un numero: ');
  ReadLn(K);

  If K= 3 Then
    Begin
       WriteLn('Il numero era tre');
    End
  Else
    Begin
       WriteLn('Sicuramente non hai premuto il tre, bensì un altro numero');
    End;

  ReadLn;
End.

Il programma chiede un numero e se questo è tre visualizza la scritta il numero era tre.
A scanso di equivoci desidero farvi notare che anche la struttura del tipo

  If K= 3 Then
    WriteLn('Il numero era tre');
  Else
    WriteLn('Sicuramente non hai premuto il tre, bensì un altro numero');

Sarebbe stata sintatticamente corretta ma è fortemente sconsigliata, la motivazione è quanto mai
ovvia: se necessitate di includere più azioni dopo il then queste andranno incluse in un blocco begin
                                                                                                  11
end in quanto l'allora della conclusione considera solo l'istruzione che segue. Rileggendo quanto
precede mi accorgo che non sono stato assolutamente chiaro, ad ogni modo limitatevi ad utilizzare
il costrutto come spiegato, eventualmente eliminate anche l'else se è inutile! Si noti infine che gli
operatori IF...THEN lavorano anche con le stringhe, provate il codice che segue:

{$APPTYPE CONSOLE}
Program Vanni;
Uses Forms;
Var S: String;

Begin
  Write('Inserisci il tuo nome: ');
  ReadLn(S);

  If S = 'Vanni' Then
    WriteLn('Salve a te grande coder');

  ReadLn;
End.

Inoltre si potranno usare anche i seguenti operatori logici oltre al segno = cioè  (diverso) <
(minore) > (maggiore), ad esempio 'Abc' > 'Def' sarà falso in quanto in ordine alfabetico 'abc'
precede 'def'!
Con il prossimo capitolo si introdurranno i concetti di routine, e unit compilata quindi si passerà
alla programmazione Windows per trattare i cicli e gli eventi (enjoy).

                                                                                                  12
Capitolo 6
LE ROUTINES

PROCEDURE

Una subroutine è una parte di programma che può essere richiamata da un punto qualsiasi del
codice. Il salto alle subroutine si verifica tramite il nome della subroutine stessa. Al termine della
subroutine l'esecuzione ritornerà al ciclo principale. Lo schema seguente chiarirà meglio la
situazione:

Come prassi di questo corso segue un esempio chiarificatore!

{$APPTYPE CONSOLE}
Program esempio;

Uses
  Forms;

Procedure INVIO;
begin
  WriteLn('Premi INVIO per continuare');
  ReadLn;
end;

begin
  WriteLn('Riga numero uno');
  WriteLn('Riga numero due');
  WriteLn;
  INVIO;
  WriteLn('il programma prosegue dopo l''invio');
  WriteLn;
  WriteLn;
  INVIO;
End.

                                                                                                         13
Il programma inizia scrivendo due righe dal corpo principale, quindi l'esecuzione passa alla
subroutine INVIO per poi continuare nel body... Qui di seguito verrà presentato un esempio un po'
più complesso che implementa il concetto di parametro che sarà meglio introdurre: il parametro
consiste in una variabile passata ad una procedura che sarà elaborata da lei stessa, ad esempio nel
vecchissimo basic msx (da cui provengo) esisteva una funzione input la cui sintassi era come segue:

Input(Stringa, Variabile)

Nell'esempio che segue si ricreerà una routine simile!

{$APPTYPE CONSOLE}
Program esempio;

Uses
  Forms;

var K: Integer;
Procedure Input(S: String; var I: Integer);
begin
  Write(S);
  ReadLn(I);
end;

begin
  Input('Inserisci un numero: ', K);
  WriteLn(K);
  Input('Inserisci un numero: ', K);
  WriteLn(K);
  Input('Inserisci un numero: ', K);
  WriteLn(K);
  ReadLn;
End.

I parametri preceduti da Var sono chiamati parametri passati per indirizzo o parametri-
variabile, quelli non preceduti da Var parametri per valore o parametri-valore.
La differenza sta nel fatto che le variabili passate a variabili cambiano anche il valore della
variabile, in altre parole rimovendo il var dalla procedura input il programma non funzionerà in
quanto la variabile I della procedura input sarà una copia di K e non K stessa. Ripetendo il concetto
le variabili passate per indirizzo diventano a tutti gli effetti le variabili locali, in breve il parametro
passato per indirizzo e la variabile passata alla procedura sono la stessa cosa, cioè condividono la
stessa locazione di memoria. Di conseguenza ogni modifica del parametro passato per indirizzo è in
realtà una modifica della variabile stessa. Al contrario il parametro S che viene passato per valore
non verrà alterato in alcun modo. Ad esempio provate ad eseguire il seguente codice:

{$APPTYPE CONSOLE}
Program esempio;

Uses
  Forms;

var
K: Integer;

                                                                                                        14
Procedure Prova1(I: Integer);
begin
  WriteLn('siamo all''interno di prova1 e la variabile sta per essere impostata
a 34');
  I:= 34;
end;

Procedure Prova2(var I: Integer);
begin
  WriteLn('siamo all''interno di prova2 e la variabile sta per essere impostata
a 56');
  I:= 56;
end;

begin
  K:= 0; WriteLn('K corrisponde a ', K);
  WriteLn('ora verrà chiamata la routine prova1');
  Prova1(K);
  WriteLn('K corrisponde ora a ', K);
  WriteLn('infine verrà chiamata la routine prova2');
  Prova2(K);
  WriteLn('K corrisponde ora a ', K);
  ReadLn;
End.

Il risultato dell'esecuzione del codice sarà il seguente

   1.   K corrisponde a 0
   2.   ora verrà chiamata la routine prova1
   3.   siamo all'interno di prova1 e la variabile sta per essere impostata a 34
   4.   K corrisponde ora a 0
   5.   infine verrà chiamata la routine prova2
   6.   siamo all'interno di prova2 e la variabile sta per essere impostata a 56
   7.   K corrisponde ora a 56

Si noti che anche se K viene alterato nella procedura prova1 al ritorno il valore assunto da esso non
sarà cambiato, questo perché in realtà era stato variato solo il valore di una copia di K, non K
stesso! Spero di essere stato abbastanza chiaro, d'altronde la programmazione a subroutine
(comunemente detta strutturata). Come sempre consiglio di provare quanto appreso, il prossimo
capitolo sarà piuttosto breve in quanto tra poco si passerà alla programmazione Windows.

                                                                                                  15
Capitolo 7
Utilizzo delle unit
Delphi viene fornito con diverse unit standard. Una di queste, la System unit, viene utilizzata
automaticamente durante la compilazione del programma. Se fosse necessario accedere alla
dichiarazione o al sottoprogramma di un'altra unit standard, è indispensabile inserire una clausola
uses, che è semplicemente un elenco delle unit da ricercare durante la fase di compilazione.
Dal punto di vista sintattico, la clausola uses fa parte dell'intestazione del programma e deve essere
inserita prima di ogni dichiarazione. L'intestazione

Program NomeFile;
Uses Forms;

indica al compilatore che il programma NomeFile di fare riferimenti ai tipi di dati, alle variabili, alle
costanti o alle routine dichiarati o realizzati dalla unit Forms. Durante l'uso delle unit, generalmente
si parte dalla necessitò di ottenere una determinata possibilità, ad esempio creare una finestra sotto
windows.

CREAZIONE DELLE UNIT
La creazione di unit personali è leggermente più complicata. All'inizio è necessario determinare a
quali dichiarazioni possono accedere le altre unit e i programmi, Queste dichiarazioni costituiscono
la sezione interface della unit (per coloro che conoscono il C++ la sezione interface corrisponde né
più né meno alla dichiarazione dei prototipo). E' quindi necessario completare le dichiarazioni,
comprese le procedure locali e le variabili, nella sezione implementation. Queste sezioni sono
illustrate nella sintassi qui riportata:

Unit NomeFile;
interface
{
dichiarazioni visibili o pubbliche
}
implementation
{
dichiarazioni nascoste o private
}

Quando la unit viene compilata su disco, viene creato un file .DCU (Delphi Compiled Unit) che
contiene il codice oggetto di quella unit.
Per meglio chiarire i dettagli relativi alla creazione di una unit, si esamini il seguente esempio:

Unit Math;

interface

procedure Quadrato(var N: Integer);

implementation

                                                                                                      16
procedure Quadrato(var N: Integer);
Begin
  N:= N * N;
End;

End.

Il file di una unit andrà salvato con estensione .pas, come tradizione del Turbo Pascal.
Per richiamare la funzione Quadrato provare il seguente esempio:

{$APPTYPE CONSOLE}
Program Quadro;

Uses
  Math;

Var Numero: Integer;

Begin
  Write('Inserisci un numero: ');
  ReadLn(Numero);
  Quadrato(Numero);
  WriteLn;
  WriteLn;
  Write('Il quadrato del numero è: ', Numero);
  ReadLn;
End.

Si noti l'utilizzo della parola riservata Uses che prepara il compilatore a linkare l'unit math
precedentemente preparata. Con questo si chiudono i capitoli dedicati all'introduzione Turbo Pascal
necessaria per creare programmi sotto Delphi. Dal prossimi capitolo si inizierà a programmare sotto
Windows!

                                                                                                17
Seconda parte: Programmazione Windows tramite Object Pascal

Capitolo 8
La programmazione sotto Windows
Per coloro che provengono dal mondo DOS la programmazione sotto Windows può apparire come
complicata (e in effetti lo è), in questo capitolo verrà introdotto il concetto di Form e logica RAD.
Nel primo capitolo si era creato il programma Hello World, si provvederà qui di seguito a creare il
programma Hello Windows, naturale evoluzione del primo. Per cominciare basterà selezionare New
Application dal menu File. Il risultato dovrebbe apparire come da figura:

Ora premendo F11 apparirà una finestra simile a quella della figura seguente:

                                                                                                  18
Sarà bene familiarizzare con l'Object Inspector, perché è da qui che si setteranno eventi e proprietà
dei programmi Windows, ad esempio si cambi le seguenti proprietà come da tabella:

                      Nome Proprietà Valore precedente Nuovo Valore
                      Caption        Form1            Hello Windows!
                      Position       poDesigned       poScreenCenter

Ora eseguite tranquillamente il programma e come per magia apparirà una finestra con titolo Hello
Windows!, Ma dove sta il trucco? Delphi è un compilatore orientato alla logica RAD, aspettatevi
quindi una programmazione notevolmente semplificata! Per vedere il codice del programma vi
basterà selezionare units dal menu views confermando quindi Unit1. Il codice della form dovrebbe
essere il seguente:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
  private
     { Private declarations }
  public
     { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

end.

Non preoccupatevi se non riuscite a capire niente! Provate quindi ad aggiungere un componente
Button prelevabile dalla palette degli strumenti

                                                                                                  19
Una volta inserito il button nella form questo apparirà come un normalissimo pulsante di windows.
Dall'Object Inspector (F11) selezionate la sezione events, ora cliccate sul pulsante del form (il
Button aggiunto precedentemente) e fate un doppio click sulla sezione onMouseMove dell'Object
Inspector, se avete eseguito il tutto correttamente dovrebbe aprirsi una finestra di digitazione codice
come segue:

procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin

end;

Modificatela nel seguente modo:

procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
  Caption:= 'Mouse sul pulsante';
end;

Modificate anche l'evento onMouseDown dell'oggetto Form1 come segue:

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
  Caption:= 'Hello Windows!';
end;

Se avete eseguito il tutto correttamente il vostro programma cambierà il titolo della finestra a
seconda che il mouse sia sul pulsante o sulla form.

Il secondo programma Windows
Nel secondo capitolo si era creato quello che forse era il più complesso programma finora trattato,
ora si proverà ad effettuare il cd. porting a windows... Creare un nuovo progetto (New Application
dal menu file) e preparare la form come segue:

                                                                                                    20
Si modifichino da Object Inspector le seguenti proprietà:
Nome Oggetto Nome Proprietà Valore precedente Nuovo Valore

Form1             Caption            Form1                Volume cilindro
Form1             Name               Form1                frmMain

Button1           Caption            Button1              Calcolo
Button1           Name               Button1              btnCalcolo

Button2           Caption            Button2              Esci
Button2           Name               Button2              btnExit

Label1            Caption            Label1               lunghezza raggio cilindro
Label1            Name               Label1               lblRaggio

Label2            Caption            Label2               lunghezza del cilindro
Label2            Name               Label2               lblAltezza

Edit1             Text               Edit1                -vuoto-
Edit1             Name               Edit2                txtRaggio

Edit2             Text               Edit2                -vuoto-
Edit2             Name               Edit2                txtAltezza

               TIP
               E' buona norma cambiare sempre la proprietà name dando un nome più significativo,
               si consiglia di vedere a questo proposito l'integrazione sulla Notazione Ungherese a
               fine corso.

Se il tutto è stato eseguito in maniera corretta la vostra finestra avrà il seguente aspetto:

                                                                                                 21
Ora basterà modificare il codice della unit come segue:

unit Unit1;

interface

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

type
  TfrmMain = class(TForm)
     lblRaggio: TLabel;
     txtRaggio: TEdit;
     lblAltezza: TLabel;
     txtAltezza: TEdit;
     btnCalcolo: TButton;
     btnExit: TButton;
     procedure btnExitClick(Sender: TObject);
     procedure btnCalcoloClick(Sender: TObject);
  private
     { Private declarations }
  public
     { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.DFM}

procedure TfrmMain.btnExitClick(Sender: TObject);
begin
  Close;
end;

procedure TfrmMain.btnCalcoloClick(Sender: TObject);
var rRaggio,
    rAltezza: Real;
    iResult: Integer;
begin
  rRaggio:= STRtoINT(txtRaggio.Text);
  rAltezza:= STRtoINT(txtAltezza.Text);

  iResult:= Round(rRaggio*rRaggio*rAltezza*Pi);

  Caption:= INTtoSTR(iResult);
end;

end.

L'unica istruzione che forse vi dovrebbe dare problemi è Round che serve per convertire da Real ad
Integer.

                                                                                               22
In definitiva la programmazione sotto Windows si svolge in quattro fasi:

   1. Inizio di una nuova applicazione
   2. Preparazione della from tramite la palette dei componenti Delphi
   3. Settaggio delle varie proprietà tramite Object Inspector
   4. Definizione dei gestori degli eventi
   5. Scrittura del codice

                                                                           23
Capitolo 9
Chiarimenti sui cicli
FOR TO DO
Questo capitolo consiste in una spiegazione sull'utilizzo dei cicli, sebbene sia alquanto breve
consiglio una lettura attenta in quanto i cicli sono tra le strutture più complesse di un linguaggio di
programmazione.
Esaminiamo il seguente problema: vogliamo riempire un ListBox con dei numeri da 1 a 100 alla
semplice pressione di un Button, teoricamente basterebbe provvedere a ripetere 100 volte
l'istruzione ListBox1.Items.Add('1'); cambiando di volta in volta il valore '1' con '2', '3', etc.
Converrete che non è così semplice, per risolverlo basterebbe teoricamente incrementare una
variabile numerica per 100 volte, convertirla in stringa (istruzione INTtoSTR vista nel capitolo 4) e
Aggiungere all'insieme Items della ListBox la stringa. A questo ci viene incontro la struttura

For :=  To (o DownTO) 
DO
Begin
 [istruzioni...]
End;

Provate quindi ad aggiungere in un form vuoto (New Application dal menu file) un ListBox ed un
Button, all'evento onClick del Button inserite il seguente codice:

procedure TForm1.Button1Click(Sender: TObject);
Var
  I: Integer;
  S: String;
begin
  For I:= 1 To 100 DO
  Begin
     S:= INTtoSTR(I);
     ListBox1.Items.Add(S);
  End;
end;

Ad ogni pressione del Button1 verranno aggiungi ogni volta 100 elementi sul ListBox. Ai fini della
comprensione del linguaggio consiglio di aggiungere anche il seguente codice all'evento DblClick
del ListBox.

procedure TForm1.ListBox1DblClick(Sender: TObject);
begin
  ListBox1.Items.Delete(ListBox1.ItemIndex);
end;

Che Vuol dire né più né meno che "togli il numero su cui fai doppio click"! Provate anche ad
aggiungere un secondo Button con il seguente codice:

procedure TForm1.Button2Click(Sender: TObject);
begin
  ListBox1.Items.Clear;
end;

Che altro non fa se non rimuovere tutti gli elementi dell'insieme Items della ListBox.

                                                                                                    24
WHILE DO
Le caratteristiche salienti di For To Do restano l'alta velocità e la semplicità d'utilizzo, tuttavia per
utilizzare questo ciclo si devono conoscere anticipatamente l'inizio e la fine. A questo pone rimedio
While DO, naturale evoluzione di For To Do! la sintassi di While DO è la seguente:

While  DO
begin
  [Istruzioni da ripetere]
end;

Supponiamo di voler creare un form nella quali finché non si inserisce un ciclo in cui finché non si
inserisce una password corretta venga ripetuto. Il programma potrebbe assumere il seguente aspetto:

{$APPTYPE CONSOLE}
Program PassWord;

Uses
  SysUtils;

Var
  PassWord: String;

Begin
  PassWord:= '';
  While PassWord  'FINE' do
  begin
     Write('Inserire password: ');
     ReadLn(PassWord);
     PassWord:= AnsiUpperCase(PassWord);
  end;
End.

Come dovreste aver imparato i programmi che iniziano con la direttiva {$APPTYPE CONSOLE}
vengono compilati in DOS mode. Il programma chiede una password finché non si inserisce fine.
Se si fosse voluto chiedere solo per tre volte la password si sarebbe potuto ricorrere al ciclo For To
Do. Un'altro ciclo dell'object pascal è Repeat Until, tuttavia un uso appropriato di While DO
sostituisce in maniera più funzionale quest'ultimo!

Ci stiamo avvicinando alla conclusione di questo corso, con il prossimo capitolo si concluderanno
le trattazioni sulla programmazione RAD e sarete quindi già in grado di passare alle migliaia di Tips
& Tricks presenti nella rete, tuttavia raccomando la lettura dell'integrazione sull'OOP e sulla
gestione dei file incluse nel corso.

                                                                                                      25
Capitolo 10
Canvas: chi fu costui?
Letteralmente canvas significa tela o canovaccio, nel linguaggio Delphi con Canvas si intende un
oggetto (TCanvas) che incapsula le operazioni grafiche di Windows rendendole molto più semplici;
un programmatore di C++ è costretto a districarsi tra handle to device context e chiamate GDI per
disegnare anche una semplice linea (a meno che non ricorra a MFC o simili). Delphi, come tutti i
linguaggio RAD oriented, offre una semplicità notevole anche in questo campo, tuttavia per coloro
che desiderassero un accesso diretto alle funzioni video la Borland mette a disposizione semplici
sistemi per chiamare le API Windows.

TIMAGE
Il sistema più semplice per visualizzare immagini grafiche è ricorrere al componente TImage
prelevabile dalla Palette 'Additional'. L'oggetto TImage dispone della proprietà Picture di tipo
TPicture che può contenere un'immagine grafica.

               TIP
               Delphi supporta nativamente i file bitmap, le icone e i metafile ma aggiungendo al
               progetto l'unit Jpeg si avrà accesso alla lettura di questo formato. L'unit jpeg è fornita
               con tutte le versioni di Delphi 3.0 esclusa la standard.

Per caricare un'immagine dall'oggetto Image1 (un TImage piazzato su di una Form) si userà la
sintassi

       Image1.LoadFromFile('Nome file.bmp');

Viceversa per salvare un file su disco

       Image1.SaveToFile('Nome file.bmp');

TBITMAP
La classes TBitmap incapsula hBitmap e hPalette di Win32, tramite Delphi non sarà più necessario
manipolare tavolozza e handle! Per creare un Bitmap la sintassi sarà la seguente:

       Var Bitmap: TBitmap;
       Begin
         Bitmap:= TBitmap.Create;
         Bitmap.LoadFromFile('File.bmp');
         Bitmap.free;
       End;

TCANVAS
La proprietà Canvas (di tipo TCanavs) è disponibile in tutti gli oggetti discendenti da
TGraphicControl e dispone delle proprietà Pen, Brush e Font. Tramite un oggetto TCanvas è quindi
possibile svolgere qualsiasi tipo di operazione grafica.

TPEN
Tramite l'oggetto TPen (proprietà Pen di un canvas) è possibile settare lo spessore e il tipo di linea
disegnata in un Canvas.

                                                                                                      26
TBRUSH
Un pennello (Brush) disegna forme o riempie aree. Le proprietà incapsulate da un pennello sono:
Color, Style e Bitmap. Ci sono otto opzioni di pennello selezionabili come stile: bsSolid, bsClear,
bsHorizontal, bsVertical, bsDiagonal, bsBDialog, bsCross, bsDiagCross.

METODI CANVAS
L'oggetto Canvas incapsula la maggior parte di API grafiche, tra i più importanti metodi ricordiamo
in questo capitolo solo TextOut, ma ve ne sono molti altri...

PROGETTO DI ESEMPIO
Probabilmente avete le idee parecchio confuse. Nella cartella 'Esempi' troverete il progetto
'dcanvas.zip' che utilizza tutto quanto spiegato. E' un buon punto di partenza per lo sviluppo di
qualche grafica primitiva.

                                                                                                27
Capitolo 11
Chiarimenti sulla programmazione Windows
PARTE PRIMA: L'oggetto Form
Tutti i programmi Windows sono costituiti da finestre, come ormai dovreste avere appreso in
Delphi le finestre prendono il nome di Form e sono discendenti dell'oggetti TForm.

   1.   Ma che metodi e proprietà dispongono le Form?
   2.   Come si fa a richiamare una seconda Form?
   3.   Come si agganciano i menu standard di Windows?
   4.   E i pop-up menu richiamabili con il tasto destro del mouse?

Queste sono le domande che verranno trattate in questo capitolo.

Supponiamo ad esempio di voler creare una finestra contenente un Menu tramite il quale sia
possibile richiamare una seconda finestra. Il primo passo sarà ovviamente creare un nuovo progetto
dal vostro compilatore preferito (Delphi, of course). Fatto questo aggiungeremo un TMainMenu
dalla palette degli strumenti.

La vostra Form dovrebbe avere ora un componente simile a questo           . Cliccate quindi sulla
proprietà Items dell'oggetto MainMenu1 (ovviamente da Object Inspector). Il risultato è una finestra
simile alla seguente:

Sarà bene familiarizzare da subito con questo editor, è da qui che si creano e modificano menu.
Nell'Object Inspector inseriremo ora come caption '&File' e nome mnuFile, vi chiederete ora che
oggetto stiamo modificando, la risposta è nessuno! Abbiamo appena creato un nuovo oggetto, un
TMenuLine (line di menu), Si noti anche che il carattere '&' è divenuto nell'editor un segno di
sottolineatura. Inseriamo un nuova line di menu cliccando sul campo vuoto sottostante il menu File,
precisamente inseriremo una linea 'About' (nome oggetto mnuAbout) una linea '-' nome oggetto
mnuN1 e una linea 'Exit' (mnuExit).

                                                                                                 28
Per capirci il risultato dovrebbe essere come segue:

Chiudiamo quindi la finestra con titolo Form1.MainMenu1 (l'editor insomma), il risultato sarà una
form con un Menu(!) Abbiamo quindi creato un componente Windows senza digitare una sola
linea di codice (e poi parlano di C) ma in maniera del tutto RAD (o Visuale, a dir si voglia).

Il secondo passo di questa lezione consisterà nel creare una seconda Form richiamabile dal menu
About, per fare ciò scegliere new dal menu File di Delphi e dalla Dialog scegliere Form.
Verrà quindi aperta una seconda Form di nome Form2 (che fantasia 'sti progettisti di Delphi...) che
provvederemo a rinominare (tramite Object Inspector, ma vi devo sempre dire tutto?) in frmAbout.
Inseriamo quindi nella form un TCalendar prelevabile dalla palette Sample di Delphi e settiamo la
proprietà Align di Calendar1 a alClient, così facendo l'oggetto calendar1 sarà autoresizable
(concedetemi il termine). L'ultimo passo sarà rendere attivo il menu About, per fare questo
richiamiamo la prima Form (Forms dal menu View di Delphi) e clicchiamo sul menu About, si
dovrebbe aprire una finestra codice nella quale digiteremo

frmAbout.Show;

Nel menu Exit inseriamo invece la riga

Form1.Close;

avviamo il progetto e se tutto è stato fatto correttamente avremo... un ERROREEEEEEE!!!!!!! (SI
AVETE LETTO BENE!!!!!!!). Per l'esattezza dovrebbe apparire una finestra di conferma come la
seguente:

                                                                                                29
Nella realtà non è stato commesso nessun errore, se ci pensate la variabile di riferimento della
TfrmAbout (frmAbout) non è dichiarata nella unit della Form1, basterebbe quindi aggiungere
semplicemente il nome del file contenente la classe TfrmAbout nella direttiva uses dalla unit Form1
(spero di essere stato chiaro). Rispondendo quindi yes alla richiesta information Delphi stesso
provvederà a correggere questa incongruenza (diavolo di compilatore!), infatti troveremo dopo la
direttiva Uses nella sezione implementation il file Unit1. Vi chiederete (almeno spero) perché non
sia stato inserito nella sezione interface, il motivo è presto detto: è la stessa identica cosa.
Aggiungiamo adesso un TPopUpMenu nel form frmAbout e dall'editor Items aggiungiamo la linea
BlaBla (Caption BlaBla e name mnuBlaBla), Nell'evento click del menu inseriamo la riga

ShowMessage('PopUpMenu');

Ora non resta che assegnare alla proprietà PopUpMenu di Calendar1 l'oggetto PopUpMenu1.
Abbiamo così creato un progetto che visualizza un semplice calendario alla pressione di un menu
About (completamente inutile ma funzionante).

Al fine di una più completa conoscenza dell'oggetto TForm provare ad aggiungere nella Form1 un
Panel (palette Standard), settatene caption a nulla e align ad alTop. All'interno del Panel si
disponga uno SpeedButton e da Object Inspector si assegni all'evento OnClick l'evento
mnuAboutClick. ATTENZIONE: non si deve creare un nuovo evento, ma tramite la drop list
selezionare un evento già presente. Per finire cambiare la proprietà Glyph dello SpeedButton con
una bitmap prelevabile dalla cartella images\buttons di Delphi. Abbiamo così creato una barra degli
strumenti presente nelle versioni datate di Office.

              TIP (Solo per Delphi 3.0)
              Settate a True la proprietà ShowHint dello SpeedButton, aggiungete del testo alla
              proprietà Hint e cambiate a true la proprietà Flat. Otterrete così dei "CoolButton" in
              stile Office '97 (pulsanti a scomparsa con testo di Help sensibile al passaggio del
              mouse).

PARTE SECONDA: Alcuni Tips & Tricks
Altre domande che il principiante programmatore Delphi si pone spesso sono:

   1. Come si manipola l'oggetto Items di una ListBox
   2. Come si ordina una lista di stringhe?
   3. Come si crea un "Hot Key" nell'applicazione?

L'oggetto Items contenuto come proprietà di una ListBox o di una ComboBox è uno dei più potenti
oggetti messi a disposizione da Delphi. Tecnicamente è assimilabile all'oggetto TStringList.
I metodi più importanti incapsulati da Items sono:

   •   Add(S: String)
   •   Delete(Index: Integer)
   •   Insert(Index: Integer; S: String)
   •   Clear

Tramite l'insieme items si può facilmente memorizzare e ordinare una lista di stringhe. Settando
infine la proprietà Sorted a true la lista di stringhe inserite si ordinerà automaticamente!

Per creare un Hot Key provate il seguente modo:

                                                                                                 30
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
  if (ssCtrl in shift) and (chr(key) in ['A', 'a']) then
     ShowMessage('Ctrl-A');
end;

                                                               31
Capitolo 12
Ottimizzazione del Codice

                    ATTENZIONE: Capitolo e codice non ancora ultimati

Sebbene la velocità dei processori del giorno d'oggi e la quantità di Hard Disk disponibile nei PC
sia aumentata in maniera esponenziale una delle tappe fondamentali per il programmatore resta
l'ottimizzazione del proprio codice. In questo capitolo si studieranno dei semplici metodi per
rendere più efficiente la velocità dei propri programmi. In generale i fattori da ottimizzare in un
programma restano 4: la velocità di visualizzazione, reale, apparente e l'utilizzo di risorse. E' buona
norma ottimizzare un programma durante la sua creazione e non a lavoro ultimato. In questo
capitolo si userà un progetto da me creato per spiegare i possibili miglioramenti di un programma.
Si tratta del progetto contenuto nel file 'optimize.zip', sempre nella cartella 'Esempi'.

VELOCITA' REALE
Con velocità reale si intende la velocità intrinseca del programma compilato e che quindi non è
ulteriormente migliorabile... Come fare ad ottimizzare una routine? Il trucco sta nell'utilizzare tipi
che il sistema operativo e il compilatore gestisce con maggior facilità, ad esempio in Windows 3.1 i
tipi numerici a 16-bit erano i più veloci, in Windows '95 e Windows NT gli interi a 32-bit sono al
contrario i più rapidi, nel Pascal il tipo Integer era (fino alla versione di Delphi 1.0) a 16-bit, nelle
versioni a 32-bit di Delphi (2.X e 3.X) con Integer si intende un intero a 32-bit.
Nella sezione "confronto di tipi" del progetto in esame verranno confrontati i tipi SmallInt, Integer,
Variant e Real. E' interessante osservare come il tipi Variant sia notevolmente più lento degli altri,
questo perché una variabile Variant può contenere sia dati interi che mobili (Integer e Real), ma
anche Stringhe o Currency. Potrebbe sembrare vantaggioso usare sempre tipi Variant, ma vi
renderete conto che una lentezza superiore di 80 volte può seccare piuttosto l'utente, anche perché è
semplice convertire dati da stringhe a numeri tramite funzioni del tipo STRtoINT o INTtoSTR :-D
Nel test anche il tipo Real appare decisamente lento, in effetti se possibile è consigliabile svolgere
calcoli in Integer e convertire solo quando necessario in dati reali.

VELOCITA' DI STRINGHE
In Object Pascal non esiste alcun modo per rendere più veloce il tipi String, tuttavia nel progetto
Optimize è mostrato un piccolo stratagemma per velocizzare operazioni di stringhe: quando si deve
eseguire la stessa funzione con determinate stringhe (ad esempio un concatenamento, S:= S1 + S2
ie.) all'interno di un ciclo è preferibile costruire il valore all'esterno del ciclo, la performance del
programma crescerà in maniera insperata...

OTTIMIZZAZIONE DEL CODICE
Per la serie le pecche del RAD... Ragazzi mettetevi in testa una cosa, in Delphi sarà pure semplice
programmare ma il risultato è notevolmente più lento del codice non RAD. Perché ci dici ciò?
Semplice perché con piccoli accorgimenti si può rendere una routine notevolmente più veloce senza
scrivere tanto codice. Siete scettici? Facciamo un esempio: l'accesso di una proprietà è più lento
rispetto all'uso di una variabile di 50 volte, se intendiamo usare in un ciclo una determinata
proprietà che resta invariata basterà quindi salvarla in una variabile temporanea. In fondo in fondo
il codice è lo stesso. Vedere per chiarimenti "ottimizzazione del codice nel progetto in esame".

VELOCITA' APPARENTE
Sapete perché vanno tanto di moda le ProgressBar? Perché migliorano la velocità apparente (anche
a scapito della reale). Come la Microsoft insegna non si deve fare un programma veloce ma un

                                                                                                      32
programma che sembri veloce, il mostrare un clessidra "avverte" l'utente che deve attendere,
l'avanzamento di una percentuale sullo schermo fa credere all'ignaro utilizzatore che il programma
sta effettivamente svolgendo qualcosa (mentre in realtà potrebbe limitarsi a resizare le immagini
porno interne al soft stesso), l'utilizzo di Thread multipli, a costo di rendere un programma il
corrispondente di una tartaruga digitale, esalta l'utilizzatore finale (tanto per capirsi se finché il
vostro programma non svolge un tubo attivaste uno Screen Saver di Pamela Andersson l'utente non
si renderebbe conto del tempo che passa, anzi... :P Se l'esempio non vi dà l'impressione di un
miglioramento di velocità probabilmente fate parte della schiera di quelli che necessitano del
suddetto Screen Saver :-)

ALGORITMI DI RICERCA

                                                                                                   33
Capitolo 13
API Handle e programmazione avanzata
Piccola premessa: in questo capitolo vi troverete di fronte argomenti del tutto nuovi, tipici della
programmazione C strutturata (cioè non orientata agli oggetti). Già con il C++ molti dei concetti
che seguono sono stati incapsulati in classi (MFC o OWL). Capirete quindi che essendo il Delphi
orientato alla logica RAD, i concetti di handle e API sono stati COMPLETAMENTE sostituiti da
oggetti VCL (Visual Component Library). Questo se da un lato il programmatore è più libero, da un
altro lato lo rende vincolato a classi scritte da altri. Questo è solo un discorso teorico, in realtà
Delphi è talmente potente da poter gestire anche le chiamate API più complesse, nonché tutti quei
concetti tipici della programmazione Windows strutturata (funzioni callback per esempio). Se avete
quindi ancora problemi nello scrivere semplici applicazioni usando i mezzi che Delphi vi propone
non posso che consigliarvi di affinare meglio le vostre tecniche, questo capitolo non fa per voi!

HANDLE
Un handle è un numero intero a 32-bit senza segno. Tutto qui! Il Windows gestisce ogni oggetto
(sia esso grafico come una finestra, sia esso hardware come la periferica video) con un handle, ad
esempio quando inseriamo un nuovo pulsante in una form, questo ha necessariamente un handle. E'
quindi ovvio che Windows può gestire fino a 232 finestre contemporaneamente, non di più perché
questi sono gli handle che può allocare in memoria. Ma perché dovremmo accedere ad un handle,
quando Delphi ci mette a disposizione tutto già pronto, ma soprattutto come si fa ad accedere ad un
handle? Riguardo alla prima domanda non c'è una risposta precisa, in questo capitolo proporrò
alcuni esempi dove per sopperire a limitazioni dell'ambiente Visuale si deve ricorrere a queste
tecniche più a basso livello (anche se è un termine improprio). Per accedere ad un handle è invece
semplicissimo, ogni oggetto ha una proprietà non visibile da Object Inspector di nome handle!

COME NASCONDERE L'ICONA SULLA TASKBAR
Avete mai provato a nascondere l'icona sulla TaskBar di Win '95? Molto semplice non si può fare in
Delphi! Per capire ciò si deve premettere che in Delphi esiste un oggetto Application che contiene
l'handle del pulsante sulla taskbar (non è propriamente così, ma per semplificarvi le cose...;-) quindi
basterebbe nascondere trovare una chiamata per nascondere un oggetto grafico conoscendo il suo
handle. Proviamo quindi ad inserire in una form vuota un pulsante e nel codice click di questo il
seguente codice

       ShowWindow(handle, SW_HIDE);

Eseguiamo il codice... magia alla pressione del tasto sparirà la finestra! Se mi avete seguito
attentamente avrete già capito che l'istruzione seguente

       ShowWindow(Application.handle, SW_HIDE);

Farà sparire il pulsante sulla taskbar... provare per credere!

Ma cos'è questa istruzione ShowWindow? E' per l'appunto una API che visualizza, minimizza,
massimizza o nasconde una finestra. Allora vi chiederete, il pulsante sulla taskbar è una finestra?
Non proprio, in realtà l'oggetto Application è costruito attorno ad una finestra non visibile che serve
solo ed esclusivamente per visualizzare il pulsante sotto, nascondendo questa finestra tramite
l'istruzione ShowWindow potremo fare sparire anche il pulsante ad essa associato. Provate, tanto
per fare, anche le seguenti istruzioni:

                                                                                                    34
Puoi anche leggere