A. Veneziani - Elementi di programmazione con interfacce grafiche

Pagina creata da Angelo Fava
 
CONTINUA A LEGGERE
A. Veneziani - Elementi di programmazione con interfacce grafiche
A. Veneziani – Elementi di programmazione con interfacce grafiche
IDE di sviluppo grafiche
Quasi tutte gli ambienti di sviluppo grafico per programmazione di applicazioni desktop tradizionali sono
ormai basati su una comune impostazione che negli anni si è rivelata pratica e capace effettivamente di
aumentare la capacità di programmazione del programmatore.
Un elemento fondamentale per migliorare lo sviluppo è stato quello di integrare le varie fasi dello stesso in
un unico tool che le rendesse sincroniche e facili da richiamare, così come possibile passare velocamente
dall’una all’altra. In questo senso si cominiciò tanti anni fà a parlare di IDE di sviluppo, piuttosto che di
semplici compilatori e tool di sviluppo. Una IDE era qualcosa che integrava in modo armonico i vari tool
permettendone un uso più veloce ed ottimizzato, e di richiamare ed utilizzare le varie fasi tipiche dello
sviluppo in modo assai più veloce.
Questo passaggio si ebbe, almeno a livello di software commerciale, con l’apparizione di prodotti tipo il
Turbo Pascal della Borland, quindi già nei primi anni ’80.
Un altro passo importante fù quello di dotare tali ambienti integrati di ulteriori funzionalità che fossero di
ausilio alla programmazione. La principale di queste, che ancor oggi è assai importante, è la presenza di
funzionalità di debugging sempre più avanzate.
Nei vecchi tool di sviluppo, esistevano già dei debugger, ma essi erano di uso poco intuitivo ed erano
staccati dal resto dei tool di programmazione. Successivamente i debugger vennero profondamente
integrati nelle IDE e ne divennero una parte fondamentale e sempre più evoluta, permettendo una
individuazione degli errori sempre più comoda e veloce, oltre e rendere spesso possibile un apprendimento
del linguaggio e del suo comportamento più veloce e chiaro nel settore educational.
Infine all’inizio degli anni ’90 si ebbe un ulteriore step evolutivo. Sul computer più diffuso del momento, il
PC, appare il primo sistema operativo con interfaccia grafica a larga diffusione: Windows 3.0. Pur con
tutta una serie di limiti dovuti alla relativa parentela con DOS e limitazioni dovute alla sua architettura,
questo sistema operativo impone di introdurre massicciamente la programmazione “a finestre” o con
interfaccia grafica anche sul PC, la macchina più diffusa del mondo.
In un primo momento tale programmazione è complessa e solo per “addetti ai lavori”, ma successivamente
appaiono via via tools che permettono con facilità sempre crescente di creare applicazioni desktop grafiche.
Il principe fra questi tool è senz’altro Visual Basic della stessa Microsoft, che già agli inizi degli anni ’90
propone un procedimento di programmazione dell’ interfaccia grafica molto intuitivo e veloce, dove
altrimenti il programmatore avrebbe dovuto scrivere numerose linee di codice, da modificare e ritoccare
magari spesso.
Si parla comunemente da quel momento di programmazione “visuale”, per indicare un tipo di
procedimento che si avvale di tool appositi, di solito interni alla IDE di sviluppo, per disegnare (nel vero
senso del termine) una interfaccia grafica che poi sarebbe stata collegata al codice sottostante di
programma.
Questo paradigma di sviluppo poi accettato universalmente da tutte le IDE (da Netbeans a Visual Studio a
molte altre), ha potenziato e velocizzato molto la parte di disegno grafico dei programmi.
Altri ausilii, ormai irrinunciabili, sono le funzionalità di autocompletamento del codice, spesso utilissime
come promemoria del programmatore.               Il sistema di sviluppo suggerisce quali scelte possa fare il
programmatore mentre stà scrivendo codice.
Numerose altre sono le funzionalità di una IDE moderna, ma sostanzialmente essa deve essere vista come
un raggruppamento di strumenti, ormai estremamente evoluto.

                                                  Pagina 1
A. Veneziani - Elementi di programmazione con interfacce grafiche
Le famiglie di componenti
Un sistema operativo, come forse avrete già sperimentato, ha molteplici modi di essere programmato.
Come prima differenza esistono vari linguaggi che permettono la programmazione del sistema operativo
stesso. Molti tra l’altro permettono di programmare in modo e con sintassi simili, sistemi operativi
differenti, ottenendo gli stessi risultati.
Un altra fonte di differenze è che le interfacce grafiche vengono di solito programmate con serie di
componenti che vanno a formarle e dare loro le funzionalità necessarie o previste.
In realtà questo strato software a componenti (basato totalmente sulla programmazione ad oggetti), non è
univoco, vale a dire non esiste una serie di componenti per Windows, ma bensì più serie e lo stesso vale
anche per Linux e gli altri sistemi operativi.
Esistono quindi varie serie di componenti “grafici”, tra loro usualmente non compatibili. Si potrebbe
parlare più giustamente di famiglie di componenti grafici. Di solito in ongnuna di tali famiglie esiste una
serie di componenti di base considerata per uso “standard” e poi un’altra serie più o meno numerosa di
componenti aggiuntivi che permettono speciali funzionalità. Questi componenti aggiuntivi in alcune
famiglie di componenti sono numerossissimi e spesso programmati da società terze che si occupano solo di
questo compito.
Così ogni “piattaforma” o linguaggio di sviluppo ha serie di componenti diversi e propri. Ad esempio Java
ha dei componenti detti Swing (multipiattaforma come il linguaggio Java), .NET ed i linguaggi che
dipendono da esso ha le Windows Forms e alcune altre tecnologie sempre a componenti differenti, Delphi
e C++ Builder due linguaggi di notevole successo soprattutto in anni passati si basano ed utilizzano la
libreria di componenti detta VCL, in precedenza a .NET lo standard Microsoft per i componenti era quello
denominato ActiveX / COM, mentre nel mondo open, molte altre librerie di componenti sono disponibili a
seconda del linguaggio e tool di sviluppo utilizzato (ad esempio wxWidget e Qt o Lazarus (Object Pascal) con
i componenti LCL).
Queste famiglie di componenti differiscono tra loro per la metodica e alcuni standard propri della famiglia
stessa di componenti ed eventualmente dal linguaggio nel quale sono programamati. Questo fà si che
quasi sempre varie famiglie di componenti non siano utilizzabili per realizzare la stessa applicazione.
Tipicamente i componenti più comuni che si trovano in tutti i set di componenti grafici sono quelli base che
troviamo di continuo in una interfaccia grafica di un qualsiasi sistema operativo, quali pulsanti (button),
etichette (label), caselle di testo (textbox), liste a discesa (combobox), liste (listbox), caselle di spunta
(checkbox), pulsanti radio (radiobutton) ecc.
Il componente fondamentale però è sempre quello che permette di tenere assieme gli altri componenti e
raggruppare l’interfaccia, ossia la finestra (o form). I vari componenti vengono quindi disposti su di essa.

Componenti e programmazione ad oggetti
Inizia in questo periodo, ossia all’inizio degli anni ’90 la diffusione massiccia della programmazione ad
oggetti, dovuta al fatto che tutti gli elementi base di una interfaccia grafica sono degli oggetti, con loro
prorietà e metodi. E proprio per questo che l’ inizio dell’era della programmazione desktop con interfacce
grafiche, coindice con lo sviluppo e l’uso impetuoso di molteplici linguaggi basati sulla OOP (Object
Oriented Programming).
Anche linguaggi tradizionali attorno circa a questo periodo iniziano a trasformarsi ed integrare sempre
maggiori funzionalità ad oggetti, quali C (evolutosi in C++) e Pascal (evolutosi in diversi dialetti di Object
Pascal).
I programmi via via divengono più complessi e massicci e sempre più prende piede anche una
programmazione che si appoggia a librerie, perciò in questi sistemi operativi appare comune l’uso e

                                                  Pagina 2
l’interazione con .DLL. Come noto, dopo qualche tempo, nascono nuovi linguaggi non direttamente
derivati da precedenti, e fortemente basati sulla OOP quali Java (1995) e successivamente C# (2000).
Un componente grafico quindi ha una sua apparenza grafica e nel contempo essendo un oggetto ha
proprietà, spesso legate al suo aspetto, e metodi per indurre modifiche e comportamenti dell’oggetto
stesso.

Un esempio di semplice progetto (C#)

Realizziamo ora un semplice esempio di programma con interfaccia grafica in C# e Visual Studio. Il
programma dovrà solo effettuare una somma tra interi e quindi sarà realizzato tramite tre label, tre box di
testo, e un pulsante, oltre che ad una form che contenga il tutto.
Le tre label (componente Label di Windows Forms), saranno opportunamente posizionate (magari sopra le
box di testo o al loro fianco a sinistra), e l’unica proprietà che verrà cambiata sarà la Text, tramite cui
cambierà la scritta all’ interno della label stessa. Per ottenenre le label selezioneremo il componente Label
nella Barra degli Strumenti e poi faremo click sulla form dove vorremo che il componente appaia. A questi
componenti dato che essi non verranno modificati (in quanto queste scritte sono fisse) e non interagiranno
con il programma potremo evitare di dare loro un nome specifico, quindi rimarrà quello di default dato da
Visual Studio.
Successivamente inseriremo sulla form tre box di testo (o caselle di testo) capaci di recepire input e di
svolgere anche funzioni di output. Nel caso del primo e secondo numero (i due addendi) ci servono per
recepire dati, mentre nel terzo caso, per il terzo elemento usato in output è possibile usare una box di testo
o una label indiferentemente.
Di queste modifichiamo la prorietà Name, dando un nome a dognuno di questi componenti, quali, txtAdd1,
txtAdd2, txtRisultato, di modo da poter individuare univocamente ogni componente. Poi modifichiamo la
proprietà Text di modo che la casella di testo all’inizio risulti vuota.
Di queste box potremo cambiare anche l’allineamento del testo per renderlo coerente con il trattamento di
dati numerici, quindi opereremo sulla proprietà TextAlign, selezionando il valore Right. Inoltre per la

                                                  Pagina 3
txtRisultato potrà essere impostata la proprietà Readonly a True, dato che essa non deve servire da input di
dati, ma solo come visualizzazione di un risultato.
Successivamente si dispongono le textbox opportunamente sulla form. Gli allineamenti tra i componenti
saranno segnalati da apposite linee blu, del sistema di disegno dell’interfaccia.
Infine inseriremo sempre con la solita procedura un pulsante (Button), dando ad esso un testo (proprietà
Text), ad esempio “Somma”, modificando opportunamente posizione e dimensioni e associandogli un
nome diciamo btnSomma.
A questo punto non resta che operare qualche regolazione sulla form di base sulla quale i vari componenti
sono stati aggiunti. Di norma non è necessario variare il suo nome, ma semmai altri parametri tra cui:
              Text – per inserire un nuovo titolo della form
              Icon – per assegnare una nuova icona alla form (icona non presente se bordo fisso)
              FormBorderStyle – per definire le proprietà del bordo della form. Varieremo questa
                  proprietà a FixedDialog, per far si’ che la form non abbia un bordo ridimensionabile.
              MaximizeBox – a false per interdire la possibilità della form di essere massimizzata.
Dopo queste modifiche relativamente semplici, ed aver dimensionato opportunamente la nostra form, la
realizzazione della nostra interfaccia è terminata e quindi apprestiamoci a scrivere del codice C#.
Per far ciò selezioneremo la sezione Events (Eventi) della finestra Properties (Proprietà). Selezioneremo
quindi il componente pulsante e cercheremo l’evento Click che è quello che vogliamo associare al pulsante
stesso. Per confermare l’associazione basterà fare doppio click nella casella corrispondente dell’evento.
In essa apparirà una scritta corrispondente al nome della routine –evento (metodo), relativo all’evento.
Tale metodo verrà richiamato solo quando un evento di quel tipo accadrà su quell’elemento, nel nostro
progetto il pulsante Somma. A questo punto sarà apparso automaticamente del nuovo codice nel listato
del progetto (modulo di codice della form, denominato di default Form1.cs), ossia il metodo legato
all’evento Click.
In tale metodo andrà inserito il codice che deve essere eseguito alla pressione del pulsante, ossia quello che
effettua l’operazione di somma. Il metodo verrà richiamato quando l’evento click sarà effettuato sul
pulsante Somma.
Il codice che và inserito nel metodo è:
         private void btnSomma_Click(object sender, EventArgs e)
         {
             int n1, n2, ris;

              n1 = Convert.ToInt32(txtAdd1.Text);
              n2 = Convert.ToInt32(txtAdd2.Text);

              ris = n1 + n2;

              txtRisultato.Text = Convert.ToString(ris);
         }
La comprensione del codice è piuttosto semplice.
    a) Si dichiarano tre variabili intere utili al calcolo
    b) Si legge il contenuto delle box di testo txtAdd1 e txtAdd2, assegnandolo alle var. n1 e n2
    c) L’assegnazione, dato che le box txtAdd1 e txtAdd2 contengono stringhe deve essere preceduta da
       una conversione.
    d) La conversione di cui sopra in .NET avviene tramite una apposita classe detta Convert. Il metodo
       ToInt32 passa ad un intero a 32 bit.
    e) I valori scritti in txtAdd1 e txtAdd2 possono essere acquisiti e passano in n1 ed n2.
    f) Viene effettuata la somma ed il risultato messo nella var. intera ris.

                                                  Pagina 4
g) In questo caso il problema è inverso. Si ha un valore intero e si vuole renderlo visibile in
        txtRisultato. txtRisultato può contenere solo testo (stringa).
    h) Si utilizza ancora la Convert in questo caso con il metodo ToString che converte a stringa da intero.
In questo modo si ottiene nella box di testo txtRisultato il risultato voluto.

Lo stesso esempio in C++ Builder
C++ Builder è un potente ambiente RAD (Rapid Application Development) che permette velocemente e con
una certa semplicità di sviluppare applicazioni con interfaccia grafica, esso utilizza una versione
relativamente standard del linguaggio C++, con alcune estensioni proprietarie, dovute soprattutto alla
libreria VCL fulcro del sistema di programmazione di interfacce grafiche.           Come tutti i RAD ed
analogamente a Visual Studio, C++ Builder utilizza la programmazione “visuale” dell’interfaccia, ossia dei
tools a due vie dove le modifiche alle proprietà hanno effetto (eventualmente) sul disegno dell’interfaccia e
modifiche al disegno vengono automaticamente recepite e registrate nelle relative ed opportune proprietà
degli oggetti che la costituiscono.

Come si vede anche in C++ Buider esiste la sezione per comporre e disegnare l’interfaccia grafica, quella per
regolare le proprietà, e la barra dei vari componenti (in questo caso della lbreria VCL).

                                                 Pagina 5
Il procedimento è del tutto simile a quello indicato per il programma in C# con Visual Studio, ma cambia il
nome dei componenti e di alcune proprietà.
In questo caso la label, sarà indicata con Tlabel, che è poi la classe che definisce una label generica VCL.
La proprietà da regolare per cambiare il testo interno delle label in questo caso sarà denominata Caption.
Le text box in questo ambiente hanno nome TEdit. In questo progettino le sono state assegnate i valori
edtAdd1, edtAdd2, ed edtRis. Le proprietà da modificare per il nome saranno la Name e per regolare il
contenuto si agirà sulla proprietà Text.
Infine per rendere di sola lettura la edtRis, si opererà sulla proprietà Readonly (nome analogo a quello che
troviamo in .NET !) del componente edtRis.
Anche qui potremo regolare l’allineamento del testo nelle editbox (box di testo), cone la proporietà
Alignment, che dovrà essere regolata a taRightJustify.
Infine la form di base potrà essere regolata come in Visual Studio con le proprietà:
              Caption – regola il titolo della form
              Icon – regola l’icona della form
              BorderStyle – serve per imporre alla form un bordo fisso. Regolato a bsSingle
              BorderIcons -> biMaximize a False, per disattivare il tasto per massimizzare la form.
Successivamente si accede alla tab Events dell’Object Inspector e si associa un evento Click al pulsante
Somma, in modo del tutto simile a quello effettuato su Visual Studio.
Appare anche qui in modo automatico del codice C++ (anche qui sotto forma di metodo) dove inserire del
codice di programma.
         void __fastcall TForm1::btnSommaClick(TObject *Sender)
         {
                 int n1, n2, ris;

                n1 = StrToInt(edtAdd1->Text);
                n2 = StrToInt(edtAdd2->Text);

                ris = n1 + n2;

                edtRisultato->Text = IntToStr(ris);
          }
Il significato della sintassi del metodo è che esso non rende valori (void), utilizza eventualmente e
preferenzialemente dei registri per il passaggio di valori dei parametri (__fastcall), e che la classe Tform1,
ha un metodo (definito al di fuori della classe stessa) di nome btnSommaClick. Il parametro Sender indica
chi è il componente (genericamente l’oggetto, quindi TObject) che ha chiamato la routine-evento.
In questo caso vediamo che C++ Builder mette a nostra disposizione funzioni di conversione diverse da
.NET. Esse fanno parte della libreria VCL, e trasformano AnsiString (una particolare forma di string propria
di VCL in intero) in intero StrToInt(...) e viceversa IntToStr(...). La proprietà Text permette come già detto
di accedere al testo delle caselle di testo (box di testo).

I principali componenti e le loro proprietà
Nei nostri programmi didattici useremo quasi sempre componenti “standard”, vale a dire quelli che in C++
Builder sono indicati nella tab “Standard” e in Visual C# nel gruppo di componenti “Common controls” o
componenti comuni, vale a dire pulsanti (button), caselle di testo (textbox), etichette (label), listbox,

                                                      Pagina 6
combobox, pulsanti radio (radiobutton), caselle di spunta (checkbox), ed altri di uso comune su tutti sistemi
operativi con interfaccia grafica, specificamente Windows, Linux e Mac OS.
Esiste poi in tutti i linguaggi “visuali”, un altro componente che agisce come substrato (o contenitore) per
gli altri, vale a dire il form (o finestra). Un programma grafico, come ben noto può essere costituito da più
form, i quali possono entrare in azione in momenti diversi dell’esecuzione del programma stesso.
Per inserire uno di questi componenti sulla form, si seleziona lo stesso dalla barra degli strumenti (toolbox)
e si riporta sulla form, dove è possibile ridimensionarlo e riposizionarlo a piacere.
Queste operazioni regolano automaticamente due importanti proprietà del componente stesso, vale a dire
Top (distanza dall’alto della form, senza contare la barra del titolo) e Left (distanza dal bordo sinistro della
form) per il riposizionamento, e Width (larghezza del componente) ed Height (altezza del componente) per
il ridimensionamento1.
Tutti i componenti inseriti, soprattutto quelli che abbiano interazioni con il codice di programma, è
opportuno che abbiano un nome ben preciso e riassegnato dal programmatore. Il nome di un
componente, già presente con un valore di default, può essere riassegnato dal programmatore con la
proprietà Name (che ha lo stesso nome e scopo sia in Windows Form che nelle VCL). Essa permette di
ridenominare opportunamente ed in maniera più propria, rispetto agli scopi nel progetto, ogni componente
presente. Usualmente è buona norma indicare con una sigla (di solito di tre le lettere) la tipologia del
componente e poi affiancarne il nome vero e proprio. Ad esempio: lblValore, btnOk, txtContatore, ecc.
Questa regolazione manuale delle proprietà, come quelle di tutte le altre proprietà può essere fatta
inserendo valori nella apposita griglia delle proprietà, denominata in Visual C# (Proprietà o Properties) ed in
C++ Builder2 nella tab Properties della finestra Object Inspector.
Le proprietà indicate sopra hanno gli stessi nomi anche in C++ Builder e nella serie di componenti VCL.
Le proprietà possono venir modificate a design-time, ma ovviamente non durante l’esecuzione del
programma, dove solo il codice ha la capacità di influenzare il layout stesso.
A questo proposito bisogna tener presente che esistono tre stati possibili della IDE (sia in Visual Studio che
C++ Builder):
       Design time - il programma è fermo ed è possibile disegnare l’interfaccia e regolare le proprietà dei
           componenti
       Run-time – Il programma è in esecuzione e NON è possibile disegnare o modificare l’interfaccia o
           regolare le sue proprietà (ed in Visual C#, neppure modificare il codice)
       Debug-time – Si tratta di uno stato particolare nel quale si effettua il debug del programma, ossia la
           sua esecuzione controllata. In tale stato è possibile visionare il contenuto delle variabili, alterarne il
           valore, visionare l’esecuzione in modalità passo-passo, osservando quali istruzioni vengano
           eseguite.
      Analizziamo in dettaglio quindi alcuni di questi componenti:

Altre proprietà comuni a vari controlli
Esistono altre proprietà che sono comuni a diversi controlli che si possono incontrare sulle interfacce. Tra
queste abbiamo analizzato:
Visible – permette la visibilità o meno di un componente                 (se è un componente visualizzabile
sull’interfaccia grafica). E’ booleana. E’ analoga e ha lo stesso effetto sia in Windows Form che VCL.

1
 In Visual C# Top e Left sono utilizzabili nel codice di programma, al momento della regolazione manuale della
posizione si deve utilizzare le componenti X e Y della proprietà Location.
2   Attualmente non esiste una versione italiana di C++ Builder, che è disponibile in Inglese e poche altre lingue.
                                                                Pagina 7
Se il componente ha tale proprietà a false non è visibile a run-time (esecuzione) , mentre come logico lo è a
design time, ossia mentre si disegna / modifica l’interfaccia.
Enable – Indica che il componente è abilitato o meno. Un componente disabilitato è visibile, ma non
svolge le sue funzioni e non attiva gli eventuali eventi ad esso associati. Il controllo apparirà graficamente
con colori più sfumati in certi dettagli, quali scritte da colore nero a colore grigio ed effetti similari.

Form
E’ il componente fondamentale per la realizzazione di programmi con interfacce grafiche. Realizza le
famose “finestre”, sulle quali, grazie ad altri componenti, sono implementate le funzionalità volute. Funge
quindi da base per tutti gli altri componenti.
Anch’essa possiede le proprietà “universali”, Top, Left, Width ed Height, oltre che Name. In particolare il
valore di Top e Left si riferiscono però in questo caso al sistema di coordinate dello schermo, quindi sono
calcolate rispetto all’angolo in alto a sinistra dello schermo.
Di una form usualmente si desidera anche cambiare il titolo, e ciò può essere fatto tramite la proprietà:
      Text (Visual C#)
      Caption (C++ Builder)
Talora si vuole rendere la form con il bordo fisso (frequentemente in progettini semplici come i nostri).
Per far questo si dovrà alterare le proprietà:
      FormBorderStyle cambiandola da Sizable a FixedSingle (in Visual C#)
      BorderStyle       cambiandola da bsSizable a bsSingle (C++ Builder)
Inoltre abbiamo visto che può essere utile eliminare la possibilità di massimizzare la finestra (form),
interdicendo il pulsante di massimizzazione della stessa, ossia regolando la proprietà:
      MaximizeBox a false (Visual C#)
      BorderIcons sottosezione biMaximize a false (C++ Builder)3
Inoltre in entrambi i sistemi di sviluppo (Visual C# e C++ Builder) è possibile modificare l’icona sulla form
tramite la modifica della proprietà Icon.

Label (Windows Form) / TLabel (VCL)
E’ un componente atto a visualizzare una scritta. Non permette la scrittura diretta da parte dell’utente, ma
solo, eventualmente, quella da parte del programma (quindi è un componente che può eventualmente,
essere usato per il solo output di dati.
Le principali proprietà del componente sono:
      Text (Visual C#)
      Caption (C++ Builder)
Per modificare la scritta stessa. Inoltre sia nelle VCL che in Windows Form, è abilitata di default la
proprietà Autosize, che ridimensiona automaticamente la label a seconda della scritta in essa presente.
Tale proprietà per vari motivi (ad esempio una label che inizialmente non contiene testo tende a divenire
poco visibile nel progetto grafico) può essere disabilitata (false).
Nel caso Autosize sia quindi a false la label può essere liberamente ridimensionata.
Inoltre abbiamo visto nel progetto dell’orologio che è possibile (come del resto in altri controlli) modificare
la dimensione e il font del testo della label, regolando:
      Font sottosezione Name
      Font sottosezione Size (in Visual C#)

                                                  Pagina 8
E
     Font sottosezione Name
     Font sottosezione Size (in C++ Builder)
Specifico che la regolazione di tali proprietà è meccanica ed intuitiva tramite l’’interfaccia grafica a design
time, ma un po’ più complessa e meno ovvia se si dovesse effettuare via codice. Ecco due spezzoni di
programma che regolano gli stessi aspetti in C# e C++ Builder:
        label1.Font = new Font("Consolas", 20);             // Visual C#
e
         this->Label1->Font->Name = "Consolas";
         this->Label1->Font->Size = 20; // C++ Builder
dove this è la form che ospita il componente (tlabel1 nel nostro caso).
E’ eventualmente possibile cambiare il colore di background di una label (cosa che potrebbe essere utile
per vari motivi), con le proprietà:
Per C++ Builder bisognerà regolare 2 proprietà:
    1. Trasparent a false (regola la trasparenza del componente - fondo opaco o trasparente )
    2. Color al valore del colore voluto
Usualmente i colori stadard in C++ Builder sono costanti predefinite il cui nome inizia con cl…., ad esempio
clRed, cl Yellow, ecc..
Per Visual C#:
     Regolare la proprietà BackColor ad un colore voluto
Come si nota dopo la regolazione, la proprietà è definita da una terna di valori tra 0 e 255, ognuno dei quali
regola uno dei colori fondamentali R (rosso), G (verde), B (blu).

TextBox (Windows Form) / TEdit (VCL)
E’ un componente che permette all’utente di inserire dei dati (di default su una sola riga).              Il suo
contenuto può anche essere scritto dal programma, e quindi si comporta come una zona dell’ interfaccia
per l’input-output di dati.
Se il desiderio del programmatore è che solo il programma possa scrivere nella casella di testo, si dovrà
regolare la proprietà Readonly a true (di default è a false). In questo caso non è più possibile scrivere dati
nel componente ed esso diviene di solo output (in modo simile alla Label).
La proprietà Readonly (booleana) è presente con lo stesso nome e significato sia in Windows Form che il
VCL.
Per alterare o leggere il testo del componente casella di testo (TextBox in Windows Form, TEdit in VCL), si
utilizza la proprietà Text (con lo stesso nome e significato sia in Windows Form che in VCL).
In alcuni progettini abbiamo modificato l’allineamento delle textbox dato che esse erano destinate a
contenere valori numerici (di solito allineati a destra), mentre l’allineamento di default delle textbox / tedit
è a sinistra (previsto per dati alfanumerici di tipo generico).
Per modificare tale aspetto esiste una apposita prorietà:
      TextAlign (di default a left) da portare a right      (Visual C#)
      Alignment (di default a taLeftJustify) che và portata a taRightJustify (C++ Builder)
E’ possibile variare il colore della textbox / tedit con:
      Proprietà Color (in C++ Builder)
      Proprietà BackColor (Visual C#)

                                                   Pagina 9
Button (Windows Form) / TButton (VCL)
Si tratta del comune pulsante o bottone, di cui sono piene le finestre di Windows e altri sistemi operativi.
Le dimensioni e posizione sono regolabili con le proprietà generali di cui si è parlato in precedenza.
La scritta sul pulsante che descrive le sue funzionalità viene modificata tramite la proprietà:
      Text (in Visual C#)
      Caption (in C++ Builder)
Ovviamente anche nei pulsanti possono essere variate le proprietà Enabled e Visible, con gli effetti detti in
precedenza.
Ai pulsanti è spesso frequente associare l’evento click, il più usato per questo tipo di componenti.
La metodica è simile sia per C++ Builder che per Visual C#:
     1) Si seleziona il componente sulla form
     2) Si assegna ad esso il nome desiderato con la proprietà Name
     3) Ci si sposta su Object Inspector (C++ Builder) o sulla finestra Prorietà (Visual C#)

    4) Si seleziona la tab Events dell’ Object Inspector (C++ Builder) o il pulsante apposito in Prorietà
       (Visual C#)
    5) Nella lista dei tipi di evento associabili al componente si cerca l’evento di tipo Click (OnClick per
       C++ Builder) (Click per Visual C#)
    6) Si effettua doppio click nella casella bianca di lato
    7) Automaticamente il tipo di evento viene associato al componente e la relativa routine (metodo)
       evento appare nel codice scritta in modo automatico
    8) Aggiungere adesso il codice desiderato all’interno della routine evento, che dovrà essere eseguito
       quando l’evento viene richiamato.

Radiobutton (Windows Form) / TRadioButton (VCL)
In un progetto proposto e realizzato come esercitazione di laboratorio è stata utilizzata una serie di pulsanti
radio, altrimenti detti in inglese radiobutton. Questi controlli operano in gruppo e la selezione di ognuno
di essi è alternativa alle altre dello stesso gruppo, vale a dire solo un radio di un certo gruppo può essere in
uno stato di selezione.
I controlli radio sia in Windows Form che in VCL hanno anche annessa una scritta abbinata al radio stesso,
esplicativa della voce selezionata.
Un solo gruppo di radio può essere utilizzato in modo piuttosto semplice. Basta posizionare i radiobutton
sulla form, dare loro dei nomi (diversi) e controllare il loro stato di selezione, tramite la proprietà Checked.
Tale proprietà è presente con lo stesso nome e significato sia In Windows Form che nelle VCL, ossia
permette di controllare se un certo radio sia o no selezionato.
Nel caso sulla form fosse necessario avere più gruppi indipendenti di radio, allora:
      In Windows Form incolla prima uno speciale componente di raggruppamento detto GroupBox. Su
         di esso si “incolla” il primo gruppo di radio. Si ripete l’operazione con altri eventuali gruppi. In tale
         modo i vari gruppi agiscono in modo indipendente.
      La proprietà Text del componente permette di regolare la scritta esplicativa del gruppo stesso di
         componenti.
      Una metodica del tutto simile si utilizza con la libreria di componenti VCL. Anche qui esiste uno
         specifico componente capace di creare gruppi di radio e farli funzionare in modo indipendente,
         esso è detto TGroupBox e fa parte della palette dei componenti Standard. Per aggiungere i
         componenti radio al groupbox si selezionano i radio e si rilasciano sul groupbox. I componenti
         radio all’ interno di ogni groupbox lavorano in modo indipendente.
                                                   Pagina 10
La proprietà Caption del componente permette di regolare la scritta esplicativa del gruppo stesso di
        componenti.

Timer (Windows Form) / TTimer (VCL)
E’ un componente che è stato utilizzato ad esempio nel progettino dell’orologio digitale. Si tratta di un
componente capace di produrre ciclicamente eventi ad intervalli di tempo predeterminati dal
programmatore. L’evento che può essere associato al Timer è uno solo ed è OnTimer nelle VCL e Tick in
Windows Form. Il componente TTimer si trova nel gruppo di componenti System in C++ Builder e Timer
nel gruppo Components in Visual C#.
Il componente Timer / TTimer non è mai visibile, quindi non è un componente grafico. Nonostante ciò, per
aggiungere lo stesso al progetto si opera come se esso fosse un componente come gli altri ossia visibile.
L’icona del componente è un orologio.
Il componente in Windows Form e anche nelle VCL possiede la proprietà Enabled, che è messa a false. Per
attivare il suo funzionamento si deve quindi portare a true tale proprietà, altrimenti il timer non produce gli
eventi ripetuti previsti.
La proprietà Interval ha lo scopo di indicare l’intervallo di tempo in millisecondi ogni quanto viene
richiamato l’evento del timer; essa ha lo stesso nome e scopo sia in Windows Form che in VCL.
Ovviamente anche il Timer ha una proprietà Name per dare ad esso uno specifico nome.
Per i componenti senza visibilità sull’interfaccia non hanno senso le proprietà Top, Left, Width ed Height.

PictureBox (Windows Form) / TImage (VCL)
Nel progettino in C# cui si doveva indovinare il numero segreto generato dal computer, abbiamo fatto uso
di due PictureBox. Questo componente è utilizzato in Windows Form per visualizzare immagini sulla form
stessa. Nel nostro caso abbiamo caricato l’immagine tramite la proprietà Image (Windows Form).
Poi abbiamo imposto all’immagine stessa di assumere le dimensioni stesse del controllo effettuando una
operazione di ridimensionamento / cambio delle proporzioni , detta strech. Questa operazione è attivata
in questo controllo dalla proprietà SizeMode messa a StrechImage (noermalmente essa è a Normal).
In questo modo abbiamo costretto l’immagine originale a ridimensionarsi fino a essere completamente
visibile nel controllo.
Nel caso di C++ Builder si può utilizzare un componente del tutto equivalente detto TImage (sezione dei
componenti aggiuntivi). Il componente viene ridimensionato e posizionato, poi con la proprietà Picture
sarà possibile caricare l’immagine voluta e visualizzarla. La proprietà Strech del controllo effettua lo strech
dell’ immagine caricata se posta a true.
La proprietà Visibile, permette di regolare la visibilità dell’immagine caricata, senza scaricarla dal controllo.

Box di messaggio
Non sono dei veri componenti, ma sono delle particolari form (di solito che appaiono in modalità modale4),
atte a mostrare messaggi all’utilizzatore del programma (grafico).
In questa sezione, in base a quanto utilizzato anche nei progettini fin qui affrontati, considereremo solo box
di messaggio con un solo pulsante di conferma (Ok), nelle quali non essendoci alternative, non si pone il
problema di comprendere quale pulsante sia stato premuto prima di chiudere la form di messaggio.

4
  Una form è in modalità modale, se essa, una volta apparsa, è l’unica form del programma su cui può operare
l’utente. Lo stato del programma, in background, resta “congelato”, in quanto l’utente non può accedere a nessuna
delle funzionalità delle form in background finchè non chiude la form principale.
                                                    Pagina 11
In Visual C# si producono con metodi cha appartengono ad una apposita classe MessageBox, preposta a
generare tali form in molte forme e varianti.
Il metodo che viene usato per produrre box di messaggio è lo Show, che a seconda
del numero di parametri indicati produce finestre con caratteristiche diverse.
Ad esempio l’istruzione:
MessageBox.Show("Semplice messaggio", "Titolo");
crea una semplice MessageBox con solo messaggio e titolo, mentre la specifica di

alcuni altri parametri consente di avere delle box con tutte le caratteristiche:
      MessageBox.Show("Semplice messaggio",
"Titolo",MessageBoxButtons.OK, MessageBoxIcon.Information);
Da notare che i valori di combinazioni di pulsanti e delle icone sono propri di
apposite enumerazioni MessageBoxButtons che contiene diversi possibili valori
quali Ok, OkCancel, YesNo, ed altri e MessageBoxIcon, che contiene costanti che
definiscono il possibile tipo di icona, quali Information, Question, Warning ed altri.

In C++ Builder sono utilizzate due funzioni VCL per produrre delle finestre di messaggio:
       ShowMessage – Crea una form con il solo pulsante Ok e una scritta esplicativa. La form di
         messaggio non ha icona ed il titolo non è
         regolabile. Ha un solo parametro, ossia il
         testo da scrivere.
         ShowMessage(“Questo e’ il messaggio”);
       MessageDlg – Permette di creare form di
         messaggio più articolate e con più elementi regolabili, tra cui un icona, il numero e tipo di pulsanti.
         Ha 5 parametri:
              o Messaggio
              o Icona (del tipo di messaggio)
              o Pulsanti da visualizzare
         Il quarto parametro relativo all’help contestuale, per scopi comuni, viene di solito messo a 0.
Ad esempio il comando C++ Builder:
MessageDlg("Messaggio                                 da
comunicare",mtInformation,TMsgDlgButtons()
viene utilizzata direttamente. Il metodo acquisisce come parametro il valore originario e rende un risultato
che è il tipo di valore desiderato.
Le conversioni, in questo caso sono effettuate da apposite funzioni VCL StrToInt(…) e viceversa IntToStr(…)
preposte a convertire interi con stringhe e viceversa. Nella libreria VCL sono a disposizione numerose
funzioni per effettuare conversioni quali StrToDate e DateToStr o StrToFloat e FloatToStr, ed altre.

Gestione degli errori in C# e C++ Builder
In alcuni listati abbiamo visto esempi di utilizzo di operazioni dotate di controllo su eventuali errori
dovessero accadere durante l’esecuzione del codice.
In particolare un esempio di semplice controllo di errore è facilmente applicabile al nostro programma che
effettua la somma, riportato nei primi paragrafi di questa dispensa.
In particolare il punto dove ovviamente potrebbero accadere delle situazioni di errore sono le conversioni
dei valori letti dalle box di testo, ove l’utente ha inserito i due addendi.
Tali conversioni sono da alfanumerico a numerico (abbiamo presunto i numeri siano interi).
Due sono i possibili motivi di errore:
      L’utente non inserisce alcun dato
      L’utente inserisce dati non convertibili (ad. es. la stringa “abc” o altra) in un numerico intero
 In ambiente .NET questa situazione produce subito una eccezione che viene segnalata da una apposita
finestra mentre il programma stà girando.
Una cosa simile con analoga modalità avviene quando l’eseguibile C++ Builder incorre in un errore di
conversione.        In questi casi però il motivo della situazione di errore non viene esplicitato, e quindi è
difficile capire cosa sia successo e quale sia la causa effettiva di errore.
In questo caso si può decidere di realizzare una gestione custom dell’errore stesso che aiuti a comprendere
con più precisione quale sia la causa del problema e a segnalarlo all’utente in modo semplice.
Il controllo di errore sia in C# che in C++ viene fatto attraverso il costrutto sintattico try….catch….
Nella parte try si mettono le istruzioni da controllare, ossia si controlla se esse producano errori, mentre
nella parte catch, oltre ad un filtro sulla tipologia/e di errore “catturata”, si predispongono le operazioni
che devono essere svolte quando l’errore si verifica ed è del tipo previsto dalla specifica istruzione catch.
Ad esempio per controllare errori di conversione relativi ai valori inseriti nelle box “Addendo 1” e “Addendo
2” del programma somma. Le conversioni normalmente effettuate in condizioni di dati corretti possono
viceversa fallire, e quindi produrre errori di run-time. A questo punto un frammento di codice del
seguente tipo può gestire qualunque errore legato al problema degli input errati:
             int n1 = 0, n2 = 0, ris;
              bool errore = false;

              try
              {
                    n1 = Convert.ToInt32(txtAdd1.Text);
                    n2 = Convert.ToInt32(txtAdd2.Text);
              }
              catch (FormatException fe)
              {
                  MessageBox.Show("Valori degli addendi non adeguati.", " - Errore - ");
                  errore = true;
              }

              if (!errore)
              {
                  ris = n1 + n2;

                    txtRisultato.Text = Convert.ToString(ris);
                                                 Pagina 13
}
In pratica il blocco try / catch entra in azione qui per motivi di dati non convertibili, ed allora viene
visualizzata una box di messaggio, oltre a non eseguire il codice successivo, ossia quello che effettuerebbe
la somma (ma non in questo caso mancando i dati).          FormatException è il tipo di errore intercettato, e
questa eccezione viene prodotta quando vi sono problemi a convertire i dati di input verso il tipo intero
previsto.
Con una metodica del tutto simile si può affrontare il problema di gestire analoghi errori in C++ Builder,
tramite un controllo di errore gestito anche da apposite classi VCL.
Con una logica del tutto simile alla precedente il codice C++ Builder è:
        int n1, n2, ris;
  bool errore = false;

         try {
                     n1 = StrToInt(edtAdd1->Text);
                     n2 = StrToInt(edtAdd2->Text);
         }
         catch (EConvertError &e)
         {
                 ShowMessage("Dati inseriti non congruenti con l'operazione.");
                 errore = true;
         }

         if (! errore)
         {
                    ris = n1 + n2;

                     edtRisultato->Text = IntToStr(ris);
         }
Come è possibile vedere la logica dei due linguaggi è del tutto simile a parte qualche dettaglio sintattico.
Anche qui la parte che controlla se ci sono errori è il try e c’è l’attivazione del codice nella parte catch se
l’errore è della tipologia della classe indicata come parametro del catch. Il puntatore ad oggetto e,
permette di accedere ad alcune informazioni proprie dello specifico errore accaduto.
In questo caso la tipologia di eccezione corretta da usare è EConvertError. Si tratta di una classe preposta a
gestire errori di conversione, essa è una tipologia di errore la cui gestione è prevista dalle librerie VCL.
Altre classi di errore VCL sono elencate in:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/VCL_Exception_Classes

                                                           Pagina 14
Puoi anche leggere