Il 0% ha trovato utile questo documento (0 voti)
8 visualizzazioni122 pagine

Io Programmo 74

Caricato da

urajco
Copyright
© All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
8 visualizzazioni122 pagine

Io Programmo 74

Caricato da

urajco
Copyright
© All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd

COP.

IoProg N°74+CD+libro ok 8/10/2003 18:45 Pagina 1

ioProgrammo

PASSO PASSO: UN APPLICATIVO


RTAGE
REPSOIV O PER IDENTIFICARE CHI TI TELEFONA
ESCLU
L IM P IATDICIA
O L’INFORMA ✔ RIVISTA+LIBRO+CD E14,90
VERSIONE PLUS VERSIONE STANDARD

RIVISTA+CD E6,90
DEL Periodicità mensile • NOVEMBRE 2003 • ANNO VII, N.10 (74)
Poste Italiane • Spedizione in a.p. - 45% • art. 2 comma 20/b legge 662/96 - AUT. N. DCDC/033/01/CS/CAL
Anno VII - N°10 (74)

DAI VOCE
Sviluppare applicazioni VB che interagiscano con la voce - Realizzare un player audio in stile WinAMP - Applicazioni distribuite: la briscola in rete

EGATO
IN ALL

ALLE APPLICAZIONI
Visual Basic: come sviluppare un software SISTEMA
che parla e obbedisce ai comandi vocali Trasformare un
documento XML
✔Sintesi della voce in codice C#
✔Nuove tecniche NETWORKING
di riconoscimento Accesso multicanale
✔Il tutorial ai dati con Flash MX
e Web Service
completo VB: l’accesso
alle risorse di rete
PALMARI
Pocket PC: operazioni
remote sul server
database
ELETTRONICA

Java
La rotazione del polso
in un braccio meccanico
ioProgrammo (plus) Anno VII - N° 10 (74) • E 14,90

La programmazione

multimediale
del Sony AIBO
ADVANCED
Realizzare un player audio Delphi 7: attachment
in stile Winamp in SOAP
CORSI
TRATTAMENTO IMPARARE
DEL TESTO GIOCANDO… Visual Basic, Java,
Le Regular Expression Applicazioni distribuite: C++, [Link], C#,
EDIZIONI MASTER

[Link]
diventano facili con .NET la briscola in rete MATLAB
IOP74

IOP74

IOP74

IOP74

IOP74

IOP74

SCOPRI LA NUOVA SEZIONE CHE METTE ALLA


PROVA IL TUO INTUITO DI PROGRAMMATORE 2 PUNTI 2 PUNTI 2 PUNTI 2 PUNTI 2 PUNTI 2 PUNTI
004 editoriale 8-10-2003 19:00 Pagina 1 Giancarlo Sicilia Lavori in Corso:ioProgrammo:74:004 editoriale:

CONTENTS Questo mese su ioProgrammo

Anno VII - n. 10 (74) Novembre 2003


News 6
Software sul CD-Rom 10
Uscire dalla crisi G
Soluzioni
La funzione T9 dei cellulari
22

S crivo queste note dallo SMAU, ultimo giorno di fiera. Chi di voi ha
avuto l’opportunità di passare e dare uno sguardo agli stand presenti,
si sarà certamente accorto della estrema riduzione, rispetto agli anni pas-
G
Teoria & Tecnica
Una segreteria studenti in VB
28
28
G Importare documenti XML con C# (prima parte) 36
sati, del numero di aziende presenti. La crisi del settore informatico e quel- G Annunci on-line con Web Service e Flash 41
la più generale dell’economia italiana, possono spiegare solo in parte la G Regular Expressions con .NET 45

riduzione degli investimenti che ha ridotto SMAU ad una pallida ombra G Giocare a briscola in rete con C++ Builder 49

dell’evento che fu. La radicale trasformazione dell’informatica, partita Reportage 54


come settore autonomo e divenuta lievito onnipresente e determinante G Olimpiadi Internazionali dell’Informatica 2003

per l’intero mondo tecnologico, non è stata probabilmente colta da molti Tips&Tricks 56
dei principali operatori. A fronte di un netto calo dei visitatori (alla fine Elettronica 62
credo arriveremo ad un -15%), c’è da registrare un aumento di presenze fra G Braccio meccanico: rotazione del polso

gli addetti al settore, testimonianza della crescita dell’interesse nell’infor- Sistema 67


G Un player audio tutto Java 67
matica come business. Meno lucette e più sostanza: potrebbe essere lo slo-
G “Scopri” chi ti telefona 72
gan di questa manifestazione che, nel bene e nel male, resta uno specchio G Java Legge (e interpreta) XML 75
fedele dello stato dell’informatica in Italia. Qui a ioProgrammo continue-
Palmari 79
remo a seguire la nostra strada, alla ricerca del lato piacevole della tecno- G Remote Data Access con PocketPC 79
logia, sempre attentissimi ai vostri suggerimenti. Fatevi sentire! G Il palmare accede al DB aziendale 81

I corsi di ioProgrammo 85
P.S.
G Java • Dalla ‘a’ alla ‘z’ 85
Non possiamo non ringraziarvi per l’attenzione che state dedicando al G [Link] • La gestione del controllo ListView 89
nostro ultimo nato: il sito di ioProgrammo continua a crescere grazie al G C# • Interfacce nella programmazione .NET 93
vostro interesse e nuove iniziative stanno per essere varate. Stay tuned… G C++ • La gestione delle eccezioni 97

raffaele@[Link] G MATLAB • Uno sguardo all’ambiente di sviluppo 101

❏ CD ❏ WEB G VB • Un visualizzatore di immagini 106

nome_file.zip Advanced Edition 111


G Attachment in SOAP con Delphi 7 111
[Link]
G Network API in VB (prima parte) 117
All’inizio di ogni articolo, troverete un nuovo simbolo che indicherà la G La programmazione dei Sony AIBO 122
presenza di codice e/o software allegato, che saranno presenti sia sul
CD (nella posizione di sempre \soft\codice\ e \soft\tools\) sia sul Web, Biblioteca 126
all’indirizzo [Link] Per scaricare software e
codice da Internet, ogni mese indicheremo una password differente.
InBox 127
Per il numero che avete fra le mani la combinazione è: L’enigma di ioProgrammo 130
Username: neo Password: matrix G Il giro di cavallo

Via Cesare Correnti, 1 - 20123 Milano primo numero utile, successivo alla data della richiesta.
Tel. 02 831212 - Fax 02 83121207 Sostituzioni: Inviare il CD-Rom difettoso in busta chiusa a:
e-mail advertising@[Link] Edizioni Master Servizio Clienti - Via Cesari Correnti, 1 - 20123 Milano
Anno VII - [Link] 10 (74) - Novembre 2003 - Periodicità: Mensile
Rete Vendita Serenella Scarpa, Cornelio Morari, Roberto Piano, John F. Assistenza tecnica: ioprogrammo@[Link]
Reg. Trib. di CS al [Link] 593 del 11 Febbraio 1997
Alborante
Cod. ISSN 1128-594X Servizio Abbonati:
Segreteria Ufficio Vendite Daisy Zonato
E-mail: ioprogrammo@[Link]
tel.02 831212
[Link]
Editore Edizioni Master S.r.l. @ e-mail: servizioabbonati@[Link]
[Link]
Sede di Milano: Via Cesare Correnti, 1 - 20123 Milano
Tel. 02 831212 - Fax 02 83121206 Stampa: Rotoeffe Via Variante di Cancelleria, 2/6 - Ariccia (Roma)
Direttore Editoriale Massimo Sesti
Sede di Rende: [Link] Lecco, zona industriale - 87030 Rende (CS) Stampa CD-Rom: Deluxe Italy S.r.l. - via Rossini, 4 - Tribiano (MI)
Direttore Responsabile Romina Sesti
Amministratore Unico: Massimo Sesti Distributore esclusivo per l’Italia: Parrini & C S.p.A.
Responsabile Editoriale Gianmarco Bruni
Via Vitorchiano, 81 - Roma
Responsabile Marketing Antonio Meduri
Abbonamento e arretrati
Editor Gianfranco Forlino
ITALIA: Abbonamento Annuale: ioProgrammo Basic(11 numeri): c 52,90 Finito di stampare nel mese di Ottobre 2003
Coordinamento redazionale Raffaele del Monaco
sconto 30% sul prezzo di copertina c 75,90.
Redazione Antonio Pasqua, Thomas Zaffino
ioProgrammo Plus (11 numeri + 6 libri): c 86,90 sconto 30% sul prezzo di Nessuna parte della rivista può essere in alcun modo riprodotta senza
Collaboratori M. Autiero, L. Buono, M. Canducci, A. Cangiano,
copertina c 123,90. autorizzazione scritta della Edizioni Master. Manoscritti e foto
M. Del Gobbo, F. Grimaldi, F. Lippo, R. Lo Storto, D. Magoga,
ESTERO: Abbonamento Annuale: ioProgrammo Basic (11 numeri): originali, anche se non pubblicati, non si restituiscono. Edizioni Ma-
A. Marroccelli, P. Martemucci, S. Monni, G. Naccarato, C. Pelliccia,
c 151,80. ioProgrammo Plus (11 numeri + 6 libri): c 257,00 ster non sarà in alcun caso responsabile per i danni diretti e/o indiretti
P. Perrotta, L. Salerno, F. Sara, L. Spuntoni, E. Tavolaro, S. Tura
Costo arretrati (a copia): il doppio del prezzo di copertina + c 5.32 spese derivanti dall’utilizzo dei programmi contenuti nel supporto multime-
F. Vaccaro, D. Vesicchio, V. Vessia,
(spedizione con corriere). Prima di inviare i pagamenti, verificare la diale allegato alla rivista e/o per eventuali anomalie degli stessi.
Segreteria di Redazione Veronica Longo
disponibilità delle copie arretrate allo 02 831212. Nessuna responsabilità è, inoltre, assunta dalla Edizioni Master per
Realizzazione grafica Cromatika S.r.l. La richiesta contenente i Vs. dati anagrafici e il nome della rivista, dovrà danni o altro derivanti da virus informatici non riconosciuti dagli
Responsabile grafico: Paolo Cristiano essere inviata via fax allo 02 83121206, oppure via posta a EDIZIONI MAS- antivirus ufficiali all’atto della masterizzazione del supporto. Nomi e
Coordinamento tecnico: Giancarlo Sicilia TER via Cesare Correnti, 1 - 20123 Milano, dopo avere effettuato il paga- marchi protetti sono citati senza indicare i relativi brevetti.
Impaginazione elettronica: Aurelio Monaco mento, secondo le modalità di seguito elencate:
“Rispettare l’uomo e l’ambiente in cui esso vive e lavora è una parte di tutto ciò • cc/p n.16821878 o vaglia postale (inviando copia della ricevuta del versa-
che facciamo e di ogni decisione che prendiamo per assicurare che le nostre mento insieme alla richiesta);
operazioni siano basate sul continuo miglioramento delle performance • assegno bancario non trasferibile (da inviarsi in busta chiusa insieme alla L’Universo Tecnologico
ambientali e sulla prevenzione dell’inquinamento” richiesta); [Link]
• carta di credito, circuito VISA, CARTASI’, MASTERCARD/EUROCARD,
Certificato UNI EN ISO 14001
(inviando la Vs. autorizzazione, il numero della carta, la data di scadenza e
N. 9191 CRMT Edizioni Master edita:
la Vs. sottoscrizione insieme alla richiesta).
• Bonifico bancario intestato a Edizioni Master S.r.l. c/o Banca Credem Idea Web, Go!OnLine Internet Magazine, Win Magazine, PC Fun extreme,
Realizzazione Multimediale SET S.r.l. S.p.a. c/c 5000 ABI 03032 CAB 80880 (inviando copia della distinta insieme Quale Computer, DVD Magazine, Office Magazine, La mia Barca,
Coordinamento Tecnico Piero Mannelli alla richiesta). ioProgrammo, Linux Magazine, Softline Software World, HC Guida
Realizzazione CD-Rom Paolo Iacona all’Home Cinema, <tag/>, MPC, Discovery DVD, Computer Games Gold,
SI PREGA DI UTILIZZARE IL MODULO RICHIESTA ABBONAMENTO POSTO inDVD, I Fantastici CD-Rom, PC VideoGuide, I Corsi di Win Magazine,
Pubblicità Master Advertising s.r.l. NELLE PAGINE INTERNE DELLA RIVISTA. L’abbonamento verrà attivato sul I Filmissimi in DVD, La mia videoteca, Le Collection.
006_007 News 8-10-2003 17:38 Pagina 6

NEWS

News WINDOWS XP
NOVITÀ
PER LE
APPLICAZIONI
MULTIMEDIALI
METANOLOGY P ronta la versione beta
nativa a 64 bit del siste-
clienti attualmente in pos-
sesso di applicazioni a 32 bit

N orpath ha rilasciato la
versione 2.1 del suo
Norpath's Norpath Elements
ENTRA
IN ECLIPSE
ma operativo Windows XP,
progettata per supportare i
sistemi a 64 bit, incluse le
compatibili con Windows
XP, di utilizzare un sistema
operativo a 64 bit. L'archi-
Studio, un software di piattaforme AMD basate su tettura WOW64 sfrutta l'ar-
authoring che permette di
creare e distribuire
U n nuovo membro si
aggiunge alla
prestigiosa e ormai
tecnologia AMD64
Il sistema operativo aggior-
chitettura AMD64 rendendo
compatibili le applicazioni a
applicazioni multimediali lunga lista di aziende nato a 64 bit, chiamato Win- 32 bit e permettendone l'e-
interattive. che supportano il dows XP 64-Bit Edition for secuzione con un buon li-
Tra le caratteristiche: consorzio Eclipse. 64-Bit Extended Systems è vello di prestazioni.
In contemporanea con progettato per supportare i "Abbiamo sentito dire dai
un editor di temi l’ingresso in Eclipse, sistemi a 64 bit, incluse le nostri clienti che, fino ad
disponibile a run-time per Metanology ha piattaforme AMD basate su ora, il maggiore ostacolo
cambiare al volo il look&feel annunciato la nuova tecnologia AMD64. Il siste- nell'investimento su tecno-
delle applicazioni; release di MDE ma operativo funzionerà su logie a 64 bit è stata l'impos-
un sistema di monitoraggio (Model-driven desktop con processore sibilità di far funzionare in
per le azioni compiute dagli Development AMD Athlon 64 e worksta- maniera efficiente le appli-
utenti; Environment) uno tion con processore AMD cazioni a 32 bit su sistemi a
un nuovo sistema di strumento di viluppo Opteron. 64 bit", ha affermato Fa-
database indirizzato alla model-driven, basato su Un vantaggio fondamentale brizio Albergati, direttore
creazione di quiz e test; Eclipse, conforme alle del nuovo sistema operativo Gruppo Windows Client e
la possibilità di inviare specifiche fornite è la tecnologia Microsoft Mobility di Microsoft Italia.
e-mail dalle applicazioni dall’Object Management Windows on Windows 64 "Combinando Windows XP
che si vanno a realizzare. Group's Model Driven (WOW64), che consentirà ai ed i nuovi processori
[Link] Architecture (MDA).
[Link]
SMALL COMPUTING
NUOVI
ORIZZONTI ESPIAL NEL FUTURO BIG BLUE
INTEGRA FLASH
PER JAVA
E XML
M acromedia ed
Espial hanno
I laboratori dell’IBM stanno lavorando su una nuova tecnolo-
gia che potrebbe portare grandi benefici al mercato wireless.

N etKernel, un innovativo
sistema operativo
virtuale Open Source, offre
raggiunto un accordo
per integrare la
Fino ad ora i chip per la trasmissione dei dati erano distinti e
non integrabili con quelli riservati alla elaborazione. Le due ti-
pologie si avvalgono infatti di leghe di silicio diverse. Con la
una nuova piattaforma per tecnologia Flash nel nuova tecnologia che IBM sta mettendo a punto, questa dico-
la manipolazione di XML. browser Espial Escape, tomia si potrebbe sanare e potremo presto vedere integrati su
Basato su Java, consente appositamente un singolo chip tutte le capacità di calcolo e trasmissione ne-
un’estrema flessibilità nel realizzato per dispositivi cessarie al funzionamento di un dispositivo wireless. Ai van-
trattamento e nella embedded. taggi in termini di dimensioni, si andranno ad aggiungere an-
visualizzazione di dati XML: che vantaggi in termini di autonomia: i nuovi chip consume-
tutto il processo di sviluppo ranno fino a cinque volte meno degli attuali.
e deploy di processi XML [Link]
sono ora possibili con Espial Escape è stato
grande razionalità e scelto da produttori del
semplicità. calibro di Intel,
È incluso il supporto al Sim- Motorola, NEC,
ple Tree Manipulation M@gicMedia, Siemens e
Language (STM) e a XPath DaimlerChrysler, e
Document API (XDA). l’accordo siglato per
Inoltre, grazie alla sua l’integrazione di Flash
modularità, può facilmente apre nuove strade al
essere esteso e anche gioiello Macromedia ed
personalizzato. ai suoi sviluppatori.
La nuova tecnologia per la costruzione
[Link]
[Link] di chip.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 6/Novembre 2003
006_007 News 8-10-2003 17:39 Pagina 7

NEWS

64 BIT IN BETA UN FUTURO NUOVO


AMD64, è possibile ottenere ti di videogiochi entreranno
tutta la potenza e la memo- in una nuova dimensione di PER LE CABINE
ria necessaria, pur conti-
nuando a utilizzare le stesse
realismo, mentre gli esperti
di digital media saranno in TELEFONICHE
applicazioni".
Windows XP 64-Bit Edition
per Extended Systems a 64-
grado di creare contenuti
con una qualità normal-
mente raggiunta soltanto
L a British Relecom ha iniziato ad installare degli Access
Point Wi-Fi nelle cabine telefoniche pubbliche della sua
rete. Oltre 108.000 sono le cabi-
Bit è stato progettato per es- dai professionisti. ne di proprietà BT, ma solo una
sere utilizzato su computer La principale differenza tra parte verranno rese Wi-Fi ena-
ad elevate prestazioni. In al- l'elaborazione basata su bled, seguendo una strategia
tre parole, gli utenti potran- Windows XP a 32 piuttosto che privilegia le zone a più in-
no superare il limite della che a 64 bit risiede nella ca- tenso affollamento di uffici, i cui
memoria fisica, pari a 4 gi- pacità della versione a 64 bit dipendenti possano effettiva-
gabyte, di un computer a 32 di utilizzare una quantità mente approfittare di questa
bit. notevolmente superiore di opportunità.
La potenza della nuova piat- memoria di sistema. La ver- Le nuove installazioni saranno
taforma Windows renderà sione a 64 bit di Windows XP a prova di vandali, possono re-
possibili nuove esperienze supporterà inizialmente fi- sistere ai rigidi inverni londine-
sul proprio PC, soprattutto no a 16 GB (gigabyte) di si e, grazie alle dimensioni ri-
nell'area dell'advanced ga- RAM e un massimo di 8 TB dotte, potranno montate in mo-
ming, della creazione di (terabyte) di memoria vir- do invisibile nelle vecchie cabi-
contenuti digitali e del vi- tuale. ne rosse che ancora caratteriz-
deo editing. Gli appassiona- [Link] zano parte dell’Inghilterra.

APPLICAZIONI
LA SFIDA DI SUN .NET SU
LINUX? ORA
È REALTÀ!
I l dominio del mercato dei sistemi
desktop è saldamente nelle mani di
Microsoft, eppure qualcosa potrebbe
cambiare. N ovell è certa che entro la
fine dell'anno sarà pronta
a lanciare sul mercato la prima
Almeno stando alle dichiarazioni di Sun
che ha finalmente svelato cosa si celava versione commerciale della
dietro il progetto Mad Hatter: una tecnologia che consente di far
completa suite di strumenti per il girare applicazioni [Link] su
desktop computing, sia per piattaforma Linux. MONO, di cui già si è
x86 che SPARC su sistemi operativi sentito parlare molto, sarà rila-
Solaris o Linux, e che annovera StarOffi- sciato in via definitiva entro la
ce 7, Mozilla, la piattaforma di sviluppo fine dell'anno. Questo il comu-
I moduli sono la novità più ghiotta. nicato rilasciato da Novell.
J2SE, applicazioni per la posta elettro-
nica e per il messaging, insomma tutto, Il progetto Mono, frutto di un
o quasi, si configuri come necessario per
intenso lavoro di sviluppo, si
un utilizzo tipico del PC. Come partner di
compone di un compilatore
questa iniziativa, nonché fornitori di
per il linguaggio C# e [Link]
importanti tasselli software, troviamo
con cui è possibile sviluppare
nomi del calibro di Computer Associates,
applicazioni compatibili con la
Adobe e RealNetworks, tutti fiduciosi in
piattaforma di Microsoft; un
nella possibilità di fare breccia nell’im-
compilatore just-in-time Com-
pero Microsoft. Java Desktop System,
mon Language Runtime, che
questo il nome della suite, avrà come
consente a Linux di far girare
asso nella manica il prezzo di appena
applicazioni scritte sotto un
100 dollari e sarà disponibile da di-
qualsiasi altro sistema operati-
cembre 2003.
vo che supporti [Link].
[Link]
[Link]

Novembre 2003/GGG
h t t p : / / w w w. i o p r o g r a m m o . i t
7 G
006_007 News 8-10-2003 17:14 Pagina 8

NEWS

L'ITALIA POTRÀ
VISIONARE
DOPO 20 ANNI,
IL COFONDATORE
LINDOWS 4.0
IL CODICE
SORGENTE
DI SUN
MICROSYSTEMS
ARRIVA IN ITALIA
DI WINDOWS ABBANDONA

I l Ministro I l sistema operativo, un


ibrido tra Windows e Li-
Le società [Link] e
Questar commercializze-
dell'Innovazione e le
Tecnologie, Lucio Stanca,
B ill Joy, attuale Chief
Scientist della società,
lascia la Sun. A lui si devono
nux, arriverà in Italia in
modo ufficiale con la sua
ranno e promuoveranno la
vendita sul mercato italia-
ha dichiarato di aver siglato molte delle rivoluzionare più recente versione: Lin- no della versione inglese
con Microsoft il protocollo idee: Solaris, i microproces- dowsOS 4.0 di LindowsOS 4.0, il siste-
d'intesa "Government sori Sparc e Java, la versione
Security Program", che Berkeley del sistema
consente al CNIPA (Centro operativo Unix (BSD), questi
Nazionale per l'Informatica alcuni dei progetti ai quali
nella Pubblica Bill Joy ha dedicato ben 20
Amministrazione), l'accesso anni di lavoro. Un vero
di codice. genio dell'informatica che
Secondo quanto dichiarato ha così commentato la sua
dal Ministro, l'accordo con decisione: "Dopo 21 anni ho
apprezzato l'opportunità di
il big di Redmond è
creare innovazione
strategico e importante per
fornitami da Sun, ma ho
la sicurezza e
deciso che è tempo di
l'interoperabilità dei
muoversi su differenti
sistemi informatici, una sfide".
tappa miliare per lo
sviluppo delle nuove
applicazioni tecnologiche SUSE LINUX
di cui beneficerà anche il 9.0 PRENDE
LA LAUREA
nostro Paese".
USA LA
MICROSOFT
L a nuova versione del si-
stema operativo di casa
SUSE riceve ufficialmente la
TASTIERA
LANCIA
IL SITO WEB
certificazione LSB già prima
della messa in commercio
CHE NON C'È!
OFFICE- del prodotto, confermando

INFOSITE la piena compatibilità del


nuovo sistema operativo L a società israelia-
na VKB presenta

D opo l'ok alla produzione


di Office 2003, Microsoft
ha messo online un portale
con gli standard universali
dettati dal mondo Linux.
LSB, il gruppo di lavoro atti-
una sorta di tastiera
"fantasma": una rap-
presentazione olo-
dedicato alla nuova versione. vo all'interno del Free grafica di una ta-
Si tratta di un portale Standard Groups e che si stiera. Via quindi le
contenente news, help- occupa della verifica della vecchie, pesanti e
online, training, compatibilità agli standard ingombranti tastie-
aggiornamenti, add-on e dei prodotti rispetto alla po- re!
plug-in per la nuova release litica di Open Source Linux Grazie alla VKB, per
di Office 2003. e dei tools su base Gnu, ha mezzo di un partico-
sviluppato una stretta colla-
Chris Linnet, Group Manager lare laser che proiet-
borazione tra la comunità di
del sito, ha dichiarato che ta l'immagine di tut-
sviluppatori, le aziende
una buona parte delle risorse ti i tasti di una co-
Linux, gli ISV e i maggiori
saranno direttamente vendor presenti sul merca- mune tastiera, è
utilizzabili e scaricabili delle to, garantendo ai clienti, at- possibile digitare di-
applicazioni Office, senza traverso la certificazione di rettamente su una
dover impiegare il browser, un prodotto, il pieno rispet- qualsiasi superficie piana. Il sistema è ovviamente in
grazie ai sistemi di to degli standard di compa- grado di identificare il tasto virtuale premuto dall'uten-
transazione garantiti dal tibilità e di sicurezza sui te. E’ possibile usare la tastiera con un PC, un palmare o
supporto XML. quali si fonda Linux. un telefonino cellulare. Fantastico!
[Link] [Link]/lsb/cert/ [Link]

h t t p : / / w w w. i o p r o g r a m m o . i t
G 8/Novembre 2003
006_007 News 4-10-2003 9:43 Pagina 9

NEWS

DA HP UNA
FOTOCAMERA
CHE TRADUCE
LE SCRITTE
S ebbene sia ancora solo
un prototipo, questo ag-
geggio potrebbe rivoluzio-
gine contenente il testo da
tradurre e "aspettando" una
risposta contenente la tradu-
nare la vita di molte persone. zione. Del prodotto, ancora
Una normale macchina foto- in via sperimentale, non è
camera digitale ma con po- stata resa pubblica la data di
Il desktop della nuova versione di LindowsOS.
tenzialità enormi: tradurre le commercializzazione.
scritte dalle im- [Link]
ma operativo Linux-based OS, spicca Click-N-Run, il magini che ritrae.
che consente di far "gi- tool che consente di scari- Cartelli stradali,
rare" gran parte delle ap- care, installare e lanciare menu al ristoran-
plicazioni Windows aven- in modo automatico te, ricevute. La te-
do a disposizione, comun- un’applicazione qualsiasi, lecamera è in gra-
que, un sistema Linux. tra le oltre 1.800 messe a do di collegarsi
Tra i molti strumenti pro- disposizione da Click-N- ad un sito Inter-
posti all’interno dell’ulti- Run Warehouse. net, fornendo al-
ma versione di Lindows [Link] lo stesso l'imma-

SONY BORLAND
UTILIZZERÀ
ERICSON IL FRAMEWORK
WXWINDOWS
Z600 P er la sua nuova linea di prodotti C++
BuilderX Borland adotterà il framework
5000 colori, fotocamera incorporata, wxWindows, capace di fornire un nutrito
6 bluetooth, 32 suonerie polifoniche, set di API per scrivere applicazioni GUI su
effetto force-feedback (in stile controller diverse piattaforme.
PS2) per i videogame. Sony Ericsson, in oc- Così facendo, Borland conferma il suo inte-
casione di un evento dedicato alla stampa resse al mondo Open Source.
internazionale, ha presentato una gam- Inoltre, Borland ha annunciato la release di
ma di nuovi telefonini cellulari; tra Together per piattaforma .NET. L'annuncio
questi lo Z600, il più sofisticato dei tre è avvenuto in occasione della conferenza
telefoni cellulari presentati. La vera VSLive di Orlando. Todd Olson, chief scien-
novità è data dal controller force- tist di Together in Borland, ha dichiarato
feedback, ovvero una versione ri- che il nuovo prodotto è sviluppato comple-
dotta del classico controller per tamente in linguaggio C#, questo per ga-
PlayStation, chiamata Gameboard rantire la massima compatibilità di Toge-
EGB-10. ther con la nuova piattaforma .NET.
Si aggancia alla base dello Z600, Together è un ambiente completamente in-
fornendo all'utilizzatore quattro tegrato per la creazione di modelli, destina-
tasti (in stile PS2) e un pulsante to ai team che producono software e che
per il pollice. necessitano di accelerare il ciclo di sviluppo
[Link] applicativo.
[Link]

Novembre 2003/GGG
h t t p : / / w w w. i o p r o g r a m m o . i t
9 G
010-021 Software 8-10-2003 17:16 Pagina 10

SOFTWARE SUL CD Internet e multimedia

Il Software di ioProgrammo

Flash MX 2004
Professional
La versione completa del più celebre applicativo per la creazione
di progetti multimediali, ancora più semplice e potente.

D opo mesi di voci non confermate


e dichiarazioni ufficiali sulle
nuove caratteristiche tecniche, il 10
ne MX. La versione Professional pos-
siede tutte le caratteristiche della ver-
sione normale con in più dei compo-
più utilizzate. Una volta aperto un nuovo
file, la Start Page lascia il posto al nuovo
ambiente di lavoro (Fig.1), caratterizzato
Settembre 2004 la Macromedia ha nenti aggiuntivi creati per agevolare lo da una nuova veste grafica: nuove icone,
messo finalmente a disposizione i nuo- scambio di dati e numerose altre nuovi colori e una nuova disposizione dei
vi prodotti MX nella versione inglese. opzioni, molte delle quali pensate per contenuti. L'impressione generale resta,
Come di consueto, le sorprese non dialogare con programmi di terze parti. comunque, quella di un layout abbastanza
sono mancate: un player più veloce, fedele a quello precedente, nonostante i
nuovi strumenti di sviluppo e ben due gradevoli cambiamenti stilistici. Inoltre - a
nuove versioni, una dedicata ai desi- proposito di grafica - per quanto riguarda
gner (Flash MX 2004) ed una pensata
LA NUOVA gli strumenti di disegno, risulta quasi inva-
per i developer (Flash MX 2004 INTERFACCIA riata la Tools bar; l'unica novità rilevante è
Professional). Questa scelta di realizza- Appena lanciamo l’applicazione appare la lo strumento Polystar, presente nel menu a
re due pacchetti distinti testimonia la Start Page. Questa finestra, oltre a fornire comparsa attivabile dallo strumento Rec-
divisione di ruoli che la Macromedia una guida sulle novità più rilevanti, mostra tangle. Discorso diverso, invece, per la di-
ha individuato nell'utilizzo della tec- a sinistra un elenco dei nuovi templates e sposizione ed i contenuti dei pannelli, do-
nologia alla base di Flash, e che possia- al centro, sotto la voce create new, una ve troviamo non poche novità. Esplorando
mo definire l'evoluzione naturale di nuova tipologia di documenti, nonché una infatti la voce Window, notiamo che tutti i
una strategia di cui si potevano coglie- serie di opzioni che hanno il compito di pannelli sono stati riorganizzati in tre sot-
re i primi segnali a partire dalla versio- agevolare l'utente nell'uso delle procedure togruppi:

UTILIZZARE EFFETTI GRAFICI PREIMPOSTATI


CON I TIMELINE EFFECTS

Ci appare una nuova finestra di Una volta premuto ok, se


1
A seconda dell'effetto scelto, pos-
sono essere applicate suddivisioni
2 dialogo che ci chiede di regolare le
3 osserviamo la timeline, notiamo
in più livelli, duplicazioni, interpolazioni impostazioni dell'esplosione. E' che sono stati occupati 20 fotogrammi
o altro, il tutto senza dover nemmeno possibile regolare una serie di della linea temporale. Inoltre, nella
sfiorare la timeline. Facciamo un esem- paramentri, come ad esempio la durata, libreria il nostro simbolo grafico
pio, con un simbolo grafico costituito da la direzione, la rotazione degli elementi, originario è stato rinominato come
una semplice scritta. Una volta posizio- e così via. A destra c'è una piccola Explode3. Se clicchiamo sul simbolo con
nato il simbolo sul primo fotogramma anteprima dell'effetto, aggiornabile il tasto destro del mouse e attiviamo la
della linea temporale, selezioniamolo cliccando sull pulsante Update Preview, voce edit, possiamo verificare cosa è
con il tasto destro del mouse e attiviamo per capire come agiranno le nostre successo nella timeline del simbolo:
la voce Effects. Dall'elenco di effetti regolazioni. Lasciamo le opzioni di Flash ha creato automaticamente più di
disponibili, scegliamo Expolde. default e premiamo ok. 30 livelli e altrettante interpolazioni.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 10/Novembre 2003
010-021 Software 8-10-2003 17:17 Pagina 11

Internet e multimedia SOFTWARE SUL CD

IL PANNELO
BEHAVIOR

Il pannello Behavior, oltre a


1 sostituire la modalità normale,
prevede alcune nuove funzioni
estremamente utili. Adesso infatti è
possibile ordinare i livelli di un clip,
anche senza ricorrere al metodo
Fig. 1: La nuova interfaccia semplifica tutte le operazioni cui eravamo abituati. swapDepth(). Prima di tutto, creiamo
tre clip, che denomineremo
rispettivamente clip1, clip2 e clip3.
il gruppo Design panel, che comprende automatismi presenti nella precedente I tre clip devono essere posizionati
tutti i pannelli relativi agli strumenti di versione, è sopravvissuta solo la possibilità sullo stage, nello stesso fotogramma
disegno. di prelevare e trascinare dall'elenco a sini- del secondo livello, in modo da essere
il gruppo Development panel, con i stra (l'actions toolbox) i vari metodi e pro- parzialmente sovrapposti.
Selezioniamo il primo clip, in modo da
pannelli relativi alla programmazione. prietà, per poi posizionarli nell'action
creare un riferimento che permetta al
il gruppo Others panel, che raggruppa panel. In altre parole, si può scrivere il pannello Behaviors di mostrare
pannelli generali non catalogabili nelle codice solo nella modalità che conosceva- all'utente l'elenco di istruzioni valide
due precedenti categorie. mo come expert mode. Un'altra significati- solo per i MovieClip. Seguiamo quindi
va novità riguarda la presenza di una nuo- il percorso Windows>Development
panel>Behaviors e clicchiamo il
Bisogna specificare che, nella maggior va sezione, posta a sinistra, sotto il con-
pulsante Add Behavior,
parte dei casi, si tratta di una semplice sueto elenco di istruzioni: stiamo parlan- contraddistinto dal segno "+".
riorganizzazione di pannelli già esistenti, do del menu Script navigator, una novità Dal menu a comparsa, selezioniamo
anche se non mancano nuovi arrivi, come che consente di esplorare i codici inseriti Movieclip: così facendo appare tutto
ad esempio il pannello History, attraverso all'interno di diverse scene, fotogrammi o l'elenco di azioni valide per i clip
previste nel pannello in questione.
il quale è possibile ripercorrere i vari clip, senza ricorrere alla timeline. Questa
"passi" compiuti, cioé le varie fasi di un scelta evidenzia la volontà della Macro-
lavoro. Ci sono, tuttavia, anche pannelli media di relegare la timeline ad un settore
già esistenti, ma completamente ripensa- prettamente ed esclusivamente grafico,
ti, come il nuovo pannello Help. Una pic- scindendola dal gruppo di strumenti de-
cola rivoluzione riguarda il pannello Ac- stinati allo sviluppo. In ogni caso, non so-
tions (ora collocato nel gruppo dei Deve- no state dimenticate le esigenze di quegli
lopment panel), che presenta parecchie utenti che gradiscono una guida nella ste-
novità, la più eclatante di tutte consiste sura del codice: di fatto, il nuovo pannello
nella totale abolizione della modalità di Behaviors, che si può aprire con il percor-
scrittura normal mode. Come tutti gli so Window>Development panel>Beha-
utenti delle versioni precedenti sanno, viors, consente di inserire un discreto pac-
quando si apriva il pannello Actions, la chetto di codici ActionScript, in modo del Selezioniamo l'azione Bring to
2 front: così facendo, al primo clip
normal mode (nelle versioni italiane mo- tutto automatico. Il pannello è contestua-
dalità normale), attraverso una finestra di le, per cui, se si seleziona ad esempio un viene aggiunto un evento On Release
che, se innescato, lo posiziona
dialogo, aiutava a scrivere il codice me- fotogramma con il pannello aperto, nell'e-
automaticamente in primo piano, a
diante vari campi che, il più delle volte, lenco delle istruzioni disponibili compari- prescindere dalla sua posizione
prevedevano valori preimpostati tra cui ranno solo quelle valide per i fotogrammi iniziale. Per fare in modo che ogni clip
scegliere. Un modo comodo e funzionale, e così via. Indubbiamente questo approc- venga posto in primo piano ad ogni
di elaborare script, anche abbastanza cio è meno formativo rispetto alla vecchia evento On Release, bisogna ripetere
lo stesso procedimento anche per gli
complessi, senza mettere direttamente modalità normal, che consentiva di inseri-
altri due.
mano al codice. Adesso, invece, dei vari re un codice più complesso seguendo vi-

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/11 G
010-021 Software 4-10-2003 10:49 Pagina 12

SOFTWARE SUL CD Internet e multimedia

sivamente le varie fasi della sua composi- bili o delle funzioni diventano tutti case- se gli sviluppatori abituati ad usare Action-
zione. Oggi, un nuovo utente che dovesse sensitive (la variabile miavar è diversa da Script 1.0 potrebbero avere qualche inizia-
iniziare l'apprendimento di Flash, usando MiaVar). Inoltre, i dati sono diventati rigi- le diiffidenza, non c'è motivo di preoccu-
esclusivamente il pannello Behavior, ri- damente tipizzati: ad esempio, quando si parsi troppo (almeno con la versione
schierebbe di attuare delle soluzioni senza dichiara una variabile, bisogna specificare attuale): nei fatti, il nuovo ActionScript
comprenderne a fondo il meccanismo. Un il tipo di dato, in modo simile a quanto convive perfettamente con il vecchio che,
discorso paragonabile ai problemi che viene fatto in Java con una sintassi del per le funzionalità già esistenti, non ha
incontra chi impara ad usare DreamWea- tipo: var MiaVariabile:String=”esempio” - l'obbligo di rispettare le nuove convenzio-
ver, senza aver mai scritto una riga di e non semplicemente miaVariabile= ni. Anche l'uso del versatile prototype, che
HTML o JavaScript. ”esempio” come accadeva in ActionScript consentiva di aggiungere metodi persona-
1.0. Adesso è anche possibile scrivere vere lizzati ai propri oggetti e MovieClip, ades-
e proprie classi, o aggiungere sottoclassi a so convive con i nuovi procedimenti. Lo
classi già esistenti, creando dei file esterni stesso file swf, del resto, è compilato anco-
ACTIONSCRIPT 2.0 con estensione .as. In pratica, la classe si ra in ActionScript 1.0. Il giudizio su Flash
Continuiamo con le grosse novità. A parti- scrive con il nuovo pannello Script MX 2004 Professional è sostenzialmente
re dalla versione 2004, nasce ActionScript (File>New>ActionScript file), che agevola positivo. La rinnovata potenza, l'utilità dei
2.0 che, oltre a nuovi oggetti, metodi e pro- la realizzazione di script posti all'esterno componenti aggiunti (è possibile farsi
prietà, introduce alcune convenzioni, ob- del filmato swf - mentre chi usa la versione un'idea dei nuovi datacomponents attra-
bligatorie in alcuni casi e solo consigliate MX 2004 "semplice" deve usare un nor- verso l'esempio [Link] disponibile
in altri. Prima di tutto, i nomi delle varia- male programma di videoscrittura. Anche sul CD allegato alla rivista) e la qualità

I DATACOMPONENTS
Una delle novità di Flash MX 2004 Professional, è l'utilizzo da alcune restrizioni che, per motivi di sicurezza,
del componente WebServiceConnector per dialogare con i impediscono la fruizione completamente automatica di un
web service. Alcuni degli utenti che per primi si sono qualsiasi web service. Facciamo un esempio concreto,
cimentati con i nuovi componenti di Macromedia, no- creando una semplice interfaccia Flash che funga da
nostante quest'ultima abbia messo a disposizione sul suo traduttore dall'italiano all'inglese, grazie al web service
sito accurate note tecniche, hanno riscontrato delle del celebre BabelFish di AltaVista. Innanzitutto, per
difficoltà. provare il file swf (sia quello che realizzeremo assieme, sia
Facciamo quindi un po' di chiarezza: il componente in quello completo, disponibile negli esempi) è necessario
questione funziona perfettamente, ma è contraddistinto essere connessi ad Internet.

Apriamo il pannello relativo alla


1 gestione dei web services:
Window>Development Panels>Web
services. Al termine di questa operazione,
Premiamo il pulsante Define Web
2 nel pannello Web Services appare
WebServiceConnector. Al
componente, diamo il nome d'istanza
Services (che ha la forma di un piccolo la voce BabelFishService. Selezioniamo babelfish. Poi, una volta aperto il
pianeta), in modo da aprire la relativa con il mouse il piccolo segno + accanto pannello Components, trasciniamo
finestra di dialogo. alla voce, e clicchiamo con il tasto due componenti TextInput sullo stage,
Nella finestra, dobbiamo premere il destro sul metodo Bablefish(), che prelevandoli dall'elenco UI
pulsante Add Web Services e, compare in basso. Ci apparirà un menu Components: al primo diamo come
successivamente, inserire nel campo con alcune voci, tra cui quella che nome istanza da_tradurre e al
che compare nello spazio sottostante dobbimo scegliere: Add method Call. secondo quale_lingua. Infine,
l'indirizzo del nostro web service: In questo modo si creerà trasciniamo anche una TextArea sullo
[Link] automaticamente sullo stage stage e diamole come nome di istanza
2001/[Link] un'istanza del componente traduzione.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 12/Novembre 2003
010-021 Software 8-10-2003 17:17 Pagina 13

Internet e multimedia SOFTWARE SUL CD

complessiva del prodotto non si discuto- ancora impensabile sviluppare video ga- mente anche molti web designer, che
no; peccato per la documentazione, che mes in Flash del tipo spara tutto, con potrebbero dover utilizzare solo occasio-
spesso appare incompleta. Quando si cer- simulazioni avanzate di percorsi 3d o nalmente le funzioni aggiuntive, non si
cano informazioni su un nuovo compo- simili. Un vero peccato se si pensa al fatto faranno spaventare dalla necessità di
nente o su una nuova funzione utilizzan- che l'architettura, la completezza e la rigo- scrivere qualche riga di codice in più, nè
do l'help panel, puntualmente appare una rosità di ActionScript 2.0 non hanno nulla dalla differenza di prezzo tra i due pro-
scritta che ci invita a cercare aggiorna- da invidiare al celebre Lingo. È facile pre- dotti (appena 200 $ di differenza).
menti sul sito, rivelando la totale mancan- vedere un grosso successo di vendite per
za di informazioni in merito. Per fortuna, la versione MX 2004 Professional di Flash, REQUISITI
il sito Macromedia ha rivelato nel tempo anche perché il livello tecnico degli uten- Per Windows
600 MHz Intel Pentium III o equivalenti
una vitalità e velocità di aggiornamento ti è cresciuto nel corso degli anni. Sicura-
Windows 98 SE, Windows 2000, o
dei contenuti unica nel suo campo: basta Windows XP
tenere d'occhio [Link] 128 MB RAM (256 MB raccomanadati)
.com per saperne di più sulle novità non Flash MX 2004 275 MB di memoria libera sull'hard disk
documentate. L'unico appunto che si po- Professional
Produttore: Macromedia Per Macintosh
trebbe fare alla Macromedia è quello di Sul web: [Link] 500 MHz PowerPC G3 processor
non aver ancora pensato ad un player, le Software su CD: Mac OS X 10.2.6
cui risorse non si appoggino quasi esclusi- flashmx2004_trial_en_win.zip 128 MB RAM (256 MB raccomanadati)
vamente sul processore. Allo stato attuale, Codice su CD e Web: [Link] 215 MB di memoria libera sull'hard disk
infatti, nonostante le evidenti migliorie, è

Flash che viene riprodotto


all'interno di un browser web, non
ha accesso a dati che risiedano fuori
dal dominio su cui si trova. Un
discorso che si applica anche su uno
stesso server: ad esempio, un
filmato situato in un sottodominio
non può leggere dati dal dominio
"genitore", e viceversa.
Come fare per ovviare al problema,
senza ricorrere a linguaggi lato
server, che facciano da intermediari?
4 A questo punto possiamo La risposta della Macromedia si
3 Sullo stage, dopo aver selezionato
il componente WebServiceConnec-
rifinire il tutto, inserendo un chiama policy file: nello scambio di
pulsante che attivi il traduttore. Dal dati tra domini, chi mette a
tor, apriamo il pannello Component pannello Components, trasciniamo disposizione il web service, per
Inspector, e scegliamo la scheda Bin- sullo stage l'istanza di un Button e consentire il libero utilizzo del
dings, attraverso la quale decideremo il diamole come nome istanza traduci. servizio, dovrebbe predisporre un
tipo dei dati e indicheremo quali com- Nel pannello Component inspector, file di sicurezza sul proprio server
ponenti trasmettono informazioni al selezioniamo la scheda Parameters e (cross-domain policy file). Un "policy
web service e quali le ricevono. Clic- scriviamo "traduci dall'italiano file" è un semplice file XML, che, una
chiamo sul pulsante Add Binding; se- all'inglese". Questa scritta apparirà volta posto sul server, comunica al
lezioniamo translationMode:String e sul pulsante. Dal pannello Behaviors, Flash Player di consentire l'accesso
poi clicchiamo sul pulsante Ok. Nel scegliamo Data>Trigger Data Source. diretto ai dati su quel server, senza
pannelo Component Inspector, fac- Nella finestra di dialogo che apre, avvisare l'utente che l'accesso viene
ciamo doppio clic sul campo bound to: selezioniamo il componente consentito. Se un server pubblico ha
così facendo si aprirà la finestra di babelfish e, infine, clicchiamo su Ok. un policy file, tutti i filmati Flash
dialogo omonima. Selezioniamo Per concludere, scriviamo nel primo possono accedere ai suoi dati.
TextInput <quale_lingua> e premiamo fotogramma quale_lingua.text="it_ Questo file viene salvato come
Ok. Sempre dal pannello Component en"; questo valore comunica al web [Link] e posizionato sulla
Inspector, premiamo nuovamente il service che la traduzione si svolgerà root del public server.
tasto Add Binding e scegliamo dall'italiano all'inglese - con en_fr, Per fare un esempio il contenuto del
sourcedata: String e poi Ok. Anche ad esempio, avremmo ottenuto una file xml dovrebbe essere di questo
questa volta dobbiamo effettuare un traduzione dall'inglese al francese. tipo:
doppio clic sul campo bound to, poi Provando il filmato, possiamo notare
selezionare TextInput <da tradurre> e che funziona perfettamente, a patto <?xml version="1.0"?>
premere su Ok. Infine, cliccato che sia attiva una connessione e che <!DOCTYPE cross-domain-policy SYSTEM
nuovamente il tasto Add Binding, il file swf si trovi sul nostro
"[Link]
scegliamo results : String e Ok. computer e non su un server remoto.
/xml/dtds/[Link]">
Effettuiamo anche questa volta un Questa limitazione deriva dalle
doppio clic sul campo bound to e, nella restizioni attuate dalla Macromedia <cross-domain-policy>
finestra dialogo, scegliamo Text Area in materia di scambio di dati tra <allow-access-from domain="*" />
<traduzione>. domini diversi. In pratica, un filmato </cross-domain-policy>

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/13 G
010-021 Software 8-10-2003 17:18 Pagina 14

SOFTWARE SUL CD Videogiochi e multimedia

DarkBASIC Professional
Per creare videogiochi ed applicazioni multimediali di livello
professionale, con la semplicità garantita dal Basic.

I videogiochi hanno da sempre affa-


scinato grandi e piccoli utenti di
computers, dai tempi di Pong a quelli
un videogioco di successo, ma per
molti quest’ultimo è rimasto solo un
desiderio, perché il C++ o l’Assembler
di programmazione creato da The Ga-
me Creators, la cui caratteristica più
importante è la possibilità di scrivere
attuali di Half Life, ed è molto difficile non erano linguaggi semplici da uti- codice per un videogioco o realizzare
per chiunque ammettere di non aver lizzare. Adesso potete finalmente rea- un’applicazione multimediale usando
mai giocato con un computer, e ma- lizzare il vostro desiderio utilizzando un linguaggio, semplice quale il BA-
gari di non aver desiderato di creare DarkBASIC Professional, il linguaggio SIC ma molto potente, che sfrutta pie-
namente l’hardware attuale. Realiz-
zare un videogioco con DarkBASIC
Professional non è più un’impresa ri-
servata a programmatori con anni di
studi e di programmazione alle spalle,
ma è alla portata di tutti, anche di un
singolo. Come avviene tutto questo?

UN LINGUAGGIO
SEMPLICE…
Appena si avvia DarkBASIC Profes-
sional, abbiamo la possibilità di scri-
vere il gioco in un ambiente IDE vera-
mente notevole, con uno degli editors
di codice più flessibili mai provati, in
cui tutte le linee sono numerate e
ogni comando viene evidenziato con
un colore. Inoltre, muovendo il mou-
se al di sopra di un comando viene vi-
sualizzato un suggerimento che mo-
Fig. 1: L’IDE integrato con due esempi di giochi forniti con il linguaggio. stra i parametri da fornire. Il pulsante

ALL’OPERA CON DARKBASIC PROFESSIONAL

L’editor in azione. Premendo … nella stessa finestra d’aiuto Con DarkBASIC Professional è
1 “F1” mentre si scrive il
2 per esaminare da vicino la
3 possibile realizzare videogio-
comando sprite, si apre una sintassi, ed eventualmente caricarlo chi commerciali di successo tipo 3D
finestra che descrive cosa fa il al posto del sorgente per osservare Mahjong, un popolare gioco di
comando. E’ possibile visualizzare quello che si può fare con i comandi carte presente su
un esempio… sugli sprites. [Link] …

h t t p : / / w w w. i o p r o g r a m m o . i t
G 14/Novembre 2003
010-021 Software 8-10-2003 17:19 Pagina 15

Videogiochi e multimedia SOFTWARE SUL CD

di debug permette di eseguire il codi- guaggio, perché non provate a sentire


ce in modalità passo-passo, o rallen- … E POTENTE… e scambiare informazioni con altri
tarne l’esecuzione in modo da seguire Potete ovviamente realizzare codice utenti di DarkBASIC Professional in
lo sviluppo dei vostri dati. Nello stes- più avanzato degli esempi suddetti, Italia?
so tempo una guida in linea completa importare modelli 3D nei vostri gio-
di sorgenti di esempio, liste di co- chi, in formati diversi, compresi quel-
mandi e collegamenti a progetti di li di giochi famosi come Quake e Half
esempio, è sempre disponibile sullo Life, applicare textures, effetti pixel e
… IN ITALIANO!
schermo per una spiegazione dei co- vertex shaders, controllare ogni mem- A differenza di altri linguaggi o tool di
mandi, per copiare ed incollare, o per bro dell’oggetto, creare e gestire programmazione per creare videogio-
aiutarvi nella ricerca di errori. È un matrici per ampi paesaggi…e tanto chi, DarkBASIC Professional è dispo-
IDE perfetto sia per nuovi utenti che altro ancora, come illustrato nelle nibile in italiano ed è presente nel no-
per programmatori veterani. Creare caratteristiche del linguaggio, ma se stro Paese grazie al sito ufficiale italia-
oggetti grafici è veramente semplice. ancora non foste convinti del lin- no: [Link] gestito da
Volete disegnare un cubo, una sfera?
Allora usate i seguenti comandi:

Make Object Cube 1,100

e disegnate un cubo di dimensioni


100 e di colore bianco per default
mentre:

Make Object Sphere 1,100

disegna invece una sfera bianca di di-


mensioni 100. Volete fare qualcosa
leggermente più complessa come di-
segnare un cubo, colorarlo e poi muo-
vervi attorno con la cinepresa?
Ecco il codice che fa tutto questo:

make object cube 1,100


color object 1,rgb(255,128,255)
do
control camera using arrowkeys 0,1,1
loop Fig. 2: Con DarkBASIC Professional è possibile creare tantissimi tipi di giochi.

… oppure creare una galleria d’arte virtuale, come


4 nell’esempio di un programma realizzato da un utente
5 … o ancora altre applicazioni multimediali
come VsdTracker per riprodurre fedelmente la
americano, con possibilità di aggiungere i vostri capolavori… vostra musica con DarkBASIC Professional!

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/15 G
010-021 Software 8-10-2003 17:19 Pagina 16

SOFTWARE SUL CD Videogiochi e multimedia

appassionati programmatori di video- commercio, costruito sullo schema mente possibile reperire su internet
giochi, dove possono incontrarsi sia il del BASIC. Difficilmente troverete editor, anche gratuiti, realizzati da
neofita che l’utente esperto, nel cui programmi che rendono così facile altri utenti del linguaggio. Infine non
forum è possibile chiedere infor- incorporare tutte le speciali caratteri- dimenticate di osservare queste pagi-
mazioni se qualche argomento del lin- stiche ed effetti che vedete nei giochi ne perché a breve saranno disponibili
guaggio non è chiaro e dove è possibi- attuali e che offrono i benefici della dei mini tutorial sul linguaggio con
le gratuitamente prelevare gli aggior- tecnologia Microsoft DirectX 9. Il ter- esempi commentati dalle basi fino
namenti di DarkBASIC Professional. mine professional serve a differenzia- alla creazione di un gioco completo.
re questo linguaggio da DarkBASIC, Roberto Lo Storto
precedente prodotto di The Game
Creators ltd, del quale ha mantenuto DarkBASIC
CONCLUSIONI tutti i benefici aggiungendo nuovi tipi Professional
Il processo di creazione di videogio- di dati, un motore grafico 3d avanza- Produttore: The Game Creators LTD
(Regno Unito)
chi diventa divertente, facile e non to, l'accesso a basso livello per gli
Sul Web: [Link]
troppo gravoso economicamente, oggetti e tantissimi nuovi comandi. In Italia: [Link]
quindi accessibile a tutti coloro vo- Nella versione ufficiale non viene for- Nel CD: \soft\tools\dbprodemo
gliano provarci. DarkBASIC Professio- nito un editor di livelli, ma è facil-
nal è il più avanzato applicativo per
sviluppare giochi attualmente in Tra le caratteristiche del linguaggio
• Per tutti i giochi creati con DarkBASIC • Mappatura con rilievo (Bump
Professional non c'è bisogno di Mapping)
pagare royalties o licenze particolari. • Mappatura di luce (Light Mapping)
• Tutti i giochi possono essere • Oggetti con multi tessiture
distribuiti come eseguibili EXE • Animazioni con scheletro (Bone based
indipendenti. animations)
• Gestione BSP • Cartoon Shading
• Insieme Visibilità Potenziale • Accesso a basso livello dei dati
• Pixel & Vertex Shaders dell'oggetto
• Ombre in tempo reale • Supporto multigiocatore
• Riflessi realistici • Manipolazione di vettori
• Luci • Uso di DLL esterne per espandere il
• Matrici linguaggio con nuove funzioni
• Terreno Avanzato • Compilatore con possibilità di criptare
• Cineprese multiple e comprimere gli eseguibili creati col
• Sistema Particellare 100% di codice macchina
• Gestione sprites 2D (trasparenza, • Debugger integrato
rotazione, sfumatura, animazioni, ...) • Editor con evidenziazione sintassi e
• Gestione collisioni guida in linea.
Fig. 3: Un esempio “reale” di Bone
Animation.

ESPLORARNE LE POTENZIALITÀ

Visitate il sito italiano Entrate nella Galleria ed …o il più famoso MatEdit e


1 dedicato a DarkBASIC
2 ammirate alcune creazioni
3 partite alla grande creando
Professional: [Link] per oppure cercate informazioni su livelli per il vostro gioco con
confrontarvi con altri utenti del programmi utili tra cui l’editor di DarkBASIC Professional in cui
linguaggio e aumentare le vostre livelli gratuito “Programmer’s l’unico limite è la vostra
conoscenze. Heaven”… immaginazione.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 16/Novembre 2003
010-021 Software 8-10-2003 17:20 Pagina 17

Sviluppo di DB relazionali SOFTWARE SUL CD

DBDesigner 4
Progettazione di database relazionali, ottimizzato per lavorare
in coppia con MySQL.

D BDesigner 4 è uno strumento davve-


ro completo e versatile, capace di da-
re un concreto aiuto nello sviluppo di da-
La zona centrale, più ampia, rappresenta la
nostra area di lavoro. E’ qui che andremo a
costruire il diagramma per il database da
getto “su carta”. DBDesigner è dotato di
due funzionalità aggiuntive:

tabase complessi. La funzionalità di que- progettare, inserendo nuove tabelle, defi- Database Synchronisation
sto software non è solo quella di assistere il nendone le tabelle e le relazioni con il resto permette di semplificare l’aggiornamento
progettista nella stesura di diagrammi ER del progetto. del database, attraverso la connessione
(Entità-Relazione), ma anche di interagire direttamente al server. In pratica, piuttosto
con il database server. Questo ci consente, che utilizzare ripetutamente la generazio-
ad esempio, di aggiornare lo schema delle ne di script SQL, DBDesigner confronta la
tabelle, oppure effettuare il reverse engi- struttura delle tabelle presenti nel modello
neering di un database esistente. Già al con quelle definite nel database, modifi-
primo utilizzo, DBDesigner dà l’impressio- cando queste ultime in modo che coinci-
ne di un programma completo e professio- dano con quelle del modello progettato;
nale oltre che veramente semplice da Reverse Engineering
usare. Infatti DBDesigner 4 dispone di sfruttando la tecnica di ingegneria inversa,
un’interfaccia utente ben realizzata, in DBDesigner è capace di collegarsi ad un
linea con i moderni strumenti di sviluppo database server, prelevare la struttura di un
Fig. 2: L’editor delle tabelle ci consente di
software. In alto troviamo la classica barra definirne tutte le caratteristiche. database e creare un modello in base alle
dei menu, a sinistra la palette di strumenti meta-informazioni presenti nell’archivio.
e funzioni più frequentemente utilizzati e a Questa possibilità si rivela particolarmente
destra un contenitore con 3 pannelli: utile quando è necessario lavorare su un
FUNZIONALITÀ database già esistente, e del quale non si
Navigator & Info: per avere informazio- Come altri strumenti per la progettazione hanno i modelli di progetto. Non meno im-
ni sul documento e selezionare la porzione di basi di dati, una volta terminata la co- portante la possibilità di importare model-
dello schema da visualizzare; struzione del modello, DBDesigner 4 ci li sviluppati con Erwin, un software pro-
Datatypes: permette di visualizzare e permetterà di ottenere il listato SQL neces- dotto dalla Computer Associates e molto
gestire i tipi di dati disponibili; sario a creare il database progettato. Inoltre diffuso in ambienti Microsoft Windows.
DB Model: mostra le tabelle presenti nel sarà possibile esportare l’immagine, in for-
progetto, con i dettagli relative alle colonne mato PNG o BMP, del modello realizzato,
ed alle relazioni; molto utile per esaminare il proprio pro-
CONCLUSIONI
In conclusione possiamo dire che DBDesi-
gner 4 è senza dubbio un ottimo strumen-
to, capace non solo di semplificare molto il
lavoro durante la progettazione di un data-
base, ma di seguirne l’evoluzioni attraver-
so modifiche ed aggiornamenti, ancor più
semplici grazie alla funzione di sincroniz-
zazione. Il mondo del software open sour-
ce aveva proprio bisogno di un software
come DBDesigner 4, soprattutto conside-
rando che alcuni dei database server più
utilizzati, come MySQL e PostgreSQL, non
forniscono un ambiente grafico per pro-
gettazione di database.

DBDesigner 4
Produttore: [Link]
Sul Web: [Link]/dbdesigner4/
Prezzo: Gratuito
Nel CD: \soft\tools\[Link]
Fig. 1: L’area di lavoro di DBDesigner, ricca e curata nei particolari.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/17 G
010-021 Software 8-10-2003 17:20 Pagina 18

SOFTWARE SUL CD Librerie di programmazione

Integrated Performance
Primitives 3.0
Dalla Intel®, le migliori librerie per far correre le tue applicazioni:
con un framework per il raggiungimento di prestazioni al top.

L e Intel Integrated Performance Primi-


tives (Intel® IPP) abbracciano un am-
pio spettro di problematiche e riescono a
dare una spinta decisiva in numerosi
campi. Le IPP sono essenzialmente divise
in cinque gruppi:

• Audio, JPEG, speech e video


codifica/decodifica
• Riconoscimento visivo
• Crittografia
• Processo digitale di immagini e se-
gnali analogici
• Riconoscimento vocale

Le Intel® IPP costituiscono una poderosa Fig. 2: Risultati di codifica e decodifica delle immagini in standard MPEG-2.
libreria che può essere vantaggiosamente
utilizzata per ottimizzare le prestazione pacchetto di installazione. Da ricordare omettendo l’ultimo passo: il download
delle applicazioni che sviluppiamo su inoltre che le librerie IPP sono tutte delle librerie, già presenti nel CD allegato
qualsiasi processore della famiglia Intel®: thread-safe e possono dunque essere im- ioProgrammo. In pochi istanti riceverete
attraverso un’unica API che fa da interfac- piegate in ambienti threaded senza causa- un file di attivazione. Salvate il file in una
cia a tutte le piattaforme, gli sviluppatori re alcun problema. Le librerie IPP sono qualsiasi directory e lanciate il program-
possono inoltre contare su un’ampia com- state utilizzate anche da Macromedia, ma di installazione delle librerie. Vi verrà
patibilità ed una sicura riduzione dei costi. nello sviluppo del Player Flash: grazie alle chiesto di indicare la posizione del file di
IPP è stato possibile ridurre tenere ridotta licenza appena ricevuto. Alla fine dell’in-
la dimensione dei filmati Flash, senza stallazione è possibile lanciare un inte-
andare a discapito della qualità e della ressante tutorial che fornisce un’utile
fluidità delle prestazioni audio-visive. overview di questa estesa libreria.

Fig. 1: Sul sito ufficiale della Intel è disponi- DOCUMENTAZIONE


bile un tutorial su come sfruttare le IPP Nel pacchetto di installazione sono inclu-
anche su piattaforma .NET.
si degli ottimi manuali in formato PDF
che esplorano in profondità le caratteri-
stiche e gli utilizzi delle librerie. Non
NUOVE FUNZIONI lasciatevi spaventare dalle migliaia di
Fig. 3: Guadagno tipico nelle prestazioni
Con la versione 3.0 sono stati coperti due pagine che vi troverete davanti: sfogliate rispetto ad applicazioni sviluppate senza
nuovi campi: la sintesi vocale e la codifica l’indice e dirigetevi verso la sezione che fa fare utilizzo delle Intel IPP.
video. Le Intel® IPP sono dunque partico- al caso vostro.
larmente indicate per la realizzazione di
applicazioni di multimediali di livello pro- Integrated Performance
fessionale, in cui il raggiungimento di pre- Primitives 3.0
stazioni allo stato dell’arte diviene di fon- INSTALLAZIONE Rivenditore per l’Italia: Creactive
Sul Web: [Link]/Intel
damentale importanza. Le Intel® IPP sono Al fine di una corretta installazione, è ne- Prezzo: E 259 ver. commerciale
adatte ad essere integrate in qualsiasi pro- cessario collegarsi al link [Link] E 60 ver. accademica
getto C o C++, e particolarmente interes- .com/cme/[Link]?formID=1474 e Nel CD: [Link]
santi risultano gli esempi MFC inclusi nel completare la form di registrazione,

h t t p : / / w w w. i o p r o g r a m m o . i t
G 18/Novembre 2003
010-021 Software 8-10-2003 17:21 Pagina 19

Strumenti di sviluppo SOFTWARE SUL CD

Metamill 3.1
UML e reverse engeneering: un ambiente completo per
i diagrammi che hanno rivoluzionato lo sviluppo.

L a nuova versione di un software per la


modellazione software UML comple-
tamente visuale. Metamill risulta parti-
so cui più sviluppatori possono collabo-
rare utilizzando i medesimi elementi
senza “pestarsi i piedi”. Con Metamill è
cosa che consente un facile riutilizzo ed
una più semplice integrazione dei dati
così generati in ambienti eterogenei. Una
colarmente semplice da usare, in special possibile sviluppare qualsiasi tipo di dia- volta sviluppato il modello, Metamill è in
modo se paragonato ad altri software di gramma UML, inclusi i diagrammi di grado di produrre il codice relativo sia in
modellazione UML. Tra le caratteristiche deployment. I modelli sono salvati in for- C++ sia in Java. E’ anche possibile il pro-
più interessanti c’è il repository, attraver- mato XMI (XML Metadata Interchange), cesso inverso: a partire da codice Java,
C++ o C# è possibile risalire alle corri-
spettive rappresentazioni UML, semplifi-
cando le operazioni di reverse enginee-
ring e la manutenzione di codice legacy.
La documentazione del codice risulta
semplificata dalla possibilità di generare
automaticamente file HTML di com-
mento. Sviluppato in C++, Metamill si
presenta particolarmente veloce. Molto
utile, in fine, la possibilità di utilizzare
template.
Versione di prova valida trenta giorni.

Metamill 3.1
Produttore: Metamill Software
Sul Web: [Link]
Prezzo: $125
Nel CD: [Link]
Fig. 1: Gli use case diagram sono completamente scalabili.

AUTHENTIC 2004
Con la semplicità di un world processor, tutte le dotazioni
dei migliori ambienti di sviluppo per XML.

D ai creatori di XMLSPY, un nuovo


eccellente prodotto per l’intera-
zione con XML. AUTHENTIC per-
mette di creare documenti con la
stessa semplicità e con l’immediatez-
come una valida alternativa agli edi-
tor HTML. Al momento della prima
installazione è necessario cliccare su
za tipica di un word processor, men- “FREE Evaluation key” e fornire il
tre l’oggetto del nostro lavoro resta un proprio indirizzo e-mail: vi sarà invia-
documento XML. Si rivela prezioso in ta la password per l’attivazione del
tutte quelle circostanze in cui si vo- prodotto.
gliano condividere e tenere aggiorna-
ti documenti e informazioni di qual- AUTHENTIC 2004
Produttore: Altova
siasi tipo, sia all’interno di un’azienda
Sul Web: [Link]
che sul Web. La semplicità è garantita Prezzo: Gratuito
da una interfaccia completamente Nel CD:
WYSIWYG e, grazie al supporto per gli [Link]
Fig. 1: Authentic in azione su di una pagina elementi grafici e le tabelle, si rivela
Web.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/19 G
010-021 Software 4-10-2003 10:53 Pagina 20

SOFTWARE SUL CD Elenco Software sul CD

IntelliJ IDEA Aurora gazione di bug e la pianificazione dello sviluppo tuare la conversione da documenti XML in PDF
Una nuova stella nel firmamento software. Può essere interrogato via browser e si o in formato PostScript. Accetta in input dati in
Java integra perfettamente con Visual Studio 6, formato XML e fogli di stile XSL, il rendere è
Idea è un am- Visual Studio .NET e Visual SourceSafe. Permet- effettuato proprio come combinazione dei due
biente di svi- te agli utenti Windows e Macintosh di accedere ingressi. Versione dimostrativa, un watermark è
luppo che con- simultaneamente allo stesso database cross- applicato su ogni documento prodotto. XEP
sente di creare platform. Inoltre, include ottime funzioni per il offra un valido supporto a XSL FO, grafici SVG e
applicazioni filtering, permettendo di creare delle liste di funzioni di link PDF-to-PDF. Piccole correzioni
Java all’interno problemi organizzate per priorità. Ottima la in questa nuova versione.
di un IDE ben possibilità di generare dei report. La notifica via Nel CD: xep36_trial.zip
fatto e grade- mail di tutti gli aggiornamenti al DB ed il pieno
vole. Pieno supporto per JSP/EJB, integrazione supporto a XML rendono sicuramente interes- Installer2Go 3.1.7
con Ant e JUnit, supporto per XML e una cospi- sante questo prodotto. Licenza di valutazione Un sistema facile e gratuito per
cua collezione di API per la realizzazione di della durata di trenta giorni, è possibile traccia- realizzare pacchetti di installazione
plug-in. Inutile sottolineare che sono presenti re un massimo di 15 bug. Un tool per la creazione di file autoinstallanti
tutte le più importanti caratteristiche comuni in Nel CD: [Link] che non impegna lo sviluppatore nel dover
un moderno IDE: un ottimo debugger, avanza- imparare l’ennesimo linguaggio di scripting:
te funzioni di search&replace, colorazione sin- XMLSPY 2004 con una interfaccia che punta tutto sul
tattica. Una menzione particolare la merita il Home Edition frag&drop, realizzare pacchetti di installazione
completamento automatico del codice che si fa Il Re è tornato... diventa un vero gioco da ragazzi. Benché gratui-
apprezzare con l’uso per la sua semplicità e per Uno dei più apprezzati editor XML si presenta to, Installer2Go va incontro a tutte linee guida
la flessibilità con cui segue le abitudini dello svi- con questa nuova versione, che qui presentia- per la certificazione WindowsXP. La versione
luppatore. Al momento dell’installazione è mo in licenza home, si rinnova e conferma tutte 3.1.7 risolve alcuni piccoli bug e relativi alla
necessario inserire uno username ed una pas- le sue migliori doti. Già nelle fasi iniziali dell’in- scrittura nel registro di Windows e alla gestione
sword, per ottenere i quali è presentato un link stallazione è possibile decidere il livello di inte- di stringhe di grandi dimensioni.
ad una pagina Web. Una volta compilato il form grazione con Windows, scegliendo se associare Nel CD: [Link]
con i nostri dati, ci verrà inviata una chiave di alcuni file a XMLSPY e se integrare la voce rela-
attivazione valida trenta giorni. tiva a XMLSPY nei menu contestuali di Explorer. Code Warehouse 1.02
Nel CD: [Link] Alla fine dell’installazione è anche possibile sca- Un unico grande archivio
ricare automaticamente dei alcuni tool aggiun- per tutto il tuo codice
Visual Paradigm for UML tivi. Al primo avvio ci viene richiesto il nostro Progettato allo scopo di rendere più facilmente
Community Edition 2.2 nome e un indirizzo mail cui verrà spedita in riutilizzabile il codice che scriviamo, Code
Un potente ambiente di sviluppo pochi, istanti, la chiave di attivazione necessaria Warehouse consente di immagazzinare tutti i
UML gratuito ad attivare il software per 30 giorni. L’interfaccia nostri snippet in un unico archivio. Code Ware-
Un ambiente di sviluppo integrato per UML è alquanto spartana ma ampiamente persona- house si occupa di passare al setaccio le nostre
(Unified Modeling Language) che farà la gioia di lizzabile, ottimo il supporto ai Web Services. classi o interi progetti, al fine di importarne
tutte le figure coinvolte nello sviluppo di appli- Nel CD: [Link] automaticamente le classi nel database. Le
cazioni di grandi dimensioni. Completamente ricerche sul codice immagazzinato possono
gratuito, non rinuncia ad una ottima interfaccia Decafe Pro 3.9 essere effettuate secondo molteplici criteri:
di livello professionale e copre tutte le maggiori Risalire al sorgente delle classi Java autore, data, nome delle classe o procedura, per
esigenze di chi si occupa di UML. Grazie ai Con una interfaccia splendida e intuitiva, uno parole nel codice o anche in modo specifico
numerosi tutorial on-line ([Link]-pa- dei più famosi decompilatori per Java: se siete all’interno dei commenti presenti nel codice.
[Link]) è possibile imparare ad utilizzar- curiosi di sapere come è stata realizzato un par- Nel CD: [Link]
lo ad un buon livello in pochi istanti. Special- ticolare applet o un intera applicazione Java,
mente chi è già esperto di UML, si troverà su- potete affidarvi a Decafe! Basterà indicare il file Iron Speed Designer 1.4
bito a suo agio, grazie ad una interfaccia che rie- .class che ci interessa per veder apparire istan- Per generare applicazioni Web su
sce ad essere al contempo completa e semplice taneamente il codice sorgente. Durante la fase piattaforma .NET
da utilizzare. Particolarmente efficace per le di decompilazione del codice, non è necessario Un ottimo aiuto per chi si trova a sviluppare
operazioni di riverse Engineerng da classi Java avere installata alcuna versione di Java SDK ne’ applicazioni Web su .NET: è possibile sviluppa-
verso diagrammi facilmente comprensibili. Sin la virtual machine. Questa nuova versione risol- re una completa applicazione three-tier, senza
integra perfettamente nella piattaforma ve alcuni piccoli problemi delle precedenti. la necessità di scrivere codice. Sofisticate inter-
Eclipse, come plug-in. Da provare. Versione di prova valida ventuno giorni. facce utente ed una robusta logica di accesso ai
Nel CD: [Link] Nel CD: [Link] dati, sono automaticamente generate da Iron
Speed, al programmatore è lasciato da scrivere
TestTrack Pro 6.0.1 RenderX XEP 3.6 solo il codice strettamente relativo alla logica
Tracciare bug e richieste degli Per convertire documenti XML applicativa. Scrivere meno codice, oltre a ridur-
utenti in PDF re i tempi di sviluppo, consente di ridurre anche
TestTrack è un tool cross-platform per la catalo- Un’applicazione commerciale in grado di effet- la possibilità di introdurre errori. Versione di

h t t p : / / w w w. i o p r o g r a m m o . i t
G 20/Novembre 2003
010-021 Software 4-10-2003 10:53 Pagina 21

Elenco Software sul CD SOFTWARE SUL CD

prova valida quindici giorni. puntuale analisi dello stato e dell’evoluzione del sante proposta per gli sviluppatori Web, che
Nel CD: Iron Speed Designer [Link] sistema. consente una più agevole migrazione dai tradi-
Versione di prova valida trenta giorni. zionali siti HTML verso più attuali siti comple-
Intelliwizard Designer Nel CD: [Link] tamente basati su XML. STYLEVISION 2004
1.2.8 include una potente funzionalità di import
Costruisci il tuo Wizard! JWin Express Enterprise HTML che separa la pagina originale in conte-
I wizard hanno rappresentato un grande passo 2003 Build 385 nuto XML, foglio di stile XSLT ed un XML
avanti nella semplificazione delle procedure di Da Java ad exe in un click Schema.
interazione fra gli utenti ed il software: con una Velocissimo e semplice da utilizzare, Jwin con- Nel CD: [Link]
semplice serie di passi, utilizzando una inter- sente di creare applicazioni Win 32 a partire da
faccia quanto mai lineare e attraverso delle qualsiasi applicazione Java. E’ necessario avere Surround SCM 2.0
domande di facile comprensione è possibile installato un JDK pari o superiore alla versione Per tenere traccia dei
guidare l’utente e ricavare tutte le informazioni 1.4.0. L’interfaccia è strutturata a schede e con- cambiamenti di produzione
che ci interessano. Intelliwizard consente di sente un fine settaggio delle applicazioni che si L’applicativo garantisce l’accesso al codice sor-
costruire dei Wizard che, pur conservando una realizzano. Finalmente uno strumento di livello gente e consente di tenere traccia di tutti i cam-
grande pulizia e semplicità nell’interfaccia, rea- professionale per la conversione in file esegui- biamenti apportati dal team in modo ordinato.
lizzano al loro interno dei complessi percorsi di bili di progetti Java. Strutturato secondo una logica client/server,
scelta. La progettazione avviene in gran parte Versione di prova valida cento giorni. l’applicativo può essere utilizzato in un am-
per via grafica in modo da semplificare e miglio- Nel CD: JWinExpressEnterprise- biente multipiattaforma: Linux, Mac e Win-
[Link]
rare la fase di sviluppo. Versione dimostrativa. dows. Questa nuova versione prevede la notifi-
Nel CD: [Link] ca via mail dei cambiamenti, la gestione cripta-
Midlogic Studio 1.1 ta delle comunicazioni client/server e molto
Tarma Installer Sviluppare e distribuire altro ancora. Alla fine della installazione è pos-
2.64.1357 applicazioni J2ME MIDP sibile richiedere la chiave di attivazione neces-
Per avere pacchetti Se il buon giorno si vede dal mattino, comincia- saria alla corretta utilizzazione dell’applicativo
di installazione in più lingue mo benissimo con un ottimo wizard per l’in- per trenta giorni. Versione dimostrativa valida
Attraverso una interfaccia particolarmente stallazione che si distingue sia per la chiarezza trenta giorni.
user-friendly, creare pacchetti di installazione grafica che per la semplicità: tra l’altro, è possi- Nel CD: [Link]
con Tarma Installer è un vero gioco! Supporta bile specificare se utilizzare una delle Virtual
tutte le piattaforme Windows (95, 98, Me, NT 4, Machine esistenti, o installarne una nuova. Color Cop 5.3
2000 e XP) e si segnala per numerose caratteri- Al primo avvio è necessario inserire un chiave di Converte valori RGB decimali in
stiche positive: piccoli pacchetti di installazio- attivazione che si può ottenere attraverso un triplette esadecimali
ne, interfaccia semplice e rapida da utilizzare, link presente nello splash. Nella pagina web cui Una piccola e utilissima applicazione che con-
funzioni di installazione e disinstallazione intel- sarete indirizzati, ricordatevi di registrarvi, sente di ottenere il codice RGB sia in decimale
ligenti. E’ possibile distribuire programmi, do- prima di chiedere la chiave di attivazione, la che in esadecimale di qualsiasi colore. Una
cumenti, controlli ActiveX, font TrueType e pagina è poco chiara e i messaggi di errore sono volta lanciata, la piccola finestra dell’applica-
OpenType, driver per periferiche, aggiorna- fuorvianti. zione resta always-on-the-top e, con il classico
menti di registro e molto altro ancora. Presenta contagocce (picker), possiamo valutare il colore
funzionalità specifiche per la distribuzione di qualsiasi punto sullo schermo. Una particola-
sicura delle applicazioni sia via Internet si attra- re lente rende anche possibile ingrandire una
verso [Link]. porzione dello schermo, sempre allo scopo di
Nel CD: [Link] ottenere i valori dei colori che ci interessano.
Gratuito.
KernelDriver 6.1 Nel CD: [Link]
Testare e creare driver
per periferiche
Per la creazione di un nuovo driver è sufficiente LTProf 1.4
installare la periferica (sia essa USB, PCI o Profilare applicazioni
ISA),scegliere la voce “Create a new project”, L’interfaccia è semplice ed ampiamente perso- Un piccolo ma efficace tool per la profilazione
selezionare il dispositivo dalla lista che si pre- nalizzabile, anche progetti di consistenti delle applicazioni in relazione al tempo di CPU
senta, testare la periferica attraverso l’interfac- dimensioni possono essere gestiti agevolmente. utilizzato. Attraverso un semplicissimo wizard è
cia grafica e definire i parametri aggiuntivi che Versione di prova valida trenta giorni. possibile specificare il processo da monitorare,
desideriamo specificare. A questi punto avremo Nel CD: [Link] dopo di che potremo utilizzare comunemente
il sorgente del nostro driver pronto per essere la nostra applicazione e verificare a posteriori il
compilato e lanciato. STYLEVISION 2004 peso, in termini di tempo-cpu, delle varie ope-
Notevoli le funzioni di monitoraggio del siste- Converte siti HTML in avanzati siti razioni effettuate. Versione di prova valida ven-
ma: tutti gli interrupt e le chiamate di sistema XML-based tuno giorni.
sono intercettate in un log che consente una Dagli autori di XMLSPY, arriva questa interes- Nel CD: LTProf_setup.exe

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/21 G
022-025-Soluzioni 8-10-2003 17:22 Pagina 22

SOLUZIONI Algoritmi per il trattamento dei testi

Metodi predittivi di inserimento testi

La funzione T9
dei cellulari
Ai tradizionali sistemi di battitura multipla, per la composizione
su tastiere con un numero “limitato” di pulsanti, come quella
di un telefono cellulare, si sono succeduti sistemi avanzati di
inserimento predittivo; T9, tra questi, è il più conosciuto.

L’
esponenziale sviluppo tecnologico degli va del trend che porta verso il piccolo. Si deve, quin-
ultimi anni ha portato con se una serie di di, poter produrre testi con keyboard ridotte, in
benefici per l’utente finale. Tra questi la particolare i dieci tasti (come si vedrà in realtà sono
possibilità di disporre di strumenti sempre meno otto o nove) su cui sono impressi i numeri per la
ingombranti e ovviamente più pratici. Inutile ricor- normale composizione telefonica devono essere
T9 dare che il primo elaboratore messo a punto da sfruttati anche per comporre testi. Uno stesso tasto
Il T9 è il sistema di John Von Neumann occupava con le sue valvole un ha molteplici funzioni ed identifica quindi cifre
scrittura SMS che intero appartamento, mentre oggi a “soli” 50 anni come set di caratteri. T9 è una tecnica di inserimen-
semplifica e velocizza la
creazione dei messaggi.
da allora, possiamo servirci di calcolatori miliardi di to predittivo di testi che rende “indolore” il proces-
Invece di utilizzare il volte più potenti nel solo spazio del palmo di una so di miniaturizzazione applicato ai telefoni cellula-
metodo tradizionale, che mano. La costruzione di hardware su scale di spazio ri fornendo buone prestazioni a fronte di un hard-
consiste nel premere i sempre minori è conosciuta come miniaturizzazio- ware che per ragioni contingenti di spazio deve
tasti più di una volta per ne. Tale processo, ci consente oggi di disporre, ad essere minimale. Tali tecniche hanno vasti campi di
selezionare le lettere più
poste in profondità, il T9 si
esempio, di telefoni cellulari che possono essere applicazione, non si riducono, infatti, ad essere
basa su un sistema comodamente manipolati con una mano e che usate per la gestione di sms su telefoni cellulari, ma
intelligente; basta che hanno ingombro minimo, comparabile ad un pac- hanno un massiccio impiego anche su computer
l’utente prema i tasti una chetto di caramelle. Sembra, che il trend futuro con- palmari, insomma, in tutte quelle occasioni in cui
volta sola e il cellulare tinui a riservarci dimensioni sempre più piccole, si per ragioni di spazio si è costretti a fare i conti con
confronterà le lettere con
le parole esistenti nel
parla di cellulari come orologi o della sola grandez- strumenti di piccole dimensioni e con pochi ele-
proprio dizionario interno. za di un dente. Ma questa estremizzazione delle di- menti di comando. Cerchiamo quindi di capire
Per esempio, immaginiamo mensioni verso valori sempre minori deve fare i come tali tecniche funzionino e si possano pro-
di voler scrivere la parola conti con delle esigenze pratiche. Sempre con riferi- grammare.
"CIAO". mento ai telefoni cellulari, qualcuno si potrebbe
Col metodo tradizionale
chiedere come sia possibile conciliare le dimensio-
ni ridotte all’espletazione di alcune funzioni, come
premeremo i seguenti tasti:
[2 abc] [2 abc] [2 abc] [4 ad esempio la composizione di brevi messaggi di
DA MULTI-TAPPING
ghi] [4 ghi] [4 ghi] [2 abc] [6 testo (sms). In qualche modo si deve disporre di una A T9
mno] [6 mno] [6 mno] tastiera se pur piccola, a meno di usufruire di siste- Il sogno di chi compone testi è quello di
Per un totale di 10 tasti.
mi di riconoscimento vocale. Certo, penso che impiegare il meno tempo possibile per la pro-
Col T9 sarà sufficiente la sarebbe auspicabile avere a disposizione un set di duzione degli stessi. Sistemi di riconoscimen-
seguente combinazione: tasti corrispondenti al completo alfabeto in modo to vocale che siano efficienti sono auspicabi-
[2 abc] [4 ghi] [2 abc] [6 da poter comporre comodamente qualsiasi tipo di li per la rapidità e la comodità d’uso. Ma an-
mno] messaggio secondo la modalità QWERTY, un tasto che la tradizionale tastiera QWERTY (che ab-
Con un risparmio del 60%.
una lettera; ma tale scelta si contrappone chiara- bia la conosciuta disposizione dattilografica
mente all’esigenza di risparmiare spazio. In effetti, dei tasti), con la quale sto scrivendo parola
esistono in commercio cellulari con l’intera tastiera, dopo parola il presente articolo, non è assolu-
ma sono poco diffusi; il rifiuto del mercato per pro- tamente un metodo da disprezzare, special-
dotti che superano alcune dimensioni è una ripro- mente per chi ha preso dimestichezza con la

h t t p : / / w w w. i o p r o g r a m m o . i t
G 22/Novembre 2003
022-025-Soluzioni 8-10-2003 17:22 Pagina 23

Algoritmi per il trattamento dei testi SOLUZIONI

LA FUNZIONE T9
Chiunque possieda un cellulare di recente
(ultimi due anni) acquisto di fatto usufruisce
delle funzionalità T9. Diamone comunque un
rapida quanto completa descrizione. Fermo
restando che si fa riferimento ad una tradi-
zionale tastiera (Fig. 1), nel caso dei telefoni
cellulari, per produrre una parola di n lettere
basterà digitare gli n tasti corrispondenti alle
singole lettere, senza curarsi della posizione
che queste hanno sulle cifre associate. Le let-
tere sono associate alle cifre che vanno da 2 a
9. Il tasto 1 (oppure zero, a seconda dei mo-
delli) produce lo spazio. Quindi per scrivere
nonno, basterà digitare per 5 volte il tasto 6 e
non 7 come nel caso multi-tapping, e non bi- TEGIC
sognerà ad ogni passo attendere il tempo di COMMUNICATIONS
produzione tipico della battitura multipla. Il sistema T9: “text on
Il sistema, in automatico, è in grado di stabi- 9 keys” è stato
sviluppato dalla Tegic
Fig. 1: La disposizione delle lettere sulla tastiera dei lire che quella combinazione di tasti può pro-
telefonini segue l’ordine alfabetico. Communication nel
durre la sola parola nonno. 1999, in pochi mesi ha
Ovviamente, può accadere, soprattutto per conquistato la fiducia
keyboard e riesce a scrivere usando il mag- parole brevi, che uguali combinazioni di tasti, della totalità dei
gior numero di dita. Tutti sistemi inutilizzabi- possano essere associate a distinte parole. produttori di telefoni
cellulari. Si pensi che
li per maggior parte dei cellulari e per molti Ad esempio, se si digitano i due tasti 64 appa- oggi è presente
palmari. Avendo a che fare con un numero ri- re la parola in, ma altre parole corrispondono praticamente su tutti i
dotto di tasti, si sono introdotti metodi alter- a tale sequenza che si possono opportuna- telefoni cellulari di
nativi per la scrittura del testo. Il primo e più mente selezionare a cui daremo il nome di nuova generazione.
conosciuto tra questi metodi ha il nome di pseudo-omonimi. Nel caso specifico, gli altri Nello stesso anno (1
dicembre 1999) la Tegic
multi-tapping, ossia, battitura ripetuta. Uti- termini sono: io, ho, go, im, gn. Si può notare è stata assorbita dalla
lizzando tale tecnica per scrivere una singola la presenza del termine inglese go che c’è AOL, il colosso delle
lettera, bisogna battere più volte lo stesso sicuramente perché di uso comune anche comunicazioni e
tasto a seconda dell’ordine in cui essa com- nelle comunicazioni in italiano. Inoltre, si internet americano,
pare sullo stesso. Così, per scrivere il caratte- scorgono due sigle di cui onestamente igno- con la quale
collaborava già da
re a basterà battere una volta il pulsante 2, ravo l’esistenza. La tecnica sviluppata in casa prima sul progetto
mentre la s si otterrà con la pressione ripetu- Tegic Communication, quindi, prevede un “Instant Messenger”.
ta di 4 volte del tasto 7. Non si possono quin- dizionario che può essere ampliato con nuovi Se si digita
di pretendere accettabili performance se si termini. Infatti, se si digita una parola che [Link]
pensa che, per la produzione di una lettera, non è riconosciuta essa si può aggiungere, è il si viene ospitati di
fatto in casa AOL.
bisogna in generale, fare più battiture, ed caso di nomi o sigle desuete. Attualmente il sistema
anche in considerazione del fatto che bisogna Inoltre, interessante è la caratteristica che è sviluppato per 42
attendere un tempo, se pur minimo, per la dispone le diverse parole secondo un ordine lingue.
generazione di un singolo carattere, che deve interno che tiene conto della “popolarità” di
trascorrere interamente qualora i due carat- una parola, per cui nell’esempio esaminato,
teri da produrre adiacenti appartengano allo in è preferito a io che a sua volta precede il
stesso tasto. Ad esempio, se si deve scrivere la verbo avere in prima persona ho. Alcuni
parola nonno bisogna battere il tasto 6 per modelli di cellulari rendono la composizione
una volta per scrivere n, poi attendere che ancora più semplice associando un pad o
venga prodotta la lettera e di nuovo battere qualcosa di simile (il sony cmdz5 ha una
per due volte il tasto 6, quindi ancora atten- rotella chiamata jog dial) per navigare più
dere il tempo di produzione e così, continua- rapidamente tra i pseudo-omonimi; cosicché
re digitando ripetutamente sempre lo stesso l’uso associato della tastiera e del pad rende
bottone. Una valida evoluzione è stata intro- la composizione a livelli di rapidità accettabi-
dotta dalla Tegic Communications che ha li. È sempre possibile passare (switchare) tra
realizzato il sistema predittivo di inserimento le due modalità, T9 e multi-tapping.
di testo T9, la cui sigla significa “Text on 9 Modelli di cellulari di ultima generazione
keys”. prevedono sistemi multilingua consentendo

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/23 G
022-025-Soluzioni 4-10-2003 10:55 Pagina 24

SOLUZIONI Algoritmi per il trattamento dei testi

così la veloce traduzione e una composizione Esempi di tale corrispondenza sono:


più particolareggiata.
Il sistema T9 è stato introdotto anche su alcu- nonno 66666
ni computer palmari. Ma è arrivato il nonna 66662
momento di dedicare la nostra attenzione io 46
all’aspetto che maggiormente ci intriga e per pane 7263
cui, noi programmatori, siamo più natural- cane 2263
mente orientati. …
Vedremo come si possa strutturare un siste-
ma predittivo di inserimento di testi. La firma è la vera chiave che porta alla solu-
zione, infatti, l’idea sta nell’associare le paro-
le con altri elementi su cui effettuare la ricer-
ca, appunto le firme. Nel caso degli anagram-
SVILUPPO mi, le firme altro non erano che le stesse let-
DI UN PROGETTO tere costituenti la parola ordinate in modo
ALCUNI In questo paragrafo tracceremo i passi fonda- crescente, così uguali firme corrispondevano
LIMITI T9 mentali per lo sviluppo di un’applicazione ad anagrammi.
Sono stati realizzati che implementi un sistema predittivo di Nel caso specifico, invece, uguali firme gene-
molti studi, numerosi inserimento di testo, come T9. In questo per- rano pseudo-omonimi. La struttura dati fir-
dei quali basati su
parametri statistici, per
corso ci toccherà fare i conti con l’hardware me può essere definita come una matrice di
verificare la bontà e la disponibile, inoltre, sarà piacevole fare riferi- due colonne e m righe, con m il numero di
qualità del metodo T9 mento ad algoritmi sviluppati tra queste termini del dizionario (cardinalità del dizio-
e di altri simili. pagine per altri problemi. nario). Nella prima colonna si collocano le
In T9 è stata Il riferimento è al numero 65 della rivista, firme mentre, nella seconda, le parole corri-
riscontrata una certa
difficoltà nella
quando abbiamo manipolato le parole, per spondenti.
gestione di tutti quei produrre anagrammi. Noteremo che, molte Una seconda soluzione, ancora più efficien-
simboli che sono delle esperienze maturate in quella occasio- te, implementa la struttura dati come un
diversi dalle lettere ne, sono fondamentali per la risoluzione del array monodimensionale costituito dalle
dell’alfabeto, come nostro problema. Un’applicazione che predi- firme, in cui ogni elemento ha una lista a
numeri e caratteri
speciali quali
sponga il dispositivo all’uso del T9, o comun- puntatori che contiene un unico nodo, in cui
punteggiatura, que di un sistema automatico di inserimento è presente la parola corrispondente.
parentesi e altri. testo, deve prevedere la creazione di una Useremo questa seconda soluzione poiché
Per testi eterogenei si hash table che fornisca una corrispondenza rende più facile il lavoro successivo.
è costretti spesso a tra un numero e una parola o set di parole. Si Una volta generato un array di firme, che de-
“switchare” tra le
modalità T9
tratta, quindi, di associare, al numero digita- finisce peraltro la prima impronta del hash
multi-tapping. to sulla tastiera del cellulare, la parola o un table, bisogna ordinare il vettore per firme.
Inoltre, sono state insieme di parole. Anche qui si possono seguire sostanzialmen-
comprovate difficoltà La sequenza di macro operazioni da compie- te due strade. Le due scelte si distinguono in
di composizione in re è riportata di seguito: base al tipo che viene assegnato alla singola
testi carichi di slang,
per la continua
firma. In alcune simulazioni del T9, che ho
necessità di caricare // Preliminari trovato nelle mie ricerche su internet, tale ti-
nuovi termini nel download(sorgente, firme) po è stato definito come stringa di caratteri,
dizionario. sort(firme) poiché è più semplice la fase di produzione
union(firme) della firma che avviene come una banale
load(firme,hashtable) concatenazione tra singoli caratteri. In tal
caso, però, la struttura ordinata non segue
Il file sorgente è il dizionario, contenente la l’ordinamento naturale, essendo dipendente
sola lista di parole della lingua, ad esempio dal codice ascii usato.
quella italiana, più le parole di uso comune, Se invece, il tipo elementare è un numerico,
anche se non di senso compiuto, quelle che l’ordinamento avviene in modo naturale e
per capirci non sono riportate nel vocabola- anche il programma risulta più efficiente. In
rio della lingua italiana, ma che vengono usa- tal caso non è banale la composizione della
te ogni giorno. Tale file è scaricato su una firma, bisogna trasformare la stringa ottenu-
struttura dati in cui si producono una serie di ta come sequenza di cifre in un numero, per
coppie di dati, parola e firma. La firma altro ogni composizione parziale prodotta. Inoltre,
non è che il numero da digitare per produrre il tipo deve essere un intero molto lungo.
la specifica parola. Essendo più efficiente consideriamo la se-

h t t p : / / w w w. i o p r o g r a m m o . i t
G 24/Novembre 2003
022-025-Soluzioni 4-10-2003 10:55 Pagina 25

Algoritmi per il trattamento dei testi SOLUZIONI

conda scelta. Come mostrato nell’algoritmo, CONCLUSIONI


si procede con l’ordinamento per firme, rea- Per completezza bisogna dire che vi sono
lizzato da sort. La fase successiva prevede il altri metodi di inserimento automatico di
collassamento della struttura (union), ossia, testi, usati soprattutto per computer palmari,
qualora ci siano delle ripetizioni di firma, si i più conosciuti sono graffiti e fitaly.
uniscono in un’unica riga producendo ap- Gli affezionati della sezione soluzioni, che
pend nella lista a puntatori corrispondente. tento sempre di animare con nuove e a volte
Per cui, ad esempio, in corrispondenza della insoliti argomenti, sanno che sono un “pati-
firma 64, sarà presente una lista a puntatori to” degli algoritmi legati alla manipolazione
di 7 elementi, ognuno dei quali contiene le di numeri e parole, intesi come forma primi-
seguenti parole: in, io, ho, go, im, gn. Una vol- tiva di informazione nelle loro parti costi-
ta prodotta la hash table si tratta semplice- tuenti, ossia le cifre e le lettere. Quale miglio-
mente di caricare la struttura sul dispositivo re occasione, quindi, per presentare un tema
(load). che legasse i soggetti da me preferiti, tenuto
Un secondo stadio di applicazioni opera sul conto anche del fatto che nel caso specifico si DIZIONARIO
dispositivo che usa il sistema di inserimento. tratta di applicare, almeno in parte, alcuni Un dizionario nell’area
Bisogna, in questo contesto, garantire alcune metodi sviluppati in occasione degli studi di della programmazione
è riconducibile alla
importanti funzioni che sono; la ricerca e anagrammatica automatica. Infine, come mera lista di termini a
l’aggiornamento. spesso ho fatto tra queste pagine, volevo cui è associato
Esaminiamo alcune possibilità di ricerca. La puntualizzare che gli studi sviluppati qual- solitamente un
ricerca dicotomica garantisce buone perfor- che mese fa per produrre in modo automati- qualcosa. Nella visione
mance se si pensa che un dizionario si aggira co anagrammi non si riducevano al solo classica, l’associazione
è il significato, in
intorno ai 2000 termini e che dopo il collas- divertimento e l’articolo di oggi ne è una informatica non è
samento si riducono ulteriormente. Con una puntuale riprova. sempre così.
decina di interrogazioni si perviene all’ele- Quindi l’algoritimica va sempre esaminata Interessante è la
mento richiesto. A tale proposito, si ricorda con occhio attento ed in considerazione che definizione che viene
che per la ricerca binaria si ha una comples- una stessa applicazione, se adattata, può proposta nel
linguaggio python, per
sità temporale dell’ordine del logaritmo in risolvere altre tipologie di problemi. cui un dizionario è una
base 2 della lunghezza del vettore, O(lg(n)). Vi aspetto per la soluzione di nuovi ed inte- struttura simile ad un
Ma un ulteriore miglioramento si ottiene ressanti quesiti. array che si distingue
considerando che la parola si compone man Fabio Grimaldi da esso, perché per gli
mano che viene digitata, e che ad ogni stadio array le chiavi di
accesso sono numeri
della composizione, viene proposta una (sostanzialmente gli
parola fino a quel momento ottenuta. Così, ❏ ULTERIORI SVILUPPI indici), mentre per un
quando si digita il primo numero, si potrebbe Esistono diversi gruppi di discussione sui dizionario sono
semplicemente cercare tra le sole firme di sistemi predittivi di inserimento testi. elementi che possono
lunghezza 1 che sono solo otto. Se la ricerca essere di qualsiasi tipo.
Da alcuni di essi sono sorte interessanti
Inoltre, nel caso più
prosegue, vuol dire che si sono battuti più proposte per migliorare le potenzialità generale, python
tasti; continuiamo a considerare l’esempio ad esempio di T9. Una riguarda la possi- descrive il dizionario
precedente; dopo aver digitato 6 si batte il bilità di rendere dinamica la posizione come una struttura in
tasto 4, non è necessario ricercare il numero delle parole, che presentino pseudo-omo- cui nuovi inserimenti
64 tra tutti. non devono essere
nimi, nella lista a puntatori in base alla
necessariamente
Si può restringere il range di ricerca a tutti i frequenza, ovviamente, le parole più ordinati.
numeri che iniziano per 6 e così via. usate secondo una teoria delle code
La seconda ricerca, così descritta, si può effi- dovrebbero collocarsi in modo opportuno
cacemente implementare mantenendo una nella lista. Un’altra proposta si riferisce
struttura ad albero in cui ogni nodo presenta alle parole lunghe che potrebbero essere
otto rami, in questo ultimo caso si velocizza automaticamente completate, è infatti
ulteriormente la fase. inutile scrivere molte lettere quando il
Discutiamo una piccola appendice, indican- termine che si può comporre è solo uno.
do che un parametro di bontà dell’algoritmo Si auspica anche un maggiore facilità di
risolutore è la dimensione del programma, passaggio tra il sistema T9 e il multi-tap-
che deve essere minima in considerazione ping. Ed infine, molti richiedono una più
che i telefoni cellulari non dispongono di funzionale integrazione tra la tastiera e
molta memoria. In questa ottica le strutture altri strumenti come piccoli joystick, pad
predisposte garantiscono un consumo mini- o simili.
mo di risorse.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/25 G
028-034 T&T Riconoscim 4-10-2003 11:00 Pagina 28

TEORIA & TECNICA Windows API

Riconoscimento e sintesi vocale in pratica

Una segreteria
studenti in VB
Le Speech API (SAPI) permettono lo sviluppo di applicazioni basate
sulla voce, in particolare sul riconoscimento vocale, e sulla sintesi
vocale, vale a dire la trasformazione di testo in parlato.

I
n questo articolo realizzeremo un sottosistema Per quanto riguarda il riconoscimento e la sintesi
della segreteria studenti (dal nome Easy vocale, l’accesso alle Api avviene a due livelli: un
Esame), sfruttando gli OCX messi a disposizio- livello alto (Voice Commands e Voice Text), in cui è
ne dalla versione 4.0 del Microsoft Speech SDK, possibile usare semplici comandi per utilizzare da
che ancora oggi meglio si sposano con Visual subito la tecnologia vocale nelle applicazioni VB:
Basic. un livello più basso (Direct Speech Recognition,
Direct Speech Synthesis) che permette di dialogare
direttamente con il motore necessario per la ripro-
❏ CD ❏ WEB duzione vocale, lo Speech Engine (SE).
[Link] SAPI SDK 4 La versione completa dello Speech sdk, può essere
[Link] Le SAPI, sono un’estensione delle API di Windows scaricata da internet all’indirizzo [Link]
che consentono di utilizzare in maniera relativa- .com/speech/download/old/[Link]. Insieme al
mente semplice la tecnologia vocale in VB, fornen- SAPI SDK 4.0, la Microsoft distribuisce i suoi
do al programmatore 6 controlli ActiveX: Speech Engine, necessari affinché un’applicazione
funzioni. È possibile scaricare anche una versione
Per il riconoscimento vocale: leggera delle SAPI (circa 7 mega) che però non
contiene gli SE. Analizziamo ora in dettaglio i due
Voice Commands componenti che andremo ad utilizzare in questo
Direct Speech Recognition articolo: Voice Text e Voice Commands
PULSANTI
APPLICAZIONI Per trasformare in testo una frase letta sotto
I pulsanti “Addestra dettatura:
riconoscimento” e SINTESI VOCALE
“Seleziona Speech
Engine” servono, Dictation CON VOICE TEXT
rispettivamente, per Il componente Voice Text rende possibile la con-
visualizzare la Per la sintesi vocale (conversione dal testo al versione di un testo qualsiasi al parlato. Per averlo
procedura guidata che parlato): a disposizione nella ToolBox di VB, è sufficiente
permette il spuntare dalla finestra di dialogo Componenti (si
miglioramento del
riconoscimento vocale
Voice Text ottiene selezionando la voce di menu Pro-
e per visualizzare un Direct Speech Synthesis getto/Componenti), la voce Microsoft Voice Text.
form che permette di Disegnando il componente in un form avremo a
selezionare uno SE tra Per l’uso della tecnologia vocale attraverso il disposizione il controllo TextToSpeech1.
quelli installati nel telefono L’uso del componente Microsoft Voice Text è molto
sistema
semplice. Per consentire la pronuncia di una qual-
Speech Telephony siasi frase al Computer, è sufficiente chiamare il
metodo Speak della classe TextToSpeech, passando
Tutte le Speech Api sono accessibili attraverso come parametro la stringa che deve essere pro-
l’OLE Component object model, ed il modello di nunciata (ricordiamo che senza nessun speech
programmazione è orientato agli oggetti. engine installato il programma non funziona).

h t t p : / / w w w. i o p r o g r a m m o . i t
G 28/Novembre 2003
028-034 T&T Riconoscim 4-10-2003 11:00 Pagina 29

Windows API TEORIA & TECNICA

Il codice necessario per pronunciare il classico chiede, oltre ad una buona potenza di calcolo e di
“Ciao Mondo” sarà semplicemente: memoria, una migliore comprensione dei fattori
che caratterizzano il linguaggio naturale nel suo
[Link] “Ciao Mondo” complesso. Prima di analizzare il componente
messo a disposizione dalle SAPI affrontiamo un
È importante sapere che il modello di programma- pizzico di teoria.
zione è asincrono, in altre parole il controllo del
programma passa subito all’istruzione successiva
senza attendere che sia terminata la sintesi del
testo. Quando la sintesi è completata viene lancia-
RICONOSCIMENTO
to l’evento SpeakingDone. DEL PARLATO SELEZIONE
Quindi, se riscriviamo il codice precedente in: In linea di principio, il riconoscimento del parlato DI UN SE
comporta l’acquisizione del segnale vocale, la sua Per selezionare un
particolare SE si deve
[Link] “Ciao Ciao Mondo” conversione in formato digitale, la separazione
utilizzare il
MsgBox “messaggio” delle singole parole e il confronto delle stesse con componente Direct
un insieme di pattern di riferimento preregistrati Speech Recognition
Noteremo che il messaggio apparirà a video prima che contengono l’associazione tra la forma parlata con i metodi:
che il testo sia letto per intero. e quella scritta. Come si può facilmente intuire, ci FindEngine e
Utilizzando l’evento SpeakingDone invece, possia- si muove in un campo caratterizzato da un alto SelectEngine
mo fare in modo che il messaggio appaia soltanto grado d’incertezza. Per questo motivo, i sistemi
quando l’engine ha finito di parlare: attuali introducono dei vincoli sull’utilizzazione
del sistema, che comportano delle semplificazioni
Private Sub TextToSpeech1_SpeakingDone() nelle varie fasi del processo di riconoscimento, SISTEMI
MsgBox “messaggio” ottenendo delle buone prestazioni a scapito di un DI SINTESI
End Sub restringimento del dominio applicativo. Un sistema di sintesi
Vediamone alcune problematiche: della voce è una
macchina che, a partire
Gli SE inclusi nel pacchetto full delle SAPI sono da appropriate
tutti in versione inglese, ma nonostante tutto leg- Pronuncia per parole isolate: durante la fase di rappresentazioni di un
gono discretamente anche l’italiano. In ogni caso, campionamento è necessario isolare le parole che evento linguistico
la programmazione del TTS non dipende dallo SE costituiscono la frase. Questo comporta una anali- (parola, messaggio,
usato e quindi dalla lingua, per questo è sufficien- si spettrale abbastanza sofisticata del segnale d’in- insiemi di messaggi,
ecc.), è in grado di
te installare uno SE italiano per ottenere una cor- gresso. Inoltre, in alcuni contesti, due o più parole produrre l’emissione
retta lettura del testo nella nostra lingua. Esiste, in sono pronunciate in modo continuo e la loro sonora corrispondente.
ogni modo, la possibilità di costruirsi uno SE che decomposizione nelle parole costituenti non è di La sintesi della voce
utilizzi la lingua e addirittura il dialetto che si pre- facile soluzione. Per queste difficoltà, alcuni siste- consente ad un
ferisce, ma per far ciò, purtroppo, non basta VB ma mi di riconoscimento impongono la pronuncia computer di inviare
istruzioni o
si devono usare le funzioni API pure. Per un cor- per parole isolate. informazioni all’utente
retto riconoscimento vocale di parole della nostra attraverso il parlato.
lingua è invece necessario uno SE italiano. Dipendenza dal parlante: la codifica della voce è
usualmente fatta attraverso dei modelli che tengo- I metodi di sintesi della
no conto sia dei parametri d’eccitazione (frequen- voce possono essere
suddivisi in due
za fondamentale (pitch), guadagno, ecc.) che delle
RICONOSCIMENTO caratteristiche del tratto vocale. La rappresenta-
categorie:
Sintesi basata sulla
VOCALE IN VB zione codificata della voce dipende quindi dalle codifica di singole
Il Riconoscimento Vocale (RV) realizza il sogno di caratteristiche del parlante. Durante la fase di rico- parole di voce umana
tanti, e vale a dire quello di poter dialogare con il noscimento, bisogna confrontare la parola pro- registrata. Tali
frammenti sono
computer in maniera naturale, senza l’uso della nunciata con un insieme di parole preregistrate opportunamente
tastiera o del mouse. Avendo poi a disposizione un (vocabolario del linguaggio) prodotte utilizzando combinati per la
sistema di sintesi, si potrà avere anche l’illusione un modello vocale con parametri predefiniti. In composizione del
che il computer comprenda le nostre parole e altri termini, il confronto viene fatto tra la parola messaggio parlato
risponda anch’esso con la sua voce. Sebbene que- pronunciata in ingresso e tra un insieme di parole (sistemi a vocabolario
limitato).
sto scenario (per certi versi apocalittico) è ancora pronunciate da un parlante le cui caratteristiche Sintesi basata su
lontano, grazie alle Speech API (SAPI), anche gli vocali sono preregistrate: se il sistema conosce le regole linguistiche,
sviluppatori VB possono contribuire alla sua rea- caratteristiche del tratto vocale dell’utente, le pos- fonetiche e acustiche
lizzazione. Il riconoscimento vocale si pone come sibilità d’errore diminuiscono. Questo principio (sistemi a vocabolario
obiettivo fondamentale il riconoscimento delle viene utilizzato da alcuni sistemi, detti speaker illimitato).
parole pronunciate in modo continuo da una per- dependent, che prevedono una fase iniziale d’ad-
sona, attività abbastanza complessa, giacché ri- destramento del sistema, al fine di estrarre i para-

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/29 G
028-034 T&T Riconoscim 4-10-2003 11:00 Pagina 30

TEORIA & TECNICA Windows API

dimensione dello spazio di ricerca, a scapito di un


aumento della possibilità d’errori.

Grammatica: definisce l’insieme delle sequenze


di parole ammissibili nel dominio del riconosci-
mento. Imporre dei vincoli stringenti sulla gram-
matica comporta ovviamente una minore proba-
bilità d’errore nel riconoscimento.
SISTEMI A
VOCABOLARIO Ambiente: la presenza di rumori di fondo, il cam-
LIMITATO biamento delle caratteristiche del microfono, la
E ILLIMITATO differenza di condizioni rispetto alla fase d’intro-
I sistemi di sintesi a duzione dei modelli fonetici di riferimento, ecc.,
“vocabolario limitato” possono influenzare notevolmente l’accuratezza
Fig. 1: L’interfaccia dell’applicazione EasyEsame.
possono riprodurre,
come indica la denomi-
del riconoscimento. Questi effetti possono essere
nazione, un numero metri caratteristici del modello vocale dell’utente compensati utilizzando dei microfoni aventi dei
limitato, seppure gran- attraverso la pronuncia di un insieme predefinito buoni rapporti Segnale/Rumore e montati in vici-
de, di parole e/o mes- di frasi. Sistemi di questo tipo si differenziano per nanza della bocca. L’utilizzazione di un sistema di
saggi. Nel primo caso, il numero di parole che devono essere pronuncia- riconoscimento in congiunzione con il telefono,
la tecnologia impiega-
ta è molto semplice, la
te durante la fase d’addestramento. La rimozione comporta analoghi problemi a causa degli even-
macchina attua la di questo vincolo (sistemi speaker independent) tuali disturbi presenti nella linea e della limitata
gestione di un archivio aumenta ovviamente la complessità del sistema: banda di frequenze.
che contiene la regi- un approccio comunemente adottato è di adde-
strazione degli eventi strare il sistema con una gran varietà di parlanti,
linguistici da riprodur-
re e cioè un insieme di
mentre uno più sofisticato è di individuare le
parametri ottenuti caratteristiche fonetiche invarianti tra parlanti. IMPOSTAZIONE
codificando il vocabo-
lario da riprodurre. Il
DEL SISTEMA
Dimensione del vocabolario: la dimensione del
messaggio viene poi vocabolario influenza notevolmente il sistema di
DI RICONOSCIMENTO
generato selezionando
riconoscimento. Un vocabolario di grandi dimen- VOCALE
i vocaboli , giustappo-
nendo, attraverso sioni, sebbene sia auspicabile poiché aumenta Il componente Voice Command rende possibile il
regole opportune, i l’insieme di parole riconoscibili, introduce un riconoscimento vocale. Per averlo a disposizione
corrispondenti para- maggior grado d’incertezza a causa di una mag- nella ToolBox di VB, è sufficiente spuntare dalla
metri, inviandoli ad un giore probabilità di contenere parole simili rispet- finestra di dialogo Componenti, la voce Microsoft
circuito, che proceden-
do in modo concettual-
to a vocabolari di dimensioni più piccole. Voice Commands. Disegnando il componente in
mente inverso alla fase Ovviamente questo problema si può manifestare un form avremo a disposizione il controllo
di analisi, dà luogo anche per vocabolari di piccole dimensioni. Un Vcommand1. Analizziamo, ora, i passi necessari
all’emissione sonora secondo problema deriva dal fatto che il tempo di all’impostazione di un sistema di riconoscimento
desiderata. Le applica- ricerca può aumentare considerevolmente: i siste- vocale.
zioni di questo tipo di
macchina si possono
mi con vocabolari di grandi dimensioni utilizzano
intuire facilmente e delle tecniche di filtraggio che diminuiscono la Primo passo: il controllo VoiceCommand deve
sono già abbastanza essere inizializzato ponendo ad uno la proprietà
diffuse: annunciatori Initialized:
per stazioni ed aero-
porti, risponditori
[Link] = 1
telefonici, allarmi di
vario tipo, giocattoli,
etc. Con i sistemi di Il secondo passo è quello della definizione del
sintesi da testo a menu dei comandi riconoscibili dal sistema, per
“vocabolario illimita- questo usiamo la funzione:
to”, è possibile trasfor-
mare in messaggio ver-
bale un qualunque MenuCreate(Application As String, State As String,
testo. Per l’elaborazio- flags As Long) As Long
ne del segnale sono
impiegati diversi stadi Dove :
di elaborazione basati
su differenti compe-
tenze specialistiche: Application è il nome dell’applicazione che usa il
linguistiche, fonetiche, menu;
acustiche. Fig. 2: I controlli da aggiungere al progetto VB. State è il nome dello stato d’uso del menu;

h t t p : / / w w w. i o p r o g r a m m o . i t
G 30/Novembre 2003
028-034 T&T Riconoscim 4-10-2003 11:00 Pagina 31

Windows API TEORIA & TECNICA

flags rappresenta un valore che serve a stabilire in rilasciare la memoria occupata dal processo di RV
che modo deve essere creato il menu (vedi box a con il metodo:
pag. 31). Le costanti usate nelle SAPI sono definite
nel modulo [Link] che pertanto deve essere ReleaseMenu (Menu as long)
incluso nel progetto, che restituisce l’identificativo
del menu.

Il terzo passo è la definizione dei comandi del


STRUTTURA
menu, creato con Menucreate, usando il metodo: DI EASY ESAME
Scopo di questo articolo è la realizzazione di
AddCommand(Menu As Long, id As Long, command As un’applicazione (chiamata Easy Esame) che im-
String, description As String, category As String, plementi un sottosistema di una segreteria stu-
flags As Long, action As String) denti con il compito di fornire informazioni su:

Dove: • Orario corsi POSSIBILI


• Programma del corso VALORI DEI
Menu è l’identificativo del menu di riferimento; • Calendario esami FLAG IN
Id rappresenta l’identificativo unico del comando • Prenotazione esami MENUCREATE
vocale; • Risultati esami VCMDMC_CREATE_ALW
AYS. Crea un menu
Command è la rappresentazione testuale del
vuoto. Se esiste un
comando; Le informazioni possono essere memorizzate in menu, con lo stesso
Description è una descrizione di quello che fa un database oppure più semplicemente in file. In nome nel database dei
l’applicazione quando viene lanciato il comando; Easy Esame utilizzeremo la struttura a file poiché menu, viene cancellato
Category è la categoria del comando; l’uso di un database renderebbe necessario descri- e sostituito da quello
corrente.
Flags indica informazioni sul comando; vere le metodologie di accesso ai database che
VCMDMC_CREATE_NEW
Action è una serie di dati inviati all’applicazione esulano dallo scopo di questo articolo. Nella direc- . Crea un menu vuoto.
quando il comando viene riconosciuto. tory contenente il programma ([Link]) dovran- Se esiste un menu con
no essere presenti i seguenti file: lo stesso nome nel
database la funzione
restituisce un [Link]
[Link] con i nomi dei corsi disponibili - No-
nuovo menu viene
[Link], [Link], NomeCorso- memorizzato nel
[Link], [Link], [Link] con database quando
le informazioni, divise in categorie, di ogni corso. l’oggetto viene
Naturalmente NomeCorso individua il nome del rilasciato
corso, perciò per ogni corso disponibile dovranno VCMDMC_CREATE_TEM
P. Crea un menu vuoto.
esistere cinque file. L’interazione con l’utente deve Se esiste un menu con
essere il più semplice possibile. Lo studente dovrà lo stesso nome nel
selezionare, tramite comando vocale, un corso tra database la funzione
quelli disponibili in una lista mostrata a video. Il restituisce un [Link]
nome del corso selezionato deve essere mostrato a nuovo menu viene
memorizzato
video per avere il feedback della corretta scelta temporaneamente e
effettuata. viene distrutto quando
l’oggetto viene
A questo punto, sempre tramite comando vocale, rilasciato
lo studente dovrà selezionare il tipo di informazio- VCMDMC_OPEN_ALWA
YS. Apre un menu
ne desiderata, che verrà letta dal sistema (e con- [Link] il menu
Fig. 2: Nella toolbar dei controlli compaiono le icone temporaneamente mostrata a video). Infine, pri- non esiste ne viene
dei due nuovi componenti installati. ma di leggere le ultime due informazioni, Preno- creato uno vuoto.
tazioni e Risultati, deve essere richiesto il numero VCMDMC_OPEN_EXISTI
NG. Apre un menu
L’ultimo passo è l’attivazione della fase di ricogni- di matricola. Per il disegno dell’applicazione, oltre
esistente. Se il menu
zione con il metodo: ai vari fronzoli per abbellire l’interfaccia, saranno non esiste la funzione
necessari: restituisce un errore.
Activate(Menu as Long)
1 ListBox (ListCorsi) che dovrà contenere l’elen-
Soltanto quando il menu è attivato lo SE controlla co dei corsi disponibili.
che le parole pronunciate facciano parte dei
comandi. 2 TextBox (TextCorso, TextMatricola) che forni-
Infine, quando l’applicazione viene chiusa, si deve ranno allo studente il feedback sul corso e sulla

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/31 G
028-034 T&T Riconoscim 4-10-2003 11:00 Pagina 32

TEORIA & TECNICA Windows API

matricola selezionata ed un TextBox (TextRisul- Dopo aver definito le due variabili NomeFileCorsi e
tato) che mostrerà a video l’informazione deside- Corso che conterranno rispettivamente il nome
rata. del file da leggere ed il nome del corso in esame,
viene chiamata la routine InitRiconoscimento che
5 Label che mostrano il nome delle informazioni si occupa di inizializzare il sistema di riconosci-
a disposizione. mento vocale mediante lo schema analizzato in
precedenza:
1 controllo VoiceCommand.
Private Sub InitRiconoscimento()
1 controllo TextToSpeech. [Link] = 1
CommandMenu = [Link](
[Link], “Menu Segreteria Studenti”,
VOICE VCMDMC_CREATE_ALWAYS)
TELEPHONY
SVILUPPO [Link] = 1
CONTROL DI EASY ESAME End Sub
Il controllo Voice A questo punto abbiamo definito tutti gli strumen-
Telephony (VT) ti necessari per scrivere il codice necessario al cor- Le istruzioni necessarie per l’apertura, lettura e
permette di creare
applicazioni di
retto funzionamento dell’applicazione. chiusura di un file sono commentate all’interno
telefonia multi-linea All’apertura del programma si dovrà: del codice per questo ne tralascio la descrizione.
con riconoscimento e All’interno del ciclo Do..While, per ogni corso ven-
sintesi vocale e con • Inizializzare il sistema di riconoscimento gono richiamate due procedure, InserisciInLista e
l’identificazione dei • Leggere dal file [Link] l’elenco dei corsi InserisciInMenuRiconoscimento, che si occupano
toni DTMF. L’uso della
rete telefonica
disponibili rispettivamente di riempire la ListBox contenente
pubblica rende • Visualizzare la lista dei corsi la lista dei corsi, ed inserire il nome del corso nel
possibile una serie di • Inserire nel menu vocale la lista dei corsi menu di riconoscimento vocale:
servizi a mezzo voce, in • Attivare il sistema di riconoscimento
cui il computer Private Sub InserisciInLista(Corso As String)
comprende e risponde.
Queste fasi saranno implementate nella routine [Link] Corso
VT è un controllo
multi-threaded, in cui InitCorsiERiconoscimento, chiamata nell’evento End Sub
ogni thread è associato Form_Load. E’ necessario, inoltre, definire la varia- Private Sub InserisciInMenuRiconoscimento(Comando
ad una linea telefonica. bile CommandMenu che dovrà contenere l’identi- As String)
Naturalmente se si ha ficativo del menu vocale. [Link] CommandMenu, 1,
a disposizione una sola
Comando, “Corso “ + Comando, “Corso”, 0, “”
linea telefonica si avrà
un solo thread. Option Explicit End Sub
Dim CommandMenu As Long
Private Sub Form_Load() Infine le ultime due procedure, InserisciOpzioniIn-
InitCorsiERiconoscimento MenuRiconoscimento e AttivaRiconoscimento, si
End Sub occupano di inserire le possibili opzioni di scelta
dello studente nel menu dei comandi ed attivare il
CONFIGURARE Vediamo nei dettagli la procedura InitCorsiERico- sistema di riconoscimento vocale:
L’HARDWARE noscimento
Le SAPI forniscono un Private Sub InserisciOpzioniInMenuRiconoscimento()
utile applicazione, Private Sub InitCorsiERiconoscimento() [Link] CommandMenu, 1,
[Link], per essere
Dim NomeFileCorsi As String “calendario”, “calendario”, “info”, 0, “”
sicuri che il microfono
sia compatibile con la Dim Corso As String [Link] CommandMenu, 1,
scheda sonora e per NomeFileCorsi = [Link] + “\[Link]” ‘definisce il “risultato”, “risultato”, “info”, 0, “”
avere una buona nome del file da aprire [Link] CommandMenu,1,
regolazione del InitRiconoscimento ”prenotazione”, “prenotazione”, “info”, 0, “”
volume. L’uso di
Open NomeFileCorsi For Input As #1 ‘ Apre il file in input. [Link] CommandMenu, 1,
micwiz e abbastanza
semplice ed intuitivo; Do While Not EOF(1) ‘ Ripete fino alla fine del file. “programma”, “programma”, “info”, 0, “”
permette di Input #1, Corso ‘legge il file una riga per volta [Link] CommandMenu, 1, “orario”,
configurare al meglio il InserisciInLista Corso “orario”, “info”, 0, “”
microfono seguendo le InserisciInMenuRiconoscimento Corso [Link] CommandMenu, 1, “fine”,
istruzioni guidate del
Loop “fine”, “Fine”, 0, “”
programma.
Close #1 ‘chiude il file [Link] CommandMenu, 1, “0”,
InserisciOpzioniInMenuRiconoscimento “zero”, “matricola”, 0, “”
AttivaRiconoscimento [Link] CommandMenu, 1, “1”,
End Sub “uno”, “matricola”, 0, “”

h t t p : / / w w w. i o p r o g r a m m o . i t
G 32/Novembre 2003
028-034 T&T Riconoscim 4-10-2003 11:00 Pagina 33

Windows API TEORIA & TECNICA

[Link] CommandMenu, 1, “2”, End Select


“due”, “matricola”, 0, “” End Sub
[Link] CommandMenu, 1, “3”,
“tre”, “matricola”, 0, “” In pratica, ogni qualvolta l’utente pronuncia una
[Link] CommandMenu, 1, “4”, parola che appartiene al set dei comandi predefi-
“quattro”, “matricola”, 0, “” niti, viene effettuato un Select Case sul comando.
[Link] CommandMenu, 1, “5”, Se l’utente pronuncia il nome dei menu: calenda-
“cinque”, “matricola”, 0, “” rio, programma, orario; allora viene dapprima
[Link] CommandMenu, 1, “6”, effettuato un controllo sull’effettiva selezione di
“sei”, “matricola”, 0, “” un corso nella funzione NessunCorsoSelezionato
[Link] CommandMenu, 1, “7”, (che ritorna un valore True se non è stato selezio-
“sette”, “matricola”, 0, “” nato nessun corso), e successivamente viene chia-
[Link] CommandMenu, 1, “8”, mata una procedura che si preoccuperà di leggere PROPRIETÀ
“otto”, “matricola”, 0, “” e mostrare a video le informazioni corrispondenti. ED EVENTI DEL
[Link] CommandMenu, 1, “9”, Se l’utente pronuncia il nome dei menu: risultato, CONTROLLO VT
“nove”, “matricola”, 0, “” prenotazione; allora viene effettuato un ulteriore Il controllo VT espone
tre proprietà:
End Sub controllo sull’effettivo inserimento di un numero
Private Sub AttivaRiconoscimento() di matricola nella funzione NessunaMatricolaSele- • AnswerAfterRings
[Link] CommandMenu zionata (che ritorna un valore True se non è stato per fissare il numero di
End Sub inserito nessun numero di matricola). squilli prima di
Se l’utente pronuncia un numero, allora non si rispondere alla
telefonata.
Nel momento in cui l’utente pronuncia un coman- deve fare altro che mostrare a video il numero
do tra quelli presenti nel menu, viene lanciato l’e- appena inserito (siamo nella fase di inserimento • Initialized per
vento CommandRecognize, perciò in questo even- del numero di matricola). inizializzare il
to scriveremo il nucleo del codice di gestione di Se l’utente pronuncia il comando fine, allora si controllo.
Easy Esame: legge un messaggio di ringraziamento e si ripuli-
scono i TextBox di selezione. • MaxLines per fissare
il massimo numero di
Private Sub Vcommand1_CommandRecognize(ByVal ID Se l’utente pronuncia un qualsiasi altro comando linee telefoniche.
As Long, ByVal CmdName As String, ByVal Flags As riconosciuto, allora si deve mostrare a video il
Long, ByVal Action As String, ByVal NumLists As Long, corso appena selezionato (siamo nella fase di sele- E genera quattro
ByVal ListValues As String, ByVal command As String) zione del corso). eventi:
Select Case command Lo schema delle procedure che si preoccupano di
• ClickIn generato
Case “calendario” leggere e mostrare a video le informazioni selezio- quando si clicca con il
If NessunCorsoSelezionato Then Exit Sub nate è simile: si definisce una variabile che contie- mouse sull’icona del
EseguiMenuCalendario ne il nome del file da leggere, si assegna il valore controllo VT.
Case “risultato” corrispondente a tale variabile, ed infine si chiama
• DoPhoneCall
If NessunCorsoSelezionato Then Exit Sub la procedura (LeggiFile) che dovrà effettivamente
generato alla ricezione
If NessunaMatricolaSelezionata Then Exit Sub leggere e mostrare a video le informazioni selezio- della chiamata
EseguiMenuRisultati nate. L’unica procedura differente è la procedura telefonica.
Case “prenotazione” EseguiMenuPrenotazioni che dovrà, al contrario
If NessunCorsoSelezionato Then Exit Sub delle altre, scrivere su file il numero di matricola • Initialize generato
quando
If NessunaMatricolaSelezionata Then Exit Sub inserito.
nell’applicazione viene
EseguiMenuPrenotazioni
settata la proprietà
Case “programma” Private Sub EseguiMenuCalendario() initialized.
If NessunCorsoSelezionato Then Exit Sub Dim nomeFile As String
EseguiMenuProgramma nomeFile = [Link] + “\” + TextCorso + “[Link]” • Shutdown generato
Case “orario” LeggiFile nomeFile, “”
quando termina un
thread associato ad
If NessunCorsoSelezionato Then Exit Sub End Sub
una linea telefonica.
EseguiMenuOrario Private Sub EseguiMenuRisultati()
Case “0”, “1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9” Dim nomeFile As String Nell’evento
TextMatricola = TextMatricola + command nomeFile = [Link] + “\” + TextCorso + “[Link]” DoPhoneCall dovrà
Case “fine” LeggiFile nomeFile, TextMatricola
essere contenuto il
codice necessario a
[Link] “Grazie per aver usato il End Sub
regolare l’intero
servizio” Private Sub EseguiMenuPrenotazioni() colloquio telefonico
TextMatricola = “” Dim nomeFile As String con l’utente.
TextCorso = “” nomeFile = [Link] + “\” + TextCorso + “[Link]”
Case Else ScriviSuFile nomeFile, TextMatricola
TextCorso = command [Link] “Prenotazione Effettuata”

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/33 G
028-034 T&T Riconoscim 4-10-2003 11:00 Pagina 34

TEORIA & TECNICA Windows API

End Sub Infine, per completezza, riportiamo le funzioni


Private Sub EseguiMenuProgramma() che controllano l’avvenuta selezione di un corso o
Dim nomeFile As String di un numero di matricola
nomeFile = [Link] + “\” + TextCorso + “[Link]”
LeggiFile nomeFile, “” Private Function NessunCorsoSelezionato() As Boolean
End Sub If TextCorso = “” Then
Private Sub EseguiMenuOrario() [Link] “Attenzione Nessun Corso
Dim nomeFile As String Selezionato”
nomeFile = [Link] + “\” + TextCorso + “[Link]” NessunCorsoSelezionato = True
LeggiFile nomeFile, “” Else
COMPONENTI End Sub NessunCorsoSelezionato = False
DI UN SISTEMA End If
DI RV La procedura LeggiFile si dovrà preoccupare di leg- End Function
Dispositivo per gere le informazioni contenute nel file passato co- Private Function NessunaMatricolaSelezionata()
l’acquisizione della me parametro e, nel caso venga passato anche una As Boolean
voce: è costituito da un
matricola non vuota, dovrà leggere soltanto la riga If TextMatricola = “” Then
microfono e da un
convertitore A/D che di informazione corrispondente alla matricola se- [Link] “Attenzione Nessuna
codifica in forma lezionata. Matricola Selezionata”
digitale la forma NessunaMatricolaSelezionata = True
d’onda vocale. Private Sub LeggiFile(nomeFile As String, matricola Else
As String) NessunaMatricolaSelezionata = False
• Digital Signal
Processor (DSP): Dim StringaDaLeggere As String End If
l’obiettivo Dim StringaTemp As String End Function
fondamentale di Open nomeFile For Input As #1
questo modulo è la Do While Not EOF(1) Naturalmente, quando l’applicazione viene chiu-
produzione di una
Input #1, StringaTemp sa, si deve rilasciare la memoria occupata dal pro-
rappresentazione
compressa della forma If matricola = “” Then cesso di RV, perciò nella Form_unload scriviamo
d’onda, estraendo quei StringaDaLeggere = StringaDaLeggere
componenti della + StringaTemp Private Sub Form_Unload(Cancel As Integer)
rappresentazione Else [Link] CommandMenu
spettrale che sono più
If Left(StringaTemp, 5) = matricola Then End Sub
significativi durante la
fase di riconoscimento. StringaDaLeggere = “la matricola numero “
+ matricola + “ risulta “ + Right( Per l’uso dell’applicazione da parte di un qualsiasi
• Pattern di StringaTemp, Len(StringaTemp) - 5) utente non è necessario nessuna particolare fase
riferimento: contiene i Exit Do di autoistruzione del parlante, poiché i comandi
modelli vocali di
End If non sono molti e sono ben distinti tra essi, per
riferimento. Questi
modelli si End If questo si riduce la possibilità di errore.
differenziano in base Se la lista dei corsi aumenta o presenta corsi dal
alle unità vocali Loop nome simile è necessario migliorare l’interazione
utilizzate: fonemi, Close #1 con il motore di riconoscimento utilizzando i
sillabe, parole, frasi.
[Link] = True metodi: GeneralDlg per visualizzare la maschera di
• Modulo di TextRisultato = StringaDaLeggere dialogo generale dello SE, oppure TrainGeneralDlg
riconoscimento: [Link] StringaDaLeggere e TrainMenuDlg (che però non è disponibile per
effettua il confronto End Sub tutti gli SE) per istruire lo SE con caratteristiche
tra le parole Private Sub TextToSpeech1_SpeakingDone() particolari della voce, è infatti consigliata una
preprocessate
[Link] = False breve fase di training se si hanno forti inflessioni
pronunciate dal
parlante e i modelli di End Sub dialettali.
riferimento
preregistrati, La procedura ScriviFile si dovrà preoccupare di
selezionando tra le scrivere sul file del corso selezionato, il numero di
parole ammissibili,
determinate dai vincoli
matricola inserito dallo studente: CONCLUSIONI
grammaticali e lessicali L’applicazione realizzata nell’articolo è un punto di
(vocabolario), quella di Private Sub ScriviSuFile(nomeFile As String, matricola partenza che serve a mostrare come la tecnologia
massima similarità As String) vocale sia alla portata dei programmatori VB.
misurata in uno spazio Open nomeFile For Append As #1 A questo punto non resta che dare spazio alla fanta-
metrico di riferimento.
Write #1, matricola sia per la realizzazione delle molteplici applicazioni
Close #1 possibili.
End Sub Ing. Luigi Buono

h t t p : / / w w w. i o p r o g r a m m o . i t
G 34/Novembre 2003
036-039-T&T XML 4-10-2003 9:49 Pagina 36

TEORIA & TECNICA Lo standard XML nella piattaforma .NET

Creare oggetti C# da un documento XML

Importare documenti
XML con C# parte prima

Oggigiorno XML è lo standard di fatto per lo scambio di dati


tra differenti sistemi e piattaforme. Per tale motivo, fornire
un meccanismo per creare oggetti a partire da codice XML potrà
risultare utile in numerosi contesti.

I
n questa serie di articoli dedicati a XML e C# uti- Ovviamente questo è un esempio molto banale. In
lizzeremo l’oggetto XmlReader e la reflection per situazioni più complesse il documento XML potreb-
realizzare un robusto e potente componente di be contenere altre classi annidate o array d’oggetti. Il
utilità generale in grado di effettuare il mapping tra nostro componente dovrà essere in grado di funzio-
dati XML e oggetti C#. L’oggetto XmlReader rappre- nare anche in questi casi più complicati. Ad una
senta la modalità standard con cui un’applicazione prima occhiata, importare codice XML usando la
.NET legge il contenuto di documenti XML. Median- reflection potrebbe non sembrare una strategia
te la reflection invece, le applicazioni possono ispe- molto intelligente poiché il framework .NET mette a
❏ CD ❏ WEB zionare propria la struttura interna, che può essere disposizione la serializzazione proprio per tale
[Link] usata per creare istanze a run-time, invocare metodi scopo. La serializzazione è una caratteristica molto
dinamicamente o reperire informazioni circa classi potente in .NET e, a differenza di quella presente in
[Link]
e relativi membri. Java, consente anche di serializzare e deserializzare
oggetti in formato XML. Nonostante questo, come
vedremo, esistono alcune situazioni nelle quali
usare la serializzazione potrebbe non essere la stra-
tegia più appropriata. Per esempio, un caso potreb-
PERCHÉ IMPORTARE be essere quando si ha la necessità di importare
XML IN OGGETTI informazioni da sistemi esterni, che magari produ-
Come abbiamo già detto, l’idea è quella di sviluppa- cono codice XML differente da quello interpretabile
re una classe C# per importare codice XML scritto dalla serializzazione .NET. Per risolvere problemi
secondo un prefissato schema. come questo, abbiamo sostanzialmente due scelte:
Questa classe, usando le informazioni contenute nel trasformare il codice XML in altro codice XML
documento XML, sarà in grado (mediante la reflec- (usando XSLT) in formato compatibile con la seria-
tion) di creare dinamicamente istanze di classi che lizzazione oppure creare un componente che legge
contengono proprio le informazioni presenti nel il codice XML e crea oggetti C# in base alle informa-
documento XML. zioni in esso contenute. Il primo metodo può essere
Consideriamo, per esempio, il seguente codice XML: un’efficace e potente strategia, ma è in ogni caso ne-
cessario seguire la seconda strada se si è interessati
<class name=”Persona”> anche al tipo dei dati. Infatti, la serializzazione .NET
<field name=”nome” value=”Mario” type=”string”/> non consente di specificare il tipo di dato e questo a
<field name=”cognome” value=”Rossi” type=”string”/> volte può rappresentare una significante limitazio-
</class> ne, specialmente in sistemi in cui il mapping dei tipi
è una problematica che non può essere tralasciata.
La classe C# che importerà tale XML, creerà un’i-
stanza della classe Persona in cui:

[Link] = “Mario”
IL PROBLEMA
[Link] = “Rossi” Lo scopo finale di questa serie di articoli su XML e

h t t p : / / w w w. i o p r o g r a m m o . i t
G 36/Novembre 2003
036-039-T&T XML 4-10-2003 9:49 Pagina 37

Lo standard XML nella piattaforma .NET TEORIA & TECNICA

C# è quello mostrare come scambiare dati tra due campi con i dati provenienti dal documento XML. Il
sistemi, nei quali il sistema che importa è imple- nome della classe, quello degli attributi ed i valori
mentato in C# e quello che esporta fornisce infor- che assumono, sono scritti all’interno dell’XML,
mazioni usando codice XML che rispetta un prede- quindi il componente avrà tutti i dati necessari per
terminato schema. Il sistema che legge il codice creare, usando la reflection, le istanze delle varie
XML deve importare e creare i dati in accordo con il classi e ritornarne un riferimento.
proprio design. Molto spesso, in sistemi orientati
agli oggetti, importare significa proprio creare
oggetti. Per realizzare ciò, si deve prevedere un mec-
canismo in grado di trasferire dati dal formato XML
in oggetti. Spesso, questo è lavoro molto delicato da
XML PARSER
realizzare, poiché tipicamente ogni classe ha una E XMLREADER
diversa struttura, diversi attributi e metodi. Per La classe XmlReader è una classe astratta che forni-
esempio, la classe Persona avrà una struttura com- sce un meccanismo ad alte prestazioni (non dotato
pletamente differente dalla classe Fattura. La prima di cache) per dialogare con codice XML. La classe
potrebbe avere attributi quali nome, cognome e XmlTextReader è un’implementazione concreta di
dataDiNascita. La seconda invece possiederà attri- XmlReader che consente di accedere e leggere codi-
buti come numero, data e importo. Per questo moti- ce XML presente in uno stream di testo. L’utilizzo di
vo, usando un approccio semplicistico, sarà neces- XmlTextReader è la modalità standard per leggere il
sario implementare del codice ad hoc per importare contenuto di un documento XML. Questa classe
ogni differente tipo classe. Naturalmente, noi voglia- non aderisce né alla filosofia SAX né a quella DOM.
mo evitare proprio questa situazione. In definitiva, Comunque, il modo di operare di XmlTextReader è
cosa vogliamo quindi? Ci piacerebbe creare una molto più vicino a SAX che a DOM, poiché la classe
classe C# di uso generale in grado di leggere codice effettua il parsing del codice XML consentendo alle
XML, interpretarlo e creare l’oggetto opportuno. applicazioni di processare gli elementi nello stesso
Inoltre, tale classe dovrà quindi: momento in cui questi vengono letti. A differenza di [Link]
DOM, un oggetto XmlTextReader non crea nessun Per interoperare con
XML, .NET mette a
• creare istanze di qualsiasi classe C# modello ad oggetti in memoria per rappresentare la
disposizione il
• importare XML scritto con uno schema pre- struttura del codice XML. Il modo in cui leggere un namespace [Link]
definito documento XML, mediante XmlTextReader, è molto che contiene un
• essere indipendente dalle classi da mappa- simile al modo in cui si legge il contenuto di un data- insieme di classi ed
re (nessuna alterazione deve essere fatta al base con un cursore. Tale cursore si sposta sui vari interfacce il cui scopo
codice sorgente di quest’ultime) elementi; l’applicazione potrà quindi di volta in principale è quello di
leggere, manipolare e
• supportare i tipi di dato volta, fare uso del contenuto dell’elemento e dei suoi scrivere codice XML. Le
attributi. Generalmente il contenuto di un docu- classi che utilizzeremo
Questo è proprio quello che realizzeremo in questa mento XML può essere visto come una rappresenta- in quest’articolo
serie di articoli. zione ad albero. Il cursore visiterà l’albero adottando saranno
la tecnica in-depth first: partendo dalla radice di un [Link]
ed alcune delle sue
qualunque sottoalbero il nodo successivo da visitare derivate come
sarà il primo a sinistra. Appena la visita arriva ad una XmlTextReader e
PROGETTAZIONE foglia, si risale al padre per visitare un eventuale “fra- XmlValidatingReader.
tello”. Se non sono presenti nodi fratelli, la visita risa-
E SVILUPPO le ancora e procede nello stesso modo. Il modello a
DEL COMPONENTE cursore, utilizzato dalla piattaforma .NET per legge-
Adesso che il problema è stato definito, possiamo re il contenuto di un file XML, è di tipo read-only for-
iniziare a svilupparne la soluzione. Prima di tutto ward-only. Non sono quindi ammesse scritture e la
sarà necessario introdurre alcune caratteristiche che visita può procedere solo in avanti (non sarà possi-
il framework .NET mette a disposizione e che ci bile ritornare indietro per visitare nodi già visitati).
saranno di grandissima utilità. Per prima cosa, dob- Usando la classe XmlTextReader, è possibile svilup-
biamo capire come C# e .NET dialogano con XML; pare rapidamente un parser XML che verifica se un
secondo, bisogna dare un’occhiata al modo in cui, documento è well-formed, ovvero se rispetta la sin-
mediante la reflection, è possibile creare dinamica- tassi imposta da XML. Se vogliamo eseguire anche
mente delle istanze di classi. Come è già stato detto, un controllo semantico del documento, si deve uti-
l’idea base è quella di sviluppare un componente lizzare invece la classe XmlValidatingReader. Essa è
che legge codice XML che rispetta un particolare una specializzazione di XmlReader che consente di
schema. Nello stesso momento in cui il componen- specificare il tipo di validazione che si intende utiliz-
te legge i vari elementi (parsing), esso deve essere in zare. Alcune delle possibili scelte sono: nessuna,
grado di creare l’opportuno oggetto C# e riempirne i DTD o XML schema (XSD). La prima operazione, per

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/37 G
036-039-T&T XML 4-10-2003 9:49 Pagina 38

TEORIA & TECNICA Lo standard XML nella piattaforma .NET

implementare un parser XML validante, è creare gli zione lancerà un’eccezione il cui messaggio sarà
oggetti XmlTextReader e XmlValidatingReader: prelevato dal parametro args.

XmlTextReader txtReader = new XmlTextReader(filename);


XmlValidatingReader xtReader =
new XmlValidatingReader(txtReader);
L’XML IMPORTER
Mettendo insieme i frammenti di codice C# visti in
Come si può vedere, abbiamo bisogno di entrambe precedenza, si può realizzare una classe che funzio-
le istanze (XmlTextReader e XmlValidatingReader), nerà da parser XML validante. Questo però non
perché XmlValidatingReader non estende diretta- sarebbe sufficiente ai nostri scopi. Infatti, è nostra
mente XmlTextReader. Per istanziare XmlValidating- intenzione implementare una classe base che potrà
Reader è necessario passare un’istanza di XmlText- poi essere utilizzata in seguito nel corso di questa
Reader come parametro del costruttore. È possibile serie di articoli. Essa dovrà essere in grado di effet-
impostare il tipo di validazione grazie alla proprietà tuare il parsing di un documento XML e delegare ad
ValidationType, come segue: un’altra classe, definita dall’utente, la possibilità di
processare le entità XML che saranno lette di volta in
[Link] = [Link]; volta. Quello che andremo a sviluppare rispetterà il
class diagram presente in Fig. 1. La figura mostra la
La proprietà ValidationType è un’enumerazione. I classe XmlImporter, che è il nostro obiettivo finale, e
valori previsti sono: Auto, DTD, None, Schema e XDR. le relazioni che essa ha con altre classi ed interfacce.
Noi utilizzeremo sempre e solo la validazione di tipo Sostanzialmente, l’XmlImporter è un parser XML
Schema (che fa uso di schemi XML). Il passo succes- validante basato sugli schemi XML che legge
sivo è quello di definire il gestore dgli eventi (event (mediante il metodo import) il documento XML ed
handler) per la validazione, che sostanzialmente è invoca un metodo definito dall’utente ogni volta che
un metodo richiamato dal framework ogni qualvol- un elemento deve essere processato. Questo meto-
ta che un errore di validazione si verifica. Il modo do, chiamato processElement, appartiene all’inter-
per impostare l’handler per la validazione è il se- faccia Handler. Come si può vedere dal class dia-
guente: gram, XmlImporter possiede un oggetto Handler.
XML L’interfaccia Handler sarà così definita:
TEXTREADER [Link] +=
Usando la classe new ValidationEventHandler ([Link]); public interface Handler {
XmlTextReader, è // processElement è chiamata dell’XmlImporter
possibile sviluppare
La funzione invocata sarà quindi ValidationEvent- // ogni volta che un elemento deve essere processato
rapidamente un parser
XML che verifica se un Handle. Tra breve, ne vedremo l’implementazione. void processElement(XmlValidatingReader xtReader);
documento è well- A questo punto sarà possibile invocare il metodo // processObject sarà invocato dall’utente
formed, ovvero se Read della classe XmlValidatingReader che inizierà a // per processare l’oggetto importato
rispetta la sintassi leggere il documento. Il metodo cesserà la propria void processObject(object obj);}
imposta da XML.
esecuzione ogni qualvolta un’entità XML viene letta.
Per entità si intendono elementi, attributi o tag XML. Il metodo processElement, come già menzionato, è
L’istanza xtReader conterrà, di volta in volta, tutte le richiamato dall’XmlImporter ogni volta che un ele-
informazioni relative all’ultima entità letta. Il meto- mento XML viene letto. Il parametro xtReader, rap-
do restituirà false se non ci sono ulteriori entità da presenta un XmlValidatingReader che contiene tut-
leggere. In questo primo esempio invocheremo il te le informazioni dell’ultimo elemento XML letto.
metodo Read fin quando non restituirà false, quindi Di conseguenza, sarà possibile implementare pro-
le informazioni presenti in xtReader non saranno cessElement in modo da utilizzare i dati provenienti
usate: dal documento XML nel modo che si ritiene oppor-
tuno. Il metodo processObject sarà invocato appena
while ([Link]()) { } un oggetto C# viene creato a partire dal codice con-
[Link]();

L’implementazione dell’handler per la validazione è


la seguente:

public void ValidationEventHandle (object sender,


ValidationEventArgs args)
{ throw new [Link]([Link],null);}

Fig. 1: Class diagram relativo alla classe


Quando avviene un errore, l’handler per la valida- XmlImporter.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 38/Novembre 2003
036-039-T&T XML 4-10-2003 9:49 Pagina 39

Lo standard XML nella piattaforma .NET TEORIA & TECNICA

tenuto nel documento XML. Implementando que- me parametro. Il metodo import prende in input il
sto metodo, l’applicazione potrà fare uso dell’ogget- nome del file XML, ne effettua il parsing - utilizzan-
to per i propri scopi. Per utilizzare l’XmlImporter, è do l’XmlValidatingReader e, per ogni elemento
obbligatorio implementare l’interfaccia Handler. È XML, invoca il metodo processElement dell’Handler.
prevista, in ogni modo, un’implementazione di de- Di seguito, è riportata usa semplice implementazio-
fault chiamata DefaultHandler (il codice è presente ne di Handler (chiamato MereHandler, ovvero Han-
sul CD o sul Web) che si comporta semplicemente dler semplice) che visualizza il nome degli elementi
come un parser XML validante. Dal diagramma si XML e dei relativi attributi:
può notare che XmlImporter è aggregata con Valida-
tionEventHandler che, nonostante il fatto sia model- public class MereHandler : Handler {
lato come una classe, in realtà è un metodo, lo stes- public void processElement(XmlValidatingReader
so che abbiamo visto nella sezione precedente. xtReader){
A questo punto possiamo implementare XmlImpor- if ([Link]==[Link]){
ter. Ecco il codice: [Link](“Element: “ + [Link]);
for (int i=0;i<[Link];i++) {
using System; [Link](i);
using [Link]; [Link](“ attribute {0} = {1}”,
using [Link]; [Link],[Link]); } } BIBLIOGRAFIA
namespace [Link] { public void processObject(object obj){} } • MAPPING XML TO C#
OBJECTS USING
public class XmlImporter {
REFLECTION
// Handler definito dall’utente Come si può notare, il primo controllo è che l’ogget- G. Naccarato
private Handler handler; to xtReader contenga informazioni relative ad ele- C#Today
// Construttore (usa il default handler) menti, in altre parole che la proprietà NodeType sia (Wrox Press)
public XmlImporter() { uguale a [Link]. L’enumeration Ottobre 2002
[Link] = new DefaultHandler(); } XmlNodeType indica il tipo di entità XML: Element,
• PROFESSIONAL C# 2ND
// Construttore (usa l’handler in input) Attribute, Comment, Document e così via. Dopo tale EDITION
public XmlImporter(Handler handler) { controllo, il nome dell’elemento e i suoi attributi S. Robinson e altri
[Link] = handler; } saranno visualizzati sulla console. Il seguente fram- Wrox Press 2002
// Legge il file XML mento di codice istanzia un oggetto XmlImporter
• .NET SERIALIZATION
public void import(string strFilename) { (usando MereHandler) ed invoca il metodo import
S. Gopikrishna,
// XmlReader passando il file chiamato [Link]: K. Sanghavi
XmlTextReader txtReader = C#Today
new XmlTextReader(strFilename); xmlImporter = new XmlImporter(new MereHandler()); Luglio 2001
XmlValidatingReader xtReader = [Link](“[Link]”); [Link]
com/[Link]?id=1532
new XmlValidatingReader(txtReader);
// Imposta la ValidationType a XML-Schema (XSD) L’applicazione visualizzerà gli elementi e i relativi • REFLECTION IN .NET
[Link] = [Link]; attributi contenuti nel file. Dovrebbe essere chiaro a Hari Shankar
// Imposta il validation handler questo punto che, implementando opportunamen- C# Corner
[Link] += te l’interfaccia Header, ed in particolare il metodo Febbraio 2001
[Link]
new ValidationEventHandler processElement, possiamo trasferire codice XML in
.com/1/Reflection_in_
([Link]); oggetti C#. Infatti, mediante l’oggetto xtReader ab- [Link]
try { biamo a disposizione tutte le informazioni che ci
// Parsing servono: il nome della classe, i campi ed i relativi • C# PROGRAMMING:
while ([Link]()) { valori. Come possiamo però creare tali oggetti dina- ATTRIBUTES AND
// Invoca processElement micamente partendo dal nome e valorizzarli con le REFLECTION
Jesse Liberty
[Link](xtReader); } } corrette informazioni? La risposta a questa doman- ([Link])
catch (Exception e) { da va ricercata all’interno di una feature molto Agosto 2001
throw new Exception([Link]);} potente: la reflection. [Link]
finally { [Link]();} } pub/r/1207
// Validation Event Handle
public void ValidationEventHandle (object sender,
ValidationEventArgs args) {
CONCLUSIONI
throw new [Link] In questo primo articolo dedicato a XML e C# abbia-
([Link],null); } }} mo visto come leggere il contenuto di un documen-
to XML usando l’XmlReader. Nel prossimo articolo
La classe presenta due costruttori: il primo crea un’i- vedremo come usare il parser XML e la reflection al
stanza di XmlImporter usando il DefaultHandler, il fine di importare oggetti semplici.
secondo, invece, consentirà di passare l’Handler co- Giuseppe Naccarato

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/39 G
041-044 T&T PHP 4-10-2003 9:50 Pagina 41

Accesso Multicanale ai dati TEORIA & TECNICA

Tecnologie: l’integrazione tra Flash MX e Web Service

Annunci on-line con


Web Service e Flash
L’unione della potenza di Flash MX con la flessibilità offerta dai Web
Service costituisce un’occasione imperdibile per qualsiasi
sviluppatore.

S
tiamo lentamente assistendo alla sostituzione za lo consentano, dove non servono grosse presta-
di vecchie tecnologie e vecchi modi di conce- zioni, e dove ha senso usarli ovvero quando si devo-
pire il web. Lato client, a non funzionare sono no far interagire sistemi diversi scritti in linguaggi di
le interfacce utente scomode, difficilmente manute- programmazione diversi. Inoltre, c’è un altro impor-
nibili e non sempre compatibili con i vari user agent. tante fattore sempre più attuale: la multicanalità.
Lato server, troppo spesso ci troviamo di fronte ad Trovandoci di fronte a numerosi device, ognuno con
architetture poco flessibili e quasi mai scalabili nella display diverso, come sviluppatori siamo obbligati a
realtà quotidiana. Intere applicazioni funzionano scindere i dati dalla logica di presentazione. In un
solo con se stesse rendendo poco agevole la coesi- sito standard una soluzione sarebbe quella di usare
❏ CD ❏ WEB
stenza con altri prodotti se non vietandone di fatto xml + xsl, noi vedremo come farlo in Flash, visto che [Link]
l’introduzione. Vengono adottati pochi standard, già esso funziona con successo su device di nuova
[Link]
quasi sempre a causa dei brevi tempi di sviluppo a generazione. Costruiremo un esempio che ci per-
disposizione per le prime consegne. Ancora lato metterà di raccogliere e visualizzare degli annunci
client, l’HTML sembra non morire mai, anzi, è sem- tramite WebServices. Costruiremo il WebService con
pre molto vivo. Coldfusion, perché magicamente riusciremo a con-
Con DHTML si possano creare effetti carini ma non densare tutta l’applicazione lato server in una deci-
sempre è facile creare una perfetta ergonomia per le na di righe di codice e qualche settaggio. Per dimo-
proprie applicazioni web. Troppi limiti: compatibi- strare di aver scritto qualcosa di veramente stan-
lità, molti giorni di sviluppo buttati per scoprire che dard, tramite php invocheremo il servizio di
un browser visualizza i dati disallineati, etc. Schema- Coldfusion. L’interfaccia sarà costituita da un movie
ticamente, possiamo riassumere che Flash Mx risol- Flash costruito con delle classi Actionscript in grado SCAMBIO
ve i problemi di ergonomia e di compatibilità, men- di separare nettamente i dati da come vengono pre- DATI
tre i Webservices quelli di poca compatibilità e di sentati. Flash è vettoriale e si adatta bene a diverse Un’applicazione web
applicazioni poco scalabili. I WebServices sono dei dimensioni e questo sarà un vantaggio aggiuntivo. basata su webservices
prevede uno scambio
componenti software che permettono, tramite pro- Le volte precedenti abbiamo già visto come Flash di stream xml
tocolli standard e aperti (ad es. SOAP) basati sull’uti- Mx può invocare un webservice ora non ci resta che formattati secondo lo
lizzo di XML, di creare delle applicazioni che utilizzi- ripercorrere pochi semplici passi per crearcene uno standard soap. Per far
no la porta 80 per veicolare dati e funzioni. Possono da zero. funzionare un
essere invocati da chiunque e sono indipendenti webservice
fondamentalmente
dalla piattaforma. Tramite essi, sistemi completa- serve solo la capacità
mente diversi possono comunicare fra loro.
Paradossalmente sistemi in cobol potrebbero dialo-
PREPARAZIONE di generare richieste
HTTP POST a un web
gare con php. Grazie a questi principi, complesse AMBIENTE server.
architetture possono essere suddivise in piccoli 1) Database
oggetti modulari, permettendo di creare framework Come database useremo Access. Creiamo una nuo-
come se si stesse disegnando un sistema oop con va tabella con questi campi: Codice, Categoria, Cap,
evidenti vantaggi in termini di eleganza, scalabilità e Testo, Inserzionista, Telefono, Email, Prezzo. Per sem-
scarsità di bachi. Essi però non vanno usati come il plicità non useremo nessuna procedura di norma-
prezzemolo, ma solamente dove le policy di sicurez- lizzazione e velocemente settiamo il campo Codice

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/41 G
041-044 T&T PHP 4-10-2003 9:50 Pagina 42

TEORIA & TECNICA Accesso Multicanale ai dati

sti metodi:

• InserisciNuovo: inserisce un nuovo annun-


cio;

• SelezionaTutti: si occupa di selezionare la


lista di annunci disponibili;

• DammiDettaglio: estrapola i dettagli di un


annuncio.

All’interno del nostro componente per ogni metodo


lo schema è: definizione funzione server con tipo di
Fig. 1: Access ha dalla sua una estrema semplicità e
una capillare diffusione. ritorno, definizione query con relativo datasource.
Ecco un esempio:

come contatore, cap e prezzo come numerici e il <cffunction name=”selezionaTutti” access=”remote”


resto dei campi come testo. Salviamo la tabella con returnType=”query”>
il nome tbl_annunci. Chiudiamo il database salvan- <CFQUERY NAME=”q_annunci”
dolo con nome “[Link]”. Datasource=”Annunci”>
SELECT Codice, Categoria, Cap, Testo, Inserzionista,
2) Configurare Coldfusion Telefono, Email, Prezzo
Andremo poi ad installare il motore di tutto ovvero FROM tbl_annunci
ColdFusion Mx (scaricabile dal sito macromedia in </CFQUERY>
prova) che è di immediata installazione, non richie- <cfreturn q_annunci>
de nessuna configurazione, basta solo lanciare il </cffunction>
setup, leggere le informazioni che si presentano e
CONDIVIDERE scegliere avanti, avanti… fine. Ricordatevi le pas- In questo modo dichiariamo il metodo selezionaTut-
Aziende che già usano sword che scegliete in fase di installazione perché ti (che poi invocheremo dal movie flash), specifican-
componenti java o com quando consulterete l’amministrazione vi verranno do la query da eseguire sul db. Il recordset risultante
utilizzando Coldfusion
possono costruirsi
chieste. Per collegarci al pannello di amministrazio- dall’operazione di selezione sarà il ritorno della fun-
webservices in modo ne di Coldfusion Mx nel nostro browser carichiamo zione. A mio avviso, qui notiamo subito una cosa
molto rapido: questa pagina: [Link] fondamentale: tutto il codice lato server si condensa
Coldfusion è strator/[Link]. (localhost o l’indirizzo della mac- in pochissime righe in quanto nel componente non
disponibile anche per china in cui è avvenuta l’installazione). Se la pagina è racchiusa alcuna logica di presentazione e visua-
piattaforme J2EE.
In questo modo i
si carica significa che tutto è andato a buon fine. Ora lizzazione tipica delle pagine html.
propri servizi possono abbiamo l’ambiente pronto; non ci resta che infor-
essere condivisi mare Coldfusion Mx della presenza del database.
facilmente senza
lavoro aggiuntivo.

Fig. 3: Creare WebServices con Coldfusion è facile


come un clic!

Il codice Coldfusion infatti è semplice e conciso in


Fig. 2: Colleghiamo il DB a Coldfusion. quanto focalizza l’attenzione soltanto alla comuni-
cazione “Client Flash” – “Server” direttamente trami-
te recordset. Gli altri metodi seguono la stessa strut-
Per questo, dall’amministrazione clicchiamo sul tura. Allegato alla rivista troverete l’esempio appena
menu Data Sources specificando nella maschera analizzato e il componente intero. Salvate il file
foto che compare come nome Annunci, come driver “[Link]” nella vostra wwwroot (se avete lascia-
Access e scegliendo il nostro file [Link]. D’ora in poi to tutti i default essa corrisponde a [directory_instal-
faremo riferimento a questa sorgente dati. lazione_coldfusion] \wwwroot). Digitate nel vostro
browser [Link] Coldfu-
3) Componente lato server sion genererà una scheda di riepilogo (ottima per la
Scriviamo ora il nostro componente (CFC). Tramite documentazione) con la lista dei metodi e relativi
dei semplici tag di alto livello esso implementa que- parametri da noi implementati.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 42/Novembre 2003
041-044 T&T PHP 4-10-2003 9:50 Pagina 43

Accesso Multicanale ai dati TEORIA & TECNICA

4) Trasformazione componente in webservice prelevati da WebServiceClass


A questo punto dobbiamo trasformare il nostro
componente in webservice e anche quest’operazio- Evitando di usare oggetti non ancora del tutto docu-
ne grazie a Coldfusion avverrà gratis. Infatti basta mentati di Flash Mx per far comunicare le due clas-
scegliere la voce “Web Services” dal menu dell’am- si ho scritto una superclasse dalla quale ereditano
ministrazione e specificare nel pannellino come no- entrambe e che ci fornisce un efficace sistema di
me “AnnuncioWs” e come WSDL URL. [Link] messaggistica basata su eventi. Vediamo come:
st:8500/[Link]? WSDL. Coldusion genererà per
voi persino il WSDL! Per vederlo caricate nel browser // Definisco classe gestione eventi inizializzando un
la WSDL-url appena aggiunta. vettore di ascoltatori
EventManager = function () {
[Link]= new Array ();
}
// metodo di aggiunta di un ascoltatore
[Link] = function (obj) {
[Link] (obj);
}
// metodo che esegue l’evento -inteso come metodo-
a tutti i nostri ascoltatori
[Link] = function (event,
param) {
for (var i in [Link])
[Link][i][event](param);
}

L’istruzione [Link][i][event](param) esegue su


tutti i propri ascoltatori il metodo specificato dall’e-
vento passando il parametro necessario. L’eredita- WSDL:
rietà la settiamo in actionscript in questo modo: GENERAZIONE
AUTOMATICA
[Link]= new EventManager (); Quando si trasforma
un componente
[Link]= new EventManager ();
Coldfusion in
webservice bisogna
Così facendo le due classi acquisiscono i metodi verificare che
addListener e sendEvent, vediamo come vanno l’attributo access del
usati: tag cffunction sia
Fig. 4: Il dettaglio dei metodi appena creati. settato a “remote”:
grazie a questo
tramite il metodo addListener registriamo le Coldfusion saprà anche
istanze delle due classi vicendevolmente. generare il file WSDL
in automatico.
MOVIE FLASH tramite il metodo sendEvent facciamo “transita-
Il nostro movie deve essere “multicanale” e per que- re” il messaggio. Supponiamo di aver ricevuto la
sto deve essere in grado di comportarsi in modo lista di annunci tramite la WebserviceClass; usando il
diverso a seconda del contesto. Tutte le classi devo- remoting la ricezione avviene implementando que-
no essere costruite per separare nettamente il dato sto metodo (notare la sintassi nomemetodoserver_
da come è rappresentato seguendo una logica OOP result):
ordinata. Noi ci serviremo di due classi actionscript
principali: // callback di risposta metodo di selezione annunci
[Link].selezionaTutti_Result=
WebServiceClass function (result) {
comunica col server invocando il webservice per // informo l’oggetto grafico che mi rappre-
estrapolare i dati dal db. Si occupa di connettersi al senta di disegnare la lista con i dati ricevuti
gateway tramite l’oggetto NetConnection e di creare [Link] (“Draw”, result);
un riferimento al web service utilizzando il metodo }
getService().
Qui viene il bello: il metodo sendEvent eseguirà il
PresenterClass metodo Draw sul suo Presenter dicendogli con che
si occupa di disegnare l’interfaccia grafica dei dati recordset disegnarsi.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/43 G
041-044 T&T PHP 4-10-2003 9:50 Pagina 44

TEORIA & TECNICA Accesso Multicanale ai dati

// metodo che disegna la lista di record (rs è il recordset) come esempio. L’interfaccia scarna potrebbe essere
[Link] = function (rs) { arricchita con nuovi elementi insieme ai controlli
// … serie di attachMovie di oggetti grafici in libreria sui tipi di dato in input; potrebbe essere aggiunto
} qualche sistema di cache lato client. Allegato alla
rivista avete tutti i sorgenti commentati dai quali
Il metodo Draw contiene una serie di attachMovie partire.
che inseriscono nello stage una serie di oggetti grafi- Divertitevi!
ci presenti in libreria. Nell’esempio ho costruito un
oggetto record che rappresenta un oggetto della lista:
esso visualizza alcuni dati riassuntivi relativi all’an-
nuncio ovvero inserzionista, categoria, cap, prezzo.
TEST DEL
Cliccando su ogni item il Presenter chiede alla Web- WEB SERVICE
serviceClass di interrogare il server e di dargli le Scopo del nostro webservice e di tutto il nostro lavo-
informazioni aggiuntive tipo il testo esteso, l’email, il ro è stato quello di costruire un servizio capace di
numero di telefono per contattare l’inserzionista dialogare con chiunque. Verifichiamo se è vero chia-
etc. Analogamente al sistema di selezione quando mando il nostro servizio utilizzando una tecnologia
clicchiamo sul pulsante inserisci tramite Web- diversa, ovvero php, realizzando qualcosa di univer-
ServiceClass invochiamo sul nostro webservice il sale oltrechè multicanale. Per richiamare il webser-
metodo inserisciNuovo(parametri) passando i valori vice appena scritto con coldfusion o qualsiasi web-
inseriti nel modulo. La gestione della presentazione service da php si utilizza la famosa libreria nusoap.
grafica è lasciata tutta alla classe PresenterClass. Il codice è il seguente:

<?
require_once(‘[Link]’);
$soapclient = new soapclient(‘[Link]
NUSOAP [Link]?WSDL’);
La creazione di un end- $ret= $soapclient->call(‘selezionaTutti’);
point soap è semplice ....
con la libreria nusoap.
for ($j=0; $j < count ($annunci[$i]); $j++) {
Basta definire una
serie di funzioni e // per ogni elemento record
registrarle presso un echo “<tr>”;
oggetto soap-server for ($k=0; $k < count ($annunci[$i][$j]); $k++)
mentre per richiamarle // per ogni campo
basta definire un
echo “<td>”.$annunci[$i][$j][$k].”</td>”;
oggetto soap-client.
La libreria open source echo “</tr>”;
scritta in php la si può }
trovare al seguente ....
indirizzo:
?>

[Link]
nusoap/[Link] Dopo aver incluso la libreria nusoap creiamo un
riferimento al nostro webservice tramite questa
istruzione:
Fig. 5: La maschera di inserimento dei record con in
basso la lista di quelli inseriti.
$soapclient = new soapclient(‘[Link]
[Link]?WSDL’);
Basterà modificare qualche riga sul metodo di dise-
gno per stravolgere l’effetto sull’interfaccia grafica In seguito invochiamo il metodo di selezione
senza intervenire sulla parte che interagisce col ser- annunci specificando il metodo implementato su
ver: questa caratteristica ci apre le porte allo svilup- Coldfusion:
po di movie multicanali. In questo modo infatti per
creare interfacce grafiche completamente diverse $ret= $soapclient->call(‘selezionaTutti’);
basta cambiare soltanto gli oggetti in libreria e qual-
che costante!!! Vi sono altri parametri da considera- La variabile php $ret rappresenta il recordset. A noi
re tipo la grandezza dello stage ma se siamo furbi non resta che scorrerlo e visualizzare una tabella.
possiamo sfruttare la “vettorialità” di flash adattan- Abbiamo così fatto comunicare due diverse piat-
do width ed height dei parametri object/ embed che taforme: PHP e Coldfusion.
si occupano di includere il flash in pagina. Lascio a Grazie Webservice!
voi il compito di estendere il movie base fornitovi Demis Magoga

h t t p : / / w w w. i o p r o g r a m m o . i t
G 44/Novembre 2003
045-048 T&T reg Expr 8-10-2003 17:23 Pagina 45

Guida alle espressioni regolari TEORIA & TECNICA

Elementi per la manipolazione delle stringhe

Regular Expressions
con .NET
Le Regular Expressions sono strumenti potenti che possono apparire
alquanto enigmatici. In questo articolo vengono esposti i concetti
base per la loro comprensione e l’utilizzo nelle applicazioni .NET.

L
e Regular Expressions (espressioni regolari) pattern. La criptica stringa citata all’inizio è un
sono uno strumento molto potente e vengo- pattern per le espressioni da confrontare median-
no utilizzate nei più svariati contesti. te un’operazione detta di match. La maggior parte
Nell’ambito dello sviluppo si sente parlare spesso degli utenti con un certo background informatico,
di regex (usuale contrazione di Regular hanno utilizzato le regex senza neppure saperlo.
Expressions) suscitando odio e amore nei pro- Ad esempio se volessimo ricercare tutti i file ese-
grammatori. Sono molto apprezzate per le loro guibili contenuti in una directory, potremmo uti-
potenzialità e per quel che permettono di realizza- lizzare il pattern *.exe nel file search di Windows.
re, ma scriverle e comprenderle non è così imme- L’applicazione più diffusa delle regex è infatti la
diato. ricerca e sostituzione di stringhe in word proces-
Si prenda in considerazione la seguente regex: sor o la ricerca mediante filtri in utilità di tipo
“trova file”. I campi di applicazione sono comun-
^((4\d{3})|(5[1-5]\d{2})|(6011))-?\d{4}-?\d{4}- que molto più vasti e sempre correlati alla mani-
?\d{4}|3 [4,7]\d{13}$ polazione di testo: vanno da programmi anti-
spam che filtrano il traffico e-mail indesiderato, al
Come si può intuire facilmente, non deve esser controllo della correttezza del formato di inseri-
stato così immediato generare una stringa di que- mento dei dati nei form, al parsing di pagine web e
sto tipo. Al di là delle abilità individuali bisogna file XML. Le regex sono insomma uno strumento
riconoscere che si tratta di una stringa poco leggi- flessibile, potente e molto efficiente per compiere
bile e alquanto criptica e che anche la scrittura operazioni su testi, anche molto estesi.
sensata di un tale pattern (modello) possa risulta- Probabilmente il lettore ha familiarità con i meta-
re un’operazione piuttosto ostica; eppure quella caratteri * e ? usati per i comandi DOS o per le
stringa, apparentemente senza senso, permette di ricerche di file nel file-system di Windows, ma le
verificare se il numero di carta di credito inserito regular expressions possono essere considerate un
da un utente sia, o meno, nel formato corretto vero e proprio linguaggio basato su caratteri
delle carte di credito Visa, MasterCard, ecc…ecc… testuali e meta-caratteri. Le regex si basano sui
Lo stesso Robert Howard, (Program Manager di meta-caratteri e sono organizzati in varie catego-
[Link]) sostiene di apprezzare le potenzialità rie: caratteri di escape, di sostituzione, classi di
delle regex, ma odia doverne scrivere di proprio caratteri, quantifiers, costrutti di gruppo, di back-
pugno. In questo articolo verrà mostrato cosa sono reference, di alternanza, ecc…ecc… A breve saran-
le regex e come vengono utilizzate da applicazioni no esposti i principali meta-caratteri utili nell’uso
.NET, cercando di svelare il significato di tali quotidiano delle regular expressions.
“misteriose” sequenze di caratteri.

META-CARATTERI
REGEX OVUNQUE I caratteri . $ {[ ^ ( ) | * + ? \ sono dei caratteri specia-
Le regex permettono la ricerca e la sostituzione di li che hanno un particolare significato nelle regular
stringhe all’interno di altre stringhe utilizzando un expressions, tutti gli altri caratteri sono detti ordina-

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/45 G
045-048 T&T reg Expr 8-10-2003 17:23 Pagina 46

TEORIA & TECNICA Guida alle espressioni regolari

ri e corrispondono a se stessi. Segue una tabella dei UN PRIMO APPROCCIO


caratteri di escape, ovvero quelle combinazioni di Se si costituisce un pattern con soli caratteri ordina-
caratteri che assumono significati di vario tipo nel ri, la regular expression risultante permetterà la
pattern delle regex: ricerca di ogni occorrenza della stringa stessa nel
testo. Ad esempio se si volesse ricercare la stringa
CAR. SIGNIFICATO
“Cangiano”, la regular expression sarebbe la stringa
\ Anteposto ad un carattere speciale lo rende
Cangiano stessa.
ordinario (o literal), privandolo del suo
Si consideri il pattern: Cangia.o, il punto indica la
significato particolare. Ad esempio \^
presenza un carattere nella posizione in cui è collo-
corrisponde esattamente al carattere ^.
cato, per cui tale espressione accerta Cangiano,
\b Carattere di backspace
Cangiato, Cangia4o e così via. Si faccia attenzione
\f Avanzamento form (form feed)
alla natura case sensitive (di default) dei pattern, per
\n Nuova riga (line feed)
la quale “cangiano” con la ‘c’ iniziale scritta in lower-
\r Invio a capo (carriage return)
case (minuscolo) non supererà l’operazione di
\t Carattere di tabulazione
match. Le parentesi quadre [ ] (brackets) come ac-
\v Tabulazione verticale
cennato nelle tabelle riassuntive, permettono la
scelta di un carattere appartenente all’insieme defi-
Oltre a singoli caratteri, è possibile specificare una nito.
classe di caratteri, ovvero una serie di caratteri Il pattern: [CMK]angiano risulta valido per Cangia-
espressi da un costrutto. Segue una tabella riassun- no, Mangiano, Kangiano ma non per angiano, can-
tiva dei principali costrutti: giano, mangiano, Vangiano o Langiano, poiché non
iniziano per C, M o K maiuscole. Si noti che [CMK] è
CLASSE SIGNIFICATO equivalente a [C|M|K], in quanto il ruolo della barra
. Uno qualsiasi carattere, eccetto \n verticale è quello di presentare una scelta (C o M o
[aeiou] Un carattere tra quelli indicati K). Il trattino – all’interno delle parentesi quadre per-
[^aeiou] Un qualsiasi carattere tranne quelli indicati mette di definire un range di caratteri consecutivi.
\w Carattere alfanumerico Ad esempio: [b-z3-9C-P]angiano è un pattern di
\W Carattere non alfanumerico regular expression valido per le stringhe aventi come
\s Indica qualsiasi carattere di white-space, primo carattere una lettera minuscola tra la b e la z
SOFTWARE equivale a [\f\n\r\t\v]. dell’alfabeto inglese, oppure una cifra tra 3 e 9, o
Un programma \S Indica qualsiasi carattere non di ancora una lettera maiuscola tra D e P. Quindi si ha
alquanto utile per la white-space, equivale a [^\f\n\r\t\v]. un match valido con le stringhe cangiano, langiano,
realizzazione e la
\d Ogni carattere decimale 3angiano, Cangiano, ecc… ecc… ma non aangiano,
verifica delle Regex è
Regex Designer: \D Ogni carattere non decimale 2angiano, Tangiano.
[2-7c-nL-T] Un carattere qualsiasi nel range di I pattern visti sinora permettono di ricercare in ampi
[Link] caratteri contigui in 2-7, c-n o L-T. testi tutte le occorrenze delle stringhe adeguate, ma
com/tools/ può capitare di dover ricercare una testo che abbia
un determinato inizio e una determinata fine.
Concludendo questa breve carrellata dei metacarat- Due importanti caratteri, molto utilizzati nella rea-
teri principali, segue una tabella dei caratteri specia- lizzazione di pattern reali, sono ^ e $. ^ indica l’inizio
li (non ordinari, alcuni di essi sono quantificatori): di una stringa, se ad esempio si ha: ^Cangiano la
stringa “Cangiano è l’autore dell’articolo” è aderente
al pattern, ma non a “L’autore dell’articolo è Can-
CAR. SIGNIFICATO
giano” perché la parola Cangiano deve essere pre-
$ Fine di una stringa
sente all’inizio della stringa. Allo stesso modo, $
^ Inizio di un stringa
indica la fine di una stringa.
* 0 o più occorrenze dell’espressione precedente.
Il pattern: Cangiano$ sarà coerente con la stringa
Ad esempio \w* indica 0 o più caratteri
“[Link] è il sito di Antonio Cangiano”
alfanumerici
ma non con “Antonio Cangiano è il content manager
? 0 o 1 carattere della precedente espressione
di [Link] .it”, perché la parola Cangiano
[...] Set di caratteri
deve essere l’ultima della stringa. Come è facilmen-
(…) Gruppo di caratteri
te intuibile, l’utilizzo combinato di entrambi i carat-
{N} Indica N occorrenze dell’espressione precedente
teri di posizione, è di ausilio nella definizione univo-
{N,} Indica almeno N occorrenze dell’espressione
ca delle stringhe.
precedente
Si consideri: ^Cangiano$ la differenza rispetto al pri-
{N,M} Indica almeno N e al massimo M occorrenze
mo esempio mostrato sta nel fatto che “Cangiano”
dell’espressione precedente
consente la ricerca di tutte le occorrenze, mentre
“^Cangiano$” verifica che la stringa sia esattamente

h t t p : / / w w w. i o p r o g r a m m o . i t
G 46/Novembre 2003
045-048 T&T reg Expr 8-10-2003 17:24 Pagina 47

Guida alle espressioni regolari TEORIA & TECNICA

“Cangiano” e non, ad esempio, “Cangiano Antonio ^((4\d{3})|(5[1-5]\d{2})|(6011))-?\d{4}-?\d{4}-?\d{4}|3


Cangiano”. [4,7]\d{13}$
Se si dovesse controllare che l’input dell’utente cor-
risponda ad un particolare codice formato da 3 La presenza di un ^ iniziale e di un $ finale, ci indica
numeri e una lettera, si potrebbe procedere definen- che si tratta di una stringa univoca (il numero di
do il seguente pattern: ^[0-9][0-9][0-9][a-zA-Z]$ la carta di credito). All’interno delle parentesi tonde
presenza dei caratteri di inizio e fine garantisce che più esterne, sono presenti 3 sottogruppi posti come
sia accettato il codice 680a ma non 222680a222. opzione (o l’uno, o l’altro o l’altro ancora): (4\d{3})
Supponendo che il codice richieda 10 numeri ed un (5[1-5]\d{2}) (6011). Tutti e tre i gruppi accettano 4
carattere finale, può risultare scomodo dover scrive- caratteri numerici. Il primo è un numero qualsiasi di
re [0-9] per 10 volte di seguito. A questo proposito quattro cifre avente come prima cifra il 4, il secondo
esistono dei quantificatori che indicano il numero di ha un 5 iniziale, una cifra tra 1 e 5 nella seconda
occorrenze di una sottoespressione posta preceden- posizione, e altri due cifre qualsiasi a completare il
temente. Nel caso citato ad esempio potremmo scri- quartetto. Il terzo gruppo richiede il numero 6011.
vere: ^\d{10}[a-z]$ come visualizzabile nelle tabelle Quindi complessivamente questa prima parte del
precedenti, \d indica che si tratta di una cifra deci- pattern ci dice che le prime quattro cifre del nume-
male ed il numero 10 racchiuso tra parentesi graffe, ro di carta di credito, potrebbe essere 4985, 4222,
è il quantificatore che indica il numero di ripetizioni 4325, 5217, 5399, 5515, 6011, ecc… ecc… Nella strin-
dell’espressione antecedente (\d). Altri quantificato- ga del pattern è poi presente un trattino di separa-
ri piuttosto comuni sono ?, * e +. zione seguito da un ?, che indica che l’utente può o
Vediamo alcuni esempi: meno inserire un trattino di separazione nel nume-
ro di carta. Seguono 4 cifre qualsiasi, un eventuale
^Cangiano?$ - Indica che una stringa aderente al trattino, altre 4 cifre qualsiasi. Tralasciamo per un
pattern deve avere zero o un carattere ‘o’ finale. momento la parte finale del numero, contenente il
Quindi “Cangiano” e “Cangianoo” sono stringhe formato di un’altra carta di credito. Sinora abbiamo
valide. mostrato 3 opzioni, carta Visa da 16 caratteri con
prefisso 4, Mastercard 16 caratteri con prefisso 51 o
^Cangiano+$ - Indica che la stringa aderente al 55, Discover con lunghezza 16 caratteri e prefisso
pattern deve avere uno o più caratteri ‘o’ finali, per 6011. American Express ha solo 15 caratteri, per
cui “Cangiano” non è valida, ma lo è “Cangianoo” o questo motivo è l’ultima opzione separata dalle SUL WEB
“Cangianoooooooo”. altre; ha come prefisso 34 o 37 ed è seguita da 13 cifre Una delle migliori
come facilmente deducibile dalla sottostringa risorse online per
reperire pattern pronti
^Cangiano*$ - L’asterisco indica in questo caso 3[4,7]\d{13}. “L’arcano è svelato”, quella espressione all’uso, utili
che il carattere ‘o’ può essere ripetuto zero o più totalmente incomprensibile ha ora un senso. informazioni e risorse,
volte. Si noti che la mancanza di parentesi tonde che è il sito:
raggruppano più di un carattere, il quantificatore
applica la ripetizione solamente all’ultimo carattere. [Link]
Se si avesse ad esempio: REGEX IN .NET
Mediante la realizzazione di adeguati pattern si pos-
^Cangia(no)*$ - la ripetizione sarebbe applicata sono effettuare manipolazioni testuali di vario tipo,
alle due lette ‘no’. Quindi sarebbero stringhe valide ma per implementare tali operazioni bisogna sfrut-
“Cangia”, “Cangiano”, “Cangianono”, Cangianono- tare gli strumenti offerti dall’ambiente di sviluppo e
no”, ecc…ecc… il linguaggio prescelto. .NET fornisce il namespace
Se si desiderasse ricercare proprio il carattere asteri- [Link] e in particolar modo [Link]-
sco, privandolo del suo significato di “jolly” basterà larExpressions per tali operazioni. Le applicazioni
anteporre un carattere di backslash \. [Link] inoltre hanno il controllo RegularExpres-
sionValidator per convalidare l’input inserito dagli
Si lascia al lettore la possibilità di approfondire le utenti nelle TextBox delle Webforms. Il RegularEx-
proprie conoscenze circa le modalità di realizzazio- pressionValidator ha la proprietà ValidationExpres-
ne di pattern per la scrittura di regular expressions. sion attraverso la quale impostare il pattern di input
corretto, in modo da segnalare all’utente eventuali
errori e impedire l’invio dei dati. Nella finestra pro-
prietà di Visual Studio, se si fa clic sulla proprietà
IL PATTERN INIZIALE ValidationExpression del controllo, è possibile utiliz-
Ora che abbiamo posto le basi per la comprensione zare alcuni template offerti dalla finestra di dialogo
delle regular expressions passiamo ad una breve che appare (mostrata in Fig. 1).
analisi del pattern “impressionante” proposto all’i- Risulta evidente l’utilità delle regex in [Link] per il
nizio dell’articolo: controllo dell’input utente nei form, ma il vero

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/47 G
045-048 T&T reg Expr 4-10-2003 9:51 Pagina 48

TEORIA & TECNICA Guida alle espressioni regolari

else
[Link](“NO! Il testo inserito non
corrisponde al pattern”, “Verifica Regex”); }

La classe Regex ha tra gli overloads più utilizzati, il


pattern (stringa) e un’opzione che nel nostro caso
impone di violare la natura case sensitive delle regu-
lar expressions. Il metodo IsMatch che riceve come
parametro la stringa da verificare, restituisce un valo-
re bool che indica se c’è o meno una corrispondenza
tra pattern e testo analizzato.
Fig. 1: La finestra di dialogo per la scelta di pattern Un metodo molto utilizzato è Replace il cui utilizzo
comuni per la proprietà ValidationExpression del più comune è:
RegularExpressionValidator.
string nuovaStringa = [Link](Stringa, Pattern,
motore delle regex nel framework .NET sono le clas- StringaSost)
si disponibili nel namespace [Link]-
Expressions. La classe Regex è un valido strumento dove ovviamente StringaSost è la stringa da sostitui-
per le operazioni più comuni con le regular expres- re ad ogni occorrenza di testo aderente al pattern. Si
sions. Realizziamo un miniprogramma per verifica- supponga ad esempio di voler rendere link tutti gli
BIBLIOGRAFIA re l’aderenza di una stringa ad un pattern. Tale pro- indirizzi url contenuti in una pagina html.
Due libri particolar- gramma che può essere realizzato in pochi secondi, Basterà qualcosa di analogo a:
mente indicati per può essere utile per la verifica dei primi pattern rea-
approfondire le lizzati nella fase di apprendimento. Avremo bisogno string Pattern = “(http|ftp|https):
Regular Expressions ed due label e di due textbox (txtStringa e txtPattern) \/\/[\w]+(.[\w]+)([\w\-\.,@?^=%&amp;
il loro uso in .NET per permettere all’utente di inserire il testo da verifi- :/~\+#]*[\w\-\@?^=%&amp;/~\+#])?”);
sono: care e il pattern con il quale controllarlo, ed un pul- string Stringa = “<p>Ecco alcuni links utili
sante per l’invio (btnConfronta). [Link]
• MASTERING REGULAR La form apparirà come mostrato in Fig. 2. [Link]
EXPRESSIONS (SECOND [Link] ecc… ecc… </p>”
EDITION) Regex miaRegex = new Regex(Pattern);
Jeffrey E. Friedl, string StringaRisultato = [Link](Stringa,
Andy Oram “<a href=””$0””>$0</a>”);
[O’Reilly]
ove $0 rappresenta l’occorrenza aderente al pattern
• VISUAL BASIC .NET (quindi in questo caso [Link] e
TEXT MANIPULATION successivamente tutti gli altri url presenti). In fine si
HANDBOOK: STRING noti l’esistenza degli oggetti Match e MatchCollec-
HANDLING AND tion utili per ottenere maggiori informazioni circa le
REGULAR EXPRESSIONS occorrenze trovate (Value, Index, Length, ecc… mag-
Paul Wilton, giori informazioni nella guida in linea o in MSDN).
Craig McQueen,
François Liger
[WROX]
Fig. 2: Il semplicissimo layout per la verifica delle
Regular Expressions.
CONCLUSIONI
La semplicità di utilizzo della classe Regex rende le
applicazioni .NET abilitate all’uso di regular expres-
Segue il codice di gestione dell’evento click sul but- sions nelle più svariate situazioni; come già visto,
ton di confronto: l’unica difficoltà è la realizzazione delle stesse che,
seppur “fastidiose”, non spaventano i programmato-
private void btnConfronta_Click(object sender, ri più attenti.
[Link] e) { Lo scopo dell’articolo non era quello di dare argo-
Regex miaRegex = new Regex([Link], mentazioni complete, a causa della vastità dell’argo-
[Link]); mento, ma mostrare una panoramica sulle regular
bool valido = [Link]([Link]); expressions e il loro utilizzo in .NET, con l’intento di
if (valido) incuriosire il lettore, invogliandolo verso uno studio
[Link](“OK! Il testo inserito è valido”, approfondito delle stesse.
“Verifica Regex”); Antonio Cangiano

h t t p : / / w w w. i o p r o g r a m m o . i t
G 48/Novembre 2003
049-053 T&T Briscola 4-10-2003 9:52 Pagina 49

Utilizzo dei socket per applicazioni di rete TEORIA & TECNICA

Programmazione distribuita in ambiente client server

Giocare a briscola
in rete con C++ Builder
In queste pagine analizzeremo un’applicazione per giocare
una partita a carte in rete.

L’
applicazione è stata progettata per il gioco int punto;
della briscola e come ambiente di sviluppo è String immagine;
stato utilizzato il C++ Builder 6. Il gioco è rea- }Carta;
lizzato con l’ausilio di due applicazioni, client e ser- class MazzoDiCarte {
ver, eseguite su computer collegati in rete. Il server public:
resta in ascolto di connessioni e quando il client sta- //attributi
bilisce una connessione, il server avvia la partita. Il Carta mazzo[40]; // Mazzo di carte
client, dopo aver impostato l’IP del computer su cui Carta briscola; // carta della briscola
è in esecuzione il lato server, si connette e resta in Carta TreCarteG1[3]; // carte del giocatore sul server
❏ CD ❏ WEB
attesa che il server gli comunichi tutte le carte del Carta TreCarteG2[3]; // carte del giocatore sul client [Link]
mazzo. Dopo aver “distribuito” le carte, si gioca a int turno; // chi è di turno? Possibili valori: 1,2.
[Link]
turno trascinando la carta da giocare su un pannel- int puntiG1, puntiG2; // punteggi dei due giocatori
lo. L’applicazione invierà la carta giocata all’avversa- //metodi pubblici
rio e resterà in attesa di una risposta. Se si è collega- MazzoDiCarte(); //costruttore
ti ad Internet, è possibile inviare dall’applicazione void Inizializza();
server una e-mail, indirizzata al client, contenente int CalcolaPunti(Carta c1, Carta c2);
l’indirizzo IP. Da cosa è composta la nostra applica- int VincitaMano(Carta C1, Carta C2);
zione: void DistribuisciCarte();
//metodi privati
• una classe per la gestione del mazzo di private:
carte; void MescolaMazzo(); };
• una DLL di risorse contenente le immagini
delle carte; La struct Carta definisce gli attributi della carta quali DLL
• un’applicazione che funge da server; il suo valore numerico (da 1 a 10), il seme (da 1 a 4), DI RISORSE
• un’applicazione che funge da client; il punteggio (in base al gioco della briscola) e il nome Le immagini delle carte
• un “protocollo” di comunicazione tra server dell’immagine corrispondente. sono contenute in una
DLL di risorse che viene
e client. caricata
dinamicamente
all’avvio
I METODI dell’applicazione. Si
DEFINIZIONE DELLA CLASSE poteva inserire la
DELLA CLASSE Il Costruttore si occupa di inizializzare il vettore
risorsa direttamente
nell’applicazione, ma
La classe MazzoDiCarte (file [Link]) si mazzo inserendo in esso i valori delle 40 carte. Ini- creare una DLL di
occupa della gestione del mazzo di carte. Diamo zializza richiama i metodi MescolaMazzo() e Ditri- risorse ha numerosi
uno sguardo al file header. Data la scarsa riutilizza- buisciCarte(). Stabilisce il turno generando un nu- vantaggi.
bilità della classe si è ritenuto opportuno definire gli mero casuale. DistribuisciCarte distribuisce le carte
attributi pubblici, per non appesantire la classe con ai due giocatori valorizzando i vettori TreCarteG1 e
metodi di lettura e scrittura di attributi privati. TreCarteG2, azzera i punteggi e imposta la briscola.
VincitaMano riceve due parametri che rappresenta-
typedef struct { no le due carte giocate e determina quale giocatore
int num; avrà diritto a giocare per primo al turno successivo
int seme; (valore restituito). CalcolaPunti riceve le due carte,

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/49 G
049-053 T&T Briscola 4-10-2003 9:52 Pagina 50

TEORIA & TECNICA Utilizzo dei socket per applicazioni di rete

somma i punti e restituisce la somma. Definendo


virtual i metodi DistribuisciCarte, VincitaMano e
CalcolaPunti, sarà possibile derivare una classe per
un altro gioco (sarà necessario ridefinire i tre meto-
di).

PROTOCOLLO
DI COMUNICAZIONE
Dovendo far comunicare il server col client (e vice-
versa) attraverso dei messaggi contenuti in stringhe,
è necessario creare un protocollo di comunicazione. Fig. 1: Briscola lato server in esecuzione.
IL SERVER Le stringhe che vengono inviate nelle due direzioni,
HA RICEVUTO contengono come primo carattere un carattere di
UNA CARTA controllo che corrisponde al tipo di messaggio che Per motivi di spazio non elencherò qui tutti i com-
Un messaggio di tipo un computer invia all’altro. Osserviamo la tabella ponenti utilizzati (e parte del codice), ma potete
‘H’ indica che il server seguente: farvi un’idea aprendo il file [Link] e
ha ricevuto la
posizione della carta
[Link]: avrete modo di vedere i compo-
giocata dal client; la Carattere Tipo di Messaggio Direzione nenti che sono stati utilizzati e le proprietà che sono
carta viene disegnata di controllo state modificate in fase di progettazione.
sul pannello e viene A Fine trasmissione carte S->C
posto a true il flag del mazzo + turno
Form di avvio
HaGiocatoG2 (indica B Carta mazzo numero S->C
che il client ha giocato Di seguito sono riportati gli attributi e i metodi
C Carta mazzo seme S->C
la sua carta). Se il aggiunti alla classe TForm1 (file UnitBriscolaServer.h)
D Carta mazzo punto S->C
server non ha ancora
E Carta mazzo immagine S->C
giocato, vengono private: // User declarations
attivate le sue carte, F Turno iniziale S->C
TStringList *Lista; //lista dei messaggi ricevuti
infine viene richiamato G Posizione carta giocata S->C
dal server (IG1) char CR,LF ;
il metodo
HannoGiocatoG1G2 H Posizione carta giocata C->S void EstraiLista(); //estrae i messaggi dalla lista
che si occupa di dal client (IG2) bool EstraiMessaggio(char &,char *); //decodifica
verificare chi dei due N Il server si è disconnesso S->C la stringa che contiene il messaggio
giocatori prende le oppure ha chiuso
il programma MazzoDiCarte GiocoBriscola; //istanza
carte, stabilisce il
M Il Client si è disconnesso C->S int carte; // carte nel mazzo
nuovo turno, aggiorna oppure ha chiuso
i punteggi e il programma bool HaGiocatoG1; //flag giocatore client
distribuisce le due Protocollo di trasmissione (Gioco Briscola in Rete) bool HaGiocatoG2; //flag giocatore server
nuove carte int IG1; //indice della carta giocata dal client
prelevandole dal Nella colonna direzione notiamo che la maggior par- int IG2; //indice della carta giocata dal server
mazzo; quando la
te delle informazioni viene inviata dal server al int treCarte; //ultime tre carte
partita è terminata,
emette un messaggio client. Il server si occupa della gestione della partita int StatoConnessione; // 0 In attesa di connessione
con il nome del dando inizio ad essa: mescola il mazzo di carte, invia // 1 Connesso
vincitore e azzera tutto al client tutte le informazioni (4 per ogni carta. //-1 Disconnesso
per una nuova partita. Messaggi B,C,D,E) relative al mazzo, invia il turno // 2 Connesso e pronto per giocare
Se il server ha ricevuto
(messaggio F) e infine invia il messaggio A che indi- void TrasmettiCarte(MazzoDiCarte);
un messaggio di tipo
‘M’ (client disconnesso) ca al client che la partita può iniziare. I messaggi G e void TrasmettiCartaGiocata(int);
azzera tutto e rimane H indicano che l’avversario ha giocato la sua carta e void HannoGiocatoG1G2();
in ascolto per una la comunica all’altro giocatore. I messaggi N ed M si void AzzeraTutto();
nuova connessione. commentano da soli. public: // User declarations
Nel caso in cui i
Passiamo ora all’interfaccia visuale. __fastcall TForm1(TComponent* Owner);
messaggi siano diversi
da ‘M’ o ‘H’ il
programma sarà Per consentire la comunicazione in rete è stata inse-
terminato. rita nella form principale un componente Server-
Socket. Questo componente ci permette di inviare e
L’APPLICAZIONE ricevere informazioni da un altro computer collega-
LATO SERVER to in rete senza dover ricorrere alle API. Il ServerSo-
Nel progetto sono state inserite due form: la form cket apre la porta di servizio 6711 e resta in ascolto di
principale e la form per l’invio dell’e-mail. connessioni TCP/IP. Se si vuole utilizzare un’altra

h t t p : / / w w w. i o p r o g r a m m o . i t
G 50/Novembre 2003
049-053 T&T Briscola 4-10-2003 9:52 Pagina 51

Utilizzo dei socket per applicazioni di rete TEORIA & TECNICA

porta sarà necessario assicurarsi che questa non sia Per gestire la lista dei messaggi è stato definito un
associata ad un servizio noto oppure non sia utiliz- attributo TstringList *Lista a cui viene assegnata la
zata da un’altra applicazione. Nell’evento FormCrea- stringa ricevuta.
te troviamo le seguenti righe di codice: I messaggi vengono poi elaborati dalla funzione
EstraiLista, che estrae dalla Lista un messaggio per
dllInstance=LoadLibrary(“[Link]”); volta e, tramite la funzione EstraiMessaggio, ne
ServerSocket1->Active=true; decodifica il contenuto, estraendo il carattere di
controllo e il contenuto del messaggio.
La prima carica la libreria di risorse che contiene le
immagini, la seconda attiva il componente Server- void TForm1::EstraiLista()
Socket e lo pone in ascolto sulla porta. Di seguito è {} È DI TURNO
riportato il codice dell’evento FormShow che mostra bool TForm1::EstraiMessaggio(char &p,char IL SERVER
come caricare l’immagine dalla risorsa. *stringaMessaggio) Quando il server è di
turno, può giocare la
{}
sua carta trascinandola
void __fastcall TForm1::FormShow(TObject *Sender) {
nel pannello. Per il
// Carica l’immagine della carta dalla DLL trascinamento delle
Image7->Picture->Bitmap->LoadFromResourceName( carte sono stati attivati
(int)dllInstance,”ROVESCIO”);
INVIARE IL PROPRIO due eventi: Image1End-
Edit1->Text=”40”;
IP PER EMAIL Drag e
Panel1DragDrop.
} La Form per l’invio del proprio IP (unit InviaEmail) Panel1DragDrop
si attiva dalla form principale selezionando la voce assegna al
Quando il client stabilisce una connessione, viene “Invia IP” del menu. Per poter inviare email, C++ componente Image9,
invocato il metodo ServerSocket1ClientConnect. Builder ci fornisce il componente NMSMTP. La Edit che rappresenta la
che contiene l’IP è di sola lettura perché l’IP viene carta giocata dal
server, l’immagine
void __fastcall TForm1::ServerSocket1ClientConnect( determinato dal programma lanciando il comando della carta che è stata
TObject *Sender, TCustomWinSocket *Socket) { dos ipconfig. Inseriti tutti i dati nelle altre edit, si trascinata sul pannello.
lblStatoConnessione->Caption=”Client Connesso”; invia il messaggio cliccando sul tasto Invia IP. Una Quando nel
StatoConnessione=1; MessageBox ci avviserà che il messaggio è stato inol- trascinamento
rilasciamo il tasto
mnuItemNuovaPartita->Enabled=true; trato e possiamo ritornare alla form principale.
sinistro del mouse e la
mnuItemInvia->Enabled=false; } Accertatevi che il server SMTP accetti connessioni carta è sul Panel, si
sulla porta 25 (alcuni server applicano restrizioni di attiva l’evento
Il gestore ServerSocket1ClientConnect aggiorna la la- sicurezza che possono bloccare l’invio di messaggi). Image1EndDrag, che
bel che ci informa sullo stato della connessione e pone a false la
proprietà Visibile della
attiva la voce “Nuova partita” del menu. La partita Membri aggiunti alla classe TformInviaMail
carta giocata,
può iniziare. (file InviaEmail.h) trasmette la sua
Il gestore dell’evento click di “Nuova Partita” azzera posizione al client
tutte le variabili, invoca il metodo Inizializza dell’i- private: // User declarations richiamando la
stanza GiocoBriscola, carica le immagini delle tre void EstraiIPdalFile(); funzione
TrasmettiCarta, pone a
carte del giocatore e della briscola, attiva le tre carte public: // User declarations
true il flag
se è di turno il server e richiama il metodo bool MsgInviato;
HaGiocatoG1 e
TrasmettiCarte __fastcall TFormInviaMail(TComponent* Owner); disabilita le carte.
Prima di uscire dalla
void TForm1::TrasmettiCarte(MazzoDiCarte Gioco) L’attributo MsgInviato sarà testato dalla form princi- funzione richiama il
metodo
{} pale per verificare se l’e-mail è stata inviata. Quando
HannoGiocatoG1G2.
il form si apre, viene richiamato il gestore FormShow Anche Image2 e
Per ogni informazione da inviare, viene creata una che esegue il comando DOS ipconfig inviando l’out- Image3 abilitano
stringa contenente come primo carattere il carattere put sul file Log_IP.txt; estrae poi dal file l’IP, tramite la l’evento
di controllo, l’informazione e infine la coppia di funzione EstraiIPdalFile e lo copia nella EditIP. Image1EndDrag.
caratteri CR LF. Col metodo SendText la stringa viene Prima di uscire cancella il file Log_IP.txt.
inviata al client. Se è di turno il client, il server resta void __fastcall
in attesa della carta giocata dall’avversario. void __fastcall TFormInviaMail::FormShow(TObject TForm1::Panel1DragDrop
Quando arriva un messaggio dal client, viene invo- *Sender) { (TObject *Sender,
cato il gestore ServerSocketClientRead char NomeFile[15]=”Log_IP.txt”; TObject *Source,
char ComandoDos[50]=”ipconfig > “; int X, int Y)
void __fastcall TForm1::ServerSocket1ClientRead( strcat(ComandoDos,NomeFile); {}
TObject *Sender, TCustomWinSocket *Socket) { system(ComandoDos); // esegue il comando DOS
Lista->Text= Socket->ReceiveText(); EstraiIPdalFile();
EstraiLista(); } // cancella il file Log_IP.txt

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/51 G
049-053 T&T Briscola 4-10-2003 9:52 Pagina 52

TEORIA & TECNICA Utilizzo dei socket per applicazioni di rete

strcpy(ComandoDos,”del “);
strcat(ComandoDos,NomeFile);
system(ComandoDos); }
void TFormInviaMail::EstraiIPdalFile()
{}

Il gestore btnInviaClick verifica che i campi per l’in-


vio della e-mail non siano vuoti e imposta tutte le
proprietà del componente SMTP:
IL CLIENT SI
È DISCONNESSO NMSMTP1->TimeOut=30000;
Il gestore di eventi NMSMTP1->Host=EtSMTP->Text;
ServerSocketClientDisc
NMSMTP1->PostMessage-
onnect viene Fig. 2: Invio dell’IP tramite email.
>FromAddress=EtEmailMittente->Text;
richiamato quando il
client si disconnette NMSMTP1->PostMessage->FromName=
oppure chiude il EtNomeMittente->Text; della label che ci informa sullo stato della connes-
programma. Il socket NMSMTP1->PostMessage->ToAddress->Text= sione e resta in attesa di ricevere le carte. Anche in
ritorna in stato di EtEmailDestinatario->Text; questo progetto sono state inserite due form: la form
ascolto in attesa di
NMSMTP1->PostMessage->Body->Text=EtIP-> principale e la form per la ricezione dell’email.
nuove connessioni.
Text+String(CR)+String(Date())+ Consultate i file [Link] e Ricevi-
String(CR)+String(Time()); [Link] per vedere i componenti che sono stati
LOCALIZZARE NMSMTP1->PostMessage->Subject=”Briscola”; utilizzati e le proprietà che sono state modificate in
UNA fase di progettazione.
APPLICAZIONE Invia l’email utilizzando i seguenti metodi:
Supponiamo di voler Form di avvio
distribuire NMSMTP1->Connect(); Per comunicare col server è stato inserito nella form
l’applicazione in un
NMSMTP1->SendMail(); principale un componente ClientSocket. La porta
Paese in cui per giocare
a carte si utilizzi un NMSMTP1->Disconnect(); utilizzata deve essere la stessa definita nel lato ser-
mazzo con immagini ver. Questo componente viene attivato quando si
diverse dalle carte Nel corpo del messaggio vengono memorizzati l’IP, clicca sulla voce Connetti del menu. Prima di attivar-
napoletane. Possiamo la data e l’ora di invio; mentre nella proprietà Object lo è necessario impostare la proprietà ClientSocket1-
inserire le immagini
delle nuove carte in
è memorizzata la stringa “Briscola” che permetterà >Address assegnandole l’indirizzo IP del server.
un’altra DLL di risorse al client di identificare il messaggio. Se il messaggio
(mantenendo invariati viene inviato, si attiva l’evento OnSuccess di ClientSocket1->Address=EditIP->Text;
i nomi delle immagini NMSMTP, che pone a true il flag MsgInviato ed ClientSocket1->Active=true;
nella risorsa) e emette un messaggio per avvisare l’utente che l’e-
chiedere all’utente,
all’avvio
mail è stata inviata. In caso di insuccesso, si attiva Stabilita la connessione tra i due computer, il client
dell’applicazione, di l’evento OnFailure e il flag MsgInviato viene posto a resta in attesa di ricevere messaggi. L’evento Client-
scegliere il mazzo di false. Inviato il messaggio, si torna alla form princi- SocketRead si attiva quando il server invia un mes-
carte che vuole pale e si resta in attesa di una connessione dal client. saggio
utilizzare. Essendo le
DLL caricate
void __fastcall TForm1::ClientSocket1Read(TObject
dinamicamente, è
possibile richiamare *Sender,
quella corrispondente TCustomWinSocket *Socket) {
alla scelta fatta
L’APPLICAZIONE String s;
dall’utente senza dover LATO CLIENT s=Socket->ReceiveText();
produrre due
Gran parte del codice, soprattutto per quel che ri- Lista->Text=s;
applicazioni diverse
per ogni mazzo di guarda la gestione delle carte è comune alle due EstraiLista(); }
carte. Si può fare la applicazioni. Quindi la descrizione di questa parte
stessa cosa per le sarà più breve. All’avvio del lato client, si può legge- Osserviamo la funzione EstraiLista presente in
didascalie dei re la posta per verificare se nella casella di posta c’è [Link]:
componenti visuali
dell’applicazione,
una mail con oggetto “Briscola” (in questo caso l’IP
inserendo in una letto dalla mail sarà scritto nella casella di testo void TForm1::EstraiLista()
risorsa le stringhe EditIP) oppure, se si conosce già l’IP del computer {}
delle didascalie su cui è installato il lato server, lo si può inserire
tradotte nella lingua direttamente nella EditIP. Impostato l’IP, ci si con- Esaminiamo i tipi di comandi:
locale.
nette cliccando sulla voce Connetti del menu.
Se il server è in ascolto, il client cambia la caption Comando B, C, D, E: il client ha ricevuto una carta

h t t p : / / w w w. i o p r o g r a m m o . i t
G 52/Novembre 2003
049-053 T&T Briscola 4-10-2003 9:52 Pagina 53

Utilizzo dei socket per applicazioni di rete TEORIA & TECNICA

e la inserisce nel mazzo. NMPOP31->DeleteOnRead=false; //non scaricare la posta


Comando F: aggiorna il turno. NMPOP31->Connect();
Comando N: il server si è disconnesso; viene for(int i=0; i<NMPOP31->MailCount; i++){
aggiornato tutto per preparare il client ad un’altra NMPOP31->GetMailMessage(i+1);
connessione. if(NMPOP31->MailMessage->Subject==” Briscola”)
Comando A: richiama il metodo NuovaPartita che { NMPOP31->DeleteOnRead=true; //scarica la
distribuisce le carte, le visualizza, aggiorna tutte le email (i+1)
variabili e, se è di turno il client, abilita le sue carte. NMPOP31->GetMailMessage(i+1);
La partita può iniziare. NMPOP31->DeleteOnRead=false;
Comando G: il client ha ricevuto la posizione della EtIP->Text=NMPOP31->MailMessage->Body->
carta giocata dal server. Strings[1]; //preleva l’IP
EtData->Text=NMPOP31->MailMessage->Body->
La gestione della partita è identica al lato server. Per Strings[2]; //preleva la data
la trasmissione della carta giocata è stato definito il EtTime->Text=NMPOP31->MailMessage->Body->
metodo TrasmettiCartaGiocata, che utilizza il meto- Strings[3];//preleva l’ora
do SendText del Socket per l’invio del messaggio break;} CREARE UNA
} DLL DI RISORSE
void TForm1::TrasmettiCartaGiocata(int G2) { NMPOP31->Disconnect(); Armatevi di pazienza e
passate allo scanner le
String s; CancellaTMP();
40 carte più una carta
Cursor=crHourGlass;
rovesciata che
s=”H”+String(G2)+String(CR)+String(LF); Dopo esserci disconnessi dal server POP dobbiamo rappresenterà il mazzo
ClientSocket1->Socket->SendText(s); eliminare dalla cartella, in cui è in esecuzione, il pro- e salvate ognuna in un
Cursor=crDefault; } gramma, tutti i file temporanei che si sono creati file bmp (scegliete
durante la lettura dei messaggi. Questa operazione è risoluzioni con
massimo 256 colori).
La voce “Ricevi IP” del menu apre la form per la rice- affidata alla funzione CancellaTMP. Richiamate Image
zione della email e imposta l’IP. Editor (tool fornito da
void TFormRiceviIP::CancellaTMP() { Borland con C++
Form RiceviEmail // calcella tutti i file temporanei che sono stati creati Builder) e create un
nuovo file di risorse
Dopo aver inserito i dati nelle Edit Server POP, User // durante la lettura della posta
(.res). Inserite nella
ID e Password, si può cliccare sul tasto “C’è nessu- char ComandoDos[50]=”del *.tmp”;
nuova risorsa tante
no?”. Il gestore dell’evento associato a questo tasto system(ComandoDos); nuove Bitmap quante
preleva, senza scaricarla, la posta; analizza per ogni strcpy(ComandoDos,”del *.jpg”); sono le carte e
messaggio l’object e se lo trova uguale alla stringa system(ComandoDos); ricopiate in ognuna le
immagini salvate
“Briscola”, scarica il messaggio e ne estrae dal corpo strcpy(ComandoDos,”del *.mme”);
precedentemente.
l’IP, la data e l’ora di invio. Se però, nel frattempo, chi system(ComandoDos);
Salvate la risorsa e
ci ha spedito il messaggio si è disconnesso dalla rete } aprite C++ Builder.
Internet, l’indirizzo IP che leggiamo non è più asso- Create un nuovo
ciato a quell’utente. Perciò, prima di connetterci, Il codice di quest’ultima funzione elimina tutti i file progetto per DLL e
diamo uno sguardo alla data e l’ora di invio del mes- con estensione tmp, jpg e mme che trova nella car- attraverso il Project
Manager inserite nel
saggio. Chiudiamo questa finestra per tornare alla tella in cui è installato il programma. Se eseguite progetto la risorsa.
form principale, dove troveremo l’IP ricopiato nella l’applicazione all’esterno della sua cartella rischiate Compilate il progetto
EditIP. Possiamo connetterci al server cliccando di perdere file che possono esservi utili. senza modificare il
sulla voce “Connetti” del menu. Nel form sono defi- codice e la DLL di
nite tre Edit per inserire i dati (Indirizzo server POP, risorse sarà già pronta
per l’uso (la
User ID e Password). Le altre tre Edit sono di sola let-
tura e conterranno i dati ricevuti nella email. Il com-
DOVEROSE compilazione produce
un file con estensione
ponente che ci permette di leggere la posta dalla RACCOMANDAZIONI DLL). Una volta creata
nostra casella sul server POP è NMPOP3. Le sue pro- Concludiamo rivolgendo una doverosa raccoman- la DLL possiamo
prietà vengono modificate in fase di esecuzione, dazione a chi esegue il lato server dell’applicazione: eliminare tutti i file
che abbiamo utilizzato
quando si clicca sul tasto “C’è nessuno?”. conoscete bene il vostro avversario? La conoscenza per la sua creazione.
del vostro indirizzo IP potrebbe stuzzicare la sua
NMPOP31->TimeOut=30000; “anima hacker” (o cracker) e, mentre giocate, lui po-
NMPOP31->Host=EtIndirizzoPOP->Text; trebbe interrogare il vostro computer per sapere se
NMPOP31->UserID=EtUserID->Text; ci sono altre porte aperte e altro. Se non vi fidate del
NMPOP31->Password=EtPassword->Text; vostro avversario e il vostro computer non è protet-
to da un firewall, sarà meglio rinunciare alla brisco-
Il metodo GetMailMessage permette di prelevare la la e farsi un tranquillo solitario.
email: Patrizia Martemucci

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/53 G
054-055 4-10-2003 9:53 Pagina 54

REPORTAGE Attualità

Olimpiadi Internazionali dell’informatica

Caccia all’oro
Le olimpiadi Internazionali dell’informatica 2003 hanno portato
all’Italia un medagliere piuttosto ricco, con due argenti e un bronzo.

G
iunte alla loro quindicesima edizio- le prove, mentre i restanti 5 giorni sono
ne, le Olimpiadi Internazionali stati dedicati a momenti di aggregazione e
dell’Informatica 2003 (IOI), svoltesi socializzazione tra i ragazzi partecipanti,
alla University of Wisconsin dal 16 al 23 con diverse attività ricreative.
agosto, sono solo una delle sei Olimpiadi
“Scientifiche” che ogni anno coinvolgono
gli studenti delle scuole superiori di nume-
rose nazioni del mondo. Le IOI ormai da 15
LA STRADA
anni affiancano le Olimpiadi di Matema- PER LA VITTORIA
tica, Fisica, Chimica, Biologia ed Astrono- Il regolamento è piuttosto semplice: ogni
mia (le ultime arrivate). Quella che si è nazione seleziona e porta alle Olimpiadi 4
svolta quest’anno negli Stati Uniti, alla studenti scelti attraverso una competizio-
University of Wisconsin dal 16 al 23 agosto ne nazionale. Una volta arrivato alle Olim-
è stata la 15ª edizione e ha visto la parteci- piadi, ogni ragazzo compete in modo indi-
pazione di 81 nazioni, con l’Italia impegna- viduale affrontando diversi problemi di
ta a recitare un ruolo importante, conqui- natura algoritmica, da risolvere utilizzando
stando tre medaglie, due argenti e un un linguaggio di programmazione a scelta
bronzo; un buon auspicio per la prossima tra C/C++ e Pascal (ma il linguaggio può
edizione, con l’inevitabile speranza che la variare tra un’edizione e l’altra delle IOI).
prossima sia una medaglia d’oro. quindi lo scopo è quello di appassionare i Per ognuno dei due giorni, di gara i ragazzi
ragazzi agli elementi di logica e ragiona- devono affrontare 3 problemi avendo a
mento che stanno alla base della program- disposizione un tempo giornaliero di 5 ore.
mazione, lasciando da parte gli aspetti Per ogni esercizio ricevono quindi un pun-
NON SOLO videoludici grazie ai quali i Pc sono tanto teggio, e la somma dei risultati ottenuti
VIDEOGAME popolari tra i più giovani. Ma le IOI non nelle due giornate di gara determina il
Lo scopo della manifestazione, patrocinata sono solo “informatica e programmazio- piazzamento in classifica e, di conseguen-
dall’UNESCO e promossa in Italia dal ne” e, infatti, durante la settimana in cui si za, la distribuzione delle medaglie.
MIUR (Ministero dell’Istruzione, dell’Uni- sono svolte le IOI, solo due erano i giorni Ovviamente affinché la prova dia esito
versità e della Ricerca) e dall’AICA impegnati con positivo, il PC su cui il concorrente ha com-
(Associazione Italiana per l’Informatica e il pilato il programma dovrà essere in grado
Calcolo Automatico), è ovviamente di dare la risposta al quesito proposto, ma
quello di stimolare l’interesse dei gio- non solo, dovrà farlo nel tempo massi-
vani nei confronti degli aspetti mo stabilito dal testo del problema. Le
scientifici e culturali relativi alle tec- premiazioni avvengono per fasce di
nologie informatiche. Per una volta medaglie e quest’anno ci sono state 24

h t t p : / / w w w. i o p r o g r a m m o . i t
G 54/Novembre 2003
054-055 8-10-2003 17:25 Pagina 55

Attualità REPORTAGE

LA SQUADRA AZZURRA
A difendere i colori dell’Italia hanno prov-
veduto, con ottimi risultati, quattro
giovanissimi ragazzi.

medaglie d’oro, 45 argenti e 63 bronzi, campo informatico rispetto a molti paesi


mentre il titolo di campione è stato con- dell’est, asiatico e europeo. I quattro ragaz-
quistato da Hwan-Seung Yeo, rappresen- zi della nostra nazionale sono, prima di
tante della squadra coreana che con il pun- tutto, appassionati di informatica e solo
teggio di 455,4 ha staccato di quasi 30 punti due hanno frequentato scuole con una
la seconda medaglia d’oro, proveniente specializzazione legata alla programma- Dal racconto di tutti è emerso l’entusiasmo
dalla Bulgaria. La Corea, insieme ad altri zione, mentre i due restanti hanno conse- per l’esperienza vissuta, a contatto, per una
paesi dell’est e dell’Europa orientale, si è guito un diploma di liceo scientifico. volta, con persone che non ti guardano
confermata la “nazione da battere”, por- Impossibile, quindi, competere con i storto solo perché trovi appassionante
l’informatica piuttosto che i videogame. Il
tando nei primissimi posti tutti i suoi rap- coreani sul piano della formazione scola-
bello di condividere una passione non ha
presentanti, conquistando due ori e due stica, anche se molto è stato fatto in fase di però messo da parte lo spirito di rivalità
argenti. preparazione proprio durante le settimane che, una volta davanti al compilatore, è
di allenamento che hanno preceduto la stato fortissimo facendo emergere la
partenza per gli Stati Uniti. Per la prossima soddisfazione di chi ha raggiunto il risultato
migliore e l’amarezza (e la rabbia) di chi
edizione, che verrà ospitata dalla Grecia,
LA STRADA PER sono già in fase avanza i preparativi. Tutte
quest’anno ha dovuto rinunciare alla

IL WINSCONSIN le informazioni per la partecipazione all’e-


medaglia. Su una cosa però tutti sono stati
d’accordo: troppo poche le ragazze (4 o 5) e
Per l’Italia tutto è cominciato verso la fine dizione 2004 (il bando si chiuderà il 31 solo una piuttosto carina, la cinese, ma que-
del 2002, quando più di 360 istituti, con ottobre), sono reperibili sul sito [Link]- sta è un’altra storia.

oltre 7500 studenti, hanno risposto al [Link] e chissà che questa


GILBERTO ABRAM
bando di concorso per le Olimpiadi volta, con il ritorno in Europa e con un Vive a: Ronzone (TN)
Età: 19 anni
Internazionali dell’Informatica 2003. Le maggior numero di partecipanti alle sele-
Studi: Diploma di Liceo Scientifico
prime, pesanti, selezioni interne alle scuo- zioni, dopo i bronzi e gli argenti delle sta- Numero di Olimpiadi: 1
Miglior piazzamento:
le hanno portato 82 candidati a disputare gioni passate, non ci scappi una bella
Medaglia d’argento
la selezione nazionale (da quest’anno medaglia d’oro. Hobby: Chitarra, musica punk
Olimpiadi Italiane di Informatica), da cui Stefano Tura
sono usciti i 21 partecipanti meglio piazza- MATTEO BRUNI
Vive a: Monte San Martino (MC)
ti che hanno seguito un corso di formazio- Età: 19 anni
Studi: ITIS – Specializzazione
ne presso l’Università di Pisa. Tra i 21 fina-
Informatica
listi sono quindi stati selezionati i 4 titolari Numero di Olimpiadi: 1
Miglior piazzamento:
e le due riserve per il team italiano, pre-
Medaglia di bronzo
miati per il bel risultato con un computer Hobby: Bicicletta, tennis tavolo, calcio
portatile. I nostri portacolori hanno otte-
nuto un ottimo risultato, ma la differenza GIUSEPPE OTTAVIANO
Vive a: Ragusa
di prestazione, per esempio, nei confronti Età: 18 anni
Studi: Diploma di Liceo Scientifico
della nazionale coreana, testimonia il ritar-
Numero di Olimpiadi: 1
do che il nostro sistema scolastico paga in Miglior piazzamento:
Medaglia d’argento
Hobby: Musica classica, rock, punk

STEFANO MAGGIOLO
Vive a: Abano (PD)
Età: 18 anni
Studi: ITIS – Specializzazione
informatica
Numero di Olimpiadi: 2
Miglior piazzamento:
Medaglia di bronzo,
Medaglia d’oro alle Olimpiadi Italiane
Hobby: Tennis tavolo a livello
agonistico, musica

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/55 G
055-060 tips 8-10-2003 17:40 Pagina 56

TIPS&TRICKS Una raccolta di trucchi da tenere a portata di… mouse

I trucchi del mestiere

Tips&Tricks
La rubrica raccoglie trucchi e piccoli pezzi di codice che solitamente non trovano posto nei manuali, ma sono frutto
dell’esperienza di chi programma. Alcuni trucchi sono proposti dalla Redazione, altri provengono da una ricerca su
internet, altri ancora ci giungono dai lettori. Chi vuole contribuire potrà inviarci i suoi tips&tricks preferiti che, una volta
scelti, verranno pubblicati nella rubrica. Il codice completo dei tips è presente nel CD allegato nella directory \tips\ o sul
Web all’indirizzo: [Link].

VISUAL 'Comandi per l'inserimento, la modifica e cancellazione dell'Icona


di notifica

BASIC Private Const NIM_ADD = &H0


Private Const NIM_MODIFY = &H1
Private Const NIM_DELETE = &H2
UN DOWNLOAD MANAGER
Spesso è capitato di progettare applicazioni che necessi- 'Ritorno informazioni del mouse integrate con l'Icona di Notifica
tano di interagire con internet per il download di file, Private Const WM_MOUSEMOVE = &H200
purtroppo non tutti hanno a propria disposizione una Private Const WM_LBUTTONDOWN = &H201 'Pulsante sinistro giù
connessione a banda larga e, di conseguenza, quando le Private Const WM_LBUTTONUP = &H202 'Pulsante sinistro su
dimensioni dei download superano qualche mega, il Private Const WM_LBUTTONDBLCLK = &H203 'Doppio click
tempo necessario per completare l'operazione non si pulsante sinistro
riduce a pochi minuti, senza contare che si potrebbero Private Const WM_RBUTTONDOWN = &H204 'Pulsante destro giù
avere delle disconnessioni accidentali, e se non si utiliz- Private Const WM_RBUTTONUP = &H205 'Pulsante destro su
zano programmi tipo "GetRight", tutto il lavoro di down- Private Const WM_RBUTTONDBLCLK = &H206 'Doppio click
load potrebbe andare perso. pulsante destro
La classe qui presentata permette di downloadare file,
con la possibilità di fermare l'operazione di download in 'Valori dei flag per attivare il messaggio, l'icona ed il tooltip
qualsiasi momento, e di riprendere l’operazione in segui- Private Const NIF_MESSAGE = &H1
to; altresì, se accidentalmente si perde la connessione, Private Const NIF_ICON = &H2
tutto ciò che si è scaricato non viene perso, poiché viene Private Const NIF_TIP = &H4
effettuare una copia dei file nella cartella temporanea
denominata "C:\Down_". 'Dichiarazione della chiamata alla funzione API
Trovate il progetto completo nella directory tips del Cd- Private Declare Function Shell_NotifyIcon Lib "shell32" Alias
Rom allegato o sul Web: [Link] "Shell_NotifyIconA" (ByVal dwMessage As Long, pnid As
Tip fornito dal sig. P .Libro NOTIFYICONDATA) As Boolean

Dim nid As NOTIFYICONDATA


COME GESTIRE LA TASKBAR
Una serie di funzioni utili a visualizzare e a gestire un'i- Public Sub AddIconaNotifica()
cona nella task bar. Il tutto funziona tramite la chiamata [Link] = Len(nid)
alla funzione API "Shell_NotifyIcon" della libreria "shell32" e [Link] = [Link]
alla dichiarazione del tipo dato "NOTIFYICONDATA". [Link] = vbNull
Tip fornito dal sig. M. Garbujo [Link] = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
[Link] = WM_MOUSEMOVE
'Dichiarazione della struttura per la gestione dell'Icona di notifica [Link] = [Link]
Private Type NOTIFYICONDATA [Link] = "Icona di notifica" & vbNullChar
cbSize As Long
hWnd As Long Shell_NotifyIcon NIM_ADD, nid
uId As Long End Sub
uFlags As Long
uCallBackMessage As Long Private Sub DeleteIconaNotifica()
hIcon As Long Shell_NotifyIcon NIM_DELETE, nid
szTip As String * 64 End Sub
End Type Private Sub Form_MouseMove(Button As Integer, Shift As Integer,

h t t p : / / w w w. i o p r o g r a m m o . i t
G 56/Novembre 2003
055-060 tips 8-10-2003 17:40 Pagina 57

Una raccolta di trucchi da tenere a portata di… mouse TIPS&TRICKS

IL TIP DEL MESE Select Case nResult


Case TAPIERR_NOREQUESTRECIPIENT
Strtemp = Strtemp & "Non è possibile avviare
UNA FUNZIONE
l'applicazione Windows si supporto"
PER CHIAMARE UN NUMERO
Case TAPIERR_REQUESTQUEUEFULL
TELEFONICO
Strtemp = Strtemp & "Il sistema è attualmente
Spesso, per comporre un numero telefonico da Visual impegnato in altre composizioni telefoniche"
Basic, si ricorre al componente OCX MSCOMM32 che, se Case TAPIERR_INVALDESTADDRESS
opportunamente configurato, consente di gestire il mo- Strtemp = Strtemp & "Il numero telefonico non è corretto"
dem per comporre un numero telefonico; tuttavia, esiste Case Else
una particolare API, tapiRequestMakeCall, che permette Strtemp = Strtemp & "Errore sconosciuto"
di effettuare la medesima operazione in modo molto più End Select
semplice e immediato. MsgBox Strtemp
Tip fornito dalla [Link] N. Martire End If

Option Explicit End Sub

Private Declare Function tapiRequestMakeCall& Lib "[Link]" Private Sub Form_Load()


(ByVal DestAddress$, ByVal AppName$, ByVal CalledParty$, Abilita_Chiamata
ByVal Comment$) End Sub
Private Const TAPIERR_NOREQUESTRECIPIENT = -2&
Private Const TAPIERR_REQUESTQUEUEFULL = -3& Private Sub cmdExit_Click()
Private Const TAPIERR_INVALDESTADDRESS = -4& Unload Me
End Sub
Private Sub cmdChiama_Click()
Dim Strtemp As String Private Sub Abilita_Chiamata()
Dim nResult As Long [Link] = Len(Trim$(txtNumero)) > 0
End Sub
nResult = tapiRequestMakeCall&(Trim$(txtNumero),
CStr(Caption), "Test telefono", "") Private Sub txtNumero_Change()
If nResult <> 0 Then Abilita_Chiamata
Strtemp = "Errore durante la composizione del numero: " End Sub

Dim msg As Long


X As Single, Y As Single)
VISUAL
Dim sToolTip As String

msg = X / [Link]
BASIC .NET
Select Case msg COME CREARE UN’ICONA
Case WM_LBUTTONDOWN PARTENDO DA UN’IMMAGINE
Case WM_LBUTTONUP Semplice ma funzionale! Poche righe di codice Visual
Case WM_LBUTTONDBLCLK Basic .NET per creare un’icona da un’immagine JPG o
MsgBox "E' stato premuto il tasto sinistro" BMP.
Case WM_RBUTTONDOWN Nell’esempio, al click di un bottone,denominato button1,
sToolTip = InputBox("Inserire il nuovo tooltip:", "Conferma") viene richiamata una procedura (Crea_Icona) che trasfor-
If sToolTip <> "" Then ma l’immagine [Link] (contenuta nel medesimo percor-
[Link] = sToolTip & vbNullChar so dell’applicazione) in una classica icona Windows.
Shell_NotifyIcon NIM_MODIFY, nid Tip fornito dal Sig. E. Mattei
End If
Private Sub Button1_Click(ByVal sender As [Link], ByVal e As
Case WM_RBUTTONUP [Link]) Handles [Link]
Case WM_RBUTTONDBLCLK Crea_Icona([Link] & "\[Link]")
End Select End Sub
End Sub Public Sub Crea_Icona(ByVal StrPercorso As String)

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/57 G
055-060 tips 4-10-2003 9:54 Pagina 58

TIPS&TRICKS Una raccolta di trucchi da tenere a portata di… mouse

Dim bmp As New Bitmap(StrPercorso) ExecuteTarget(nil);


Dim img As IntPtr = [Link] except
Dim ico As Icon = [Link](img) Result:=False;
Dim fStream As New FileStream([Link] & end;
"\[Link]", [Link]) finally
[Link](fStream) Free;
[Link]() end;
[Link]() end;
MsgBox("Icona Creata", [Link], "Creazione
Icone") procedure [Link](Sender: TObject);
End Sub const
URL_XML = '[Link]
var
File_Locale : TFileName;

DELPHI StartItemNode : IXMLNode;


ANode : IXMLNode;
COME RECUPERARE UN FILE XML DAL WEB STitle, sDesc : widestring;
Il tip consente di agganciarsi ad un indirizzo Web e down- begin
loadare, in locale, il contenuto di un documento XML; i File_Locale := IncludeTrailingPathDelimiter(ExtractFilePath(
dati presenti in quest’ultimo saranno quindi formattati e [Link])) + '[Link]';
inseriti in una ListBox appositamente configurata.
Nell’esempio, il sito web dal quale reperire il file xml è [Link]:=crHourglass;
segnato come [Link] mentre il file XML è try
identificato come [Link]. if not DownloadURLFile(URL_XML, File_Locale) then
begin
unit Unit1; [Link]:=crDefault;
interface Raise [Link]('Non è stato possibile connettersi
uses al Web',[]);
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Exit;
Forms, Dialogs, xmldom, XMLDoc, msxmldom, ComCtrls, end;
StdCtrls, ExtCtrls, XMLIntf; if not FileExists(File_Locale) then
type begin
TForm1 = class(TForm) [Link]:=crDefault;
lv: TListView; raise [Link]('Errore!');
XMLDoc: TXMLDocument; Exit;
pnlTop: TPanel; end;
btnRefresh: TButton; [Link];
procedure btnRefreshClick(Sender: TObject); [Link] := File_Locale;
private [Link]:=True;
{ Private declarations } StartItemNode:=[Link]
public .[Link]('item');
{ Public declarations } ANode := StartItemNode;
end; repeat
var STitle := [Link]['titolo'].Text;
Form1: TForm1; sDesc := [Link]['descrizione'].Text;
implementation with [Link] do
{$R *.dfm} begin
uses ExtActns; Caption := STitle;
function DownloadURLFile(const URL_XML, File_Locale : TFileName) : [Link](sDesc)
boolean; end;
begin
Result:=True; ANode := [Link];
with [Link](nil) do until ANode = nil;
try finally
URL:=URL_XML; DeleteFile(File_Locale);
Filename:=File_Locale; [Link]:=crDefault;
try end;

h t t p : / / w w w. i o p r o g r a m m o . i t
G 58/Novembre 2003
055-060 tips 4-10-2003 9:54 Pagina 59

Una raccolta di trucchi da tenere a portata di… mouse TIPS&TRICKS

end; infatti, si parla di ponte JDBC-ODBC. Le classi Java che


end. permettono l'accesso ai database sono contenute nel
package [Link].

JAVA Ecco un esempio in grado di sfruttare il database di


Access appena registrato nel sistema:

SCRIPT import [Link].*;

COME INTERAGIRE class JavaDatabase {


CON UN DATABASE ACCESS
Java realizza le connessioni ai database attraverso il com- public static void main(String[] args) {
ponente noto come JDBC. Poiché Java è multipiattafor- try {
ma, tale insieme di API fornisce funzionalità generiche // Carico il driver JDBC-ODBC
per l'accesso alle fonti condivise, indipendentemente dal [Link]("[Link]");
loro formato. Il trucco è abbastanza semplice: JDBC fa da // Apro una connessione con il database
"tramite" tra un'applicazione Java ed il DBMS che si Connection con = [Link](
intende sfruttare, spesso attraversando anche altri colle- "jdbc:odbc:MioDatabase"
gamenti interni. );
Tip fornito dal sig. C. Pelliccia // Preparo l'oggetto che mi permetterà
// l'utilizzo di SQL
Per testare la connessione con gli archivi di Access, rea- Statement stat = [Link]();
lizza un archivio chiamato [Link], e al suo // Eseguo l'interrogazione, ottentendo
interno crea una tabella nominata Persone, suddivisa in // un oggetto ResultSet come risultato
quattro campi: ResultSet res = [Link](
"SELECT * FROM Persone"
• ID, un banale contatore usato come chiave primaria. );
• Nome, di tipo testuale. // Scorro ogni record presente e stampo
• Cognome, di tipo testuale. // l'output sul video
• Indirizzo, di tipo testuale. while ([Link]()) {
[Link]([Link]("Nome") + ", " +
Quindi popola la tabella con qualche dato arbitrario. [Link]("Cognome") + ", " +
A questo punto è necessario far riconoscere al sistema [Link]("Indirizzo"));
operativo il database, in modo che possa essere introdot- }
to tra le fonti di dati ODBC gestite. Per far ciò, è necessa- // Chiudo il ResultSet
rio configurare un DSN. [Link]();
L'operazione è semplice: // Chiudo lo Statement
[Link]();
1. Dal "pannello di controllo" di Windows accedi alla voce // Chiudo la connessione
"origine dati ODBC". [Link]();
} catch (Exception e) {
2. Seleziona "aggiungi" nella scheda "DSN utente". [Link]("Problema: " + [Link]());
}
3. Scegli, dall'elenco presentato, il driver di Access, iden- }
tificato solitamente dalla dicitura "Microsoft Access
Driver (*.mdb)". }

4. Nella maschera ora presentata, immetti i dati necessa- Per prima cosa viene caricato il driver JDBC-ODBC:
ri per la creazione del DSN. Usa il nome MioDatabase,
inserisci una descrizione a piacere, e con il pulsante [Link]("[Link]");
"seleziona" collega il DSN al file [Link] prece-
dentemente creato. Quindi la classe Connection è sfruttata per aprire la con-
nessione verso il database. La stringa utilizzata, ovvia-
5. Conferma ogni operazione effettuata, salvando così il mente, non è casuale:
DSN utente creato.
jdbc:odbc:MioDatabase
Ora la base di dati è ufficialmente riconosciuta dal siste-
ma operativo, e JDBC può accedervi sfruttando, come MioDatabase, infatti, è proprio il nome del DSN creato
tramite, il driver ODBC del sistema. In casi come questo, pocanzi. A questo punto è superfluo commentare il resto:

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/59 G
055-060 tips 4-10-2003 9:54 Pagina 60

TIPS&TRICKS Una raccolta di trucchi da tenere a portata di… mouse

il package [Link] contiene tutte le funzionalità necessa- if([Link](i)==" ")


rie per ogni scopo, e la documentazione ufficiale (http:// inizio=i;
[Link]/docs/) le illustra nel dettaglio. else
break;
}
DOWNLOADARE UN FILE for(i=[Link]-1;i>0;i--)
DAL WEB E SALVARLO IN LOCALE {
La procedura proposta consente di scaricare un file par- if([Link](i)==" ")
tendo dal suo URL e di salvare lo stesso in una directory fine=i;
locale. Affinché il tip possa funzionare è necessario im- else
portare i package [Link] e [Link]. break;
}
public static void download(String url, String filename) stringa = [Link](inizio+1,fine);
{ return(stringa);
try }
{ function ltrim(stringa)
URL u = new URL(url); {
URLConnection conn = [Link](); var i;
InputStream in = [Link](); var inizio=-1;
FileOutputStream out = new FileOutputStream(filename); for(i=0;i<[Link];i++)
byte[] bytes = new byte[1024]; {
int l = 0; if([Link](i)==" ")
while ((l = [Link](bytes)) != -1) inizio=i;
[Link](bytes,0,l); else
[Link](); break;
[Link](); }
} stringa = [Link](inizio+1,[Link]);
catch (Exception e) return(stringa);
{ }
[Link]("Problema: " + [Link]()); function rtrim(stringa)
} {
} var i;
var fine=[Link];
La seguente riga di codice: for(i=[Link]-1;i>0;i--)
{
download("[Link] if([Link](i)==" ")
"hello_ioprogrammo.zip"); fine=i;
else
recupera il file denominato [Link], presente all'URL break;
indicato, e lo salva sul proprio hard-disk con il nome }
hello_ioprogrammo.zip stringa = [Link](0,fine);
return(stringa);
}
UNA FUNZIONE TRIM EVOLUTA… %>
Il tip proposto emula la funzione trim di Visual Basic,
ovvero rimuove gli eventuali spazi presenti all'inizio o
alla fine di una stringa; utile da utilizzare anche solo lato
client, nel browser.
Tip fornito dal sig. C. Miele PHP
<%@ LANGUAGE="JScript"%> LA VERIFICA DELLA CARTA DI CREDITO
function trim(stringa) Questa funzione sviluppata in linguaggio PHP verifica l’e-
{ sattezza di un codice di partita iva. La funzione restitui-
var i; sce 1 nel caso in cui il codice risulta corretto. Per l’utiliz-
var inizio=-1; zo basta includere il programma in un file e richiamare la
var fine=[Link]; funzione CheckIVA passando come argomento la partita
for(i=0;i<[Link];i++) iva da controllare
{ Tip fornito dal Sig. R. Sensale

h t t p : / / w w w. i o p r o g r a m m o . i t
G 60/Novembre 2003
055-060 tips 8-10-2003 17:41 Pagina 61

Una raccolta di trucchi da tenere a portata di… mouse TIPS&TRICKS

<?php {
## Creato da Rosario Sensale ## $somma_pari=$somma_pari + intval($temp_str[0]) +
## [Link] gsensa@[Link] ## intval($temp_str[1]);
function CheckPIva($partita_iva) }
{ else
$dimensione=strlen($partita_iva); {
$somma_disp=0; $somma_pari=$somma_pari + $temp_somma;
$somma_pari=0; }
$somma_totale=0; //somma totale
$temp=0; //ritorna 0 se c'è un errore e 1 nel caso contrario $somma_totale=$somma_pari+$somma_disp;
//controllo la dimensione //elemento unita'
if ($dimensione == 11) $temp_str=strval($somma_totale);
{ $controllo=10-intval($temp_str[1]);
$somma_disp=intval($partita_iva[0]) + intval($partita_iva[2]) if (intval($partita_iva[10]) == $controllo)
+ intval($partita_iva[4]) + intval($partita_iva[6]) + {
intval($partita_iva[8]); $temp=1;
//controllo pari }
$temp_somma=intval($partita_iva[1])*2; else
$temp_str=strval($temp_somma); { $temp=0;}
if ($temp_somma >= 10){ }
$somma_pari=$somma_pari + intval($temp_str[0]) + else
intval($temp_str[1]); { $temp=0; //non sono 11 caratteri}
} return $temp;
else }
{$somma_pari=$somma_pari + $temp_somma; } ?>
$temp_somma=intval($partita_iva[3])*2;
$temp_str=strval($temp_somma);

IL TIP
if ($temp_somma >= 10){
$somma_pari=$somma_pari + intval($temp_str[0]) +
intval($temp_str[1]);
}
else
{

}
$somma_pari=$somma_pari + $temp_somma;

$temp_somma=intval($partita_iva[5])*2;
$temp_str=strval($temp_somma);
che ti premia
if ($temp_somma >= 10){
$somma_pari=$somma_pari + intval($temp_str[0]) Questo mese
}
+ intval($temp_str[1]);
in palio
else
{
$somma_pari=$somma_pari + $temp_somma;
UN ECCEZIONALE
}
$temp_somma=intval($partita_iva[7])*2;
MONITOR IIYAMA
AS4332UT
$temp_str=strval($temp_somma);
if ($temp_somma >= 10){ IIYAMA 17”
$somma_pari=$somma_pari + intval($temp_str[0])
+ intval($temp_str[1]); Inviaci la tua soluzione ad un problema di
} programmazione, una faq, un tip…
else Tra tutti quelli giunti mensilmente in redazione,
{
$somma_pari=$somma_pari + $temp_somma;
saranno pubblicati i più meritevoli e, fra questi,
} scelto il Tip del mese,
$temp_somma=intval($partita_iva[9])*2; PREMIATO CON UN FANTASTICO OMAGGIO!
$temp_str=strval($temp_somma); Invia i tuoi lavori a ioprogrammo@[Link]
if ($temp_somma >= 10)

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/61 G
062-066 elettronica 8-10-2003 19:01 Pagina 62 Giancarlo Sicilia Lavori in Corso:ioProgrammo:74:062-066 elettronica:

ELETTRONICA Braccio meccanico - terza parte

Robotica: hardware e software

Braccio meccanico:
rotazione del polso
Al termine della lettura di queste pagine avremo visto come gestire
la rotazione del polso della nostra mano meccanica, al fine di rendere
possibile al nostro Robot lo svolgimento di compiti complessi.

L’
esecuzione di compiti complessi da parte di
un Robot, che vadano oltre il semplice spo-
stamento di oggetti, presuppone la capacità
di poter ruotare quell’appendice che tecnicamente
viene chiamata manipolatore, ma che a noi piace
chiamare ‘mano’. Nello svolgimento delle più comu-
ni azioni della vita quotidiana, diamo per scontato
di conoscere le azioni meccaniche che ci consento-
❏ CD ❏ WEB no di compiere anche i gesti più semplici.
[Link] Fig. 2: Come riportato in figura per posizionare il servo-
comando a fondo corsa in senso antiorario, rispetto alla
[Link] direzione della mano, occorre inviare un treno di impulsi
LA SCELTA lunghi 2 mSec.
DEGLI ATTUATORI mento a quel tipo di attuatori dotati di blocco, che
Per azionare le articolazioni del braccio meccanico, ne limita l’escursione a circa +/-100° rispetto alla po-
abbiamo bisogno di attuatori leggeri, semplici da sizione centrale, anche se esistono servomeccani-
controllare, potenti ed affidabili. I servocomandi smi di questo genere liberi di ruotare sul loro asse,
‘Pulse Width Modulation’ (PWM), sono un tipo par- come semplici motori. Le caratteristiche meccani-
ticolare di attuatore elettromeccanico, comune- che di questi servocomandi li rendono molto interes
mente utilizzato in applicazioni di modellismo di- santi: la coppia utile risulta essere di almeno 2,5 Kg
namico, che basano il loro funzionamento sulla de- cm per i modelli più leggeri, fino a raggiungere un
codifica di un treno di impulsi che viene inviati sul valore di oltre 15 Kg cm. Esternamente, il servoco-
QUESITI terminale di controllo. In questa sede faremo riferi- mando è molto semplice e compatto e si adatta per-
ALL’AUTORE fettamente alle applicazioni di Robotica. Il conge-
L’autore è lieto di gno presenta tre terminali, due dei quali (rosso e ne-
rispondere ai quesiti ro), servono alla sua alimentazione, mentre il terzo
dei lettori
sull’interfacciamento
(bianco) permette l’invio del treno di impulsi di
dei PC all’indirizzo: comando. In commercio esistono diversi modelli di
[Link]@ servocomando, ma tutti riconoscono lo stesso stan-
[Link] dard di controllo. Il parametro fondamentale è la
durata dell’impulso positivo di controllo che può
variare tra 1 mSec e 2 mSec, valori che corrispondo-
no alle due posizioni estreme. Le due figure riporta-
te in questa sede mostrano il movimento rotatorio
del servocomando, al variare della lunghezza del-
l’impulso di controllo. La frequenza degli impulsi,
entro certi limiti non è un parametro critico, gene-
Fig. 1: Il servocomando utilizzato per la rotazione del
polso del Robot è reperibile in qualunque negozio di hob- ralmente questo valore si aggira intorno ai 20-30 HZ.
bistica e modellismo. Ovviamente, se si desidera posizionare il servoco-

h t t p : / / w w w. i o p r o g r a m m o . i t
G 62/Novembre 2003
062-066 elettronica 8-10-2003 17:42 Pagina 63

Braccio meccanico - terza parte ELETTRONICA

mando nella posizione centrale, sarà sufficiente


inviare un treno di impulsi positivi, della durata di
1,5 Msec. Le tolleranze costruttive dei componenti,
servocomando incluso, potrebbero comportare una
deviazione della posizione reale, rispetto a quella
richiesta, a questo scopo è stato inserito nello sche-
ma elettrico, un potenziometro per effettuare la
regolazione dell’escursione dell’attuatore. Comple-
tata la descrizione funzionale degli attuatori, proce-
diamo ad analizzarne le metodologie di implemen-
tazione, prima nella struttura hardware e poi nel
programma di gestione software.
Fig. 4: Il circuito viene realizzato senza la necessità di
effettuare saldature, per mezzo della apparecchiatura ‘PC
Explorer light’.

lando l’apposito circuito elettronico. Il lettore potrà


risalire alle funzionalità delle altre linee consultando
gli articoli dello stesso autore, pubblicati nei due SCHEMI
numeri precedenti. A BLOCCHI
Su richiesta dei lettori,
gli schemi a blocchi
Fig. 3: Diminuendo la durata degli impulsi, l’attuatore sono stati inseriti nel
ruota progressivamente fino a raggiungere l’altro estre-
mo quando gli impulsi hanno una lunghezza di 1 mSec.
LO SCHEMA CD-Rom all’interno del
file:
ELETTRICO
La progettazione di un circuito che svolga il control- ‘ROBOT_Mano_e_Rotazi
lo di un servomeccanismo PWM non è complicata, one_del_Polso.ZIP’
L’IMPLEMENTAZIONE ma presuppone una serie di conoscenze elettroni-
DEL CONTROLLO che il cui insegnamento esula dallo scopo di queste
Per completezza, si riporta di seguito lo schema a pagine. Volutamente si cercherà di evitare una ter-
blocchi dei circuiti di controllo del braccio meccani- minologia troppo specializzata, rimanendo a dispo-
co realizzato fino a questo punto. Nella tabella ripor- sizione per i lettori che vogliano approfondire l’argo-
tata di seguito, si riassumono tutte le caratteristiche mento in forma epistolare, attraverso l’indirizzo di
salienti del sistema, che verranno poi tradotte sotto posta elettronica che viene riportato a lato. E’ stato
forma di schema elettrico più avanti in queste pagi- descritto il principio di funzionamento dei servo-
ne. Per gestire il movimento dell’attuatore, utilizzia- meccanismi PWM (Pulse Width Modulation): il mo-
mo il bit D3 della porta dati, presente sul retro del do attraverso il quale si vuole generare il treno di im- IL BRACCIO
nostro PC, nella porta parallela. Attraverso questa pulsi, in merito al quale si è già discusso, è quello di MECCANICO
linea provvederemo ad inviare un segnale di coman- realizzare un circuito oscillatore per mezzo dell’inte- E PC EXPLORER
do del circuito di gestione che analizzeremo più grato 555. Senza scendere in ulteriori dettagli, dicia- LIGHT
avanti. In questo modo vedremo come sia possibile mo che la lunghezza dell’impulso positivo viene sta- Per maggiori
comandare il movimento di un attuatore a modula- bilito dai valori dei componenti R1, R2 e C1, che informazioni sul
braccio meccanico,
zione della lunghezza dell’impulso (PWM), control- determinano la costante di tempo di carica del con- sulle interfacce relative
e sull’apparecchiatura
PIN PC Master SEGNALE DIREZIONE TIPO PORTA PIN PORTA DESCRIZIONE ‘PC Explorer light’ è
possibile visitare il sito:
2 D0 OUT PARALLELA DATA D0 2 Open Hand
3 D1 OUT PARALLELA DATA D1 3 Close Hand [Link]
4 D2 OUT PARALLELA DATA D2 4 INFRA RED sensor spuntosoft/
EMITTER
5 D3 OUT PARALLELA DATA D3 5 PWM Wrist rotation
10 ____ IN PARALLELA STATUS S6 10 INFRA RED sensor
ACK RECEIVER
11 BUSY IN PARALLELA STATUS /S7 11 Reserved
12 PE IN PARALLELA STATUS S5 12 Pression sensor 1
17 SLCT IN IN PARALLELA STATUS S4 17 Pression sensor 2
14 _________ IN PARALLELA STATUS S3 14 Pression sensor 3
AUTO FD
18 GND PARALLEL GND PARALLELA 18-25 Signal Ground
Tab. 1: Tabella riassuntiva del sistema.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/63 G
062-066 elettronica 4-10-2003 9:56 Pagina 64

ELETTRONICA Braccio meccanico - terza parte

densatore C1 (ed il tempo in cui raggiunge un certo


uF pF
valore di soglia corrispondente a T1), mentre la sua
C1 2,2E-07 0,22 220000
scarica, proporzionale all’intervallo di tempo T2
R1 1000
dipende soltanto da R3 e C1. Per i componenti scelti R2 3300 T1 T2
nel nostro caso, possiamo calcolare i valori degli R3 100000 0,000656 0,015246
intervalli di tempo T1 ,T2, nonché della frequenza di F 62,8868
oscillazione F e del ‘Duty Cycle’ D, corrispondente D 4,12272
percentualmente a T1/(T1+T2) *100, che in poche Tab. 2: Valori del progetto con N5=2/3V.
parole fornisce un’idea immediata del tempo in cui
la linea di uscita è a livello logico ‘1’. In Tab. 2 sono mo ad inserire prima i componenti più piccoli ed a
mostrati i valori di progetto, nel caso in cui sul piedi- profilo più basso, ovvero il circuito integrato, i diodi
no N 5 dell’integrato si trovino i 2/3 della tensione di e le resistenze, posizioniamo quindi il potenziome-
alimentazione. Il lettore attento noterà che la fre- tro ed i condensatori. Provvediamo ad eseguire i col-
quenza di uscita è di 62 HZ, rispetto ai 20-30 HZ con- legamenti per mezzo di spezzoni di filo rigido, cer-
siderati come riferimento: questo è dovuto al fatto cando di eseguire un cablaggio ordinato, per facilita-
che abbiamo inserito una resistenza variabile (R4) re l’eventuale ricerca degli errori. Il montaggio della
che ha lo scopo di regolare il punto di ‘zero’ del ser- parte relativa alla gestione del motore della mano
vocomando aggiustando la durata dell’impulso T1, meccanica e della parte relativa ai sensori di pressio-
variando la tensione di ‘commutazione’ dei compa- ne e prossimità sono stati pubblicati sui numeri di
ratori di Soglia e Trigger presenti all’interno dell’in- ioProgrammo dei due mesi precedenti. Il cablaggio
tegrato. Variando la tensione ai capi del piedino N5 può essere eseguito facilmente utilizzando l’appa-
possiamo quindi variare la posizione del servoco- recchiatura mostrata in figura, chiamata ‘PC Explo-
mando: quando applichiamo +4,81V questo si posi- rer light’, la più semplice della famiglia ‘PC Explorer’,
zionerà a fondo corsa in senso orario, mentre for- sulla quale è possibile avere maggiori informazioni
nendo 1,84 V a fondo corsa in senso antiorario: un sul sito ‘[Link] /spuntosoft/’, oppure scri-
valore intermedio farà posizionare l’attuatore in una vendo all’indirizzo spuntosoft@[Link]. In alternati-
posizione intermedia in modo proporzionale. Com- va è possibile utilizzare le tecniche costruttive con-
IL BRACCIO mutando il Bit D3 della nostra porta parallela, varie- venzionali, ovvero dotandosi di stagno, saldatore ed
MECCANICO remo la tensione sul piedino N5 attraverso D3 ed R4 una buona dose di pazienza: il lettore ha in ogni caso
IN AZIONE tra questi estremi di tensione, facendo ruotare il pol- tutte le informazioni necessarie alla realizzazione
Nel CD allegato alla so del robot a fondo corsa da un lato e dall’altro. Per della parte hardware e più avanti troverà il software
rivista sono disponibili ottenere un posizionamento più accurato dovremo di gestione, completo di componenti pronti all’uso,
due filmati che
mostrano la mano
aggiungere un ulteriore circuito di conversione digi- del programma compilato e funzionante dotato di
meccanica in azione. tale-analogico, che tratteremo nel prossimo appun- codice sorgente.
tamento. Sul lato destro dello schema si possono
Robot_rotazione_ notare le connessioni alle linee della porta parallela,
del_polso1.AVI o dell’apparecchiatura ‘PC Explorer light’, sulla quale
è possibile avere maggiori informazioni visitando il
IL SOFTWARE
Robot_rotazione_
del_polso2.AVI sito: [Link] oppure scriven- DI CONTROLLO
do all’indirizzo: spuntosoft@[Link]. L’architettura Il software di controllo è il responsabile della gestio-
del sistema rende possibile il massimo controllo ne di tutta la applicazione: gli schemi elettrici infatti
software del braccio meccanico, rendendo disponi-
bili tutti i segnali di uscita ed ingresso per la sua
gestione: il circuito elettrico è volutamente molto
semplice, occorre però un accurato controllo degli
errori e delle condizioni logiche proibite attraverso il
software di gestione.

LA REALIZZAZIONE
DEL CIRCUITO
La lista dei componenti necessari viene riportata a
lato di queste pagine e nel circuito elettrico, per
comodità e su richiesta dei lettori all’interno del file:
ROBOT_Mano_e_Rotazione_del_Polso.ZIP, incluso
nel CD ROM allegato alla rivista, con il nome: Rota- Fig. 5: L’immagine mostra il circuito completamente
zione_del_polso_schema_Elettrico.bmp. Provvedia- montato.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 64/Novembre 2003
062-066 elettronica 4-10-2003 9:56 Pagina 65

Braccio meccanico - terza parte ELETTRONICA

rimanda il lettore alla lettura dei due articoli dello


stesso autore, pubblicati nei due numeri precedenti
di questa rivista. Per quanto riguarda la rotazione
del polso, diciamo che la procedura HandAction vie-
ne chiamata da un apposito timer ogni 50 millise-
condi, viene generato quindi un segnale ad onda
rettangolare, con un duty cycle variabile tra 0 e
100%, in funzione della posizione dello scrollbar
ScrollBarWrist, chiamando le procedure SetWrist-
PWMHigh e SetWristPWMLow: l’interpretazione di
questo segmento di codice è autoesplicativo.

procedure [Link];
Fig. 6: Il programma è dotato di tutti i comandi relativi al
movimento di apertura della mano meccanica, del con- // Controls the ROBOT’s Hand
trollo dei sensori di pressione e di prossimità IR e della Var
rotazione del polso. W,DataPortValue:Word;
Begin
sono ridotti all’essenziale e deve essere posta la mas- // Wrist Control
sima cura da parte del programmatore affinché con- Inc (PWMCounter); //Loops from 1 to 20
dizioni proibite nello stato logico delle linee hardwa- If PWMCounter>20 then PWMCounter:=1;
re di controllo non vengano a verificarsi. Il program- //Every 50 mSec
ma Delphi descritto di seguito ha la caratteristica di If [Link]>=PWMCounter then begin
accedere all’hardware del PC attraverso i propri in- SetWristPWMHigh;
dirizzi fisici di I/O. Questa tecnica, dal momento che End
scavalca il sistema operativo, potrebbe non ‘piacere’ Else Begin COMPONENTI
a Windows NT, 2000, oppure XP, pertanto si consiglia SetWristPWMLow; NECESSARI
di utilizzare un calcolatore dotato di Win 3.X, Win 9X, End; N1 Servocomando PWM
oppure Millennium. In alternativa occorre scrivere // Unconditioned Hand Movement
N1 Circuito integrato
una parte di codice che gestisca i privilegi del siste- If [Link] then begin
555
ma, per non incorrere ad un errore del tipo Privi- [Link]:=False; N3 Diodi 1N4148
leged error. Una ulteriore alternativa che risolve ogni If [Link] then CloseHand N1 Resistenza 1 K Ohm ?
problema è la scrittura di un appropriato ‘Device else OpenHand; W
N1 Resistenza 3,3 K
Driver’, che però esula dallo scopo di queste pagine, End
Ohm ? W
data la complessità dell’argomento. La classe princi- Else Begin
N1 Resistenza 100K
pale, il codice della quale si trova sul CD allegato alla If [Link] then Ohm ? W
rivista, ingloba tutte le funzionalità del programma, StopHand; N1 Resistenza 100 Ohm
in particolare per quanto riguarda la gestione del End; ?W
N1 Condensatore
servocomando notiamo le procedure SetWristPWM- // Reads Hand Sensor Status and updates the LEDs
220000 pf poliestere
Low e SetWristPWMHigh, che si occupano rispetti- ReadHandSensorsStatus;
N1 Condensatore 10 uF
vamente di posizionare il pin N5 dell’integrato 555 a // Conditioned Hand Movement elettrolitico 16 V
livello basso ed alto. La variabile globale PWMCoun- If [Link] then begin N1 Trimmer 10 K Ohm
ter rappresenta il valore di un loop chiuso, che ha lo [Link]:=False; lineare
scopo di generare un segnale di Duty Cycle variabile, // Start closing the hand
in funzione della posizione della scrollbar ScrollBar- CloseHand;
Wrist, come viene meglio specificato di seguito. Alla //Waits the pression sensor activation
creazione della finestra principale, viene eseguita la IF IsAnyPressionSensorPressed Then Begin
procedura FormCreate, nella quale vengono inizia- [Link]:=False;
lizzati tutti i parametri fondamentali per la corretta // Stops the hand
esecuzione del programma. In particolare è impor- StopHand;
tante notare l’inizializzazione delle variabili: Paral- End;
lelPortDataAddress e ParallelPortStatusAddress, im- End;
postate per default sui valori di LPT1, per cui se il let- End;
tore ha intenzione di utilizzare una porta diversa
dovrà impostare queste variabili in modo congruen- Le procedure SetWristPWMHigh e SetWristPWM-
te con gli indirizzi fisici del suo sistema. La procedu- Low, riportate di seguito, provvedono a leggere il va-
ra HandAction è il cuore della gestione dei sensori lore della porta, a posizionare il bit D3 allo stato logi-
della mano, del movimento della pinza e della rota- co 1, oppure 0 rispettivamente ed ad impostare il
zione del polso. In merito ai primi due aspetti, si LED presente sulla form in modo appropriato.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/65 G
062-066 elettronica 4-10-2003 9:56 Pagina 66

ELETTRONICA Braccio meccanico - terza parte

procedure [Link]; che nessuna parte metallica della mano possa urta-
// Sets Wrist PWM to Low re il circuito elettrico. Colleghiamo al nostro circuito
Var il cavo relativo alla porta parallela del PC, se posse-
W,DataPortValue:Word; diamo PC Explorer oppure PC Explorer light oppure
Begin provvedendo a costruire un cavo seguendo lo sche-
DataPortValue:=Readport(ParallelPortDataAddress); ma elettrico e la tabella riportati all’inizio dell’artico-
// Reads Port Data lo. Alimentiamo il circuito e lanciamo il programma
W:=(DataPortValue and $F7); // Sets bit D3 to ‘0’ di gestione: la prima operazione da fare a questo
WritePort(ParallelPortDataAddress,W); punto è posizionare il cursore dello scrollbar in uno
[Link]; dei due estremi e verifichiamo che la mano mecca-
End; nica ruoti a fine corsa dal lato corrispondente: prov-
procedure [Link]; vediamo quindi a regolarne la posizione per mezzo
// Sets Wrist PWM to High del trimmer R4. Spostiamo il cursore dalla parte
Var opposta e controlliamo che la mano ruoti di conse-
W,DataPortValue:Word; guenza all’altro estremo, se necessario ritorniamo a
Begin regolare il trimmer R4. Se il circuito non funziona,
DataPortValue:=Readport(ParallelPortDataAddress); provvediamo a spegnere tutto prima di ricontrollare
// Reads Port Data i collegamenti e riprovare di nuovo. La nostra appli-
W:=(DataPortValue OR $08); // Sets bit D3 to ‘1’ cazione di controllo della rotazione del polso della
WritePort(ParallelPortDataAddress,W); mano meccanica è a questo punto terminata: dispo-
[Link]; niamo di un sistema che è in grado di azionare la
End; pinza, controllarne la presa per mezzo di sensori di
STRUMENTAZIONE pressione e verificare il corretto posizionamento
PER MONTAGGI dell’oggetto per mezzo del sensore a raggi infrarossi,
SPERIMENTALI nonché azionare la rotazione del polso del nostro
Il sistema proposto in braccio meccanico.
queste pagine è stato
realizzato e collaudato
con l’apparecchiatura
per il collaudo e la
sperimentazione di
circuiti elettronici con
Personal Computer ‘PC
EXPLORER light’:
ulteriori informazioni su
come si possa reperire
questa apparecchiatura
è possibile visitare il Fig. 7: Il software è dotato di un monitor della porta par-
WEB all’indirizzo: allela, che permette l’accesso diretto ai tre indirizzi fisici
delle porte Dati, di Status e di Controllo.
[Link] Fig. 8: Dopo avere completato l’assemblaggio del cir-
spuntosoft/ cuito, siamo pronti a verificarne il funzionamento, colle-
Il programma discusso in precedenza è contenuto gando il sistema al PC per mezzo della porta parallela.
oppure inviare una e- nel CD allegato alla rivista, completo di codice sor-
mail a: gente e file eseguibile, per motivi di brevità ne sono
state analizzate solamente le parti fondamentali alla
spuntosoft@[Link].
comprensione della gestione software della rotazio- CONCLUSIONI
ne del polso della mano meccanica: per quanto Il progetto dello schema elettrico, tutti i collegamen-
riguarda il controllo del motore di azionamento ti necessari, il software compilato ed i relativi codici
della pinza e la gestione dei sensori, si invita il letto- sorgenti sono stati messi a completa disposizione
re a consultare gli articoli relativi pubblicati nei del lettore: due filmati dimostrativi sono inoltre
numeri precedenti. disponibili sul CD ROM allegato alla rivista.
Il lettore vorrà comprendere che nonostante quanto
esposto in queste pagine sia stato debitamente veri-
ficato e collaudato, tuttavia viene riportato a scopo
COLLAUDO illustrativo e di studio, pertanto l’editore e l’autore
DEL SISTEMA non sono da considerare responsabili per eventuali
Prima di collegare il circuito al nostro PC occorre conseguenze derivanti dell’utilizzo di quanto espo-
verificare la nostra realizzazione con attenzione per sto in questa sede, soprattutto per la tipologia e la
assicurarci che tutto sia stato connesso come previ- complessità dell’argomento.
sto: controlliamo che i connettori siano ben serrati e Luca Spuntoni

h t t p : / / w w w. i o p r o g r a m m o . i t
G 66/Novembre 2003
67-71 SistemaExcel 4-10-2003 9:57 Pagina 67

Digital Audio SISTEMA

JavaX: applicazioni multimediali in Java

Un player audio
tutto Java
In questo articolo realizzeremo un lettore audio in linguaggio Java
tramite l’impiego del package [Link], introdotto
nella piattaforma Java 2, a partire dalla versione 1.3, e che consente
una robusta e sofisticata gestione dell’audio digitale.

A
partire dalla versione 1.3, SUN ha incluso
nella piattaforma Java 2 le cosiddette Java
Sound API: una collezione di classi ed inter-
facce che consentono la realizzazione di complessi e
sofisticati sistemi di elaborazione dell’audio digitale.
Le Java Sound Api sono state inserite in due diffe-
renti package: [Link] e [Link]-
pled. Il primo package (del quale non ci occuperemo
in quest’articolo) fornisce una serie di strumenti
utili per la gestione di dati MIDI; il secondo, invece,
❏ CD ❏ WEB
[Link]
mette a disposizione una ricca collezione di classi ed Fig. 1: Il lettore audio in azione.
[Link]
interfacce utili per la cattura, il mixaggio e la ripro-
duzione dell’audio digitale. Scopo di questo articolo sente il codice sorgente dell’intera applicazione.
è quello di muovere i primi passi nello studio del Gran parte di esso è dedicato alla gestione dei com-
package [Link], tramite la realizza- ponenti GUI, sulla quale però non ci soffermeremo,
zione di un semplice lettore audio sviluppato intera- concentrandoci invece su quegli aspetti maggior-
mente in linguaggio Java. mente legati alla gestione dell’audio digitale.
JAVA SOUND
API HOME
CHE COSA OCCORRE L’AUDIO DIGITALE PAGE
All’indirizzo
PER REALIZZARE ED IL PACKAGE
IL LETTORE AUDIO [Link] [Link]
products/java-media/
Per realizzare il nostro lettore audio avremo bisogno Prima di addentrarci nella realizzazione del lettore sound/[Link]
di tre elementi fondamentali: un sistema in grado di di file audio, è bene spendere qualche parola sulla
acquisire l’audio dall’esterno (da un file audio o particolarità esclusiva del package [Link]. è presente una sezione
direttamente da un microfono), un sistema in grado sampled: la possibilità di gestire il segnale sonoro a di [Link]
interamente dedicata
di riprodurlo all’esterno (ad esempio tramite degli livello di “campione audio”. Un campione audio è un alle Java Sound Api, da
altoparlanti) ed ovviamente un sistema di controllo “numero” che rappresenta l’ampiezza di un’onda cui è possibile
in grado di coordinare tutte le operazioni di cattura, sonora in un certo istante. E’ noto infatti che ciò che scaricare, oltre alla
elaborazione e/o riproduzione del suono. In questo il nostro cervello percepisce come “suono” è una documentazione
primo articolo ci limiteremo a realizzare un lettore successione di onde di pressione, dotate ciascuna di ufficiale (e alla
esaustiva Java Sound
audio in grado di aprire ed eseguire un file audio una certa intensità, che pervengono al nostro orec- Programmer Guide),
arbitrario (fra quelli supportati dal proprio sistema), chio. I comuni microfoni convertono queste onde di alcuni utili esempi
mentre nel prossimo articolo verrà spiegato il modo pressione in tensioni elettriche proporzionali a tali dimostrativi.
in cui catturare e riprodurre l’audio proveniente intensità; un convertitore analogico-digitale (di cui
direttamente da un microfono per poi salvarlo sotto sono dotate le attuali schede audio per PC) è in
forma di file audio. Nel CD allegato alla rivista è pre- grado infine di convertire tali valori di tensione sotto

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/67 G
67-71 SistemaExcel 4-10-2003 9:57 Pagina 68

SISTEMA Digital Audio

forma di numeri, a loro volta proporzionali ai valori che restituisce un array di oggetti di tipo AudioFile-
di tensione registrati. Ciascuno di tali numeri corri- [Link], una classe in grado di fornire informa-
sponderà appunto ad un preciso campione audio. Il zioni utili per l’identificazione di uno specifico for-
vantaggio principale dell’audio digitale è che, a que- mato di file audio. Ad esempio, tale classe possiede il
sto punto, è possibile elaborare un segnale audio metodo String getExtension() che restituisce l’esten-
semplicemente agendo su tali numeri. Ad esempio, sione del particolare formato di file audio supporta-
moltiplicare tutti i campioni audio per un fattore to. In questo modo è possibile, tramite l’impiego di
comune corrisponderà ad una variazione di scala un oggetto JFileChooser e di un oggetto di tipo
del segnale acustico, in altre parole ad una variazio- ExampleFileFilter (un’estensione della classe astrat-
ne del suo volume. Una volta elaborato il segnale ta [Link]), fornire all’uten-
audio, è possibile infine riprodurlo acusticamente te una finestra di dialogo per la scelta del proprio file
mediante un convertitore digitale-analogico (che audio, grazie ad un particolare filtro che consente
converte i valori numerici dei singoli campioni in l’apertura dei soli file audio di estensione compati-
corrispondenti segnali di tensione) collegato a sua bile col sistema in uso:
volta ad un altoparlante che è in grado di generare
all’esterno nuove onde di pressione (il segnale acu- JFileChooser chooser = new JFileChooser(currentPath);
stico vero e proprio) in funzione dei segnali di ten- ExampleFileFilter filter = new ExampleFileFilter();
sione al suo ingresso. Ebbene, il package javax. if (supportedAudioFormat==null) return false;
[Link] mette a disposizione una serie di uti- int numFormats = [Link];
li strumenti per effettuare, con grande semplicità, if (numFormats<1) { [Link](“Il sistema
tutte le operazioni fin qui descritte. Ed ora all’opera! non supporta alcun formato audio” + “compatibile
con l’attuale implementazione delle
JAVA MEDIA Java Sound Api”);
FRAMEWORK return false;}
Per chi non ha la COME APRIRE for (int i=0;i<numFormats;i++) {
necessità di impiegare UN FILE AUDIO [Link](supportedAudioFormat[
delle classi a così basso
In breve, i file audio sono dei contenitori di campio- i].getExtension()); }
livello, come le Java
Sound Api per la ni audio. In effetti, esistono molti modi con cui tali [Link](“Tutti i file audio supportati”);
gestione dei file audio campioni possono essere immagazzinati in un file, [Link](filter);
nelle proprie ed è per questo che ogni file audio possiede gene- [Link](“Apertura File audio”);
applicazioni, può ralmente una sezione iniziale (chiamata header) che int returnVal = [Link](this);
risultare più
specifica il cosiddetto formato del file: in altre paro- if(returnVal == JFileChooser.APPROVE_OPTION) {
conveniente ricorrere
al Java Media le, il modo in cui i campioni audio vengono in esso currentPath = [Link](
Framework, un rappresentati (come ad esempio il numero di byte ).getAbsolutePath();
package che consente riservati per rappresentare ciascun campione). return openAudioFile(new File(currentPath));
la gestione di Detto questo, la cosa da fare prima di tentare di apri- }
numerosissimi formati
multimediali (sia audio
re un file audio generico è accertarsi che il proprio
che video). Ulteriori sistema sia in grado di gestirlo. Attualmente, gli unici A questo punto, ottenuto un riferimento valido ad
informazioni sul Java formati di file audio supportati da Java sono i forma- un file audio supportato dal proprio sistema, è pos-
Media Framework si ti WAVE, AU, AIFF e SND (la documentazione uffi- sibile procedere alla lettura del file vero e proprio. Le
possono trovare presso ciale della Sun non esclude però la possibilità che operazioni da effettuare sul file dovranno consistere
il sito
[Link]
future implementazioni delle Java Sound Api sup- nel:
products/java-media/ porteranno ulteriori formati audio). Tuttavia, non è
jmf/[Link] affatto detto che ogni sistema sia in grado di gestire leggere l’insieme dei campioni audio in esso conte-
tutti i formati audio supportati da Java (il sistema nuti (codificati tramite una sequenza di byte e rap-
dell’autore, ad esempio, è in grado di supportare i
formati WAVE, AIFF ed AU, ma non il formato SND).
A questo scopo, le Java Sound Api ci mettono a
disposizione la classe AudioSystem, che tra le altre
cose è in grado di fornire un elenco completo dei
dispositivi audio installati nel proprio sistema, non-
ché la lista di tutti i formati di file audio da esso sup-
portati. In particolare, per quest’ultima operazione è
possibile invocare il seguente metodo della classe
AudioSystem:

[Link][] supportedAudioFormat = Fig. 2: La finestra di dialogo per l’apertura del file


[Link](); audio.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 68/Novembre 2003
67-71 SistemaExcel 4-10-2003 9:58 Pagina 69

Digital Audio SISTEMA

presentanti il segnale audio vero e proprio);


ottenere una serie d’informazioni relative al parti-
colare formato dei campioni audio da leggere, co-
me il numero di bytes impiegati per rappresentare
ogni singolo campione, la frequenza di campiona-
mento (ossia il numero di campioni audio necessari
per rappresentare un secondo di segnale sonoro), il
numero di canali impiegati (in altre parole, sapere se
il segnale è mono oppure stereo), e così via.
Fig. 3: La gerarchia delle linee nelle Java Sound Api.
Per la prima operazione è sufficiente invocare anco-
ra una volta la classe AudioSystem per ottenere un tremmo impiegare indifferentemente sia un oggetto
riferimento ad un oggetto di tipo AudioInputStream di tipo SourceDataLine che uno di tipo Clip. Tutta-
(diretta sottoclasse di [Link]), che con- via, mentre gli oggetti di tipo SourceDataLine sono
terrà una sequenza ordinata di tutti i campioni au- stati ideati per supportare lo streaming di campioni
dio presenti nel file. Per la seconda operazione, inve- audio in tempo reale (tramite il continuo aggior-
ce, è possibile ottenere un riferimento ad un oggetto namento, in fase di riproduzione audio, di in un
di tipo AudioFormat direttamente dall’oggetto Au- apposito buffer interno contenente i prossimi cam-
dioInputStream appena creato. Quanto detto è rea- pioni da suonare), gli oggetti Clip sono stati imple-
lizzabile mediante le seguenti righe di codice: mentati per consentire il precaricamento in memo-
ria di un intero brano audio (o comunque di una
AudioInputStream ais = null; arbitraria porzione di esso, anche in relazione alle
AudioFormat af = null; risorse di memoria del proprio sistema). Di conse-
... guenza, risulta conveniente impiegare una linea di LA CLASSE
private boolean openAudioFile (File audioFile) { tipo Clip tutte le volte che è possibile disporre del- AUDIOSYSTEM
try{ l’intera sequenza dei campioni audio del brano da DEL PACKAGE
ais = [Link](audioFile); riprodurre (e di cui sia nota la dimensione); vicever- [Link]
af = [Link](); sa, è conveniente (se non necessario) impiegare una .SAMPLED
} catch (Exception ex){[Link](ex); linea SourceDataLine ogniqualvolta non si può La classe AudioSystem
è probabilmente la più
return false; } conoscere a priori la lunghezza del segnale audio da
importante di tutto il
... riprodurre (si pensi ad esempio al caso di un’appli- package
return true; } cazione che deve amplificare in tempo reale una [Link].
voce catturata da un microfono, o ancora al caso in I vari metodi messi a
Il metodo [Link](au- cui un file audio è troppo lungo per poter essere disposizione da tale
dioFile), nel caso si tenti di aprire un file audio non immagazzinato tutto in una volta in memoria). classe consentono
infatti, fra le altre cose,
supportato dal proprio sistema, scatena una ecce- D’altra parte, le linee di tipo Clip sono le uniche a di ottenere un elenco
zione apposita di tipo UnsupportedAudioFileExcep- fornire dei metodi diretti che consentono di ripro- completo di tutti i
tion. durre un numero arbitrario di volte il brano audio, dispositivi audio
nonché di specificare la posizione da dove far parti- installati nel proprio
re (o sul quale far terminare) la sua esecuzione. Nel sistema, di indagare
sui formati di file
nostro caso – avendo a che fare con dei campioni audio supportati,
ASCOLTARE IL FILE audio immagazzinati in un file audio (e potendo nonché di leggere e
quindi risalire alla loro quantità) sarà conveniente scrivere file audio di
AUDIO APERTO: impiegare un oggetto di tipo Clip. Le seguenti linee formato diverso.
L’IMPIEGO DELLE LINEE di codice mostrano il modo in cui è possibile ottene-
Nelle Java Sound Api l’audio può essere catturato re una linea di tipo Clip a partire dall’oggetto
e/o riprodotto tramite le cosiddette “linee”, partico- AudioInputStream ais ricavato dal file audio aperto
lari oggetti, che consentono ai campioni audio di in precedenza:
interagire con i dispositivi audio di I/O del proprio
sistema. Tali oggetti implementano l’interfaccia Line public Clip mySound = null;
insieme alle sue derivate di tipo DataLine: l’interfac- ...
cia TargetDataLine, che consente l’acquisizione au- private boolean setClipFromAudioInputStream() {
dio da un dispositivo di input come il microfono (e [Link] info = new [Link]([Link],
su cui si tornerà a parlare nel prossimo articolo), e le [Link](), ((int) [Link]() * ()));
interfacce SourceDataLine e Clip che consentono, try{
invece, l’invio dei campioni ad un dispositivo audio mySound = (Clip) [Link](info);
di output (come ad esempio un altoparlante). Per [Link](ais);
riprodurre musicalmente il file aperto, in effetti, po- ...

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/69 G
67-71 SistemaExcel 4-10-2003 9:58 Pagina 70

SISTEMA Digital Audio

} catch (Exception ex) {[Link](ex); colo. Nel caso invece la linea di tipo Clip sia stata
return false;} aperta senza problemi, da questo momento in poi
sarà possibile impostare una posizione arbitraria
Per ottenere una linea di tipo Clip è necessario in- all’interno del file a partire dalla quale far partire la
nanzitutto crearsi un oggetto di tipo [Link], il riproduzione audio, mediante l’invocazione del
cui costruttore prende in ingresso, nell’ordine, i metodo seguente:
seguenti parametri:
[Link](int frame)
un oggetto di tipo Class (che, a seconda del tipo di
linea che si vuole creare, dovrà essere SourceDataLi- dove il parametro frame specifica la posizione desi-
[Link], [Link], o [Link]). derata all’interno del file audio in termini di “nume-
un oggetto di tipo AudioFormat (nel nostro caso ro di frammento musicale”. Un frame musicale altro
specifico si tratta del formato dei campioni audio non è che un raggruppamento di byte necessari per
contenuti nel file precedentemente aperto che – si rappresentare adeguatamente un istante di segnale
ricorda – sono stati memorizzati in un oggetto sonoro. Così, ad esempio, nel caso il nostro file audio
AudioInputStream ais) fosse dotato di una frequenza di campionamento di
la dimensione (espressa in numero di byte) del buf- 8000 Hz (ovvero di 8000 campioni audio al secon-
fer in cui memorizzare i campioni audio. Nel caso di do), e di una durata di 10 secondi, per poter ascolta-
creazione di una linea di tipo Clip, esso corrispon- re il brano dal quinto secondo in poi dovremmo
derà al numero di byte necessari per contenere tutti impostare il seguente valore di frame: 8000*5 =
i campioni audio del brano da riprodurre; nel caso 40000. Per far partire l’esecuzione musicale vera e
LE INTERFACCE invece si debba creare una linea di tipo Target- propria, dalla posizione di frame corrente è suffi-
SOURCEDATALINE DataLine oppure SourceDataLine, tale valore dovrà ciente invocare il metodo start():
E CLIP indicare la dimensione del buffer interno utilizzato
Le interfacce per la memorizzazione temporanea dei campioni [Link]();
SourceDataLine e Clip audio rispettivamente da catturare o riprodurre di
consentono entrambe
la riproduzione audio
volta in volta. Sui criteri da adottare per una scelta mentre per metterla in pausa si deve ricorrere al
di un brano sonoro. La appropriata della dimensione di tale buffer ritorne- metodo stop():
differenza sta nel fatto remo nel prossimo articolo.
che, mentre una [Link]();
SourceDataLine può Una volta creato il nostro oggetto [Link] info,
essere impiegata per lo
streaming di campioni
è finalmente possibile ottenere un riferimento ad Se si desidera invece riprodurre l’effetto del pulsan-
audio in tempo reale una linea di tipo Clip, tramite la seguente istruzione: te di “stop” del player audio (che arresta l’esecuzio-
(come la riproduzione ne audio e la riavvolge al punto di partenza) è possi-
in tempo reale mySound = (Clip) [Link](info); bile operare semplicemente nel modo seguente:
dell’audio catturato da
un microfono), una Clip
Tale operazione può scatenare una eccezione di tipo /**
può essere impiegata
solo in quei casi in cui è LineUnavailableException, qualora non sia possibile * Metodo che fa cessare la riproduzione audio del brano
possibile disporre da disporre del tipo di linea richiesta. Per poter rendere * e lo riposiziona all’istante di esecuzione iniziale
subito dell’intera operativa la Clip appena creata, è necessario aprirla */
sequenza di campioni nel modo seguente: public void stopSound() { [Link]();
audio da riprodurre
[Link](0); }
(come la riproduzione
di tutti i campioni [Link](ais);
relativi ad un file
audio). in cui l’argomento ais è, ancora una volta, l’oggetto
AudioInputSream contenente l’intera sequenza dei RICAVARE LA
campioni audio del nostro file audio. In questo mo- DURATA IN SECONDI
do, il Clip può risalire alla dimensione da assegnare E LA POSIZIONE
al proprio buffer interno per la memorizzazione di
tutti i campioni audio presenti in ais. Nel caso il
CORRENTE
sistema non sia in grado di memorizzare l’intera DEL FILE AUDIO
sequenza audio (ad esempio perché il file audio è La durata (in secondi) del brano musicale caricato
troppo lungo per poter essere immagazzinato tutto nell’oggetto Clip (alla luce di quanto spiegato nel
in una volta in un buffer interno) viene lanciata una paragrafo precedente) può essere calcolata nel
eccezione di tipo LineUnavailableException. In que- modo seguente:
st’ultimo caso, per poter riprodurre il proprio file
audio sarà necessario ricorrere ad una linea di tipo float duration = ((float) [Link]())/
SourceDataLine, come vedremo nel prossimo arti- [Link]().getSampleRate();

h t t p : / / w w w. i o p r o g r a m m o . i t
G 70/Novembre 2003
67-71 SistemaExcel 4-10-2003 9:58 Pagina 71

Digital Audio SISTEMA

(dove il metodo [Link]() restitui- generazione di un evento di tipo [Link]


sce il numero di frame musicali appartenenti alla .STOP). In particolare, il raggiungimento della fine di
Clip), mentre la posizione corrente della Clip (sem- un file audio equivale ad un evento di tipo STOP. Le
pre in secondi) può essere facilmente ricavata come seguenti righe di codice mostrano il modo in cui è
segue: possibile dotare la nostra Clip di un ascoltatore
LineListener:
/** Metodo che restituisce la posizione corrente dello
stream audio private LineListener lineListener = new LineHandler();
* contenuto nella Clip corrente (in secondi) ...
*/ [Link](lineListener);
public float getCurTimePosition() { ... SUL WEB
return (mySound==null) ? /** A partire dalla pagina
all’indirizzo
0.0f : (float) [Link]( * Classe che consente la gestione degli eventi relativi
)/1000000; } * alle linee su cui viaggiano i campioni audio
[Link]
*/ products/java-media/
public class LineHandler implements LineListener { sound/
public void update (LineEvent ev) {
RIPRODURRE if ([Link]() == [Link])
è disponibile la Java
Sound Programmer
CICLICAMENTE { [Link](“LineEvent: STOP ->
Guide, concepita per
raggiunta la fine del file audio.”);
UNA PORZIONE stopSound(); }
tre categorie di lettori:

DI FILE AUDIO } • SVILUPPATORI:


programmatori che
Un’altra caratteristica esclusiva delle linee di tipo }
desiderano scrivere
Clip è quella di consentire la riproduzione ciclica di applicazioni o applet
una porzione di sequenza musicale. Per far questo è Se necessario, è possibile rimuovere dalla linea il Java che fanno uso di
necessario innanzitutto invocare il metodo setLoop- proprio ascoltatore, nel modo seguente: audio o MIDI. La
Points specificando il frame iniziale (start_frame) ed maggior parte dei
lettori rientrano in
il frame finale (end_frame) da riprodurre: [Link](lineListener);
questa categoria.

[Link](int start_frame,int end_frame) • FORNITORI DI SERVIZI:


sviluppatori di moduli
e quindi far partire l’esecuzione nel modo seguente:
COME CHIUDERE (plug-in) che
I DISPOSITIVI AUDIO estendono le capacità
di implementazione
[Link](int count) Al termine dell’applicazione è buona cosa ricordarsi della Java Sound
di chiudere tutti i dispositivi audio aperti in prece- Application
dove il parametro count indica il numero di volte in denza. Nel nostro caso, sarà sufficiente chiudere la Programming Interface
cui si desidera riprodurre la porzione di brano sele- nostra Clip nel modo seguente: (API). Ad esempio, un
zionata. venditore potrebbe
fornire un nuovo mixer
if (mySound!=null)
audio o un
{ if ([Link]()) [Link](); sintetizzatore MIDI, o
mySound = null; la capacità di leggere e
COME INDIVIDUARE } scrivere un nuovo
formato audio.
LA FINE DELLA
RIPRODUZIONE AUDIO • API IMPLEMENTOR:
sviluppatori che
Ciascuna linea può essere dotata di un ascoltatore CONCLUSIONI generano nuove
apposito di tipo LineListener, in grado di notificare la In questo articolo si è iniziato a parlare delle Java implementazioni di
sua apertura (in seguito all’invocazione del metodo Sound Api mediante la realizzazione di un semplice Java Sound API.
open() e la conseguente generazione di un evento di lettore di file audio. In particolare, si è visto come Naturalmente, si
tipo [Link]), la sua chiusura (in individuare i formati di file audio compatibili col presume che il lettore
seguito all’invocazione del metodo close() e la con- proprio sistema, come aprirli e come ascoltarli. abbia una conoscenza
seguente generazione di un evento di tipo Line- Nel prossimo articolo introdurremo nuove impor- di base di
[Link]), l’istante iniziale di riproduzione tanti funzionalità del nostro lettore audio, come la programmazione Java.
La familiarità con
(o cattura) dell’audio (in seguito all’invocazione del possibilità di catturare l’audio da microfono, ripro- l’audio e con il MIDI è
metodo start() e la conseguente generazione di un durlo ed infine salvarlo sotto forma di file audio, utile ma non
evento di tipo [Link]) e l’istante fina- magari dopo avervi aggiunto qualche effetto sonoro. necessaria.
le di riproduzione (o cattura) dell’audio (in seguito Non mancate all’appuntamento!
all’invocazione del metodo stop() e la conseguente Stefano Monni

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/71 G
072-074 Sistema 4-10-2003 9:58 Pagina 72

SISTEMA TAPI (Telephony Application Programmers Interface)

Interazione Telefono – Personal computer

“Scopri”
chi ti telefona
L’identificazione del numero nelle chiamate in entrata, fino a poco
tempo fa prerogativa delle compagnie telefoniche che offrono tale
servizio, è ora possibile anche attraverso il modem del nostro PC.

C
iò è reso possibile dall’interfaccia TAPI linea telefonica (Device Line). Selezionato il
(Telephony Application Programmers dispositivo, se ne potranno verificare sia le
Interface), progettata per permettere compatibilità (CommandCaps) che le impo-
alle applicazioni l’impostazione ed il control- stazioni (CommandSetting).
lo dei dispositivi di telefonia. Attraverso que-
sta interfaccia si possono avere informazioni
sulle telefonate ricevute prima che si rispon-
da, in particolare si possono ricevere infor-
❏ CD ❏ WEB mazioni circa il nome e il numero telefonico
\[Link] del chiamante.
Naturalmente sono richiesti sia l’abilitazione
[Link]
della linea telefonica a ricevere l’IdCaller
ossia l’identificativo del chiamante, che la
compatibilità del modem con l’interfaccia
TAPI.

ACTIVEX
Il componente TAPI, utilizzato per la realizza-
zione dell’applicativo, è stato realizzato dalla
TAPI Allen Martin inc. ([Link]
Abbreviazione di [Link]). Tale componente viene distribuito
Telephony API. in tre versioni: Lite, Professional e Enterprise.
Un´interfaccia
In Tab. 1 sono riportate sia le caratteristiche Fig. 1: Il Form dell’applicazione.
telefonica standard per
Microsoft Windows, del componente, che le differenza tra le varie
progettata per versioni. Per la realizzazione dell’applicativo
permettere alle NumberID (disponibile sul CD-Rom o sul All’interno del Frame Status, oltre al controllo
applicazioni Web) è stata utilizzata la versione Pro TextCallState, che ci fornisce tutto l’Output
l´impostazione e il
controllo delle
dell’ActiveX amTAPI. del programma, troviamo sia il pulsante Ri-
chiamate. spondi (CommandAnswer) che “aggancia” ad
una telefonata in arrivo, sia il pulsante Riag-
gancia (CommandHangUp) che chiude la te-
L’APPLICAZIONE lefonata.
NUMBER ID
Analizzando il Form del programma notiamo
innanzitutto un controllo ComboBox Combo-
LineName che permette la visualizzazione e DEVICE LINE
la scelta dell’apparato che interfaccerà la Come evidenziato precedentemente, la prima

h t t p : / / w w w. i o p r o g r a m m o . i t
G 72/Novembre 2003
072-074 Sistema 4-10-2003 9:58 Pagina 73

TAPI (Telephony Application Programmers Interface) SISTEMA

cosa da fare è identificare l’interfaccia con


linea telefonica. Il componente amTapi Pro CHIAMATA IN ARRIVO
riesce a catturare, attraverso il codice che L’evento di chiamata in arrivo, “Incoming-
segue, tutti i Device Line disponibili sulla pro- Call”, è generato dal componente TAPI nel
pria macchina: momento in cui si riceve il primo squillo tele-
fonico.
For i = 0 To [Link] - 1
[Link] [Link](i) Supported Features Lite Pro Ent
Next i Phone Lines Supported Unlimited *2 Unlimited *2 Unlimited *2
Multiple addresses per line device
Caller ID - Name, number and flags
Così il ComboLineName risulterà popolato.
Called ID - Name, number and flags
Sarà quindi possibile effettuare una scelta dei
SIT Tone Detection
vari dispositivi telefonici o modem rilevati
Answer
dall’ActiveX. Hangup
La scelta nel nostro caso è ricaduta sul Fax Call progress messages and call state
Modem Duxbury SM56 PCI. Translate number - Using dialing properties
Per visualizzare le impostazioni del dispositi- Make Call - Dial full or partial number
vo scelto è necessario inserire il seguente co- Dial - Completion of dialing on existing call
dice: Generate DTMF - Generate tones - 0-9, *, #, A-D
Detect DTMF tones - remote party key press
Private Sub CommandSetting_Click() Call Privilege - Owner, Monitor, Owner + Monitor
*3 Media Modes - Interactive Voice, Automated Voice, Data, Fax
[Link] [Link]
Data Rate Property For Data Modems
End Sub
Location Dialog - Windows dialing properties dialog
Enumerate Location Names
Get/set Current Location
IL DATABASE Get Current Country Code - Useful to pre-fill number to dial

TELEPHON BOOK Get Current Area Code - Useful to pre-fill number to dial
Enumerate County Names
L’applicativo che abbiamo realizzato permet- Line Dialog - Telephony device/modem setup dialog
te di conoscere, prima di rispondere alla Get/Set Current Line Device
telefonata in arrivo, il nome della persona che Device Caps - Discover device hardware capabilities
ci sta chiamando. Enumerate line names - Installed telephony/modem devices
Get/set current settings - data modem
Questo è possibile poiché al programma è
Line wave ID’s ( Record and Play wave files with amWave)
associato un Database Access che memorizza
Open Comm port handle - data modem (Use amComm for
i nostri contatti telefonici.
data stream)
Negotiated Line TAPI version - OS, TSP, Application
Negotiated Phone TAPI version - OS, TSP, Application
Speaker Phone Control - Microphone, Speaker, Mic/Speaker
Speaker Phone Volume and Gain Controls
Headset Control - Microphone, Speaker, Mic/Speaker
Headset Volume and Gain Controls
Handset Control - (Local Phone) Mic, Speaker, Mic/Speaker
Handset Volume and Gain Controls
Hook Switch Detection - On hook/Off hook
Phone wave ID’s ( Record and Play wave files with amWave)
Local Phone Ring
Phone Dialog - Telephony Phone device setup dialog
Local Phone Button Detection
Terminal Mode Support
Silence Detection
Pass Through - Direct communication with device hardware
Line Hold/Unhold
Line Blind Transfer
Fig. 2: Compatibilità del dispositivo telefonico.
Dispose Metod -
Dot Net Compatibilità
Call Handoff
[Link] è un semplice DBMS con
Transfer, park, conference calls and many other features to
una sola tabella “TelephonBook”, che identifi-
be announced. Feature requests and suggestions welcome.
ca il chiamante attraverso i campi: Number,
Name, Adress e Other Info. Tab. 1: Caratteristiche del componente della Allen Martin.

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/73 G
072-074 Sistema 4-10-2003 9:58 Pagina 74

SISTEMA TAPI (Telephony Application Programmers Interface)

A questo punto amTapi Pro è in grado di con- chiamante.”)


tare gli squilli effettuati: AddressUser = InputBox(“Inserisci l’indirizzo del
chiamante.”)
Private Sub amTapiPro_IncomingCall(ByVal OtherInfoUser = InputBox(“Inserisci altre
RingNumber As Long) informazioni sul chiamante.”)
[Link] = “Chiamata in arrivo” [Link]
CallStateMessage “Squillo “ & CStr(RingNumber) [Link] ‘ Inserisce i dati relativi alla persona
End Sub che ha telefonato
[Link](“Number”) = Number
e di acquisire le informazioni relative al chia- If NameUser = “” Then [Link](“Name”) =
mante: “—-” Else [Link](“Name”) = NameUser
If AddressUser = “” Then [Link](“address”) =
Private Sub amTapiPro_CallerID(ByVal Number As “—-” Else [Link](“address”) = AddressUser
String, ByVal name As String, ByVal flags As Long) If OtherInfoUser = “” Then [Link](“OtherInfo”)
‘Caller ID info = “—-” Else [Link](“OtherInfo”) = OtherInfoUser
If (flags And LINECALLPARTYID_NAME) > 0 Then [Link]
CallStateMessage “Nome: “ & name [Link]
If (flags And LINECALLPARTYID_NUMBER) > 0 Then [Link] = “SELECT * FROM TelephonBook
CallStateMessage “Numero: “ & Number where number like ‘“ & Number & “‘;”
If (flags And LINECALLPARTYID_BLOCKED) > 0 [Link]
Then CallStateMessage “Caller ID bloccato” End If
If (flags And LINECALLPARTYID_OUTOFAREA) > 0 ‘Visualizza le informazioni nella TextBox
Then CallStateMessage “Caller out of area” CallStateMessage “———————————————-”
If (flags And LINECALLPARTYID_UNKNOWN) > 0 CallStateMessage “Numero telefonico: “ &
Then CallStateMessage “Caller ID sconosciuto” [Link](“Number”)
FindUser (Number) CallStateMessage “Nome: “ & [Link](“name”)
End Sub CallStateMessage “Indirizzo: “ & [Link](“address”)
AMTAPI PRO CallStateMessage “Altre informazioni:
amTapi Pro è un La funzione FindUser interroga il database “ & [Link](“OtherInfo”)
controllo ActiveX che alla ricerca del numero telefonico catturato CallStateMessage “———————————————-”
può essere incorporato
dall’evento CallerId: [Link]
nelle applicazioni per
effettuare e rispondere [Link]
alle chiamate vocali e Sub FindUser(Number As String) Set Rs = Nothing
dati, catturare l’ID del Dim strDBName As String Set Cn = Nothing
chiamante, identificare Dim strConnect As String End Sub
toni DTMF remoti,
Set Cn = New [Link]
geneare toni DTMF etc.
amTapi Pro è un Set Rs = New [Link] Il risultato sarà la visualizzazione nella text-
componente TAPI strDBName = “[Link]” ‘ Nome del Box TextCallState del nome di chi ci sta chia-
(Microsoft and Intel Database mando; nel caso in cui il nominativo non è
Telephony API).
strConnect = “Provider=[Link].4.0; presente nel database, automaticamente si
Data Source=” apriranno delle finestre di input che permet-
strConnect = strConnect & [Link] & teranno l’inserimento dei dati mancanti.
“\” & strDBName
[Link] strConnect
[Link] = adUseClient
[Link] = adLockPessimistic
CONCLUSIONI
[Link] = “SELECT * FROM TelephonBook where L’applicativo realizzato, efficace strumento di
number like ‘“ & Number & “‘;” controllo e sicurezza, è inoltre finalizzato
[Link] = Cn all’ottimizzazione dei tempi nell’erogazione
[Link] di servizi, fruibili attraverso la linea telefoni-
If [Link] Then ‘ Il numero di telefono non è stato ca: si pensi ad esempio alla quantità di infor-
trovato mazioni contenute in un database di un Hotel
[Link] e alla possibilità che lo strumento da noi rea-
[Link] = “SELECT * FROM TelephonBook;” lizzato, per l’identificazione del numero tele-
Dim NameUser fonico delle chiamate in entrata, diventi in un
Dim AddressUser simile contesto un input per altri applicativi
Dim OtherInfoUser che gestiscono i dati.
NameUser = InputBox(“Inserisci il nome del Luigi Salerno

h t t p : / / w w w. i o p r o g r a m m o . i t
G 74/Novembre 2003
075-078-Sistema SAX 4-10-2003 10:10 Pagina 75

Java e XML SISTEMA

Un pattern per il parsing SAX di file XML

Java Legge
(e interpreta) XML
L’XML è a tutt’oggi uno standard collaudato e consolidato, tanto
da essere utilizzato ampiamente in quasi tutte le applicazioni.

N DESCRIZIONE
el corso dell’articolo descriveremo un
pattern utile nel parsing di un file XML e
nella creazione degli oggetti Java che DEL PATTERN
contengano le informazioni lette. Il pattern è Il pattern che andiamo ad illustrare è basato su
facilmente utilizzabile in tutti i contesti in cui è poche classi (vedi Fig. 1) che si occupano del lavoro
necessario leggere un file XML. In questo caso di preparazione alla lettura del file XML mediante la
mostreremo un esempio di utilizzo del pattern creazione e la configurazione degli oggetti SAX
per un’applicazione che legge la propria configu- necessari, permettendoci di concentrarci sulla sola
razione da un file XML. Tale esempio potrà essere gestione degli elementi XML letti. La strategia del
❏ CD ❏ WEB
velocemente integrato in qualsiasi applicazione. pattern è infatti quella di leggere il file XML, gestirne [Link]
gli eventi e comunicare con l’esterno mediante il
[Link]
metodo readElement dell’interfaccia XMLParser-
Listener. Come illustrato in figura il pattern consta
INTRODUZIONE soltanto di altre due classi principali oltre all’inter-
Da quando l’XML è diventato uno standard de faccia vista: XMLParser e XMLFileReader. Passiamo
facto, i metodi possibili per effettuare il parsing ora ad esaminare in maggior dettaglio le classi del
sono principalmente due: il DOM ed il SAX. Non pattern. Quando leggiamo un file XML mediante
entreremo troppo in dettaglio sulle caratteristi- SAX, dobbiamo implementare alcune interfacce, i
che dei due metodi. In ogni caso maggiori infor- cui metodi verranno invocati al verificarsi di deter-
mazioni sono disponibili nei relativi box. Il pat- minati eventi. L’interfaccia più importante è
tern oggetto dell’articolo si basa sul SAX 2 (in ContentHandler, la quale esporta una serie di meto-
particolare nel codice si è utilizzata la libreria di riportati nella tabella seguente:
Xerces 2). In tal modo si sfrutta il vantaggio, offer-
to dal SAX, di poter gestire anche file di grosse public void startDocument( ) throws SAXException
dimensioni. L’esempio che introdurremo si basa public void endDocument( ) throws SAXException
sulla lettura di un file XML in cui è riportata la public void startElement( String namespaceURI, String
configurazione di una generica applicazione. localName, String qName, Attributes attr ) throws
L’utilizzo di un file di configurazione per una SAXException
qualsiasi applicazione, piccola o grande che sia, public void endElement( String namespaceURI, String
è una problematica ricorrente, in quanto spesso localName, String qName ) throws SAXException
è necessario impostare il valore di alcuni para- public void characters( char[] ch, int start, int length )
metri per il corretto funzionamento dell’applica- throws SAXException
zione stessa senza intervenire sul codice. Con
l’avvento di Java, i file properties si sono rivelati Questi metodi vengono richiamati dal parser SAX,
utilissimi soprattutto per la facilità di utilizzo. mentre legge il file, al verificarsi di eventi quali l’a-
L’XML poi ha rivoluzionato la scena, in quanto pertura o chiusura del tag document o dei vari tag Fig. 1: Class diagram
relativo al pattern.
ha permesso di organizzare i dati di configura- element. Un parser abbastanza semplice dovrebbe
zione in una struttura gerarchica semplice e fles- fornire almeno una classe che implementi tale inter-
sibile, pronta a crescere in complessità quando faccia, contenendo nel metodo startElement il codi-
sia necessario. ce che gestisce la lettura degli attributi dell’element,

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/75 G
075-078-Sistema SAX 4-10-2003 10:10 Pagina 76

SISTEMA Java e XML

il cui tag è aperto in quel momento (un banale ment possono comparire in differenti punti della
esempio potrebbe stampare semplicemente il nome struttura. A tale scopo osserviamo la struttura
dell’element fornendo così un dump della struttura dell’XML riportata di seguito, dove sono descritti i
del file XML). Inoltre, per utilizzare il parser SAX, bi- dati di un ordine di un cliente, comprensivo dell’in-
sogna creare, mediante factory, un oggetto XML- dirizzo di spedizione (elemento DeliveryAddress),
Reader che si incarica di gestire la lettura del file (per per una serie di libri.
ulteriori informazioni riferirsi all’uso del SAX) e con-
figurarlo con alcune righe di codice. <CustomerOrder number=”1285901”
date=”15-09-2003”>
[Link](“[Link]”, <Customer cname=”Robert” csurname=”Palmer” />
”[Link]”); <DeliveryAddress daddress=”6539 Dumbarton Circle,
// Create SAX 2 parser... Fremont” zipcode=”94555”/>
XMLReader xr = [Link](); <Position number=”1”>
[Link](“[Link] <Book book-title=”Design Patterns” />
/validation”, true); </Position>
// Set the ContentHandler... <Position number=”2”>
[Link](new MyContentHandler()); <Book book-title=”C++ Handbook” />
SINGLETON // Parse the file... </Position>
Per Singleton si [Link]( new InputSource(new FileReader(fileName))); </CustomerOrder>
intende una classe tale
che non permetta la
creazione di più di una
Come si vede, per prima cosa si setta il SAX driver In questo caso, il nome degli element è sufficiente ad
istanza all’interno utilizzato (in questo caso Xerces 2) e quindi si crea un indentificare in modo univoco la posizione dell’ele-
della medesima Virtual oggetto XMLReader impostando su di esso una ment nella struttura. Viceversa, osserviamo la por-
Machine Java. Tale istanza di ContentHandler. Dopodiché, nell’ultima zione di XML seguente, dove ogni posizione dell’or-
tipologia di classe è riga, inzia il parsing. Notare che l’operazione fonda- dine può avere associato un proprio indirizzo di spe-
spesso presente nei
modelli logici delle
mentale è proprio l’impostazione del Content- dizione differente da quello generale relativo all’or-
applicazioni. Il suo Handler con l’implementazione (classe MyContent- dine.
design è ormai ben Handler in questo caso) adatta al nostro scopo,
definito nella mentre il resto del codice resta più o meno invariato <CustomerOrder number=”1285901” date=”15-09-2003”>
letteratura dell’OOP nella maggior parte dei casi. L’implementazione del- <Customer cname=”Robert” csurname=”Palmer” />
tanto che si parla
l’interfaccia ContentHandler richiede di implemen- <DeliveryAddress daddress=”6539 Dumbarton Circle,
spesso di pattern
Singleton. tare tutti i metodi visti nella tabella precedente Fremont” zipcode=”94555”/>
In Java, tale classe si anche se fondamentalmente, nella lettura di un file <Position number=”1”>
realizza creando un XML mediante SAX, l’evento principale a cui siamo <Book book-title=”Design Patterns” />
metodo pubblico e interessati è unicamente quello relativo all’apertura <DeliveryAddress daddress=”243 Major Street,
statico che restituisce
del tag di un element, evento gestito mediante il Fremont” zipcode=”94555”/>
l’istanza della classe,
mantenendo protetto metodo startElement. Iniziamo pertanto definendo </Position>
il costruttore. l’interfaccia XMLParserListener che definisce un <Position number=”2”>
metodo readElement del tipo <Book book-title=”C++ Handbook” />
public class Singleton { </Position>
protected Singleton () {} public boolean readElement(String url,Attributes attr) </CustomerOrder>
public static Singleton
throws SAXException;
getInstance(){
In tale caso è utile conoscere, oltre al nome dell’ele-
if (instance == null) {
Diamo innanzitutto un’occhiata ai parametri facen- ment, la posizione in cui esso si trova all’interno
instance = new
Singleton ();
do prima una piccola premessa. Quando riceviamo della struttura XML. Ciò può essere realizzato cono-
} un evento relativo all’apertura del tag di un element, scendo il percorso seguito rispettando la sequenza
return instance; il parser SAX chiama il metodo startElement che degli element che si visitano a partire dal root fino ad
} abbiamo implementato passando tra i vari parame- arrivare a quello corrente. Tale percorso può essere
private static Config tri il nome dell’element. Spesso accade che la lettura registrato in una stringa in cui sono presenti, nel giu-
Object instance = null; di un file XML richieda l’interpretazione o l’elabora- sto ordine di visita, i nomi degli element visitati
} zione della struttura, compiendo una operazione separati dal punto. Ad esempio, possiamo avere un
diversa (ad esempio la creazione di un oggetto) a path del tipo
seconda dell’elemento corrente che ha generato l’e-
vento. Per decidere tale operazione abbiamo a [Link]
disposizione solo il nome dell’elemento, ma in realtà
questa informazione non basta ad identificare in Tale path rappresenta il primo parametro del meto-
modo univoco un element all’interno di una struttu- do readElement dell’interfaccia XMLParserListener,
ra XML, in quanto diverse istanze dello stesso ele- mentre il secondo è invece l’oggetto Attributes con-

h t t p : / / w w w. i o p r o g r a m m o . i t
G 76/Novembre 2003
075-078-Sistema SAX 4-10-2003 10:10 Pagina 77

Java e XML SISTEMA

tenente gli attributi dell’elemento. A questo punto, tua la lettura ed inizia il parsing.
passiamo ad esaminare il tipo di ritorno del metodo
che è un boolean. Tale valore, se ritornato come true, public void readFile(ErrorHandler eHandler) throws
comunica che l’entità XMLParserListener ha elabo- SAXException,IOException,FileNotFoundException {
rato l’elemento. Vedremo come utilizzare questa [Link](“[Link]”,
caratteristica più avanti, quando esamineremo l’ap- ”[Link]”);
plicazione di esempio. Tutte le classi che utilizzano il // Create SAX 2 parser...
pattern e che sono interessate all’apertura del tag di XMLReader xr = [Link]();
un element implementeranno l’interfaccia XMLPar- [Link](“[Link]
serListener e, in base al parametro path ricevuto, po- /validation”, true);
tranno determinare se sono interessate o meno alla // Set the ContentHandler...
lettura degli attributi di quell’element oppure scar- [Link](parser);
tare la chiamata. La prima classe del pattern, XML- [Link](eHandler);
Parser, deriva direttamente da DefaultHandler, una // Parse the file...
classe che implementa con metodi vuoti tutte le [Link]( new InputSource(new FileReader(fileName)));
interfacce del SAX (ContentHandler, ErrorHandler, }
ecc…). Essa può registrare, mediante il metodo add-
XMLParserListener, tutte le entità XMLParserListener Si può notare che l’ErrorHandler utilizzato è atteso
a cui comunicherà il verificarsi dell’apertura del tag come parametro del metodo readFile. In questo mo-
relativo ad un element. do si consente di gestire errori di parsing al di fuori
del pattern. Come ContentHandler invece viene pas-
public void startElement( String namespaceURI, sato il riferimento all’oggetto XMLParser creato.
String localName, String qName, L’uso del pattern è mostrato dal sequence diagram
Attributes attr ) throws SAXException { riportato in Fig. 2.
index = [Link]();
if(index != 0)
[Link](“.”); PARSING:
[Link](localName); DOM VS SAX
for(int k=0;k<[Link]();k++) { La principale differenza
tra i due metodi sta nel
XMLParserListener xml = (XMLParserListener)
fatto che mentre con il
[Link](k);
DOM l’intera struttura
if([Link]([Link](),attr) == true) è caricata in memoria e
return;} } mantenuta in una
public void endElement( String namespaceURI, Fig. 2: Sequence diagram per l’uso del pattern. gerarchia di oggetti le
cui classi sono ben
String localName, String qName ) throws
definite, con il SAX al
SAXException {
momento della lettura
[Link](index,[Link]()); LETTURA DEL FILE da file vengono
index = [Link]().lastIndexOf(“.”); generati degli eventi
if(index == -1)
CONFIGURAZIONE nell’apertura o
index = 0; }
DI UN’APPLICAZIONE chiusura di particolari
tag o di altre
Per il nostro esempio, immaginiamo un piccolo ser- condizioni.
Come si può notare dal codice, tale classe costruisce ver RMI che esporti metodi per accedere ad un data-
anche la stringa path dell’elemento corrente da pas- base. Possiamo definire la sua configurazione in una
sare come parametro a tutte le istanze XMLPar- struttura molto semplice, mostrata di seguito.
serListener registrate. Se una chiamata al metodo
readElement di un XMLParserListener ritorna true, <!—Specify the configuration.—>
significa che l’elemento è stato elaborato (o letto) e <server-config xmlns:xsi=”[Link]
quindi non si ritiene necessario continuare nella /XMLSchema-instance”
notifica dell’evento. La classe XMLFileReader è re- xsi:noNamespaceSchemaLocation=”[Link]”>
sponsabile invece della lettura del file mediante SAX <!—Specify the db access configuration.—>
ed è il punto centrale della struttura. Il costruttore <db-access db-driver= ”[Link]”
riceve una stringa che identifica il nome (o il path) db-url=”jdbc:oracle:thin:@kyoto:1521:ORADB”
del file da leggere e crea un oggetto di tipo user=”admin” password=”jack” />
XMLParser che riceve le notifiche degli eventi relati- <!—Specify logging.—>
vi al ContentHandler. Inoltre, è presente un metodo <logging debug=”true” file=”./[Link]”/>
addXMLParserListener che registra nell’oggetto <!—It specifies the path of the policy file.—>
XMLParser tutte le entità XMLParserListener interes- <java-security policy-file=”./[Link]”/>
sate. Infine, è presente il metodo readFile che effet- <!—It specifies the used port and if the RMI registry

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/77 G
075-078-Sistema SAX 4-10-2003 10:10 Pagina 78

SISTEMA Java e XML

should be created within the agent process or not.—> nome dell’elemento e dei suoi attributi. Quindi
<rmi-registry external=”false” port=”1099”/> viene implementato il metodo readElement. Que-
</server-config> st’ultimo controlla che il path dell’elemento sia
quello a cui siamo interessati ed in caso positivo
Sono presenti pochi elementi: cicla sugli attributi e li memorizza ritornando true.
Generalmente un’applicazione legge la sua configu-
db-access, relativo alle proprietà di accesso al data- razione e ne valida il contenuto al momento dell’av-
base (driver da utilizzare, URL del database ed uten- vio, ma potrebbe utilizzare i parametri letti in punti
za e password); del codice e/o momenti di esecuzione diversi. A tal
logging, per le informazioni sul logging in modalità fine si può utilizzare una classe singleton (per mag-
di debug su file; giori informazioni vedere il relativo box), Config-
java-security per impostare il file di policy da uti- Object, che funziona come contenitore di tutti le
lizzare; classi (in questo caso DbAccess, Logging e RMIServer)
VANTAGGI rmi-registry per i settaggi del registro RMI (porta e le quali gestiscono al loro interno i parametri della
DEL PATTERN se utilizzare o meno un registro esterno al processo configurazione. A questo punto non resta altro che
Come abbiamo visto Java del server). creare una semplice classe che avvii il processo di
nell’esempio, per lettura del file XML ed imposti i relativi listener.
l’utilizzo del pattern
sono richieste poche
I parametri di configurazione non sono altro che gli
righe di codice e attributi degli elementi letti, i cui valori vengono public class TestXML implements ErrorHandler {
l’integrazione in registrati in una classe che esporrà dei metodi get
qualsiasi applicazione per consentire l’accesso agli elementi a chiunque li La classe implementa l’interfaccia ErrorHandler, i
si rivela veloce ed richieda. In generale però, soprattutto nel caso di file cui metodi vengono richiamati nel caso si verifichi-
efficace. L’esempio si è
basato sulla lettura di
di configurazione complessi, è consigliabile parti- no errori di lettura o di validazione. Nel nostro caso
un file di zionare la struttura XML in diverse classi di gestione essi stamperanno a video l’errore interrompendo
configurazione ognuna relativa alla configurazione di una differen- l’applicazione. Nel costruttore della classe si trova la
espresso in XML, ma te funzionalità dell’applicazione. Nel nostro caso parte più importante del codice.
nulla vieta di applicare partizioniamo il file XML in tre classi: DbAccess, Log-
tale pattern anche in
ging e RMIServer. Esse contengono degli attributi in public TestXML(String fileName) throws
altri contesti. Infatti si
è riscontrato che l’uso cui registrano i parametri letti dal file XML e dei SAXException,IOException,FileNotFoundException {
del pattern comporta metodi get per accedervi. Inoltre tali classi imple- [Link](“reading file “ + fileName);
grossi benefici in mentano l’interfaccia, definita nel pattern, XMLPar- XMLFileReader reader = new
termini di velocità di serListener in quanto devono registrare i valori dei XMLFileReader(fileName);
sviluppo del codice e
parametri degli elementi a cui sono interessati. [Link](
soprattutto della sua
manutenzione. Vediamo in dettaglio come è fatta la classe DbAccess [Link]().getDbAccess());
(le classi Logging e RMIServer sono concettualmen- [Link](
te identica). [Link]().getLogging());
[Link](
private final static String DB_ACCESS_ELEMENT [Link]().getRMIServer());
= “db-access”; [Link](this);
private final static String DB_DRIVER = “db-driver”; // dumping
private final static String DB_URL = “db-url”; DbAccess db = [Link]().getDbAccess();
private final static String USER = “user”; [Link](“db-driver = “ + [Link]());
RISORSE private final static String PASSWORD = “password”; [Link](“db-url = “ + [Link]());
Java Technology & XML public boolean readElement(String path,Attributes attr) { Logging log = [Link]().getLogging();
[Link] if([Link](DB_ACCESS_ELEMENT)) { [Link](“debug = “ + [Link]());
for ( int i = 0; i < [Link]();i++ ) { [Link](“file = “ + [Link]());
JAXP
[Link] if([Link](i).equals(DB_DRIVER)) ... }
dbDriver = [Link](i);
SAX 2.0 if([Link](i).equals(DB_URL)) L’utilizzo del pattern è condensato in poche righe
[Link] dbUrl = [Link](i); (come visto nel sequence diagram precedente).
if([Link](i).equals(USER)) Viene creato un oggetto XMLFileReader con il nome
Xerces 2
[Link] user = [Link](i); del file XML e vengono registrati, come XMLParser-
xerces2-j/ if([Link](i).equals(PASSWORD)) Listener, gli oggetti DbAccess e Logging. Infine viene
password = [Link](i); } avviata la lettura del file, impostando come Error-
return true; } Handler l’istanza this della classe TestXML. Suc-
return false;} cessivamente si stampano a video tutti i parametri
di configurazione letti.
Sono innanzitutto definite delle costanti relative al David Visicchio

h t t p : / / w w w. i o p r o g r a m m o . i t
G 78/Novembre 2003
079-080 Mobile 2003 4-10-2003 10:11 Pagina 79

L’accesso ai dati con Pocket PC PALMARI

Sincronizzazione dati tra SQL Server e PocketPC

Remote Data Access


con PocketPC
L’utilizzo di RDA permette di effettuare operazioni remote sul Server di
Database direttamente dal pocketPC e fornisce molte altre funzionalità.

P
rima di descrivere in dettaglio il componete pubblicazione non valida deve riguardare il fatto che
Remote Data Access (RDA), pensiamo sia i client non si accorgano dell’errore di “Pubblicazio-
essenziale metterlo a confronto con il compo- ne non valida”. Infatti, effettuare una nuova sotto-
nente di Merge Replication. Infatti, potrebbe sem- scrizione di una pubblicazione potrebbe comporta-
brare che i due componenti di SQL Server CE 2.0 fac- re la perdita dei dati sul database del palmare se
ciano le stesse cose dato che entrambi assicurano questi non fossero stati sincronizzati sul server
una connettività remota con SQL Server. Prima di prima della invalidazione. In sintesi, possiamo dire
tutto, l’esistenza di RDA è giustificata dal suo utiliz- che uno dei possibili scenari in cui utilizzare la tec-
zo in scenari in cui la Merge Replication non sareb- nologia della Remote Data Access è quando sono
be adatta per motivi che spiegheremo nel corso talmente poche le tabelle del database replicate sul
della trattazione. palmare da non giustificare la gestione di una pub-
RDA consente, inoltre, la connettività remota alle le blicazione.
versioni precedenti di SQL Server. E’ appena il caso
di evidenziare che mentre la Merge Replication è
supportata solo in SQL Server 2000, RDA è suppor-
tato dalla versione 6.5 di SQL Server.
TIPICHE
OPERAZIONI RDA REQUISITI
L’Object Model della tecnologia RDA utilizza l’ogget- Ingredienti Hardware:
Pocket PC o
MERGE REPLICATION to RemoteDataAccess per implementare la sua logica
(dispositivo Windows
di connettività remota. Questo oggetto dispone di
E I PROBLEMI DELLA tre metodi fondamentali con i quali è possibile effet-
CE Based), Computer
con almeno processore
PUBBLICAZIONE tuare operazioni direttamente su SQL Server oppure Pentium II e 128 MB di
Le potenzialità offerte da RDA sono più limitate compiere delle modifiche dei dati sul palmare e memoria.
rispetto alla Merge ma offre il vantaggio di non dover aggiornarli in un secondo momento. Il primo meto- Ingredienti Software:
Windows 98 SE
costruire la pubblicazione dei dati con tutti i proble- do che prendiamo in considerazione è il metodo /2000/XP, IIS (oppure
mi che questa potrebbe presentare. I problemi che SubmitSQL. Con questo metodo possiamo inviare PWS-Personal WEB
potrebbero aversi con una una pubblicazione dei delle istruzioni SQL direttamente su SQL Server e Server con Windows
dati in un database SQL Server potrebbero essere quindi effettuare operazioni di inserimento, aggior- 9x), SQL Server 2000
dovuti alla invalidazione della pubblicazione stessa namento o cancellazione remota di records. La logi- con Service Pack 1 o
superiore, SQL Server
per via di modifiche nelle sue impostazioni. ca di SubmitSQL mette in risalto il fatto che è il CE 2.0, Embedded
Ad esempio, alcune tabelle del database potrebbero PocketPC che controlla la comunicazione. Gli altri Visual Tools.
non appartenere più alla pubblicazione oppure lo due metodi che passiamo in rassegna sono i metodi
schema delle tabelle pubblicate potrebbe essere Push e Pull.
stato modificato per la contemporanea modifica Il metodo Pull permette di trasferire i dati da SQL
delle specifiche di progetto. In pratica, tutte le mo- Server al database del PocketPC. Il metodo Push per-
difiche che riguardano le tabelle della pubblicazione mette di trasferire i dati dal PocketPC verso il Server
possono invalidarla e quindi tutti i client devono di Database. E’ appena il caso di evidenziare che i
effettuare una nuova sottoscrizione dei dati. È appe- dati sono inviati al server e inseriti nella tabella inte-
na il caso di evidenziare che la nuova operazione di ressata dal “pushing” in modo incondizionato,
sottoscrizione va resa del tutto trasparente all’uten- modificando i dati inseriti con una precedente ope-
te e quindi gestita via codice. La gestione di una razione di Pull.

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/79 G
079-080 Mobile 2003 4-10-2003 10:11 Pagina 80

PALMARI L’accesso ai dati con Pocket PC

creare sul palmare il file di database nella posizione


PULL DEI DATI specificata se questo non esistesse. Ecco una possi-
Diamo un’occhiata alla procedura PullData che fa bile implentazione di CreateDB:
uso del metodo Pull dell’oggetto RemoteDataAccess:
Function CreateDB() As Boolean
Dim paco As [Link] On Error Resume Next
Set paco = CreateObject(“[Link].3.1”) Dim paca As [Link]
Dim pRDA As [Link] Set paca = CreateObject(“[Link].3.1”)
Dim strSQL As String [Link] CONNECTION_STRING
CONNECTION_STRING = “Provider=[Link]. CreateDB = True
[Link].2.0; Data Source=\ [Link]” Set paca = Nothing
‘ creo il database End Function
If CreateDB Then
MsgBox (“Database creato”) Impostate le proprietà del componente si può invo-
REMOTE On Error Resume Next care la Pull passandovi il comando SQL di SELECT
DATA ACCESS PushData per selezionare i dati della tabella MiaTabella; il
Rappresenta una Set pRDA = CreateObject(“[Link].2.0”) Data Source, ovvero il nome del computer su cui è
tecnologia alternativa [Link] = “[Link] installato SQL Server; Initial Catalog che rappresen-
alla Merge Replication
CartellaAgenteSynch/[Link]” ta il nome del Database; infine la password e la use-
in grado di supportare
connettività remota a [Link] = rid dell’utente anonimo che si connette al computer
client PocketPC con “Data Source=\[Link]” remoto con la tecnologia RDA. Precisiamo che l’o-
SQL Server CE a ‘Cancello le eventuali tabelle perazione di Pull permetterà di creare nel File di
computer con [Link] CONNECTION_STRING database [Link] lo schema della tabella
installato SQL Server.
[Link] “DROP TABLE “ & pstrDoubleQuote & MiaTabella presente sul server insieme ai dati com-
Rispetto alla Merge
Replication ha due “MiaTabella” & q pstrDoubleQuote patibili con la query di selezione passata come
sostanziali vantaggi:1) [Link] primo parametro del metodo PULL. L’operazione di
Assenza della gestione ‘ Effettuo il Pull della tabella PULL non andrà a buon fine nel caso in cui il File di
di una pubblicazione [Link] “Mia_Tabella”, “SELECT Campo1, Campo2,.. Database già contenesse la tabella MiaTabella, per
sul server; 2) maggiore
campoN FROM MiaTabella”, “Provider=sqloledb;Data cui è necessario un’operazione di DROP utilizzando
velocità poichè
vengono inviati una Source=NomeIstanzaSQLServer; Initial l’oggetto connessione paco di ADOCE 3.1. Fatta
quantità di dati Catalog=MioDBServer;user id=guest; questa considerazione, comprendiamo perché pri-
inferiore. password=”, TRACKINGOFF ma della PULL venga invocata la procedura Push-
If [Link] > 0 Then Data. PushData utilizzerà il metodo Push dell’ogget-
ShowErrors [Link] to RemoteDataAccess per inviare i dati al server. Ecco
End If una possibile implementazione della procedura:
Set pRDA = Nothing ‘ Distruggo l’oggetto RDA
End Sub Dim pRDA As [Link]
CONNECTION_STRING = “Provider=Microsoft.
RDA, Nella procedura di Pull precedente possiamo notare [Link].2.0; Data
QUANDO? il componente di RDA pRDA che viene istanziato Source=\[Link]”
RDA dovrebbe essere con il PROGID [Link].2.0 corri- On Error Resume Next
usata in scenari in cui i spondente alla versione 2.0 di SQL Server CE. Una Set pRDA = CreateObject(“[Link].2.0”)
dati possano essere
volta istanziato l’oggetto di RDA dobbiamo impo- [Link] = “[Link]
partizionati in maniera
univoca tra diversi stare le sue property: CartellaAgenteSynch/[Link]”
utenti in modo tale che [Link] = “Data Source=
non accadano mai i 1) InternetURL: rappresenta il percorso dell’agen- \[Link]”
conflitti. te di sincronizzazione [Link]. Ovviamente, poi- [Link] “MiaTabella”, “ Data Source=
I conflitti possono
chè la connettività remota avviene tramite proto- NomeIstanzaSQLServer; Initial Catalog=
accadere nel caso che i
client pocketPC collo HTTP allora dobbiamo fare in modo che il MioDBServer;user id=sa;password=”
modifichino gli stessi computer MioServer, che agisce da server di Databa- If [Link] > 0 Then
record di una o più se, abbia installato IIS come WEB Server e sia stata ShowErrors [Link]
tabelle. opportunamente configurata la cartella Cartella- End If
AgenteSynch per rendere accessibile dai client l’a- Set pRDA = Nothing
gente di soncronizzazione; End Sub
2) LocalConnectionString: la stringa di connes-
sione relative alla istanza del database sul palmare. In un prossimo articolo vedremo come applicare la
Nella procedura possiamo notare l’invocazione del logica ad un caso reale.
metodo CreateDB; lo scopo del metodo è quello di Elmiro Tavolaro

h t t p : / / w w w. i o p r o g r a m m o . i t
G 80/Novembre 2003
081-084 Mobile 4-10-2003 10:12 Pagina 81

Multicanale: l’accesso remoto PALMARI

Applicazioni multicanale e Java 2 Micro Edition

Il palmare accede
al DB aziendale
Negli articoli precedenti abbiamo lavorato molto sulla multicanalità
applicativa, cercando di capirne i concetti di base e sviluppando
insieme una completa applicazione multicanale.
Estendiamola verso dispositivi J2ME.

IL CANALE J2ME
L’
applicazione multicanale, realizzata con
tecnologia J2EE ed utilizzando il Pattern L’architettura software della nostra applicazione
MVC, consente allo stato attuale il dispat- multicanale, basata sul Pattern MVC, prevede che
ching dei servizi su canali tradizionali come HTML esista una componente di dispatching delle chiama-
su HTTP e WML su Wap, ma comprende anche una te che in funzione della tipologia del canale utilizza-
completa integrazione verso il mondo dei Web to dal dispositivo chiamante effettui una ridistribu-
Services su SOAP. Attualmente quindi è possibile zione della chiamata stessa alla componente
consumare i servizi applicativi sia da un tradiziona- software che implementa la logica di business per
le client sia in maniera trasparente da applicazioni quello specifico canale. Questa componente è una ❏ CD ❏ WEB
terze che, con l’obiettivo di erogare i propri servizi, Servlet implementata dalla classe [Link] la [Link]
utilizzano in maniera trasparente quelli messi a cui struttura è descritta in Fig. 1.
[Link]
disposizione dalla nostra applicazione. A questo
punto non ci resta che identificare l’ultimo dei cana-
li che intendiamo far gestire alla nostra applicazione
ed aggiungerlo ai meccanismi di erogazione, si trat-
ta del canale J2ME.

Fig. 1: La struttura della classe Controller.


OBIETTIVO
Quello che vogliamo ottenere è che la nostra appli- Come si può vedere il controller è dotato del meto-
cazione multicanale possa erogare i suoi servizi di do privato getOutputType() che consente di recupe-
ricerca all’interno della rubrica telefonica anche ad rare le informazioni sul canale in base al valore del-
una qualsiasi applicazione Java 2 Micro Edition che l’header HTTP “User-Agent”. Modifichiamo l’imple-
ne faccia richiesta attraverso una chiamata HTTP. mentazione di questo metodo in modo che sia in
In questo modo saremo in grado di scrivere un’ap- grado di riconoscere ed identificare la stringa
plicazione J2ME che possa girare indifferentemente “MIDP” e di conseguenza gestire diversamente que-
su palmari o telefoni cellulari compatibili e che, sto canale
dopo essersi collegata ad una rete attraverso un pro-
tocollo di comunicazione come GPRS, possa effet- private String getOutputType(HttpServletRequest request)
tuare ricerche all’interno della nostra rubrica telefo- { String userAgent = [Link](“User-Agent”);
nica. Per raggiungere questi risultati dovremo ope- [Link](“userAgent: “ + userAgent + “\n”);
rare su due fronti distinti: innanzi tutto aggiungere il if ([Link](“[Link]”) >= 0) {
canale J2ME all’applicazione e poi sviluppare una return “wml”; }
Midlet (applicazione J2ME) che sia in grado di utiliz- if ([Link](“MIDP”) >= 0) { return “midp”; }
zare il nuovo canale. return “html”;}

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/81 G
081-084 Mobile 4-10-2003 10:12 Pagina 82

PALMARI Multicanale: l’accesso remoto

A questo punto il Controller è in grado di gestire cor- richieste dal canale “midp” dovremo aggiungere una
rettamente un nuovo canale identificandolo come porzione di codice:
quello utilizzato dai dispositivi che possiedono la
stringa “MIDP” all’interno dell’header HTTP “User- if (getLanguage().equals(“midp”)) {
Agent”. output += [Link](“Cognome”) + “ “
+ [Link](“Nome”) + “\n”;
output += “email: “ + [Link](“Email”) + “\n”;
output += “tel: “ + [Link](“TelefonoFisso”) + “\n”;
IL SERVIZIO output += “cell: “ + [Link](
DA ESPORRE “TelefonoCellulare”) + “\n”;
Per come funziona la nostra applicazione sappiamo output += “filiale: “ + [Link](“Filiale”) + “\n”;
che la tipologia del servizio che il consumatore output += “unità: “ + [Link](
richiede è identificata dal parametro Action che “UnitaOrganizzativa”) + “\n”;
viene inviato al controller e sappiamo anche che la output += “\n”; }
produzione dei dati da inviare come risposta è a
carico di una pagina JSP la cui nomenclatura è nella A questo punto abbiamo concluso l’implementazio-
IL PATTERN forma action_canale.jsp. Poiché in un’applicazione ne del nuovo canale, rivediamo la sequenza di passi
MVC J2ME possiamo demandare parte dell’interfaccia che abbiamo compiuto:
Uno degli obiettivi del all’applicazione stessa più di quanto non si possa
paradigma Object fare, per esempio, con un’applicazione Web, possia- • Modifica del Controller perché riconosca i
Oriented è la
possibilità di realizzare
mo decidere che l’unico servizio applicativo che ci dispositivi che utilizzano il canale J2ME
classi che possano interessa utilizzare da remoto sia una lista dettaglia- • Scrittura della pagina JSP che spedisce i dati
vivere autonomamente ta di tutti i nominativi conformi ad un certo criterio al dispositivo chiamante
in qualsiasi contesto e di ricerca, quindi il servizio che andremo ad imple- • Modifica del custom tag per renderlo com-
non solo in quello nel mentare sarà quello identificato dal parametro patibile con il nuovo canale
quale vengono
realizzate.
Action=lista. Dovremo quindi implementare la pagi-
Questo implica che le na lista_midp.jsp che avrà il seguente contenuto: A questo punto abbiamo terminato le modifiche
componenti di all’applicazione multicanale e possiamo concen-
un’applicazione <%@ page contentType=”text/html; charset= trarci sulla realizzazione dell’applicazione J2ME.
debbano essere iso-8859-1” language=”java” import=”[Link].*” %>
sufficientemente
<%@ taglib uri=”[Link]
separate tra loro e che
possano essere prefix=”mcapptags” %>
sostituite con altre <% String cognome = (String)[Link]
IL WIRELESS TOOLKIT
implementate (“cognome”);%> Per realizzare la nostra Midlet utilizzeremo il J2ME
diversamente a
<mcapptags:ListTag language=”midp” Wireless Toolkit 1.0.4 che implementa le specifiche
condizione che ne
cognome=”<%=cognome%>”/> 1.0 del profilo MIDP. L’interfaccia del Wireless Toolkit
rispettino l’interfaccia.
Per realizzare consiste sostanzialmente in un tool chiamato KTo-
applicazioni che Come si può verificare guardando il codice di questa olbar visibile in Fig. 2 che consente la creazione e la
soddisfino questi pagina JSP l’intera pagina demanda la produzione gestione di interi progetto J2ME e la produzione
requisiti si utilizza il del proprio contenuto al custom tag ListTag che ben automatica di tutti i file di configurazione e struttu-
pattern MVC che
consente di separare
conosciamo e che viene utilizzato dall’applicazione ra che servono per la realizzazione di una Midlet.
tra loro le componenti per generare i contenuti per tutti i canali. I parame-
applicative: il Model tri che vengono passati al tag sono il canale, che sap-
che implementa le piamo essere “midp”, ed il cognome, cioè il criterio di
funzionalità di ricerca per effettuare la query sul DB. Per il resto la
business, la
componente di View
pagina non si occupa di impaginare in alcun modo i
che implementa la dati, ma ne effettua una semplice distribuzione al
logica di presentazione dispositivo chiamante. Fig. 2: La KToolbar del J2ME Wireless Toolkit.
ed il Controller
che implementa la Per creare una nuova Midlet è sufficiente seleziona-
logica di controllo.
re il pulsante “New Project” ed indicare il nome del
L’IMPLEMENTAZIONE progetto (nel nostro caso TestRubrica) ed il nome
Come sappiamo il custom tag ListTag è implemen- della classe che implementa la Midlet principale
tato attraverso la classe [Link] che si occupa di dell’applicazione (nel nostro caso RubricaTelefo-
fare la query sul database utilizzando come criterio nica). Appena premuto il pulsante “Create Project” il
di ricerca una stringa da ricercare nel campo cogno- toolkit genererà automaticamente l’alberatura delle
me sul database della rubrica. Per fare in modo che directory deputate a contenere tutti i file della nostra
questa classe implementi correttamente anche le applicazione. L’alberatura ha la seguente struttura a

h t t p : / / w w w. i o p r o g r a m m o . i t
G 82/Novembre 2003
081-084 Mobile 4-10-2003 10:12 Pagina 83

Multicanale: l’accesso remoto SISTEMA

partire dalla directory di installazione del Wireless if ([Link](“Exit”)) {destroyApp(true);}


Toolkit: else if ([Link](“Back”)) {mainMenu();}
else if ([Link](“Submit”)) {
apps\TestRubrica\bin: contiene il file di manife- user = [Link]();
sto dell’applicazione ed il file JAD di descrizione try {invokeServlet(url + user);}
della Midlet catch(IOException e) {}
apps\TestRubrica\classes: contiene le classi } else {addName();} }
compilate che implementano la Midlet
apps\TestRubrica\lib: contiene eventuali librerie La pressione del tasto Submit del dispositivo in cor-
esterne necessarie al funzionamento dell’applica- rispondenza dell’unica voce di menù causa quindi
zione l’esecuzione del metodo addName() che si occupa
apps\TestRubrica\res: contiene file di risorsa di raccogliere il criterio di ricerca che sarà poi passa- J2ME
come le immagini utilizzate nell’applicazione to all’applicazione multicanale. Sun Microsystem
propone tre diverse
apps\TestRubrica\src: contiene i sorgenti delle Il metodo addName() è fatto in questomodo:
architetture software
classi dell’applicazione basate sulla tecnologia
public void addName() { Java, queste sono
input = new TextBox(“Inserisci il cognome:”, “”, 5, indirizzate ad ambienti
[Link]); e a dispositivi
LA MIDLET [Link](submitCommand);
differenti.
Si tratta di J2SE (Java 2
Sappiamo che la Midlet che dobbiamo implementa- [Link](backCommand);
Standard Edition), J2EE
re si deve chiamare [Link] e sappia- [Link](this); (Java 2 Enterprise
mo che questo file deve essere posizionato nella [Link](“”); Edition) e J2ME (Java 2
directory src dell’alberatura dell’applicazione, ma [Link](input); } Micro Edition).
cosa ci aspettiamo da questa applicazione? Il nostro Java 2 Micro Edition è
un sottoinsieme della
obiettivo funzionale è realizzare un’applicazione e consente di visualizzare un oggetto di input sul piattaforma Java 2
business che possa essere scaricata ed installata sui display del dispositivo per fare in modo che l’utente Standard Edition
cellulari o sui palmari aziendali dei dipendenti e che possa inserire la stringa da ricercare, quando l’uten- alleggerito ed
consenta di effettuare ricerche all’interno della te preme il tasto di submit del dispositivo (verosi- ottimizzato per essere
rubrica aziendale. Per prima cosa quindi dovremo milmente dopo aver inserito il cognome da ricerca- compatibile con il
maggior numero di
implementare il metodo startApp() della Midlet che re) la stringa che ha inserito viene memorizzata e dispositivi elettronici
viene eseguito quando il controllore dei processi viene successivamente appesa all’url da raggiungere di consumo.
della macchina virtuale inizia l’esecuzione dell’ap- in una chiamata HTTP. La chiamata viene instrada- L’architettura di J2ME è
plicazione. Ecco il codice del metodo: ta all’applicazione remota attraverso il metodo composta da moduli
invokeServlet(String url) che si occupa di effettuare tra loro ortogonali: le
configurazioni ed i
public void startApp() throws una Request HTTP e stampare a video il pacchetto profili.
MIDletStateChangeException { di byte ricevuto nella Response. Per effettuare la Le configurazioni
display = [Link](this); connessione remota si utilizza un oggetto Connector determinano quale
menu = new List(“Rubrica Aziendale”, [Link]); che prende in input un parametro stringa che iden- virtual machine sarà
utilizzata su una
[Link](“Ricerca cognome”, null); tifica la URL da raggiungere. La URL dell’applicazio-
particolare classe di
[Link](exitCommand); ne multicanale è memorizzata in una stringa ester- dispositivi e poi, più
[Link](this); na ed è valorizzata in questo modo: nel dettaglio, i profili
mainMenu(); } determinano quali
String url = “[Link] moduli applicativi
potranno essere
La prima cosa che viene fatta all’interno del codice /Controller?Action=lista&cognome=”;
utilizzati all’interno di
della Midlet quindi è costruire un oggetto di inter- una particolare
faccia istanza della classe Display. Si tratta di un Come si vede l’URL è esattamente quello dell’appli- configurazione.
oggetto appartenente al package [Link]- cazione multicanale che gira (in questo caso) in L’architettura generale
[Link] che si occupa di gestire lo schermo del locale ed a questa viene passato il parametro della piattaforma J2ME
dispositivo attraverso API ad alto livello. Questo è di Action=lista che identifica il servizio che ci aspettia- è visibile in figura 2.
Le applicazioni J2ME
fatto il menù di primo livello della nostra Midlet, un mo dall’applicazione stessa. Al Controller viene prendono il nome di
menù dotato della sola voce “Ricerca cognome”. anche passato, per poter effettuare la ricerca, il para- Midlet e possono
Il listener dei comandi è realizzato attraverso l’invo- metro cognome= cui viene appeso il testo che l’uten- essere eseguite su
cazione di un oggetto Command su un oggetto te ha inserito all’interno del textbox della Midlet. qualsiasi dispositivo
visualizzabile (Displayable) ed il codice che imple- In questo modo l’applicazione multicanale potrà per il quale esista una
macchina virtuale
menta questo comportamento è il seguente: effettuare la query sul database e restituire, secondo J2ME.
le modalità che abbiamo visto in precedenza, il pac-
public void commandAction(Command c, Displayable d) { chetto di dati al dispositivo chiamante che non
String label = [Link](); dovrà far altro che visualizzarlo all’interno dell’og-

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/83 G
081-084 Mobile 4-10-2003 10:12 Pagina 84

PALMARI Multicanale: l’accesso remoto

getto Display. L’ultima cosa che ci rimane da fare è


implementare il metodo setRequestHeaders(Http-
Connection c) che si occuperà di valorizzare gli hea-
der della chiamata HTTP secondo lo schema classi-
co delle Midlet, cosa che non viene fatta, e questo
può essere un vantaggio, in automatico dalla mac-
china virtuale J2ME. Ecco il codice di questo meto-
do:

void setRequestHeaders(HttpConnection c) throws


IOException {
String conf = [Link]( Fig. 5: Inserimento dei criteri di ricerca.
RIASSUMENDO “[Link]”); Fig. 6: I risultati della ricerca restituiti dal servizio
Con questa serie di String prof = [Link](“[Link]”); remoto.
articoli abbiamo String locale = [Link](
analizzato a fondo lo
“[Link]”); ca voce disponibile, cioè la funzionalità di ricerca
sviluppo di applicazioni
multicanale toccando String ua = “Profile/” + prof + “ Configuration/” + conf; per cognome all’interno della rubrica aziendale.
aspetti di architettura [Link](“User-Agent”, ua); Quello che ci aspettiamo è che ci venga consentito
come il Pattern MVC e la if (locale != null) { di inserire il criterio di ricerca ed infatti, come se
piattaforma J2EE e [Link](“Content-Language”, locale); } vede in Fig. 5, la Midlet presenta un campo di testo
ragionando su
} nel quale inserire il cognome da ricercare. Pre-
tematiche concettuali
anche complesse come mendo il pulsante di Submit otterremo l’esecuzione
il dispositivo Il valore dello User-Agent per la nostra Midlet sarà
consumatore, il quindi il seguente:
protocollo di erogazione
ed il canale.
Profile/MIDP-1.0 Configuration/CLDC-1.0
Siamo partiti dal
realizzare
un’applicazione in
grado di erogare servizi
sui canali Web e Wap, TESTIAMO
poi con Axis abbiamo
reso i servizi applicativi
L’APPLICAZIONE
dei veri e propri Web Una volta inserito il codice della Midlet all’interno
Services. In questa del file [Link] possiamo compilare
ultima puntata abbiamo l’intera Midlet attraverso il pulsante Build presente
aggiunto il canale sulla KTollbar. Il risultato dovrebbe essere “Build
mobile di nuova
generazione, J2ME,
Complete” che identifica il successo della compila-
indipendente dalla zione senza errori. A questo punto possiamo sele-
piattaforma, dal zionare tra quelli disponibili il dispositivo all’interno
dispositivo e dalla Fig. 7: Gli stessi risultati su un palmare collegato al
del quale emulare la Midlet e premere il pulsante servizio remoto.
modalità di Run, otterremo l’esecuzione dell’emulatore con la
comunicazione, sia essa
GSM, GPRS, UMTS o 4G.
Midlet già pronta. In Fig. 3 la nostra applicazione
Non resta che J2ME eseguita all’interno dell’emulatore Default della chiamata all’applicazione multicanale che sarà
sperimentare e Color Phone e ci permette di selezionare l’unica in grado di riconoscere il canale J2ME e ci restituirà
realizzare le proprie Midlet a disposizione, cioè TestRubrica. A questo la lista di tutti i nominativi compatibili con il criterio
architetture tenendo punto la Midlet parte (Fig. 4) e viene mostrato il di ricerca che abbiamo inserito. Questa lista verrà
sempre presente i
principi di massima
menù di primo livello nel quale selezioniamo l’uni- presentata direttamente sul display del telefonino e
flessibilità senza legarsi sarà navigabile direttamente come si può vedere in
troppo al canale di Fig. 6. Naturalmente la nostra Midlet si può far gira-
erogazione e tenendo re su qualsiasi dispositivo compatibile J2ME, sia
presente che il mobile è esso un telefono cellulare, un palmare, uno smart-
dietro l’angolo e le
nostre applicazioni
phone, un orologio, una macchina fotografica o
devono essere pronte a qualsiasi dispositivo dotato della possibilità di con-
supportarlo senza nettersi alla rete sulla quale si trova in esecuzione
essere stravolte. l’applicazione multicanale che fornisce il servizio. In
Fig. 7, per esempio, il risultato della ricerca effettua-
ta su un Palm m515, dispositivo per il quale esiste
Fig. 3: Lanciamo la nostra Midlet. un’ottima implementazione del profilo MIDP.
Fig. 4: Selezione della voce di menu. Massimo Canducci

h t t p : / / w w w. i o p r o g r a m m o . i t
G 84/Novembre 2003
085-088 Java_Base 4-10-2003 10:14 Pagina 85

Java CORSI BASE

Testiamo la nostra abilità nel risolvere alcuni problemi

Dalla ‘a’ alla ‘z’


E’ venuto il momento di applicare quello che hai imparato nei mesi
scorsi a qualche problema un po’ più interessante. Ma prima dovrai
sottoporti alla solita badilata di cultura e imparare un po’ di roba
nuova.

R
iassunto della puntata precedente. Tanto per non lo fai ti sarà facile sbagliare. Ad esempio potresti
darti una rinfrescata, ti propongo un esercizio trovarti ad usare un “minore” dove invece avresti
molto semplice: dovuto usare un “minore o uguale”.
L’istruzione while è per ora l’unico modo che cono-
Esercizio 1: Scrivi un programma che usa un ciclo sci per costruire un ciclo. In alcuni casi è il modo
while per stampare un conto alla rovescia da 10 a 0. ideale. Ad esempio puoi usare un ciclo while per dire
facilmente cose come: “resta in ascolto su questa
Se ricordi bene l’articolo del mese scorso non dovre- porta di comunicazione fino a quando non ricevi un
sti avere difficoltà. Ecco una soluzione: comando di questo tipo”. Ma quando il ciclo si basa
su un semplice contatore che viene incrementato o
❏ CD ❏ WEB
[Link]
class Countdown { decrementato, come quello che hai appena visto, ti
[Link]
public static void main(String[] args) { conviene di solito usare un’altra istruzione: l’istru-
int i = 10; zione for.
while(i >= 0) {
[Link](i);
i--;
}
PASSO PER PASSO OBIETTIVI
} La sintassi dei cicli for non è particolarmente bella DI QUESTA
} da vedere. Purtroppo ci tocca tenercela così com’è (è LEZIONE
una sintassi che deriva dal linguaggio C, che non è Ecco cosa ti aspetta
questo mese:
La condizione del while è che i sia maggiore o ugua- noto per la sua leggibilità). Un ciclo for è fatto così:
le a 0 (questo è il significato dell’operatore ‘>=’). Farai la conoscenza di
L’operatore di decremento, che si scrive con un dop- for(inizializzazione; condizione; passo) una nuova istruzione
pio segno “meno”, è il compagno di quello di incre- istruzione per costruire cicli.
mento che hai conosciuto il mese scorso.
L’istruzione “i--” equivale quindi a “i=i-1”. Il resto del L’inizializzazione consiste di solito nella definizio- Studierai il
meccanismo del
codice dovrebbe esserti familiare. ne/inizializzazione di una variabile. La condizione è casting.
Diamo un’occhiata al ciclo, per essere sicuri di non quella che deve essere soddisfatta per entrare nel
aver sbagliato niente. Appena entriamo nel ciclo la ciclo. Il passo è un’istruzione che viene eseguita alla Ti cimenterai con
variabile i vale 10. Quindi il programma stampa “10” fine di ogni ciclo. Ad esempio, ecco un ciclo che qualche esercizio
e decrementa i. Cosa succede quando stiamo per stampa il contenuto di un array di nome a: abbastanza
impegnativo.
uscire dal ciclo? Quando i vale 1, il valore viene stam-
pato e i diventa 0. La condizione del ciclo (i>=0) è for(int i = 0; i < [Link]; i++) Ti consiglio di seguire
ancora soddisfatta. Quindi il programma entra nel [Link](a[i]); questo articolo davanti
ciclo un’ultima volta, stampa “0” e decrementa i, che a un computer. Usa un
ora vale -1. A questo punto la condizione del ciclo L’inizializzazione definisce una variabile i e le asse- computer soprattutto
quando cerchi di
non è più soddisfatta, perché i è minore di 0. Quindi gna il valore 0. Il passo incrementa i al termine di risolvere gli esercizi,
il programma esce dal ciclo. ciascun ciclo. La condizione dice: “esegui questo che ormai sono troppo
Abbiamo ragionato sulle condizioni limite del ciclo: ciclo fintanto che i è minore della lunghezza dell’ar- complicati per
cosa succede quando il ciclo inizia, e cosa succede ray a”. risolverli “a mente”.
quando il ciclo sta per finire. Questo modo di ragio- Ragioniamo sulle condizioni limite. All’inizio i vale
nare ti diventerà familiare. Dovresti ragionare sulle 0, quindi viene stampato l’elemento a[0]. L’ultimo
condizioni limite ogni volta che scrivi un ciclo. Se elemento che viene stampato è a[[Link] - 1], cioè

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/85 G
085-088 Java_Base 4-10-2003 10:14 Pagina 86

CORSI BASE Java

l’ultimo elemento dell’array (se la lunghezza di a è Se hai buona memoria, forse ricordi che abbiamo
10, il suo ultimo elemento è a[9]). Subito dopo i rapidamente introdotto il tipo char (carattere) un
diventa uguale ad [Link], quindi la condizione paio di mesi fa. Le costanti carattere si mettono tra
non è più soddisfatta e si esce dal ciclo. Se l’array singoli apici:
avesse lunghezza nulla, la condizione non sarebbe
mai verificata (sia i che [Link] varrebbero 0), e char c = ‘x’;
tutto il ciclo verrebbe semplicemente ignorato. Il
ciclo è composto da una sola istruzione, ma natural- Ricorda che un carattere non è una stringa di lun-
mente puoi sempre usare un blocco delimitato da ghezza uno; è proprio un tipo a sé stante. Una cosa
parentesi graffe per eseguire più istruzioni per cia- interessante è che ciascun carattere è rappresentato
scun “passo”. da un codice Unicode. Nello standard Unicode, a
Puoi sempre scegliere tra for e while, a seconda della ciascun “codice” (un numero intero tra 1 e 65535)
NON forma che ti sembra più chiara e leggibile in ciascu- corrisponde un carattere univoco.
SEMPRE SI PUÒ na circostanza. Il ciclo che hai appena visto scritto Dato che un carattere è anche un codice numerico,
Non sempre è possibile equivale quasi esattamente a questo (tra poco ti possiamo usarlo in un’espressione aritmetica:
fare un cast, anche se spiegherò perché ho detto “quasi”):
esplicito. Ad esempio
[Link](‘a’ + 1);
Java non permette di
fare nessun tipo di cast int i = 0;
tra il tipo boolean e while(i < [Link]) { Questa istruzione stampa un risultato inatteso: il
qualsiasi altro tipo. Un [Link](a[i]); numero 98. Perché? Cerchiamo di capire come ra-
boolean è sempre un i++; giona il sistema. L’espressione somma il carattere ‘a’,
boolean, e non lo si
} che nello standard Unicode corrisponde al codice
può convertire:
97, con il numero intero 1. Come si fa a sommare un
int x = (int)true; // errore In questo caso la versione del ciclo che usa il for è carattere ad un numero? In queste situazioni il siste-
boolean b = (boolean)0; probabilmente più leggibile di quella che usa il while ma deve operare una conversione di formato, cioè
// errore – almeno per chi è abituato a leggere entrambe le trasformare un valore da un tipo ad un altro tipo. Nel
sintassi. nostro esempio trasforma il primo operando dal
L’unica differenza tecnica tra le due forme di questo tipo char al tipo int (usando il suo codice di caratte-
ciclo ha a che fare con la visibilità delle variabili. Nel re Unicode) e fa la somma.
caso del ciclo for, la variabile i viene definita all’in- Questa conversione automatica avviene anche in
terno del ciclo (il contenuto delle parentesi tonde si molti altri casi. Ad esempio, se chiedi a Java di con-
PERDERE considera una parte del ciclo). Quindi la sua visibi- catenare una stringa con un numero:
PEZZI lità si estende solo al ciclo e la variabile esce dallo
Non è un caso se il “scope” alla fine del ciclo. Se provi a leggere il valore [Link](“10” + 12);
compilatore non si di i al termine del ciclo il compilatore dichiarerà di
assume la
responsabilità di alcuni
non conoscere la variabile: Qual è il risultato di questa stampa? Il sistema avreb-
casting e ci costringe be due possibilità: o trasforma la stringa in un inte-
ad usare un cast for(int i = 0; i < [Link]; i++) ro, o trasforma l’intero in una stringa. Il risultato
esplicito: in questi casi, [Link](a[i]); sarebbe completamente diverso nei due casi, anche
infatti, è possibile
[Link](i); // errore! perché il simbolo ‘+’ può rappresentare due opera-
perdere informazioni.
Ad esempio:
tori diversi a seconda del contesto: quando gli ope-
Nel caso del while, invece, la variabile i è definita randi sono stringhe, il ‘+’ rappresenta l’operatore di
[Link]((int)1 all’esterno del ciclo, quindi resta visibile anche concatenazione tra stringhe; quando gli operandi
2.9); quando il ciclo è finito. sono numerici, il ‘+’ rappresenta l’operatore di
somma. Quindi se il sistema decidesse di convertire
Questa riga stampa Esercizio 2: Riscrivi il programma Countdown usan- la stringa in un numero il risultato stampato sullo
sullo schermo il
numero 12, che è il
do un ciclo for invece del ciclo while. schermo sarebbe 22; se invece decidesse di conver-
risultato della tire il numero in una stringa il risultato sarebbe
conversione forzata del “1012”. Se vuoi puoi fare tu stesso l’esperimento, ma
double 12.9 al tipo int. posso dirti subito che il risultato è “1012”. Quindi il
Nota che il numero non UN TIPO sistema converte il numero in una stringa. Per quale
è stato arrotondato
all’intero più vicino,
DI CARATTERE motivo Java fa sempre questa scelta e non quella
ma semplicemente e Ora vorrei usare l’istruzione for per risolvere un opposta? Prima di tutto perché capita più spesso di
brutalmente troncato. nuovo problema: stampare tutte le lettere dell’alfa- convertire i numeri in stringhe (ad esempio per
beto in sequenza. Ma per fare questo devo prima stampare dei risultati sullo schermo) che non vice-
parlarti un po’ del tipo char, che finora non abbiamo versa. Pensa a un caso comune come questo:
mai usato. Questa digressione ci porterà a toccare
un argomento nuovo e importante: il casting. [Link](“La variabile x vale: ” + x);

h t t p : / / w w w. i o p r o g r a m m o . i t
G 86/Novembre 2003
085-088 Java_Base 4-10-2003 10:14 Pagina 87

Java CORSI BASE

Ma esiste anche un altro motivo, forse più impor- 65535) in un intero, ma non sempre è possibile con-
tante: mentre è sempre possibile convertire un vertire un intero (che può valere decine di milioni) in
numero in una stringa, non sempre è possibile fare un carattere. Quindi quando converto un int in char
il contrario (pensa ad una stringa che contiene dei potrei superare i limiti del tipo char. Il compilatore
caratteri alfabetici). Quindi il comportamento stan- non può sapere quale valore assumeranno le espres-
dard di Java è quello di convertire i numeri in strin- sioni in fase di esecuzione, quindi per sicurezza mi
ghe nelle espressioni “miste”. ferma sempre. Questo principio vale in molte altre
Questa conversione automatica da un tipo all’altro è circostanze:
una caratteristica importante del linguaggio, e la
vedrai diventare sempre più importante man mano float f = 12.0; // errore
che imparerai cose nuove. La conversione di tipo si
chiama casting. Quando viene fatta automatica- Le costanti numeriche con la virgola sono interpre- ARRAY IN
mente da Java, come nel caso che abbiamo visto, si tate dal compilatore come dei double. Se cerchi di QUATTRO E
chiama cast implicito. infilare un double in un meno capiente float, il com- QUATTR’OTTO
pilatore ti avvisa che rischi di perdere informazioni. Di solito inizializzare
Lo stesso vale, ad esempio, se cerchi di mettere un un array è
un’operazione
valore long in una variabile int. Come risolvere que-
TRA DUE TIPI sto problema? Visto che il compilatore “non si assu-
piuttosto noiosa:

Torniamo ai caratteri. Vogliamo costruire un array me responsabilità”, questa responsabilità ricade su int[] a = new int[3];
che contiene le 26 lettere dell’alfabeto anglosassone. noi programmatori. Dobbiamo essere noi a sapere a[0] = 12;
Possiamo riempire l’array con un ciclo for: che il valore assegnato non può superare i limiti a[1] = 2 + 2;
della variabile alla quale lo assegniamo. Se sai che la a[2] = 137;

char[] alfabeto = new char[26]; conversione è innocua (o se non ti interessa perdere


Java però ha anche una
for(int i = 0; i < [Link]; i++){ parte delle informazioni) puoi forzarla con un cast sintassi speciale per
<…> esplicito. Ecco quale sintassi devi usare: rendere il compito più
} facile.
float f = (float)12.0; // OK (casting esplicito)
Come facciamo ad assegnare a ciascun elemento int[] a = {12, 2 + 2,
137};
dell’array il carattere corrispondente? Possiamo Quindi possiamo riempire l’array in questo modo:
approfittare del fatto che nello standard Unicode le Grazie alle parentesi
lettere dell’alfabeto sono già nella sequenza giusta. char[] alfabeto = new char[26]; graffe ho detto due
In realtà esistono due sequenze distinte, una per le for(int i = 0; i < [Link]; i++) cose in un colpo solo:
lettere minuscole (che parte da ‘a’) e una per le alfabeto[i] = (char)(‘a’ + i); che l’array ha tre
maiuscole (che parte da ‘A’). Noi useremo le minu- elementi, e quali sono i
valori iniziali di questi
scole. Una semplice soluzione può essere quella di Nota che ho dovuto mettere tra parentesi anche elementi. Puoi usare
assegnare all’elemento alfabeto[i] il carattere otte- tutta l’espressione (‘a’ + i). Se non lo avessi fatto, il questa sintassi solo nel
nuto sommando il valore di i al codice del carattere mio cast esplicito avrebbe riguardato solo sulla punto in cui dichiari
‘a’. In questo modo l’elemento alfabeto[0] avrà valo- costante ‘a’, perché l’operatore di casting ha la pre- l’array, quindi non puoi
re ‘a’, alfabeto[1] avrà valore ‘b’ e così via fino ad alfa- cedenza sull’addizione. Il risultato sarebbe stato usare le parentesi
graffe per assegnare
beto[25], che avrà valore ‘z’. Proviamo: un’inutile “conversione” da char a char, e il solito nuovi valori ad un
errore di compilazione sull’assegnamento. array già inizializzato.
for(int i = 0; i < [Link]; i++){
alfabeto[i] = ‘a’ + i; // errore!
}
MANTIENITI
Il compilatore mi ha dato un inatteso errore di com- IN ESERCIZIO ASCII DEI
pilazione. Perché? Per questo mese hai imparato abbastanza. E’ il TEMPI ANDATI
Il problema sta nel casting. Nell’espressione ‘a’ + i, il momento di cimentarti con qualche esercizio. Lo standard Unicode è
char viene convertito automaticamente in un int un’estensione del
vecchio standard ASCII,
prima di fare la somma. Il risultato della somma dei Esercizio 3: Scrivi un programma che: che prevedeva solo 256
due int è un int. Fin qui tutto bene. A questo punto, possibili caratteri ed
però, l’intero risultante viene assegnato ad una 1) riempie un array di char di nome alfabeto era insufficiente
variabile di tipo char (un elemento dell’array alfabe- con le lettere dell’alfabeto; quando si prendevano
to). Ora, alcuni casting vengono fatti automatica- in considerazione
lingue diverse
mente. Altri invece no. Ad esempio, mentre la con- 2) crea un nuovo array di nome otebafla; dall’inglese.
versione da char a int è automatica, la conversione
da int a char non lo è. Questo perché è sempre pos- 3) riempie otebafla con il contenuto di alfabe-
sibile convertire un carattere (che al massimo vale to al contrario (da ‘z’ ad ‘a’);

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/87 G
085-088 Java_Base 4-10-2003 10:14 Pagina 88

CORSI BASE Java

4) stampa sullo schermo il contenuto di ote- “pseudocasuale”, compreso tra 0.0 (incluso) e 1.0
bafla. (escluso). Il numero viene restituito sotto forma di
double. Ad esempio, prova a far girare questo pro-
Esercizio 4: Scrivi un programma che: grammino:

1) riempie un array di char di nome alfabeto class Random {


con le lettere dell’alfabeto; public static void main(String[] args){
for(int i = 0; i < 4; i++){
2) riempie un array di int di nome numeri con double d = [Link]();
i numeri da 110 a 120; [Link](d + “ “); } }
}
3) crea un nuovo array di char di nome molti-
Caratteri, grande come alfabeto e numeri Una delle prove che ho fatto io ha generato questo
messi insieme; output:

UN CICLO 3) riempie moltiCaratteri con il contenuto di 0.0035210922116278853 0.02310674969913329


DENTRO alfabeto seguito da quello di numeri (il con- 0.9117132792043209 0.83098815566099
UN CICLO tenuto di numeri deve essere convertito in
Nella mia soluzione caratteri); Prova a risolvere l’esercizio 5 usando [Link]()
all’ultimo esercizio per generare degli indici casuali per il primo array.
(che trovi solo sul CD)
ho usato due cicli
4) stampa sullo schermo il contenuto di Ricorda che [Link]() non genera mai il valo-
“annidati”, cioè un moltiCaratteri. re 1.0. Ecco il cuore della mia soluzione:
ciclo all’interno di un
altro ciclo. Volevo Se riesci a risolvere questi esercizi (o se ne hai capito char[] qualcheLettera = new char[10];
stampare due la soluzione dopo aver sbirciato sul CD) puoi affron- for(int i = 0; i < [Link]; i++){
“sillabe”, ciascuna
tarne uno un po’ più complicato: // crea un indice random compreso tra 0 e
composta da una
vocale seguita da due [Link]-1
lettere qualsiasi. Esercizio 5: Scrivi un programma che: int indiceRandom = (int)([Link]()
Quindi ho scritto due * [Link]);
cicli che vanno da 1 a 1) riempie un array di nome alfabeto con le // inserisci nell’array qualcheLettera un elemento scelto
2: il più esterno genera
lettere dell’alfabeto (e questo ormai lo sai // a caso dall’array alfabeto
un’intera sillaba, il più
interno genera una fare); qualcheLettera[i] = alfabeto[indiceRandom];
lettera qualsiasi: }
2) crea un nuovo array di nome qualcheLet-
for(int i = 1; i <= 2; tera composto da soli 10 elementi; Concludiamo con un esercizio un po’ più interes-
i++){ sante:
<stampa una vocale> 3) seleziona dieci lettere a caso da alfabeto
for(int j = 1; j <= 2; (anche ripetute) e le usa per riempire qual- Esercizio 6: Scrivi un “generatore di parole casuali”
j++) cheLettera; che stampa dieci parole casuali sullo schermo. Ogni
<stampa una lettera parola deve essere composta da 8 lettere, in questo
qualsiasi> 4) stampa sullo schermo il contenuto di qual- ordine: una lettera qualsiasi, una “sillaba”, una
} cheLettera. seconda sillaba, una vocale. Una sillaba deve essere
composta da una vocale seguita da due lettere qual-
Nei cicli for si usa Qui incontri per la prima volta il concetto di casua- siasi. Sia le vocali che le lettere qualsiasi devono esse-
spesso una variabile di
controllo di nome i,
lità, che fino ad ora non avevamo mai tirato in ballo. re scelte a caso.
che sta per “indice”. Il modo più semplice per generare numeri casuali in
Se servono altre Java è usare la funzione [Link](). Le funzioni Questo è un esercizio interessante, perché dovrai
variabili di controllo sono un argomento piuttosto complesso, che per creare due vettori: uno che contiene tutte le lettere
(ad esempio per ora non abbiamo trattato (ne parleremo abbondan- dell’alfabeto, e uno che contiene solo le vocali. Puoi
costruire più cicli
annidati) si usano di
temente nei prossimi due mesi, quando comincere- trovare la mia soluzione sul CD (si chiama Pa-
solito i nomi j e k. mo ad affrontare la programmazione orientata agli [Link]). Prova comunque a risolverlo
oggetti). Le uniche funzioni che hai visto finora sono da solo, e non scoraggiarti se ti ci vorrà un po’ di
quelle che stampano sullo schermo: [Link]. tempo. Ne sarà valsa la pena: non capita tutti i gior-
println() e la sua gemella che non va a capo, System. ni di sviluppare un utile programmino che genera
[Link](). parole interessanti come “wakjurde”, “uazoodao” o
La funzione [Link]() è un po’ diversa: ogni “caskulti”. Buon divertimento, e arrivederci al mese
volta che scrivi [Link]() il sistema calcola un prossimo!
numero casuale, o come dicono i più precisini Paolo Perrotta

h t t p : / / w w w. i o p r o g r a m m o . i t
G 88/Novembre 2003
89-92_Corso_VB.NET 4-10-2003 10:15 Pagina 89

Visual Basic .NET CORSI BASE

Presentare informazioni in un elenco “elegante”

La gestione
del controllo ListView
Il controllo ListView consente di presentare all’utente informazioni
sotto forma di elenco, utilizzando le immagini memorizzate
nel controllo ImageList, per renderle più esplicite.

I
n questo articolo presenteremo il controllo, cer- riferimento, si dovrà utilizzare soltanto il relativo
tamente più utilizzato per mostrae all’utente indice numerico. In pratica espone una collezione di
informazioni sotto forma di elenco: il ListView. oggetti Image, contenenti ciascuno un’immagine, la
Le informazioni presentate nel controllo, general- collezione Images (sostituisce la collezione ListIma-
mente presentano, di fianco, un’icona che può esse- ges di VB6), essa deriva dall’interfaccia di base Ilist,
re memorizzata in un controllo ImageList. Infine, perciò si possono utilizzare gli usuali Add e Remove
come di consueto, descriveremo una semplice rispettivamente per aggiungere o eliminare immagi-
applicazione per gestire una videoteca in modo da ni da codice in fase di progettazione, si può fare rife-
chiarire i concetti presentati nell’articolo. rimento ad ogni oggetto Image utilizzando l’indice ❏ CD ❏ WEB
numerico nel metodo Item. Per aggiungere immagi- \[Link]
ni a livello di programmazione, si deve tener presen- [Link]
te che il metodo Add accetta oggetti di tipo Image,
IL CONTROLLO per questo si può utilizzare il metodo FromFile che
IMAGELIST crea un oggetto Image dal file specificato, pertanto,
Il controllo ImageList (elenco immagini), contiene per inserire nel controllo un’immagine di esempio si
un insieme d’immagini visualizzabili da tutti i con- può scrivere:
trolli di VB .NET che espongono la proprietà Image- COLORDEPTH
List. Un elenco immagini consente di ridurre i tempi ‘si deve scrivere l’intero path valido del file Possibili valori
dell’Enumerazione
di sviluppo, poiché è possibile scrivere codice che fa Dim myImage As [Link] =
ColorDepth che
riferimento ad un unico catalogo di immagini; si [Link](“C:\[Link]”)
permette di specificare
tratta di un controllo “invisibile” in fase di esecuzio- [Link](myImage) il numero di colori
ne, perciò, per visualizzare le immagini che esso utilizzati per
contiene, deve essere associato ad altri controlli, lo Le proprietà peculiari del controllo sono: visualizzare
potremo definire un controllo di servizio per altri un’immagine in un
controllo ImageList.
controlli. Per aggiungere immagini in fase di proget- La proprietà TransparentColor (che sostituisce
tazione si deve: MaskColor). Serve per definire il colore che deve Depth4Bit - definisce
diventare trasparente quando si sovrappone un’im- un’immagine a 4 bit
Cliccare sul pulsante con i tre puntini accanto alla magine a un’altra.
proprietà (collezione) Images, in questo modo si La proprietà ColorDepth. Consente di definire il Depth8Bit - definisce
un’immagine a 8 bit
visualizza la finestra Editor dell’insieme Image, il cui numero di colori da utilizzare per riprodurre le
semplice utilizzo permette di popolare il controllo. immagini (4, 8, 16, 24 o 32 bit) Depth16Bit - definisce
Nella finestra Editor dell’insieme Image si deve clic- La proprietà ImageSize. Consente di definire le di- un’immagine a 16 bit
care sul pulsante Aggiungi, per selezionare, dalla mensioni dell’immagine all’interno del controllo. Le
finestra di dialogo, le immagini da aggiungere al con- eventuali immagini più grandi sono adattate in scala. Depth24Bit - definisce
un’immagine a 24 bit
trollo. Utilizzando le freccette si può variare la po-
sizione e quindi l’indice delle immagini. Con il pul- Per associare l’elenco immagini ad un controllo, si Depth32Bit - definisce
sante Rimuovi si elimina un’immagine dall’elenco. deve impostare la proprietà ImageList del controllo un’immagine a 32 bit
in base al nome del componente ImageList (come
Rispetto a VB6 non è più possibile assegnare una vedremo in seguito). In pratica, se si associa un con-
chiave di tipo stringa all’immagine, perciò, per farvi trollo ImageList ad un altro controllo, non sarà

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/89 G
89-92_Corso_VB.NET 4-10-2003 10:15 Pagina 90

CORSI BASE Visual Basic .NET

necessario scrivere nessuna riga di codice poiché La proprietà SmallImageList consente di associare
tutto avviene automaticamente. Per l’applicazione al ListView un controllo ImageList da utilizzare per
di esempio, che descriveremo nel proseguo dell’arti- visualizzare immagini in modalità List, Details e
colo, popoliamo il controllo con le icone corrispon- SmallIcon.
denti al semaforo verde, rosso e giallo che di norma La proprietà StateImageList, consente di associare
si trovano nella directory di installazione di Visual al ListView un controllo ImageList, da utilizzare per
Studio .NET nella cartella \Common7\Graphics\ visualizzare immagini che rappresentano lo stato di
icons\Traffic. un elemento del ListView (ad esempio lo stato di
selezionato nella modalità CheckBoxes pari a True).
Le immagini di stato vengono visualizzate a sinistra
dell’icona posta accanto ad ogni elemento, sono vi-
IL CONTROLLO sibili in tutte le visualizzazioni disponibili del con-
LISTVIEW trollo ListView. Per visualizzare le immagini si deve:
Il controllo ListView (Controllo Visualizzazione
Elenco), è uno dei controlli più interessanti ed utili. Impostare la proprietà appropriata (SmallImage-
IMAGELIST Per avere subito un esempio di utilizzo del controllo List, LargeImageList o StateImageList) sul controllo
Il controllo ImageList ListView in Windows, è sufficiente aprire la finestra ImageList che si ha intenzione di utilizzare. In fase di
può essere utilizzato Esplora risorse in cui la parte destra dell’elenco dei progettazione è sufficiente visualizzare la finestra
con i controlli che
espongono la proprietà
file non è altro che un ListView. Il controllo espone delle proprietà e selezionare dall’elenco a discesa,
ImageList oppure, nel due rilevanti oggetti collezione: accanto alle proprietà corrispondenti, uno tra i con-
caso del controllo trolli ImageList presenti nella form. Da codice si può
ListView, delle • La collezione Items di oggetti ListViewItem scrivere ad esempio:
proprietà che rappresenta ogni elemento visualizzato.
SmallImageList e
• La collezione Columns di oggetti ColumnHea- [Link] = ImageList1
LargeImageList. In
particolare può essere der che rappresenta ogni colonna con la relati-
associato ai controlli va intestazione. Impostare la proprietà ImageIndex (o StateImage-
ListView, TreeView, Index) di ciascun elemento del ListView con l’icona
ToolBar, TabControl, È disponibile, inoltre, la collezione SelectedItems che associata. In fase di progettazione, si deve visualiz-
Button, CheckBox,
RadioButton e Label
contiene gli elementi selezionati nel controllo. Il zare l’editor dell’insieme ListViewItem cliccando sul
controllo ListView consente di mostrare i dati, in pulsante con i tre puntini di sospensione accanto
esso contenuto, attraverso quattro modalità di vi- alla proprietà Items nella finestra delle proprietà, e
sualizzazione, semplicemente modificando la pro- selezionare un’icona (tra quelle presenti nell’Image-
prietà View con una delle seguenti costanti: List associato) dalla proprietà ImageIndex.
Da codice si può scrivere:
LargeIcon modo icone grandi - Permette di visua-
lizzare icone grandi sopra al testo dell’elemento. Gli [Link](0).ImageIndex = 1
elementi sono disposti in più colonne (se le dimen-
IMAGESIZE sioni del controllo lo consentono) Analizziamo ora alcune delle proprietà peculiari del
La proprietà ImageSize SmallIcon modo icone piccole - Permette di visua- controllo:
permette di impostare lizzare icone piccole accanto al testo dell’elemento.
la dimensione delle
immagini
Gli elementi sono disposti in più colonne (se le AutoArrange permette di specificare se le icone ven-
nell’ImageList agendo dimensioni del controllo lo consentono) gono disposte automaticamente e bloccate sulla gri-
sull’’oggetto Size che List modo elenco - Permette di visualizzare icone glia. Questa proprietà ha effetto soltanto nelle mo-
rappresenta le piccole accanto al testo dell’elemento. Gli elementi dalità LargeIcon e SmallIcon.
dimensioni di un’area sono disposti in un’unica colonna. AllowColumnReorder in modalità Details, se impo-
rettangolare definendo
altezza e larghezza
Details modo dettaglio - Permette di visualizzare gli stata a True, permette all’utente di modificare l’ordine
delle immagini elementi in più colonne. Soltanto in questa modalità delle colonne, trascinando le rispettive intestazioni;
nell’elenco. L’altezza e saranno visualizzate le colonne con le relative inte- CheckBoxes permette di visualizzare, all’interno del
la larghezza stazioni. ListView, le caselle CheckBox, in modo da poter sele-
predefinite sono zionare con il segno di spunta alcune righe;
16x16. La dimensione
massima è 256x256.
In tutte le modalità è possibile visualizzare le imma- FullRowSelect per dare la possibilità di selezionare
gini contenute in un controllo ImageList, in partico- l’intera riga (solo in modalità Details);
lare possono essere visualizzate immagini incluse in GridLines per visualizzare una griglia tra le righe e le
tre controlli ImageList diversi. colonne contenenti gli elementi nel ListView (in
visualizzazione Details);
La proprietà LargeImageList consente di associare Activation per indicare se un elemento del ListView
al ListView un controllo ImageList da utilizzare per può essere attivato con uno oppure due clic del
visualizzare immagini in modalità Icone grandi. mouse;

h t t p : / / w w w. i o p r o g r a m m o . i t
G 90/Novembre 2003
89-92_Corso_VB.NET 4-10-2003 10:15 Pagina 91

Visual Basic .NET CORSI BASE

HoverSelection per consentire di selezionare, auto- Add(testo, larghezza, allineamento)


maticamente, un elemento del ListView quando il
puntatore del mouse viene posizionato per alcuni Ognuna di queste proprietà può essere impostata
secondi su di esso; anche separatamente, ad esempio con le seguenti
MultiSelect consente la selezione multipla di più linee di codice:
elementi del ListView.
[Link] = [Link]
[Link] = [Link] \ 3

LE COLONNE naturalmente queste istruzioni devono essere ripe-


DEL LISTVIEW tute per ogni oggetto ColumnHeader.
Per creare in fase di progettazione le colonne (ogget- ACTIVATION
ti ColumnHeader) del ListView, si deve cliccare sul La proprietà Activation
pulsante con i tre puntini accanto alla proprietà permette di
(collezione) Columns, in modo da visualizzare la fi-
GLI OGGETTI selezionare il tipo di

nestra Editor dell’insieme ColumnHeader. Premere LISTVIEWITEM azione che l’utente


deve eseguire per
il pulsante Aggiungi e digitare i valori della proprietà: Dopo aver definito l’aspetto del ListView la cosa più attivare un elemento
importante è riempirlo di dati, per mezzo dell’ogget- nel ListView. Le
Text; - consente di inserire il testo visualizzato nel- to ListViewItem. Per creare nuovi elementi del possibili opzioni sono:
Standard, OneClick e
l’intestazione delle colonne; ListView in fase di progettazione si deve cliccare sul TwoClick. L’opzione
TextAlign; - consente di specificare l’allineamento pulsante con i tre puntini accanto alla proprietà OneClick richiede un
degli elementi della colonna, i possibili valori sono: (collezione) Items in modo da visualizzare la finestra solo clic del mouse per
Editor dell’insieme ListViewItem. Premere il pulsan- attivare l’elemento.
L’opzione TwoClick,
• Left - allineamento a sinistra; te Aggiungi e digitare i valori delle proprietà:
richiede che l’utente
• Right - allineamento a destra; faccia doppio clic per
• Center - allineamento centrato; • Text contiene il testo presente nel ListView; attivare l’elemento,
• Width; - larghezza della colonna. • Font consente di selezionare il tipo di carat- mentre un solo clic
tere visualizzato nel ListView; modifica il colore del
• BackColor e ForeColor consentono di defini- testo dell’elemento.
Sarà possibile referenziare le colonne appena inseri-
L’opzione Standard
te, tramite l’indice numerico visualizzato a sinistra re i colori di sfondo e del testo di ogni sin- richiede che l’utente
del nome della colonna. golo elemento. faccia doppio clic per
attivare l’elemento,
Per aggiungere sottoelementi è sufficiente cliccare senza modificarne
l’aspetto.
INTESTAZIONE sui tre puntini a destra della proprietà (collezione)
SubItems. Anche in questo caso è possibile modifi-
DELLE COLONNE care l’aspetto di ogni singolo sottoelemento. Un og-
IN FASE D’ESECUZIONE getto ListViewItem è costituito da testo, dall’indice di
La creazione ed intestazione delle colonne può un’icona (ImageIndex) associata tramite il controllo
avvenire anche in fase d’esecuzione. Ad esempio de- ImageList e, nella visualizzazione Details, da una col-
finiamo la procedura IntestaColonne, per popolare lezione di oggetti ListViewSubItem che rappresenta-
la collezione Column. In essa dichiariamo la varia- no i sottoelementi. Per aggiungere nuovi elementi si
bile colX di tipo ColumnHeader. deve utilizzare il metodo Add della collezione List-
ViewItems CHECKBOXES
Private Sub IntestaColonne() Impostando la
proprietà CheckBoxes a
‘dichiarazione della variabile di tipo ColumnHeader [Link](“prova”)
True e specificando un
Dim colX As ColumnHeader
controllo ImageList per
‘L’istruzione With consente di eseguire una serie di Per creare un oggetto ListViewSubItem, e popolare il la proprietà
istruzioni su un oggetto specificato senza ListView nella visualizzazione Details, è necessario StateImageList, le
riqualificare il nome dell’oggetto utilizzare il classico metodo Add. Naturalmente immagini con indice 0
e 1 vengono
With [Link] anche per i SubItem vale la regola che il numero di
visualizzate
colX = .Add(“Titolo”, 100, [Link]) oggetti ColumnHeader determina il numero di rispettivamente al
colX = .Add(“Regista”, 100, [Link]) oggetti ListViewSubItem che è possibile impostare posto della casella di
colX = .Add(“Durata”, 100, [Link]) per l’oggetto ListItem. controllo non
End With In particolare il numero di oggetti ListViewSubItem è selezionata e della
casella di controllo
End Sub sempre inferiore di uno rispetto al numero di ogget-
selezionata.
ti ColumnHeader, poiché il primo oggetto Column-
Per aggiungere un elemento alla collezione Column Header è sempre associato alla proprietà Text del-
si deve utilizzare il metodo Add: l’oggetto ListViewItem.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/91 G
89-92_Corso_VB.NET 4-10-2003 10:15 Pagina 92

CORSI BASE Visual Basic .NET

aggiunge un nuovo ListViewItem nella collezione


UNA SEMPLICE Items, ed ha come effetto di visualizzare il testo con-
VIDEOTECA tenuto (il titolo del film) in un nuovo rigo del List-
Realizziamo una semplice applicazione che mostri View (sotto la prima colonna). Per visualizzare l’ico-
l’elenco dei film della nostra videoteca con accanto na corrispondente alla visibilità del film si assegna
un semaforo che consigli l’età adatta per la visione. alla proprietà ImageIndex il valore dell’indice
Per il nostro scopo avremo bisogno di: nell’ImageList dell’icona corrispondente al Radio-
Button selezionato, restituito dalla funzione In-
• Tre TextBox che rappresentino il titolo, il regi- diceIconaSelezionata. L’istruzione successiva asse-
ORDINARE sta e la durata del film con i seguenti nomi: gna il colore Blu al titolo.
GLI ELEMENTI TextBoxTitolo, TextBoxRegista, TextBoxDurata Con l’istruzione:
DEL LISTVIEW • Tre RadioButton che consiglino l’età adatta per
E’ possibile attivare la la visione del film, con i seguenti nomi: Radio- SItem = [Link](Regista)
proprietà Sorting per ButtonTutti, RadioButtonGenitori, RadioBut-
ordinare
automaticamente gli
tonAdulti si può scrivere il testo nelle successive colonne
elementi presenti nel • Un ListView, in modalità Details, che visualizzi ognuno con un carattere ed un colore diverso. La
ListView impostando il la lista dei film. Richiamando, nell’evento Load funzione IndiceIconaSelezionata dovrà semplice-
tipo di ordinamento in della form, la procedura IntestaColonne vista mente testare il valore della proprietà checked dei
ascendente o in precedenza, si otterranno le colonne neces- RadioButton, e nel caso sia pari a True assegnare alla
discendente.
Prestate attenzione,
sarie. funzione l’indice dell’immagine (nell’ImageList)
l’ordinamento del • Un’ImageList popolato dalle icone con il corrispondente al RadioButton:
ListView è di tipo semaforo (nell’ordine) verde, giallo e rosso.
alfanumerico, per • Due Button per inserire o rimuovere un film Private Function IndiceIconaSelezionata() As Integer
questo i campi dalla lista. If [Link] = True Then
numerici e le date non
‘semaforo verde
sono ordinati
correttamente. L’unico L’utente dovrà scrivere le caratteristiche del film nei IndiceIconaSelezionata = 0
modo per riuscire ad TextBox corrispondenti, selezionare un RadioButton End If
ordinare i numeri e le e premere il bottone Aggiungi per inserire il film If [Link] = True Then
date, è di formattarli nella lista. Il codice necessario alla gestione dell’in- ‘semaforo giallo
opportunamente. I
serimento di un film nella lista sarà, quindi, scritto IndiceIconaSelezionata = 1
numeri devono essere
formattati come nell’evento Click del button ButtonAggiungi. End If
stringhe aggiungendo If [Link] = True Then
degli spazi, le date Private Sub ButtonAggiungi_Click(ByVal sender As ‘semaforo rosso
devono essere invece
[Link], ByVal e As [Link]) IndiceIconaSelezionata = 2
formattate nel
Handles [Link] End If
formato americano.
E’ possibile ordinare il Dim Litem As ListViewItem End Function
contenuto del Dim SItem As [Link]
controllo applicando Dim Titolo As String; Dim Regista As String Infine nell’evento Click di ButtonRimuovi si dovrà
diversi criteri. Basta
Dim Durata As Integer scrivere il codice necessario a rimuovere dalla lista il
semplicemente
Titolo = [Link] film selezionato, utilizzando la classica istruzione
definire una classe che
implementi Regista = [Link] Remove.
l’interfaccia Durata = [Link] Per evitare incresciosi errori di run-time introducia-
IComparer, assegnare ‘questo ListItem andrà sotto ColumnHeader(1) mo, inoltre, un controllo sul numero di elementi
un’istanza di tale
Litem = [Link](Titolo) selezionati, se tale numero è pari a zero mostriamo
classe alla proprietà
[Link] = IndiceIconaSelezionata() un messaggio uscendo dall’applicazione
ListViewItemSorter del
controllo ListView e [Link] = [Link]
invocare, quindi, il SItem = [Link](Regista) Private Sub ButtonRimuovi_Click(ByVal sender As
metodo Sort. La [Link] = [Link] [Link], ByVal e As [Link])
funzione CompareTo di
SItem = [Link](Durata) Handles [Link]
questa classe riceve un
[Link] = [Link] If [Link] = 0 Then
riferimento ai due
oggetti ListViewItem End Sub [Link](“Nessun Film Selezionato”)
che vengono Exit Sub
confrontati, pertanto è Si sono dichiarate le variabili Litem di tipo ListView- End If
possibile accedere alle Item ed SItem di tipo ListViewSubItem, oltre alle va- ‘rimuove il primo tra gli elementi selezionati
relative proprietà ed a
riabili che conterranno i valori dei TextBox. [Link](
quelle dei
corrispondenti L’istruzione: [Link](0))
sottoelementi. End Sub
Litem = [Link](Titolo) Ing. Luigi Buono

h t t p : / / w w w. i o p r o g r a m m o . i t
G 92/Novembre 2003
093-096 Corso C# 4-10-2003 10:16 Pagina 93

C# CORSI BASE

Eredità multipla semplificata con le interfacce

Interfacce nella
programmazione .NET
Dopo aver esaminato i concetti legati all’ereditarietà, passiamo
all’analisi di un’altra fondamentale caratteristica della
programmazione orientata agli oggetti con .NET: le interfacce.
Riprese direttamente da Java, le interfacce di C# estremizzano
il concetto di classe astratta e consentono una sorta di ereditarietà
multipla, in versione semplificata.

L
e interfacce sono una completa estre- dichiararlo esplicitamente con la parola ab-
mizzazione del concetto di classe stract.
astratta. Servono per specificare cosa
una classe debba fare, ma non come debba Prendiamo in esame una prima semplice
farlo. Sommariamente, è possibile pensare interfaccia. Nel corso della lezione preceden-
alle interfacce come a delle classi astratte te è stata sviluppata la classe astratta Anima-
costituite da soli metodi astratti. Cionon- le. Applicando alcune piccole variazioni, è
ostante, il paragone rischia di essere forvian- possibile mutare la classe in un’interfaccia:
te. Le interfacce, infatti, rappresentano
anche la via di C# e di .NET all’ereditarietà interface Animale {
❏ CD ❏ WEB
\ codici_csharp19.zip
multipla.
[Link]
void faiVerso();
void dimmiCiboPreferito();

DEFININIZIONE }
DELLE INTERFACCE
La definizione di un’interfaccia, a grosse Come avviene con le classi astratte, non è
linee, ricalca quella di una classe: possibile istanziare direttamente un’interfac-
cia:
interface NomeInterfaccia {
Animale a = new Animale(); // Errore!
tipo-ritorno nomeMetodo1(lista-argomenti);
tipo-ritorno nomeMetodo2(lista-argomenti); Un’interfaccia esiste solamente per essere
tipo-ritorno nomeMetodo3(lista-argomenti); implementata da una o più classi.
...
P
}
IMPLEMENTAZIONE
Rispetto alle classi, è importante osservare le DI UN’INTERFACCIA
seguenti differenze: Implementare un’interfaccia significa realiz-
zare una classe che dia definizione ai metodi
La parola chiave utilizzata per la definizione da essa richiesti. L’implementazione di
di un’interfaccia è interface, anziché class. un’interfaccia, in C#, sintatticamente è simi-
Tutti i metodi dichiarati in un’interfaccia le alla derivazione da una classe base:
non hanno corpo. Pertanto, sono automati-
camente metodi astratti, senza il bisogno di class NomeClasse : NomeInterfaccia {

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/93 G
093-096 Corso C# 4-10-2003 10:16 Pagina 94

CORSI BASE C#

// ... Animale a2 = new Cane();


} Animale a3 = new Topo();
[Link](“- Gatto ————————”);
Ecco un esempio pratico: [Link]();
[Link]();
class Gatto : Animale [Link](“- Cane ————————-”);
{ [Link]();
public void faiVerso() [Link]();
{ [Link](“- Topo ————————-”);
[Link](“Miaaaaaaaaooo!”); [Link]();
} [Link]();
public void dimmiCiboPreferito() }
{ }
System. [Link](“Pesce!”);
} L’output è abbastanza ovvio:
}
class Cane : Animale { - Gatto ————————
public void faiVerso() { Miaaaaaaaaooo!
[Link](“Bau!”); Pesce!
} - Cane ————————-
public void dimmiCiboPreferito() Bau!
{ Carne!
[Link](“Carne!”); - Topo ————————-
} Squit!
} Formaggio!
class Topo : Animale
{ Benché non sia possibile istanziare diretta-
EREDITÀ public void faiVerso() mente degli oggetti di tipo Animale, è possi-
MULTIPLA { bile creare dei riferimenti di questo tipo. La
Come si è detto più [Link](“Squit!”); situazione ricorda da vicino i temi già discus-
volte, le interfacce } si dell’ereditarietà.
permettono una sorta
public void dimmiCiboPreferito() Su un riferimento di tipo Animale è possibile
di ereditarietà
multipla. Anzitutto, { richiamare tutti i metodi richiesti dall’inter-
una classe può [Link](“Formaggio!”); faccia Animale.
contemporaneamente } Lo smistamento verso la reale definizione del
estendere un’altra
} metodo è automatico e affidato direttamente
classe ed
implementare
al runtime di .NET.
un’interfaccia. Sono state realizzate tre classi che imple-
mentano l’interfaccia Animale. All’interno di
ognuna di esse, è stato necessario dare corpo
ai due metodi faiVerso() e dimmiCiboPreferi-
to(). Non si può prescindere da questo punto.
IMPLEMENTARE
Se non si dà implementazione a tutti i meto- PIU’ INTERFACCE
di richiesti da un’interfaccia, si riceve un Come si è detto più volte, le interfacce per-
errore di compilazione tipo il seguente: mettono una sorta di ereditarietà multipla.
Anzitutto, una classe può contemporanea-
error CS0535: “NomeClasse” non implementa mente estendere un’altra classe ed imple-
il membro di interfaccia “NomeInterfac- mentare un’interfaccia:
[Link]()”.
Ora che sono state realizzate le tre classi class NomeClasse : ClasseBase, Interfaccia
Gatto, Cane e Topo, è possibile eseguire un {
test: // ...
}
class Test
{ Inoltre, ogni classe può implementare due o
public static void Main() più interfacce simultaneamente:
{
Animale a1 = new Gatto(); class NomeClasse : Interfaccia1, Interfaccia2,

h t t p : / / w w w. i o p r o g r a m m o . i t
G 94/Novembre 2003
093-096 Corso C# 4-10-2003 10:16 Pagina 95

C# CORSI BASE

Interfaccia3, ... do suona().


{
// ... Usando una variabile di tipo OggettoDiLe-
} gno. In questo caso, sono a disposizione
esclusivamente i metodi esposti dall’inter-
In generale, quindi, ogni nuova classe può faccia OggettoDiLegno, cioè il solo metodo
estendere una classe base ed implementare n dimmiTipoLegno().
interfacce:
Si verifichi il funzionamento delle strutture
class NomeClasse : ClasseBase, Interfaccia1, realizzate, mediante il seguente test:
Interfaccia2, ..., InterfacciaN
{ class Test {
// ...
} public static void Main() {
// Definisco un oggetto Chitarra usando un
Si prendano in esame le interfacce esemplifi- riferimento
cative StrumentoMusicale e OggettoDiLegno: // del medesimo tipo.
Chitarra c = new Chitarra(“Palissandro”);
interface StrumentoMusicale // Uso normalmente i metodi di Chitarra.
{ [Link]();
void suona(); [Link]();
} // Passo ad un riferimento di tipo
interface OggettoDiLegno StrumentoMusicale.
{ StrumentoMusicale s = c;
void dimmiTipoLegno(); // Ora ho a disposizione solo suona(); CLASSI
} [Link](); ASTRATTE
// Passo ad un riferimento di tipo OggettoDiLegno. E METODI
Una chitarra è sia uno strumento musicale OggettoDiLegno o = c; ASTRATTI
sia un oggetto di legno. Quindi, si può defini- // Ora ho a disposizione solo dimmiTipoLegno(); Le classi astratte sono
classi create
re una classe Chitarra al seguente modo: [Link]();
appositamente per
}
essere derivate. Una
class Chitarra : StrumentoMusicale, OggettoDiLegno { } classe astratta può
string tipoLegno; essere derivata, ma
public Chitarra(string tipoLegno) { non è possibile avere
delle sue istanze da
[Link] = tipoLegno;
impiegare
}
// Richiesto da StrumentoMusicale:
EREDITARIETA’ direttamente in un
software. Alla base
public void suona() {
TRA INTERFACCE dell'astrazione di una
[Link](“Do Re Mi Fa Sol La Si”); Due interfacce possono derivare l’una dal- classe è la parola
chiave abstract
} l’altra. Il meccanismo è semplice:
// Richiesto da OggettoDiLegno:
public void dimmiTipoLegno() { interface Interfaccia1 {
[Link](tipoLegno); void metodo1();
} }
} interface Interfaccia2 : Interfaccia1 {
void metodo2();
In questo caso, ci si può riferire ad un ogget- }
to Chitarra in tre maniere differenti:
Interfaccia2 eredita da Interfaccia1. Questo
Usando una variabile di tipo Chitarra, alla significa che le classi che implementeranno
maniera classica. In questo caso, tutti i Interfaccia2 dovranno definire sia i metodi
metodi esposti da Chitarra possono sempre richiesti da Interfaccia2 sia quelli voluti da
essere richiamati. Interfaccia1.
Ecco un esempio:
Usando una variabile di tipo StrumentoMu-
sicale. In questo caso, sono a disposizione class Esempio : Interfaccia2 {
esclusivamente i metodi esposti dall’inter- // Richiesto da Interfaccia1.
faccia StrumentoMusicale, cioè il solo meto- public void metodo1()

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/95 G
093-096 Corso C# 4-10-2003 10:16 Pagina 96

CORSI BASE C#

{ riferimento più dettagliato. Il trucco, oltre


[Link](“metodo1()”); che con le interfacce, funziona anche nei casi
} di semplice ereditarietà.
// Richiesto da Interfaccia2.
public void metodo2()
{
[Link](“metodo2()”);
CONCLUSIONI
} Mancano pochi tasselli al completamento
} dello studio della programmazione orientata
agli oggetti con C# e .NET. Rinnovo l’appun-
Agli oggetti di tipo Esempio ci si potrà riferire tamento per il mese prossimo, per parlare di
sia usando variabili di tipo Esempio, sia quel- strutture ed enumerazioni, che sono tra gli
le di tipo Interfaccia1, sia quelle di tipo In- aspetti più originali e peculiari di C# e .NET.
terfaccia2, secondo le norme già note: Vi aspetto!
Carlo Pelliccia
class Test {
public static void Main()
{ PROGRAMMAZIONE
Esempio e = new Esempio(); IN VISUAL C# .NET
e.metodo1(); Il linguaggio C#, il
e.metodo2(); nuovo linguaggio
Interfaccia1 i1 = e; Microsoft e parte in-
i1.metodo1(); tegrante del frame-
Interfaccia2 i2 = e; work .NET si appre-
i2.metodo2(); sta a diventare uno
BIBLIOGRAFIA } dei linguaggi di pun-
Guida a C# } to per la program-
Herbert Schildt mazione del nuovo
McGraw-Hill, 2002
millennio. In questo
ISBN 88-386-4264-8
testo l’autore nei
Introduzione a C#
INTERFACCE primi capitoli mostra come realizzare un
Eric Gunnerson E CASTING semplice servizio Web e come creare un'ap-
Mondadori Si torni a considerare l’esempio di Animale, plicazione in grado di sfruttarlo, rendendo
Informatica, 2001
ISBN 88-8331-185-X
Gatto, Cane e Topo. E’ stato detto che una così familiari al programmatore le risorse a
variabile di tipo Animale (che è un’interfac- sua disposizione; nel prosieguo si addentra
cia) può tenere riferimento di un oggetto di nei dettagli di C# e della sua relazione con
C# Guida per lo tipo Gatto, Cane o Topo (che sono classi che il Framework .NET, in modo che il lettore si
sviluppatore implementano l’interfaccia Animale). ritroverà in grado, al termine del volume,
Simon Robinson e altri
Hoepli, 2001
La faccenda è semplice: di affrontare i più svariati aspetti di pro-
ISBN 88-203-2962-X grammazione. Sono proposti svariati
Animale a = new Gatto(); argomenti, tra questi:

In certi casi, si desidera poter compiere l’o- • i file e gli oggetti di serializzazione;
perazione inversa. • la creazione di programmi di
Ad esempio, avendo a disposizione un riferi- messaggistica;
mento di tipo Animale, si immagini di voler • l’utilizzo di XML e ADO .NET per interagire
risalire al riferimento verso la reale classe con i database.
dell’oggetto.
L’operazione è possibile attraverso un ca- • Difficoltà: Medio – Alta
sting esplicito, a patto di conoscere quale • Autore: Harold Davis
classe sia quella di appartenenza dell’og- • Editore: MCGraw-Hill
getto: [Link]
• ISBN: 88-386-4311-3
Animale a = new Gatto(); • Anno di pubblicazione: 2003
// ... • Lingua: Italiano
Gatto g = (Gatto)a; • Pagine: 624
• Prezzo: E 38,00
Con questa tecnica, è possibile tornare al

h t t p : / / w w w. i o p r o g r a m m o . i t
G 96/Novembre 2003
097-100 Corso C++ 4-10-2003 10:17 Pagina 97

C++ CORSI BASE

Controllare gli eventi “anomali” nelle applicazioni

La gestione
delle eccezioni
Una caratteristica conosciuta da pochi è la possibilità di gestire
eventi anomali di un programma tramite il meccanismo delle
eccezioni. Vediamo come funziona.

M
olte volte si è parlato su queste pagine di anomala", in altre parole il fatto che qualcosa è
robustezza del codice, cioè di quella carat- andato storto. Una eccezione può verificarsi virtual-
teristica che misura la capacità del mente in qualsiasi parte del codice e, ovviamente,
software di "reagire", in maniera ragionevole, al scrivere un blocco di istruzioni di trattamento del-
presentarsi di situazioni anomale. Ad esempio un l'errore per ogni singola linea di codice del program-
programma che, non trovando un file che deve ma sarebbe una strada impercorribile. L'idea quindi
aprire, mostra un messaggio di errore, è più robu- è quella di raggruppare una serie di istruzioni e dire
sto di un programma che nelle stesse condizioni al programma: "Prova ad eseguirle, se qualcosa va
causa un crash del sistema. Inutile dire che più un storto esegui quest'altro codice". ❏ CD ❏ WEB
software è robusto, maggiore è la sua qualità. Una Le parole chiave del C++ che riguardano questo Codici_lez_17_C++.zip
buona strada da percorrere per rendere il proprio meccanismo sono try e catch; il loro utilizzo è il [Link]
codice robusto, è quella di cercare di prevedere seguente:
tutti i possibili errori che possono presentarsi in
una certa situazione e scrivere del codice adatto a try
trattarli. Purtroppo questo è un metodo di pro- {
grammazione usato da pochi. Quando program- //blocco istruzioni senza trattamento dell'errore
miamo, infatti, siamo naturalmente portati all'ot- }
timismo (che sarà pure il sale della vita, ma si sa catch (<tipo di eccezione> <identificatore>)
che troppo sale fa male...) e quindi tendiamo a {
scrivere del codice che funzionerà soltanto nel //gestione dell'errore
migliore dei modi possibili, che, come ogni pro- }
grammatore sa, è quello in cui non si verificano
errori software. Forse questa tendenza è dovuta al Il blocco di istruzioni preceduto dalla clausola try è
fatto che scrivere codice per la gestione di errori è un blocco istruzioni ordinario del C++, quindi per
una cosa noiosa e ripetitiva, inoltre rende il più esso valgono tutte le regole di visibilità delle variabi-
delle volte il codice stesso difficile da leggere e li viste nelle prime puntate di questo corso. Per
capire. La cosa ideale sarebbe avere un meccani- quanto riguarda il blocco preceduto dalla parola
smo che renda possibile separare la parte di codice chiave catch, è da notare il fatto che in esso è possi-
"interessante" (quella del mondo perfetto) dalla bile definire un particolare <identificatore>, che rap-
parte, noiosa ma necessaria, della gestione degli presenterà l'oggetto "eccezione" all'interno del
errori. Ovviamente i progettisti del C++ non fanno blocco.
mancare nulla e hanno implementato questa Questo oggetto è di tipo <tipo eccezione> e può esse-
caratteristica col meccanismo delle eccezioni. re, ad esempio, di uno qualsiasi dei tipi predefiniti
del C++ ma, più verosimilmente, sarà una istanza di
una classe creata apposta per contenere informazio-
ni relative al tipo di errore che si è verificato.
ECCEZIONALE Parleremo in seguito delle caratteristiche di questo
VERAMENTE blocco, dopo avere analizzato in che modo sia pos-
Per "eccezione" si intende per l'appunto "situazione sibile, come si dice in gergo, "lanciare" un’eccezione.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/97 G
097-100 Corso C++ 4-10-2003 10:17 Pagina 98

CORSI BASE C++

int numero;
LANCIALA E VAI cout << "Ciao! Inserisci un intero positivo: ";
A RIPRENDERLA cin >> numero;
Quando scriviamo codice capita, a volte, di avere a if (numero < 0) throw ErroreInteroNegativo(numero);
che fare con errori che nel contesto specifico non return numero;
sappiamo come trattare e che desidereremmo fos- }
sero trattati a un livello più alto del software. Quello
che dobbiamo fare in questi casi, è racchiudere tutte L'uso di try e catch per la chiamata di RichiediIn-
le informazioni, relative all'errore, in un oggetto e teroPositivo() prevede la scrittura di codice simile al
lanciare tale oggetto come eccezione. Questa opera- seguente:
zione viene compiuta in C++ mediante la parola
chiave throw. Supponiamo ad esempio di dovere try
implementare una funzione per richiedere da con- {
PER solle un numero intero positivo. Il corpo di tale fun- //... codice
SAPERNE zione potrebbe essere il seguente: RichiediInteroPositivo();
DI PIÙ //... altro codice
A chi volesse int RichiediInteroPositivo() }
approfondire la sua { catch (ErroreInteroNegativo ein)
conoscenza sulle int numero; {
librerie standard del cout << "Ciao! Inserisci un intero positivo: "; //gestione dell'errore
C++, consigliamo il cin >> numero; cout << "Attenzione! Hai inserito un numero negativo!\n";
validissimo libro return numero; }
}
• THINKING IN C++ - Come si può vedere, il blocco istruzioni catch gesti-
2ND ED. - VOLUME 2" Ovviamente, come è facile vedere, la funzione è sce l'errore semplicemente stampando un messag-
Bruce Eckel incompleta, in quanto manca un controllo sul valo- gio a schermo. Tuttavia, questo è stato fatto solo a
e Chuck Allison re intero inserito, qualcosa del tipo: scopo didattico, in realtà la gestione dell'errore
potrebbe essere molto più complessa (ad esempio
che rappresenta if (numero < 0) { /* ERRORE! */} prevedere dei rollback su un database, oppure la
sicuramente un ottimo chiusura di una connessione di rete ecc.); la cosa
riferimento per i Il problema di inserire questa istruzione, consiste interessante risiede nel fatto che chi ha scritto la
programmatori più nel fatto che non sappiamo, in questo contesto, funzione RichiediInteroPositivo() non ha dovuto mi-
avanzati (o aspiranti come tale errore debba essere trattato; in altre paro- nimamente pensare al modo in cui trattare un even-
tali) ed è oltretutto le non conosciamo quale debba essere il contenuto tuale errore, ma ha demandato tutta la fatica a chi ha
disponibile del blocco istruzioni dell'if. Quello che allora dob- scritto la relativa clausola catch. Inoltre, in questo
gratuitamente per il biamo fare è costruire un oggetto apposito, in grado modo, tutta la parte della gestione dell'errore è con-
download, partendo di contenere l'informazione riguardante l'errore centrato in una ben precisa porzione di codice inve-
dall'indirizzo avvenuto. Questo oggetto potrebbe essere una istan- ce di essere sparsa in giro per il programma. La fles-
[Link] za della seguente, semplice, classe: sibilità di questo costrutto è estrema, infatti è possi-
Books/TICPP/ bile, ad esempio, utilizzare l'informazione portata
[Link] class ErroreInteroNegativo dall'oggetto eccezione per raffinare la gestione del-
{ l'errore. Supponiamo ad esempio che se il valore
Se volete invece dare public: inserito è compreso tra -10 e -1 l'utente abbia la pos-
un'occhiata a una ErroreInteroNegativo(int num) : numero(num) {} sibilità di inserirne uno nuovo, altrimenti il pro-
reference delle int GetValore() {return numero;} gramma debba terminare la sua esecuzione.
funzioni standard del C private: Il codice per fare questo è:
per la manipolazione int numero;
di stringhe (o meglio: }; int num = 0;
di array di caratteri while (true)
terminati da "\0" :-) Questa classe porta con se l'informazione più ele- {
consultate l'indirizzo: mentare che potremmo pensare di trasmettere, cioè //ciclo infinito!
[Link] il valore negativo inserito. A questo punto siamo try
/ref/cstring/ pronti a inserire nel codice della funzione Richiedi- {
InteroPositivo() il controllo di validità sul dato inseri- num = RichiediInteroPositivo();
to; esso apparirà più o meno così: break; //esce dal "while"
}
int RichiediInteroPositivo() catch (ErroreInteroNegativo ein)
{ {

h t t p : / / w w w. i o p r o g r a m m o . i t
G 98/Novembre 2003
097-100 Corso C++ 4-10-2003 10:17 Pagina 99

C++ CORSI BASE

if ([Link]() >= -10) qualche nuova classe per le nostre eccezioni:


continue; //altro ciclo "while"
else class ErroreZeroDieci
{ { //codice della classe };
cout << "Questo non lo dovevi fare...\n"; class ErroreMenoDieci
exit(-1); //esco dal programma { //codice della classe };
}}
} Con la prima classe verrà identificata l'eccezione
cout << "Bravo! Hai inserito il numero *positivo* " sollevata nel caso in cui l'input sia un numero nega-
<< num << "!\n"; tivo, ma esso sia compreso tra -1 e -10 (in questo
caso daremo all'utente un'altra chance di inseri-
Come si vede l'oggetto eccezione è stato utilizzato mento). La seconda classe serve ad incapsulare
all'interno del blocco catch esattamente come una un'eccezione data da un input negativo inferiore a -
variabile generica, tramite il suo identificatore ein. 10 (e in questo caso non verrà data altra chance
Inoltre non è stato necessario modificare in alcun all'utente). Predisporre le classi non è sufficiente:
modo il corpo della funzione RichiediInteroPo- dobbiamo modificare anche il blocco di codice da
sitivo(). Vediamo di seguito una gestione ancora più controllare inserendo la nuova gestione delle ecce-
sofisticata della clausola catch. zioni, ma soprattutto dobbiamo modificare la fun-
zione RichiediInteroPositivo() affinchè possa lancia-
re le eccezioni in maniera corretta. La nuova funzio-
ne RichiediInteroPositivo() assumerà adesso la se-
TRY&CATCH MULTIPLI guente forma:
All'interno di un blocco di codice possono essere
presenti molte fonti di errori, quindi molte fonti di int RichiediInteroPositivo()
eccezioni. In effetti, la struttura dei blocchi try&- {
catch può essere estesa in maniera molto immedia- int num; THROW
ta per fare fronte all'esigenza di controllare tutte le cout << "Ciao! Inserisci un intero positivo: "; L'esecuzione di throw
provoca l'uscita dal
possibili eccezioni in un blocco di codice: basta in- cin >> num;
blocco in cui essa si
serire tutte le clausole catch necessarie. In altre paro- if (num<0 && num>-10) throw ErroreZeroDieci();
trova; in questo
le, la struttura vista all'inizio va modificata nel modo if (num<-10) throw ErroreMenoDieci(); contesto si dice che la
seguente: return num; funzione ha sollevato
} un’eccezione. La throw
accetta un argomento
try
come parametro che
{ Mentre il blocco di codice da tenere sotto controllo viene utilizzato per
//blocco istruzioni diverrà: creare un oggetto, che
} non “ubbidisce” alle
catch (<tipo di eccezione 1> <identificatore>) int num = 0; classiche regole di
scope e che viene
{ while (true)
restituito a chi ha
//gestione dell'errore {
tentato l'esecuzione
} //ciclo infinito! dell'operazione.
catch (<tipo di eccezione 2> <identificatore>) try
{ {
//gestione dell'errore num = RichiediInteroPositivo();
} break; //esce dal "while"
catch (<tipo di eccezione 3> <identificatore>) }
{ catch (ErroreZeroDieci ezd)
//gestione dell'errore} {
//e cosi' via... cout << "Pentiti! E reinserisci un nuovo numero...\n";
continue; }
Come i lettori più attenti avranno notato, per usare catch (ErroreMenoDieci emd)
un blocco di questo tipo abbiamo bisogno di tante { cout << "Cosi' proprio non va...\n";
classi quante sono le possibili eccezioni nel blocco di exit(-1); }
codice: ogni catch cattura una sola eccezione, di un }
solo tipo, e se in un blocco possono venire sollevate //fine while
N tipi di eccezioni allora dovremo avere N classi che cout << "Bravo! Hai inserito " << num;
descrivano ognuna un tipo di eccezione. Vediamo un cout << " che in effetti e' *positivo*!\n";
piccolo esempio, modificando un po' il codice dell'e-
sempio precedente. Innanzi tutto introduciamo A guardare bene quello che abbiamo fatto e come lo

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/99 G
097-100 Corso C++ 4-10-2003 10:17 Pagina 100

CORSI BASE C++

abbiamo fatto, una cosa è sicuramente evidente: un


codice ben strutturato e robusto è qualcosa che LEZIONI DI C++
nasce da prima del debug. Le eccezioni devono far
parte del nostro modo di pensare all'interno di un Un testo che rende particolarmente agevole
l’apprendimento dei fondamenti della
programma così come il pensare a classi e l'elabora- programmazione e del codice C++.
zione di un algoritmo, e questo perché codici ed L’autore John Smiley, presidente della Smiley
errori sono legati in maniera indissolubile. Prima di and Associates, un’azienda di consulenza
pensare alla parte successiva di codice, bisogna informatica, è autore di altri otto libri e, con
sempre pensare alle possibili eccezioni in quella ap- Lezioni di C++, ha pensato bene di fornire un
testo adatto ad un lettore neofita, che non ha
pena scritta. nessuna esperienza in campo di
programmazione e che comunque si appresta
a voler apprendere un linguaggio come il C++
che, sicuramente, non si annovera tra i
L'ACCHIAPPA-TUTTO linguaggi più semplici nell’apprendimento. Gli
argomenti, secondo lo stile dell’autore e
Siccome nessuno è perfetto, non possiamo aspet- ormai divenuto un suo standard, sono trattati
tarci di aver pensato a tutto: magari questa volta sì, in modo semplice e “divertente”. Tra gli
ma prima o poi succederà che ci dimenticheremo argomenti trattati: imparare i concetti della
qualcosa, oppure qualche fonte di eccezioni sfug- programmazione applicabili a più linguaggi;
girà alla nostra vista. Ci sono bug che si annidano sviluppare delle competenze in C++ per il
mondo reale e utilizzare la programmazione a
nel codice per anni e vengono fuori in combinazio- oggetti; lavorare con le variabili, le costanti e i
ni di eventi incredibilmente improbabili, ma non dati tipizzati del C++.
impossibili. I software real-time di una centrale nu-
cleare o di un razzo spaziale non possono permet- Difficoltà: Medio – Alta
CONTATTA tersi il lusso di una eccezione non gestita, ad esem- Autore: [Link]
GLI AUTORI! pio. Sta alla bravura del programmatore usare bene Editore: McGraw-Hill
Se hai suggerimenti, il meccanismo di cattura delle eccezioni. Nel [Link]
critiche, dubbi o try&catch possiamo avvalerci di una clausola gene- .[Link]
perplessità sugli rica di cattura di eccezioni, la quale serve per gesti- ISBN: 88-386-4325-3
argomenti trattati e re le più impreviste tra le situazioni impreviste (per- Anno di pub.: 2003
vuoi proporle agli donate il gioco di parole). Lingua: Italiano
autori puoi scrivere Ad esempio, in un software di importanza strategi- Pagine: 573
agli indirizzi: ca, che sia real-time, potrebbe verificarsi qualche Prezzo: E 32,00
situazione inattesa che generi una eccezione non
[Link]@ gestita (magari perché proprio non considerata
[Link] (Alfredo) possibile o perché non ci si è avveduti della sua pos- Quindi, l'ultimo catch è quello che ci permette di
e sibile esistenza): in quel caso dobbiamo poter por- non far scappare alcuna eccezione: non c'è molto da
marcodelgobbo@ tare il sistema che fa uso di tale software in uno fare quando si verifica una eccezione non gestita da
[Link] (Marco) stato stabile che non pregiudichi la sicurezza di altri catch precedenti (vuol dire che è successo qual-
niente o nessuno. cosa di cui si ignorava l'esistenza), tuttavia è me-
Questo contribuirà Possiamo pensare ad una struttura di questo tipo: diante quel catch che ad esempio si potrebbero atti-
sicuramente a vare le procedure di emergenza di una centrale nu-
migliorare il lavoro di try cleare (ovviamente, in un software real-time di quel
stesura delle prossime { //blocco istruzioni } tipo vengono a cadere molte delle nostre "conven-
puntate. catch (<tipo di eccezione 1> <identificatore>) zioni" di programmazione, quindi probabilmente le
{ //gestione dell'errore } eccezioni non hanno motivo di essere pensate: que-
//e cosi' via... sto esempio è solo a fini didattici, per dare un'idea).
catch (<tipo di eccezione 2> <identificatore>)
{ //gestione dell'errore }
catch (...)
{ //gestione dell'errore generico:
CONCLUSIONI
//si porta il sistema in uno stato sicuro } Abbiamo appreso un meccanismo molto potente
per il controllo degli errori nei nostri programmi: ci
Questa struttura è come quella che abbiamo visto salverà (probabilmente) spesso da seri problemi,
nel paragrafo precedente, solo che abbiamo aggiun- oltre a farci guadagnare molte ore di sonno.
to una nuova clausola catch il cui argomento non è E' sempre bene trattare le eccezioni nei propri pro-
una convenzione tipografica: il simbolo "..." è parte grammi, perché la robustezza è un requisito della
del vocabolario C++ e sta ad indicare una generica qualità.
lista di argomenti. Alfredo Marroccelli e Marco Del Gobbo

h t t p : / / w w w. i o p r o g r a m m o . i t
G 100/Novembre 2003
101-105 Corso_Matlab 4-10-2003 10:18 Pagina 101

Matlab CORSI BASE

Sviluppare “applicazioni” con MATLAB

Uno sguardo
all’ambiente di sviluppo
Dopo aver acquisito una buona conoscenza delle potenzialità
di calcolo di MATLAB, rivolgiamo il nostro interesse ad argomenti
maggiormente attinenti all’uso dell’ambiente. In altre parole
esaminiamo quali siano le caratteristiche che influiscono sulla
produttività in misura, per lo meno uguale, alle funzioni
del linguaggio di programmazione che abbiamo potuto esplorare
nei numeri precedenti.

N
ei primi appuntamenti dedicati a viene in soccorso poiché ci consente di per-
MATLAB abbiamo volutamente dato correre il programma un’istruzione alla volta
maggiore spazio alla trattazione delle e verificare al volo i valori delle variabili. In
caratteristiche di calcolo del prodotto, poiché questo numero vedremo all’opera sia il
é naturale pensare che queste siano quelle Debugger sia altre applicazioni di ausilio al-
caratterizzanti e che maggiormente incurio- l’uso di MATLAB interattivo e procedurale.
siscono coloro i quali abbiano la necessità di
disporre di uno strumento di calcolo. Abbia-
mo volutamente trascurato la trattazione di
LA COMMAND HISTORY ❏ CD ❏ WEB
molte di quelle informazioni che fossero atti- \matlab_74.zip
nenti all’uso dell’ambiente MATLAB. Per cita- Durante l’uso interattivo di MATLAB, abbia-
[Link]
re un buon esempio, che rende chiaro il con- mo imparato a conoscere la finestra chiama-
cetto, proviamo a pensare all’uso di un de- ta Command Window il cui uso è molto sem-
bugger. Chi abbia sviluppato programmi e al- plice. Infatti, essa consente di scrivere istru-
goritmi di una certa complessità, sa bene che zioni e di visualizzare immediatamente il ri-
un programma può mostrare una complessa sultato della loro elaborazione. Non sappia-
casistica di malfunzionamenti; scoprire quale mo ancora che tutto quello che noi scriviamo
sia la causa di un errore può essere un compi- viene effettivamente registrato e può essere
to lungo e doloroso. Soprattutto quando ci utilizzato in seguito. Una seconda finestra
occupiamo di calcolo, sappiamo bene che dell’ambiente MATLAB ci mostra la storia
una delle situazioni peggiori in cui ci possia- delle istruzioni digitate sulla Command Win-
mo imbattere è quella in cui un subdolo erro- dow. Da questa finestra (vedi Fig. 1) abbiamo
re genera un risultato del calcolo non corret- la possibilità di eseguire alcune semplicissi-
to. Quello che rileviamo sono numeri “quasi” me azioni che si rivelano utili e veloci. Clic-
esatti che non bloccano il fluire delle infor- cando due volte sul singolo comando, che ap-
mazioni, ma ci sfuggono proprio per la loro pare nella lista, si forza la sua immediata ese-
apparente esattezza. Alla lunga inquinano cuzione. Mentre, se si clicca col tasto destro
sempre più il risultato numerico ma riman- appare un menu che ci dice che possiamo co-
gono comunque molto difficili da scoprire. piare il comando o addirittura creare diretta-
Nel momento in cui ce ne rendiamo conto, mente un m-file che contenga le righe che
ciò che immediatamente ci preoccupa è il abbiamo selezionato. Se proviamo ad esegui-
processo di ricerca del punto in cui abbiamo re quest’opzione vediamo immediatamente
generato l’errore. Ed ecco che il debugger ci comparire le righe evidenziate sull’editor di

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/101 G
101-105 Corso_Matlab 4-10-2003 10:18 Pagina 102

CORSI BASE Matlab

Window, comandi e risultati compresi.


È poi possibile aprire questo file per mezzo
dell’Editor e modificarlo per estrarne le parti
che riteniamo più utili per il nostro lavoro.
Un suo uso un po’ più sofisticato prevede che
si possa specificare un nome di file sul quale
riversare la copia della sessione di lavoro.
È sufficiente usare la seguente sintassi:

>> diary(‘[Link]’)

CURRENT DIRECTORY
Questa finestra ha l’aspetto di una lista di fi-
LANCIO le e permette la navigabilità delle directory in
DELLA una maniera molto intuitiva. Essa è utile per
APPLICAZIONE vedere i file che fanno parte di una directory,
L’applicazione puo’ potere facilmente aprirli nell’Editor ed ese-
essere lanciata dalla guire nell’ambiente.
Command Window per
mezzo di:

>> workspace WORKSPACE


Fig. 1: Command History. La finestra che mostra il contenuto del work-
space (vedi Fig. 2) consente alcune funziona-
lità interattive di una certa comodità. Se pro-
MATLAB. Abbiamo gia usato l’Editor per scri- viamo a cliccare doppio su una variabile, cau-
vere i nostri primi programmi, e nel seguito siamo l’apertura di un’applicazione ausiliaria
vedremo alcuni dettagli utili su quest’appli- chiamata Array Editor.
cazione così preziosa. Se invece trasciniamo
la selezione sulla Command Window, ne ese-
guiamo una semplice copia ma il codice non
viene automaticamente eseguito. MATLAB
attende il successivo Enter per effettuare il
calcolo. In altre parole, la Command History é
un contenitore che ci consente di recuperare
ARRAY dal lavoro interattivo porzioni di codice che
EDITOR possono rivelarsi utili per una loro riesecu-
L’Array Editor può es- zione o per la composizione di programmi e
sere invocato dalla algoritmi. Abbiamo compreso dalle nostre
Command Window per esperienze precedenti, che l’uso interattivo di
mezzo di: MATLAB è destinato a qui tentativi di elabo-
razione dati che non debbano necessaria-
>> open solemese mente divenire parte di un algoritmo. Avviene Fig. 2: Il WorkSpace.
spesso invece che queste manipolazioni
É necessario specifica- esplorative siano un buon punto di partenza
re il nome di una varia- o di riferimento per quello che deve divenire La variabile in questione, a questo punto, può
bile presente in work- l’algoritmo definitivo. La conservazione del essere modificata interattivamente (vedi Fig.
space lavoro interattivo del passato si rivela ora par- 3). Qui abbiamo visualizzato una variabile
ticolarmente utile. Una variazione sul tema è proveniente da un file che abbiamo imparato
la funzione diary. Se digitiamo il semplice co- a leggere in uno dei numeri precedenti. Esso
mando diary sulla Command Window, atti- riporta le date (anni e mesi) e le registrazioni
viamo la registrazione su file della sessione di del numero medio di macchie solari nel pe-
lavoro fino alla successiva digitazione del co- riodo. Questi dati si trovano nel file soleme-
mando diary. A questo punto viene generato [Link] e sono presenti ora in MATLAB poiché
un file di nome diary contenente la copia fe- sono stati importati per mezzo dell’Import
dele di quello che é apparso sulla Command Wizard (vedi Fig. 4).

h t t p : / / w w w. i o p r o g r a m m o . i t
G 102/Novembre 2003
101-105 Corso_Matlab 4-10-2003 10:18 Pagina 103

Matlab CORSI BASE

disponibile circa l’uso dei singoli strumenti e


funzioni.

L’EDITOR
Lo scopo principale di un editor é quello di
fornire un ambiente comodo dove poter crea-
re un programma. Descritto in questo modo
può suonare semplicistico; in realtà ci trovia-
mo di fronte ad un’applicazione di servizio
Fig. 3: Array Editor. agile ma allo stesso tempo sofisticata.
Se apriamo un programma MATLAB (vedi
Fig. 6) e lo visualizziamo, ci accorgiamo di al-
Esso ci consente di importare vari formati di cune caratteristiche non banali.
file in maniera interattiva, e ci risparmia l’ap-
prendimento della sintassi di comandi spe-
cializzati.
L’Import Wizard può essere invocato sia
dall’Array Editor sia da MATLAB per mezzo
del menu File e di un item chiamato “Import IMPORT
Data…”. WIZARD
L’Import Wizard può essere
invocato dalla Command
Window per mezzo di:

>> uiimport

Fig. 6: Editor.
Fig. 4: Import Wizard.

Prima di tutto notiamo che compaiono i nu-


meri che individuano la singola riga all’inter- EDITOR/
IL LAUNCH PAD no del codice. Questi sono particolarmente DEBUGGER
Il Launch Pad di MATLAB elenca gli strumenti utili poichè sono il riferimento principale L’Editor/Debugger può
e le applicazioni di servizio di ogni prodotto. quando viene segnalato un errore. MATLAB essere invocato dalla
Command Window per
informa l’utilizzatore mostrando il numero di mezzo di:
riga dove si è verificato un problema insor-
montabile. Per esempio: >> edit

>> corrcoef(0);
Warning: Divide by zero.
(Type “warning off MATLAB:divideByZero” to suppress
this warning.)
> In D:\MATLAB6p5\toolbox\matlab\datafun\
corrcoef.m (correl) at line 189
In D:\MATLAB6p5\toolbox\matlab\datafun\
corrcoef.m at line 77

Inoltre, notiamo che l’Editor colora in manie-


Fig. 5: Launch Pad. ra differente alcune parole. Nell’esempio di
Fig. 6 vediamo quattro differenti colori: il ver-
Inoltre, è disponibile il riferimento al sistema de evidenzia i commenti, il blu fa risaltare le
di help che contiene tutta la documentazione funzioni appartenenti al linguaggio MATLAB,

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/103 G
101-105 Corso_Matlab 4-10-2003 10:18 Pagina 104

CORSI BASE Matlab

il celeste è riservato alle stringhe ed infine il fermato. Possiamo ora esplorare il contenuto
nero viene usato per tutti gli altri caratteri del workspace per mezzo di:
(nomi di variabile e separatori). Anche qui è
possibile evidenziare alcune linee di codice e K>> whos
farle eseguire nella Command Window di MA- Name Size Bytes Class
TLAB semplicemente attivando l’appropriato
menu, per mezzo del tasto destro. varargin 0x0 0 cell array
x 3x3 72 double array

Grand total is 9 elements using 72 bytes


IL DEBUGGER
In moltissimi casi, in cui si deve individuare il Non dobbiamo aspettarci di vedere il work-
punto in cui si verifica un errore, è di estremo space base di MATLAB (quello usato per ri-
aiuto poter seguire l’elaborazione un passo chiamare la funzione corrcoef) ma invece
alla volta. Per fare questo è necessario stabili- quello locale della funzione. Ed in effetti tro-
re un punto preciso da cui iniziare il debug e viamo il cell array vuoto dei parametri di in-
possedere quindi un meccanismo di avanza- put opzionali della funzione e la variabile “x”
mento manuale dell’elaborazione. Tutto que- che è l’input richiesto dalla funzione.
sto si ottiene per mezzo dell’uso dei bottoni A questo punto potremmo variare il valore di
presenti sulla Toolbar dell’Editor MATLAB e “x”, visualizzarlo o creare nuove variabili ausi-
riportati in Fig. 7. liarie. Scegliamo invece di proseguire; la linea
su cui siamo posizionati richiama una fun-
zione presente nella porzione successiva del
m-file. Per poterci entrare dobbiamo eseguire
Fig. 7: Gestione del Debug. uno step in. Se posizioniamo il cursore del
mouse sui bottoni che gestiscono il debug, e
RIFERIMENTI Diamo uno sguardo ai primi tre bottoni e al proviamo a scorrere bottone per bottone, ve-
“Getting Started with penultimo. Il primo bottone da sinistra con- diamo apparire un piccolo riquadro giallo
MATLAB” sente di impostare un breakpoint nella posi- che riporta in chiaro l’azione che ogni singo-
[Link]
m/access/helpdesk/help/pd
zione desiderata; l’elaborazione si fermerà in lo bottone esegue. Fermiamoci a quello che
f_doc/matlab/[Link] quel punto e consentirà all’utilizzatore di ve- indica Step in e premiamolo.
dere il valore delle variabili, di eseguire por- Immediatamente ci vediamo proiettati in una
“Using MATLAB” zioni di codice, ecc. In altre parole la Com- nuova funzione che, per mezzo di quattro li-
[Link] mand Window diviene pienamente accessibi- nee di codice, calcola i coefficienti di correla-
access/helpdesk/help/pdf_doc
/matlab/using_ml.pdf
le e consente ogni tipo di interazione con i zione della matrice “x”. Se dopo alcune righe
dati, le funzioni e gli archivi su file. ci ritenessimo soddisfatti dell’esplorazione
“Using MATLAB Il secondo bottone cancella tutti i breakpoint. potremmo terminare la sessione di debug
Graphics” Il terzo bottone ci fa avanzare di un’istruzio- premendo il bottone che ha come descrizio-
[Link] ne e fa bloccare nuovamente l’elaborazione ne Continue (riquadro giallo attivato dal pas-
/access/helpdesk/help/
pdf_doc/matlab/[Link]
per consentire una nuova indagine. Il penul- saggio del cursore del mouse). Questo co-
timo bottone a destra forza l’elaborazione a mando forza MATLAB ad interrompere il de-
proseguire sino al successivo breakpoint im- bug e ad eseguire il codice sino al termine
postato oppure fino a fine programma. dell’elaborazione.
Proviamo a seguire l’elaborazione di un pro- A questo punto il risultato del calcolo compa-
gramma: apriamo il programma MATLAB che re sulla Command Window.
calcola i coefficienti di correlazione (edit
corrcoef) e piazziamo un breakpoint alla linea
77. Lanciamo ora il programma con un sem-
plice comando sulla Command Windows: IL PROFILER
Un’altra applicazione ausiliare molto utile è il
>> corrcoef(rand(3,3)) Profiler. Essa è in grado di monitorare l’elabo-
razione di una catena di programmi per indi-
A questo punto il programma si blocca e sul- viduare dove venga speso tempo di elabora-
la Command Window compare un nuovo zione. Lo scopo è ovviamente quello di sco-
prompt (K>>), indicante che ci troviamo in prire dove vi sia la possibilità di ridurre e otti-
un altro modo di funzionamento dell’am- mizzare la scrittura del codice con il fine di li-
biente. Viene quindi attivato l’editor visualiz- mare il più possibile i tempi di calcolo.
zando il punto in cui il programma è stato Per attivare il Profiler é necessario visitare il

h t t p : / / w w w. i o p r o g r a m m o . i t
G 104/Novembre 2003
101-105 Corso_Matlab 4-10-2003 10:18 Pagina 105

Matlab CORSI BASE

menu View di MATLAB e quindi ciccare su come pilotare tale funzionalità.


Profiler. Si aprirà una finestra su cui spicca un
bottone con la dicitura Start Profiling.
Proviamo a premerlo e a lanciare sulla Com-
mand Window il comando:

>> corrcoef(rand(300,300));

Quindi premiamo nuovamente lo stesso bot-


tone che ora riporterà la dicitura Stop Pro-
filing. A questo punto apparirà una statistica
circa i tempi esecutivi della catena di pro-
grammi che sono stati eseguiti per completa-
re il compito che abbiamo imposto a MA-
TLAB dalla Command Window.

Fig. 8b: Profiler.

CONCLUSIONI PROFILER
In questo numero abbiamo esplorato molte Il Profiler puo’ essere
delle applicazioni ausiliarie di MATLAB. Esse invocato dalla
sono destinate a rendere il lavoro di coloro i Command Window per
quali devono sviluppare algoritmi il più sem- mezzo di:
plice possibile. In molti casi si tratta di ausili
Fig. 8a: Statistiche del Profiler.
al processo di sviluppo che sono volti ad au- >> profile viewer
mentare in maniera considerevole la como-
Proviamo a cliccare sul programma cov che dità di scrittura. In altri casi, come quello del
pare essere uno di quelli che consumano più Profiler, l’uso di questi strumenti migliora
risorse (corrcoef è la funzione lanciata da sensibilmente la qualità del prodotto finale
Command Window, mentre corrcoef/correl è consentendo l’ottimizzazione dei tempi di
una sottofunzione di corrcoef che contiene esecuzione.
proprio la funzione cov). Come sempre, invito tutti coloro i quali vo-
Quello che ci appare è riportato nelle Fig. 8a e gliano contribuire con suggerimenti e idee a
8b. Vediamo è una sintesi delle misure del contattarmi direttamente per mezzo dell’in-
tempo di elaborazione. Da qui individuiamo dirizzo di posta elettronica citato in calce. Per
velocemente i punti più critici (Fig. 8a), men- maggiori informazioni sui prodotti della fa-
tre nel seguito viene riportato il codice con miglia MATLAB potete consultare il sito di
una vista analitica dei tempi (Fig. 8b), dalla The MathWorks ([Link]).
quale scopriamo quali siano i punti sui quali Suggerisco a tutti di guardare una porzione
possiamo intervenire per apportare migliora- del sito web chiamato “MATLAB Central”
menti significativi al codice con lo scopo di ([Link]/matlabcentral/).
velocizzare il calcolo. Esso riporta innumerevoli esempi d’uso di
Esiste anche un modo procedurale di accede- MATLAB in una varietà molto ampia di disci-
re alle funzioni di profiling. Se si prova a digi- pline tecnico scientifiche.
tare help profile sulla Command Vindow si ot- Fabrizio Sara
tengono le notizie necessarie a comprendere ([Link]@[Link])

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/105 G
106-110 Corso VB Av 8-10-2003 17:46 Pagina 106

CORSI AVANZATI Visual Basic

Applicazioni che interagiscono con effetti speciali

Un visualizzatore
di immagini
In questo appuntamento completeremo l’applicazione Visualizzatore
Immagini e, parallelamente, descriveremo come farla interagire con il
“mondo esterno”.

N
ei precedenti articoli, dedicati alla ge- mente, possono essere usati per creare finestra di
stione avanzata dei Form, abbiamo qualsiasi forma. In questo appuntamento com-
usato gli elementi dell’API di Windows pleteremo il nostro Visualizzatore Immagini e
per modificare il layout dei form e per creare parallelamente vedremo nuove caratteristiche
degli effetti speciali durante la loro attivazione o del Visualizzatore Immagini di Windows XP; in
disattivazione. Nei due precedenti appuntamen- particolare implementeremo le routine per la
ti, abbiamo avviato l’implementazione di un’ap- ricerca di immagini su internet e per gestire il
plicazione, “laboratorio”, con la quale abbiamo ridimensionamento degli oggetti presenti sui
descritto come utilizzare i concetti che man form.
mano esponevamo. L’applicazione è un “Visua- Innanzitutto, però, dobbiamo descrivere, som-
lizzatore Immagini”, essa presenta un layout par- mariamente, le parti principali dell’applicazione,
ticolare e le sue “sottofinestre” compaiono e sia quelle già implementate che quelle da imple-
scompaiono con effetti speciali come esplosione mentare.
ed implosione. Ricordiamo che abbiamo dato un
aspetto particolare ai Form, utilizzando princi-
palmente le funzioni dell’API della categoria
Region (tra tutte citiamo la CombineRgn), mentre STATO DELL’ARTE
abbiamo impostato degli effetti speciali utiliz- Il Visualizzatore Immagini è un’applicazione che
zando le funzioni che consentono di manipolare permette di visualizzare file di immagini conte-
oggetti Rect (cioè oggetti rettangolari) come per nute in una directory. Le immagini possono an-
esempio la GetWindowRect; in particolare l’esplo- che essere scaricate da internet, come mostrere-
sione/implosione di un form è stata simulata di-
segnando aree rettangolari di estensione cre-
scente/decrescente. I concetti esposti, natural-

Fig. 1: La finestra principale del Visualizzatore


Immagini. Fig. 2: Il form per connettersi ad Internet.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 106/Novembre 2003
106-110 Corso VB Av 4-10-2003 10:19 Pagina 107

Visual Basic CORSI AVANZATI

mo tra poco. L’interfaccia della finestra principa- Nella procedura internet_Click, dopo aver creato
le dell’applicazione è mostrata in Fig. 1. Essa pre- un oggetto Internet Explorer ne fissiamo le di-
senta una barra di comando costituita di una se- mensioni e lo facciamo apparire con l’effetto
rie di pulsanti che permettono di sfogliare le esplosione, utilizzando la procedura espandiform
immagini, di proiettarle, di ricercarle sul compu- descritta nell’articolo precedente. Notate che in
ter o su internet, d’ingrandirle ecc. L’applicazio- questo caso l’ID della finestra da passare alla
ne, per la ricerca di file nelle directory utilizza la espandiform è fornito da IEApp che non è un
finestra FrmRicerca (Fig. 2), mentre per la ricerca form, per questo l’interfaccia della espandiform
su Internet utilizza la finestra FrmBrowser (Fig. 3) deve essere modificata impostando il parametro
o direttamente Internet Explorer, come mostre- “frm” di tipo Object, cioè:
remo tra poco.
Ricordiamo che le immagini sul Form sono mo- Sub espandiform(frm As Object, passaggi As Long)
strate attraverso un Frame della libreria MsForms. …
Nel precedente articolo abbiamo descritto buo- End Sub
na parte del codice dell’applicazione, lasciando L’OGGETTO
in sospeso la ricerca di immagini su internet, il ERR
ridimensionamento della finestra principale e la Per gestire gli errori di
gestione degli errori. Run-Time è importante
Iniziamo dalla ricerca delle immagini su internet,
LA FINESTRA conoscere le

poi vedremo qualcosa sul ridimensionamento. CON IL WEBBROWSER caratteristiche


dell’oggetto Err,
Per quanto riguarda la gestione degli errori, dare- Per eseguire la ricerca delle immagini su internet, descriviamone
mo solo un cenno agli elementi di Visual Basic alternativamente, possiamo servirci dell’oggetto brevemente le
utilizzabili per lo scopo. proprietà ed i metodi.
WebBrowser (che si trova nella libreria SHDoc-
[Link]); per questo nel progetto introduciamo Number: restituisce o
un nuovo form che chiamiamo FrmBrowser. imposta il numero di
In esso inseriamo un oggetto WebBrowser, un errore;
RICERCA ComboBox e una PicturBox come in Fig. 3 (in real-
Source: imposta o
tà bisognerebbe inserire anche la barra dei pul-
SU INTERNET santi, i menu a tendina, …). Con questo form,
restituisce il nome
dell’oggetto o
Questa funzionalità può essere realizzata in due oltre ad illustrare un modo alternativo per pro- dell’applicazione che
modi: utilizzando direttamente delle chiamate iettare la nostra applicazione su Internet voglia- ha generato l’errore;
ad Internet Explorer oppure attraverso un form mo mostrare, come grazie alle PictureBox e ad
che contiene l’oggetto WebBrowser. Iniziamo a una serie di accorgimenti, è possibile creare una Description contiene la
descrizione dell’errore;
descrivere come utilizzare Internet Explorer. finestra con oggetti “ridimensionabili”. Nella Fig.
3 notate che il Combo (nominato indirizzo) si tro- HelpFile restituisce o
Private Sub internet_Click() va all’interno della PictureBox (nominata picindi- imposta
Dim IEApp As [Link] rizzo) e che quest’ultima è allineata al Top del un’espressione stringa
che contiene il
Set IEApp = New [Link] form (valore della proprietà Align=1 – Align Top).
percorso completo
[Link] = 500 Sul form gli elementi dovrebbero essere posti relativo a un file della
[Link] = 500 come in Fig. 3, altrimenti il codice, che tra poco Guida del progetto;
espandiform IEApp, 200 definiremo, nell’evento Resize, non funziona cor-
[Link] = True rettamente. HelpContext contiene
un ID di contesto
[Link] “[Link]
valido per il file della
End Sub
guida specificato.

La procedura precedente permette di creare ed I Metodi dell’oggetto


attivare un’istanza di Internet Explorer. Questo Err sono:
viene fatto attraverso gli elementi della libreria
Clear: azzera i valori di
SHDocVw (Internet Information Controls - SHDoc- tutte le proprietà
[Link]). Se non volete referenziare la libreria po- dell’oggetto Err;
tete utilizzare le seguenti istruzioni:
Raise genera un errore
Dim IEapp As Object
di run-time.

Set IEapp = CreateObject(“[Link]”)

In questo secondo caso, per aprire ed attivare In-


ternet Explorer, utilizziamo CreateObject con la
stringa “[Link]”. Fig. 3: FrmBrowser connesso ad internet.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/107 G
106-110 Corso VB Av 4-10-2003 10:19 Pagina 108

CORSI AVANZATI Visual Basic

Descriviamo le procedure a partire dalla [Link] [Link]


Form_Load. End Sub
Private Sub indirizzo_KeyPress(KeyAscii As Integer)
Private Sub Form_Load() On Error Resume Next
On Error Resume Next If KeyAscii = vbKeyReturn Then
[Link] = 1 indirizzo_Click
[Link] [Link], _ End If
[Link] + [Link] + 20 End Sub
[Link] = “[Link]
indirizzo_Click Oltre alle due procedure precedenti prevediamo
End Sub il codice per mantenere, nel ComboBox “indiriz-
zo”, gli URL già visitati. A tal fine definiamo la
In questa procedura impostiamo il valore del variabile nonusare che ci servirà per stabilire una
ComboBox “indirizzo” e la posizione del Web- condizione nella indirizzo_Click.
Browser e della PictureBox. Come accennato, con La nonusare verrà impostata dopo aver visitato
le istruzioni precedenti facciamo in modo che gli un indirizzo, come sarà chiaro tra poco.
elementi del form si ridimensionino quando vie-
ne attivato l’evento Resize (attraverso la proprietà Dim nonusare As Boolean
WindowState). Ricordiamo che il metodo Move
serve a posizionare gli oggetti, esso ha la seguen- Private Sub indirizzo_Click()
te sintassi: If nonusare Then Exit Sub
[Link] [Link]
[Link] sinistra, superiore, larghezza, altezza End Sub

Naturalmente nel Resize dobbiamo prevedere del Prima d’illustrare la procedura che carica gli URL
codice simile al seguente. nel ComboBox indirizzi descriviamo, l’evento del
WebBrowser, NavigateComplete2. Esso si verifica
CATTURARE Private Sub Form_Resize() dopo che il browser si è connesso con successo
ERRORI On Error Resume Next ad un nuovo indirizzo, quindi lo possiamo utiliz-
Per catturare gli errori WBordo = ([Link] - [Link]) / 2 zare per inserire gli URL nel ComboBox dopo che
in un’applicazione HTitolo = [Link] - [Link] - WBordo sono stati caricati. Di seguito presentiamo il co-
Visual Basic si possono
[Link] = [Link] - 2 * WBordo dice per questo evento.
utilizzare i seguenti
elementi: [Link] = [Link] - 2 * WBordo
On Error Goto [Link] = [Link] - _ Private Sub intWebBrowser_NavigateComplete2(By
<etichetta riga>, On [Link] - HTitolo - WBordo Val pDisp As Object, URL As Variant)
Error Resume, On Error
End Sub On Error Resume Next
Resume Next,
Dim i As Integer
l’oggetto Err. Questi
sono stati descritti A livello globale dobbiamo definire le variabili: Dim trovato As Boolean
ampiamente nei nostri [Link] = [Link]
precedenti articoli. Dim WBordo As Single, HTitolo As Single. For i = 0 To [Link] - 1
If [Link](i) = [Link]
Ricordiamo che ScaleWidth fornisce il numero di Then
pixel per l’asse orizzontale nel sistema di riferi- trovato = True
mento all’interno del Form (ScaleHeight per quel- Exit For
lo verticale) e che Width e Heigth per il form ven- End If
gono calcolate comprendendo i bordi e la barra Next i
del titolo. nonusare = True
Oltre a queste procedure, naturalmente, preve- If trovato Then
diamo il codice per gestire la fase di inserimento [Link] i
dell’indirizzo del sito, da cui vogliamo scaricare End If
le foto. Infatti, dopo essere state trovate su Inter- [Link] [Link], 0
net, le foto devono essere scaricate in una direc- [Link] = 0
tory (per esempio Immagini!) per essere, succes- nonusare = False
sivamente, sfogliate in modalità off-line. End Sub
L’indirizzo del sito, da consultare, lo connettiamo
tramite le seguenti istruzioni: Nella procedura precedente, oltre ad inserire gli
indirizzi nel combo, impostiamo il valore della
Private Sub indirizzo_Click() variabile nonusare che, come s’intuisce, serve per

h t t p : / / w w w. i o p r o g r a m m o . i t
G 108/Novembre 2003
106-110 Corso VB Av 4-10-2003 10:19 Pagina 109

Visual Basic CORSI AVANZATI

evitare di rivisitare un URL dopo aver impostato del form in base alle sue dimensioni (determina-
il valore da mostrare sul combo indirizzi (indiriz- te da WindowsState). Form_Resize per esempio
[Link] = 0). Inoltre facciamo in modo che può essere la seguente.
l’indirizzo che si sta visitando sia sempre nella
prima posizione del combo; per questo sullo Private Sub Form_Resize()
stesso elemento eseguiamo prima la Remove e Dim PuntoRife As Long
poi la Add. WBordo = ([Link] - [Link]) / 2
La procedura associata al pulsante Internet, della HTitolo = [Link] - [Link] - WBordo
FrmTrasparente, che serve per attivare la Frm- [Link] = [Link] - WBordo – 450
Browser è la seguente. [Link] = [Link] - [Link] -
HTitolo - 450 - 50
Private Sub internet_Click() PuntoRife = [Link] + 300
espandiform frmBrowser, 1000 [Link] = PuntoRife
‘descritta nel precdente articolo [Link] = PuntoRife
[Link] 1 [Link] = PuntoRife
End Sub [Link] = PuntoRife
[Link] = PuntoRife
Ora occupiamoci del ridimensionamento del [Link] = PuntoRife
form FrmTrasparente, cercando di non ingarbu- [Link] = PuntoRife
gliare le cose già definite nel precedente articolo. [Link] = PuntoRife
[Link] = PuntoRife
[Link] = PuntoRife
disegnaform
‘disegnaform l’abbiamo descritta nel
FRMTRASPARENTE ‘precedente appuntamento
RESIZE End Sub
Dato che in generale un form trasparente è senza NAVIGATE
bordo conviene gestire soltanto il ridimensiona- Notate che 450 è la dimensione della barra di La sintassi del metodo
mento innescato dalla proprietà WindowsState, scorrimento (non inclusa in quella del framefo- navigate è la seguente
[Link] URL [Flags,]
che come è noto può assumere tre valori: 0=posi- to) e che 50 serve per inserire dello spazio tra i [TargetFrameName,]
zione normale, 1=miniminizzata e 2=massimiliz- bottoni e il framefoto. [PostData,] [Headers]
zata. Il pulsante che attiva WindowsState, come si I parametri principali
nota in Fig. 1, è posto in basso vicino al pulsante sono: URL che
chiudi. La procedura associata al pulsante è la rappresenta il
documento da caricare.
pulsanteresize_Click, nella quale oltre alla pro- Flags che specifica se
prietà WindowState è gestita la proprietà Picture aggiungere l’URL
del pulsante (cioè l’immagine associata al pul- visitato alla history
sante). list. TargetFrameName
che è il frame in cui la
pagina verrà mostrata.
Private Sub pulsanteresize_Click()
If WindowState = 0 Then
WindowState = 2
[Link] = LoadPicture([Link] +
“/[Link]”)
Else
WindowState = 0
[Link] = LoadPicture([Link] +
“/[Link]”)
End If
End Sub
Fig. 4: Il Visualizzatore Immagini di Windows.
Le immagini [Link] e unrettangolo
.bmp (questa ultima mostrata in Fig. 1) devono Inoltre, per ridimensionare automaticamente
trovarsi nella directory del progetto. anche l’immagine, presente nel framefoto, pos-
Naturalmente questa funzione ha effetto, sugli siamo impostare la sua proprietà PictureSizeMode
elementi del form, se inseriamo del codice nell’e- cioè:
vento Resize. Quindi nella Form_Resize dobbiamo
prevedere del codice che posiziona gli elementi [Link] = fmPictureSizeModeZoom

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/109 G
106-110 Corso VB Av 4-10-2003 10:19 Pagina 110

CORSI AVANZATI Visual Basic

Questa proprietà ammette tre valori: fmPictureSi- [Link] 0, 2


zeModeStretch, fmPictureSizeModeZoom e fmPictu- End Select
reSizeModeClip. La PictureSizeMode di default è End Sub
impostata su fmPictureSizeModeClip.

IL VISUALIZZATORE
LO SCROLLING IMMAGINI DI XP
MANUALE Concludiamo con tre istruzioni a dir poco scon-
Per rendere più semplice lo spostamento delle volgenti!?
immagini sul framefoto, oltre alle scrollbar pos-
siamo utilizzare il metodo Scroll ed attivarlo at- Dim comodo As String
traverso una combinazione di tasti come per comodo = “[Link] [Link],
esempio i tasti freccia. ImageView_Fullscreen “ + “c:\foto”
Innanzitutto illustriamo la sintassi del metodo Shell comodo, vbNormalFocus
Scroll:
Se inserite queste istruzioni in un CommandBut-
[Link]( [ ActionX [, ActionY]]) ton potrete consultare i file di immagini (di sva-
riati tipi) contenuti nella cartella “c:/foto”. Vi con-
I due parametri opzionali, ActionX e ActionY, rap- sigliamo di studiare attentamente queste istru-
presentano rispettivamente l’azione che verrà zioni e di capire come poterle usare nelle vostre
fatta sull’asse orizzontale e su quello verticale. applicazioni.
I valori che questi parametri possono assumere Ricordiamo che Shell avvia un eseguibile e resti-
RUNDLL32 sono simili a quelli dei parametri nell’evento tuisce il suo ID.
Per avviare il FrameFoto_Scroll, descritto nell’articolo prece- La sintassi di Shell è la seguente
visualizzatore dente, ed in parte riportati nella seguente:
immagini di Windws
Shell(pathname[,windowstyle])
XP dal Prompt dei
Stringa Valore Descrizione
comandi, oppure
tramite il programma fmScrollActionNoChange 0 Nessuna azione Pathname è il nome del programma da eseguire,
Esegui, possiamo usare fmScrollActionLineUp 1 Spostamento a sinistra windowstyle serve per specificare lo stile della
una riga di comando o verso l’alto finestra che mostra il programma.
come la seguente: fmScrollActionLineDown 2 Spostamento a destra I valori della windowstyle sono riportati nella ta-
o verso il basso
[Link] bella seguente:
[Link], Tab. 1: Alcuni valori delle proprietà Action.
ImageView_Fullscreen Costante Valore Descrizione
c:\[Link] Il codice per gestire il movimento lo inseriamo vbHide 0 La finestra è attiva e nascosta
vbNormalFocus 1 La finestra è attivata nella
Questo comando apre
nella procedura PicMove che richiamiamo dall’e-
posizione originale.
il Preview di Windows vento framefoto_KeyDown.
vbMinimizedFocus 2 La finestra è attiva ad icona.
XP a pieno schermo e
vbMaximizedFocus 3 La finestra è attiva e
mostra l’immagine Private Sub framefoto_KeyDown(KeyCode ingrandita.
“[Link]” As [Link], Shift As Integer) vbNormalNoFocus 4 La finestra è nella posizione
PicMove (KeyCode) originale ma non attiva.
End Sub vbMinimizedNoFocus 6 La finestra è ridotta ad icona
ma non è attiva.
Sub PicMove(KeyCode As Integer) Tab. 2: I valori di windowstyle.
Select Case KeyCode
Case 37
‘freccia a sinistra
[Link] 1, 0
CONCLUSIONI
Case 38 In questo appuntamento abbiamo chiarito di-
‘freccia sopra versi aspetti sulla gestione dei form e parallela-
[Link] 0, 1 mente abbiamo aggiunto nuove caratteristiche
Case 39 all’applicazione Visualizzatore Immagini.
‘freccia a destra Nei successivi appuntamenti ci occuperemo di
[Link] 2, 0 argomenti caldi come HotKey, gestione porte
Case 40 parallele ed USB … Seguiteci!
‘freccia sotto Massimo Autiero

h t t p : / / w w w. i o p r o g r a m m o . i t
G 110/Novembre 2003
111-116 ADV Soap 4-10-2003 10:20 Pagina 111

Programmare il Web con i WebService ADVANCED EDITION

Web Service: funzionalità avanzate

Attachment in
SOAP con Delphi 7
SOAP ha rappresentato una vera e propria rivoluzione nel mondo
dell’interoperabilità di servizi applicativi esposti da sistemi
eterogenei. Quello che mancava era il supporto agli attachment; la
specifica è stata finalmente completata e Borland, con la versione 7
di Delphi l’ha implementata.

A
mio avviso SOAP è davvero una delle più L’effetto positivo è di ottenere un unico grande
grandi rivoluzioni informatiche degli ultimi testo, quello negativo è che la dimensione in byte
anni. Probabilmemte non è ancora recepita del testo può essere anche molto maggiore (persino
ed utilizzata fino in findo per quello che è, ma spes- del 50%) della dimensione in byte del binario origi-
so viene vista come una delle tante tipologie di nario. Ovviamente lo stream base64 viene riconver-
applicazioni che si possono creare da Visual Studio tito con un processo contrario quando arriva a
.NET o da Delphi, ma non come il protocollo stan- destinazione e il file binario viene così ricostruito.
dard di fruizione di oggetti da sistemi eterogenei.
Sarà quindi un processo lento di assimilazione e di
❏ CD ❏ WEB
presa di coscienza, ma sicuramente inesorabile.
Quello che finora mancava era il supporto agli alle- LA SPECIFICA SOAP 1.1 [Link]

[Link]
gati, cioè a file e stream che si possono inviare al ser- La specifica SOAP 1.1, la prima rilasciata ad avere
ver o ricevere da questo. In effetti non è facile invia- una reale implementazione, non conteneva nes-
re in formato xml una cartina raster di una planime- sun riferimento alla possibilità di inviare binari.
tria o il database Access dei clienti, ma non è nem- Solo successivamente è stata messa a punto la
meno impossibile considerando che da anni, senza specifica SOAP con attachment che prevede
dare troppo importanza alla cosa, facciamo dal essenzialmente di utilizzare il protocollo MIME, lo
browser il download o l’upload via http di file. Il stesso utilizzato nella posta elettronica. In pratica
principio è semplice: il file binario viene trasferito si tratta di una sovrastruttura sul protocollo
come se fosse un normale file di testo, cioè ogni byte base64. MIME multipart, però, prevede alcune
che lo compone viene trattato come un carattere scelte progettuali che rendono la sua implementa-
stampabile e poi viene riassemblato a destinazione. zione poco efficiente, almeno a detta di alcuni.
Il vero problema dei binari è come rappresentare in Questo resterebbe soltanto un giudizio di parte e
xml o in testo libero i caratteri non stampabili, quel- persino sterile, se non fosse che è condiviso, anzi
li che praticamente rendono problematica, ad propugnato da uno dei massimi ideatori ed imple-
esempio, la lettura di file binari aperti con Notepad. mentatori della specifica SOAP: Microsoft. Infatti,
Fortunatamente esiste un formato di trasformazio- nonostante siano stati tra gli autori della specifica,
ne che si chiama base64 che si basa su un principio al momento della reale implementazione in .NET
molto semplice: per ogni byte che compone il file e nella versione 3 del Soap Toolkit per COM hanno
binario, se questo corrisponde ad un carattere deciso di avallare una nuova specifica standard di
stampabile, allora lo si lascia inalterato, se invece cui loro stessi, ancora una volta, sono stati tra gli
non è stampabile, si trasforma in una sequenza di n ideatori cioè DIME (Direct Internet Message En-
caratteri stampabili corrispondenti a quel byte. capsulation). Anch’essa usa base64 per l’enco-
Stesso discorso vale per eventuali byte corrispon- ding/decoding degli allegati, ma introduce un
denti a caratteri stampabili incompatibili con xml o protocollo completamente diverso per tutta la
html: in questo caso vengono nuovamente sostitui- parte di header. Gli autori sostengono che sia più
ti con una sequenza di caratteri stampabili innocui. semplice, più potente e che renda meno probabili

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/111 G
111-116 ADV Soap 4-10-2003 10:20 Pagina 112

ADVANCED EDITION Programmare il Web con i WebService

errori di implementazioni che ne inficino l’intero- ti BizSnap Update Pack 3 interagisce con pochissimi
perabilità. Intanto, al di la di quella che sia la o nessun problema con .NET, IBM WebSphere e
verità, il problema è che ci sono due differenti spe- quasi tutti gli altri, come ho mostrato in alcuni miei
cifiche e quel che è peggio è che le suite SOAP precedenti articoli. Cosa ci si poteva aspettare da
attualmente disponibili abbiano deciso di imple- Delphi 7, allora? Un’interoperabilità ancora più
mentare l’una piuttosto che l’altra. Microsoft .NET completa e senza l’uso di alcuni trucchetti come
implementa DIME, Borland BizSnap implementa avveniva per la 6 e soprattutto l’implementazione di
MIME multipart… Quindi? La brutta notizia è che ciò che di SOAP mancava ancora in BizSnap: i
non sono interoperabili. Suppongo, ma sono SOAP Header e i SOAP Attachment. Questi secon-
quasi certo, che saranno Borland e tutti gli altri di, come avrete potuto ampiamente già “sospetta-
implementatori pro MIME a piegarsi in futuro, re”, ci occuperemo in questo articolo. Per una
coprendo anche DIME perché attualmente non si migliore comprensione dell’articolo sarebbe neces-
può pensare di implementare SOAP rendendosi saria una conoscenza, seppur minima di BizSnap o
incompatibili con Microsoft e la sua corazzata almeno dei concetti legati a SOAP. La rete è ricchis-
.NET. sima di materiale, ma anche le edicole e le librerie…
Sia per i neofiti che per coloro che già conoscono
SOAP e/o BizSnap è interessante notare come è
strutturato un messaggio SOAP contentente un
BORLAND BIZSNAP attachment MIME multipart; si immagini di voler
DI DELPHI 7 invocare un servizio strutturato col seguente proto-
Borland ha introdotto con Delphi 6 la tecnologia tipo in linguaggio Delphi:
BizSnap che altro non è che l’implementazione del-
la specifica SOAP 1.1. All’epoca dell’uscita di Delphi function GetFile(username, password, filename :
6 nemmeno .NET era stato ancora rilasciato, era in String) : TSOAPAttachment;
beta, in giro si trovavano alcuni toolkit SOAP più o
meno efficaci e Sun, IBM e tutti quelli che “bazzica- Si tratta di un semplice metodo che richiede al ser-
no” Java erano ancora a rigirarsi i pollici mentre ver un certo allegato. Infatti, il valore di ritorno del
riflettevano se e come supportare Java. Borland, in- metodo è un oggetto TSOAPAttachment che è la
vece, era già pronta e il suo prodotto era fantastico: rappresentazione BizSnap di un allegato MIME
completo, semplice e potente. multipart. In Tab. 1 è possibile osservare la firma
dell’oggetto TSOAPAttachment. L’oggetto, come
Nome Tipo Descrizione tutti gli oggetti che sono rappresentazioni di para-
ContentType Proprietà Legge e imposta il ContentType MIME dell’allegato metri o oggetti da trasmettere o ricevere via SOAP,
Encoding Proprietà Legge e imposta l’alfabeto di encoding dell’allegato. discende da TRemotable. Internamente rimappa
Il default è lo standard UTF-8
un TStream che, concettualmente, è la cosa più
Headers Proprietà Ritorna o imposta il TStrings contentente gli header MIME dell’allegato.
vicina ad un attachment SOAP, cioè uno stream
Ownership Proprietà Ritorna od imposta il tipo di controllo sullo stream (TStream) che
contiene l’allegato vero e proprio. Si tratta di un tipo enumerato che può
binario di dati eterogenei.
contenere i valori soReference (lo stream è solo riferito e non viene distrutto Questo ci consente di creare un Soap attachment a
alla distruzione del TSOAPAttachment) o soOwned (lo stream ha scope solo partire da uno stream e di deserializzare un attach-
nell’ambito del TSOAPAttachment).
ment in uno stream.
SourceStream Proprietà Il TStream interno.
Osserviamo la richiesta SOAP:
SourceString Proprietà L’encoding in base64, secondo l’alfabeto descritto da Encoding, quindi
rappresenta proprio la stringa di encoding dell’allegato.
ObjectToSOAP Metodo Converte un allegato nella sua rappresentazione SOAP. <?xml version=”1.0” encoding=”UTF-8”?>
SaveToFile Metodo Salva l’allegato SOAP su un file <SOAP-ENV:Envelope xmlns:SOAP-ENV=
SaveToStream Metodo Salva l’allegato SOAP in uno stream ”[Link]
SetSourceFile Metodo Imposta il file di origine dell’allegato SOAP, in pratica il file che si intende ”[Link] xmlns:xsi=
spedire ”[Link]
SetSourceStream Metodo Imposta lo stream di origine dell’allegato SOAP, quindi lo stream da spedire
xmlns:SOAP-ENC=
SOAPToObject Metodo Converte un allegato SOAP in un oggetto.
”[Link]
Tab. 1: L’oggetto TSOAPAttachment. <SOAP-ENV:Body SOAP-ENV:encodingStyle=
”[Link]
Certo la specifica non era ancora consolidata e <NS1:GetFile xmlns:NS1=”urn:
quindi l’interoperabilità era ancora un sogno nem- AttachmentsManagerIntf-IAttachmentsManager”>
meno troppo confessabile. Tant’è che i tre service <username xsi:type=”xsd:string”>ciro</username>
pack che si sono succeduti su Delphi 6 erano in <password xsi:type=”xsd:string”>ciro</password>
realtà dei service pack per BizSnap, non tanto per <filename xsi:type=”xsd:string”>
correggerne i bug, ma per renderlo pienamente [Link]</filename>
interoperabile. L’obiettivo è stato raggiunto ed infat- </NS1:GetFile>

h t t p : / / w w w. i o p r o g r a m m o . i t
G 112/Novembre 2003
111-116 ADV Soap 4-10-2003 10:20 Pagina 113

Programmare il Web con i WebService ADVANCED EDITION

</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Fin qui, per chi ha già osservato altre volta come è


strutturata una richiesta SOAP, non c’è nessuna
novità. Le novità si incontrano ovviamente nella
risposta del server che dovrà contenere anche l’alle-
gato MIME multipart richiesto: Fig. 1: Il Web App Debugger visto dal browser.
DEBUGGING
Content-ID: <[Link] troviamo finalmente il contenuto del nostro allega- DI APPLICAZIONI
Content-Location: [Link] to che, nell’esempio, è un file in chiaro. Se si fosse WEB SENZA WEB
Content-Length: 538 trattato di un file binario puro avreste trovato una SERVER
<?xml version=”1.0”?> incomprensibile sequenza di caratteri base64. Borland ha deciso di
fornire anche la
<SOAP-ENV:Envelope xmlns:SOAP-ENV= L’allegato inizia e termina con il tag —MIME_
possibilità di testare le
”[Link] xmlns:xsd= boundaryB0R9532143182121. Semplice, ma effi- applicazioni Web
”[Link] xmlns:xsi= cace, da far venir voglia di implementarsi MIME (WebSnap e BizSnap)
”[Link] multipart da zero e senza l’uso di alcun toolkit. Ma anche in mancanza di
xmlns:SOAP-ENC=”[Link] questa idea balzana vi passa quasi subito se osser- un web server. Per far
ciò ha introdotto un
soap/encoding/”> vata quanto è banale utilizzare tutta questa roba in
tool con Delphi 6 che si
<SOAP-ENV:Body SOAP-ENC:encodingStyle= Delphi 7. Ma andiamo con ordine. chiama Web App
”[Link] Debugger, esso
<NS1:GetFileResponse xmlns:NS1=”urn: permette di mandare
AttachmentsManagerIntf-IAttachmentsManager”> in esecuzione, e di
<return href=”cid:EF58639D-EB0E-4F7E-
UN ESEMPIO REALE effettuare il
debugging, di queste
A92B-D23397264C49”/> Siccome comprendere la teoria è importante, ma applicazioni anche
</NS1:GetFileResponse> vederne un’applicazione reale è spesso più efficace, senza il server http.
</SOAP-ENV:Body> immaginiamo di voler realizzare un web service che L’idea è ingegnosa: si
</SOAP-ENV:Envelope> faccia da repository remoto di nostri file, una sorta realizza una nuova
applicazione web, ma
—MIME_boundaryB0R9532143182121 di ftp basato su SOAP. Certo, poteva trovare un’idea
questa volta di tipo
Content-ID: <EF58639D-EB0E-4F7E-A92B-D23397264C49> più intelligente, ma l’obiettivo e mostrare la tecno- Web App Debugger
Content-Length: 346 logia e le sue potenzialità: le implementazioni reali executable. In questo
Content-Type: application/binary e plausibili sono lasciate al lettore… Implementere- modo viene realizzato
[SCC] mo il nostro web service come un’applicazione di un oggetto COM
ActiveX Exe (si, avete
SCC=This is a source code control file tipo Web App Debugger in modo da non rendere
letto bene) che
[[Link]] necessaria la presenza di un web server sulla nostra implementa
SCC_Project_Name=this project is not under source macchina durante le fasi di scrittura del codice e per un’interfaccia
code control poter facilmente effettuare il debug del codice convenzionale.
SCC_Aux_Path=<This is an empty string for the durante la scrittura, cosa possibile solo attraverso la Al progetto verrà
infatti aggiunta
[Link] file> tecnologia Web App Debugger (Box laterale). Per le
automaticamente una
[[Link]] fasi di creazione di un web service con Delphi 6/7 e unit con un form nella
SCC_Project_Name=this project is not under source per la scelta della tipologia di applicazione SOAP da cui parte di
code control creare si rimanda alla documentazione specifica. inizializzazione viene
SCC_Aux_Path=<This is an empty string for the Il nostro file server deve essere dotato dei seguenti istanziato l’oggetto
COM, cioè
[Link] file> metodi raccolti nella tipica interfaccia che deve
l’applicazione stessa:
—MIME_boundaryB0R9532143182121— essere sempre definita quando si intende produrre
un web service con Delphi BizSnap: implementation
Innanzitutto la risposta è preceduta da un tipico uses ComApp;
header http che preannuncia alcune informazioni IAttachmentsManager = interface(IInvokable) const
relative alla risposta contenente l’allegato. Subito [‘{1FCAC702-CD3C-4260-BF05-743EECEB3C3C}’] CLASS_ComWebApp:
dopo, però, riconoscerete sicuramente il tradiziona- function GetFileList(username, password : String) TGUID = ‘{B1076694-
le envolope SOAP Response. Questo ha particola- : TStringArray; stdcall; 49C4-4CC1-BD70-

rità: il tag <return> fa riferimento ad un file allegato function GetFile(username, password, filename 66F83908F851}’;
initialization
raggiungibile http, cioè href=”cid:EF58639D-EB0E : String) : TSOAPAttachment; stdcall;
TWebAppAutoObject
-4F7E-A92B-D23397264C49”. Infatti la parte suc- function UploadFile(username, password, filename: String;
[Link](
cessiva del messaggio è proprio un file MIME multi- fileToUpload : TSOAPAttachment) : Boolean; stdcall;
Class_ComWebApp,
part con lo stesso Id. Il suo Content /Type è il tradi- end;
‘PartTwo’, ‘PartTwo
zionale (ed indeterminato) application/binary e la Object’);
sua lunghezza è 346 byte (caratteri). A questo punto Il metodo GetFile, che abbiamo già introdotto in

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/113 G
111-116 ADV Soap 4-10-2003 10:20 Pagina 114

ADVANCED EDITION Programmare il Web con i WebService

Il metodo UploadFile, invece, funziona al contrario:


consente ad un client di inviare un allegato sul ser-
ver. Osserviamone l’implementazione:

function [Link](username,
password, filename: String;
fileToUpload: TSOAPAttachment): Boolean;
begin
Fig. 2: La console del Web App Debugger. Result:= false;
DEBUGGING if (username = STD_USERNAME) and (password =
DI APPLICAZIONI precedenza per spiegare la messaggistica SOAP, si STD_PASSWORD) then
WEB SENZA WEB occupa di tirare giù un allegato dal server identifica- begin
SERVER to da un nome. I parametri username e password [Link](FILE_PATH + filename);
Il Web App Debugger consentono di effettuare questa operazione solo se Result:= true;
può essere mandato in si è autorizzati. In realtà la gestione degli account end
esecuzione (Fig. 2),
nell’esempio è davvero primitiva. Il metodo GetFile- else
mettendosi in ascolto
sulla porta 1024 locale List restituisce invece un array di stringhe conten- Raise [Link](‘Login errata!’);
(o su altre configurabili tente l’elenco di tutti i file presenti sul server. Infine end;
ad hoc). Questo tool, UploadFile consente di fare l’upload di un nuovo file
tra le altre sul server che, da quel momento, diventerà disponi- L’implementazione di questo metodo è ancora più
funzionalità, permette
anche di tracciare un
bile per un successivo download. Il web service è banale: il TSOAPAttachment, giunto come parame-
log completo di tutte definito nel progetto [Link] dispo- tro dal client, viene salvato direttamente nella car-
le chiamate http al nibile tra i sorgenti allegati al presente articolo. Per tella del server in cui vengono conservati i file espo-
server. Infatti, comprendere l’assoluta semplicità di gestione degli sti ai client. Ma, come abbiamo già fatto per GetFile,
accedendo all’URL: allegato SOAP con la libreria BizSnap, osserviamo osserviamo come, a basso livello, viene assemblata
[Link]
l’implementazione dei metodi dell’interfaccia nella ed inviata la richiesta UploadFile dal client al server:
[Link] classe TAttachmentsManager del progetto a comi-
nciare dalla GetFile: Content-Type: text/xml
si richiamerà un SOAPAction: “urn:AttachmentsManager
eseguibile Web App const FILE_PATH : String = ‘c:\prove\’; Intf-IAttachmentsManager#UploadFile”
Debugger di sistema,
const STD_USERNAME : String = ‘ciro’; Content-ID: <[Link]
con ProgID ServerInfo.
ServerInfo, che ci const STD_PASSWORD : String = ‘ciro’; Content-Location: [Link]
mostrerà la mappa function [Link](username, Content-Length: 700
delle applicazioni password, filename: String): TSOAPAttachment; <?xml version=”1.0” encoding=”UTF-8”?>
WebApp installate nel var <SOAP-ENV:Envelope xmlns:SOAP-ENV=
sistema locale, tra cui
stream : TFileStream; ”[Link] xmlns:xsd=
la nostra (con ProgID
[Link]). begin ”[Link] xmlns:xsi=
Così possiamo if (username = STD_USERNAME) and (password = ”[Link] xmlns:
finalmente far STD_PASSWORD) then SOAP-ENC=”[Link]
eseguire la nostra begin <SOAP-ENV:Body SOAP-ENV:encodingStyle=
applicazione da
stream:= [Link](FILE_PATH + ”[Link]
WebAppDebugger e
farci restituire il WSDL filename, fmOpenRead); <NS1:UploadFile xmlns:NS1=”urn:
invocando la URL: Result := [Link]; AttachmentsManagerIntf-IAttachmentsManager”>
[Link](stream, soOwned); <username xsi:type=”xsd:string”>ciro</username>
[Link] end <password xsi:type=”xsd:string”>ciro</password>
[Link]/wsdl
else <filename xsi:type=”xsd:string”>[Link]
E’ inutile dire che poter Raise [Link](‘Login errata!’); </filename>
effettuare il debugging end; <fileToUpload href=”cid:2477FD62-6EB3-4655-B6F2-
step by step, è D08AC06A26DA”/>
impareggiabile. Basta Dopo aver verificato la login, confrontandola banal- </NS1:UploadFile>
mettere in Run
mente con due costanti definite nel codice, viene </SOAP-ENV:Body></SOAP-ENV:Envelope>
l’applicazione con un
F9 e il gioco è fatto. caricato il file richiesto in un TFileStream (un —MIME_boundaryB0R9532143182121
Finalmente le stringhe discendente di TStream che lavora sul filesystem). Content-ID: <2477FD62-6EB3-4655-B6F2-D08AC06A26DA>
di debugging stampate Viene dunque creato il TSOAPAttachment che Content-Length: 141
direttamente nella costituirà il valore di ritorno della funzione, nonché Content-Type: application/binary
pagina web del client
l’allegato da inviare al client e lo stream verrà asse- Content-transfer-encoding: binary
saranno solo un
ricordo (triste)… gnato al TSOAPAttachment con l’istruzione Set- <%
SourceStream. E il gioco è fatto… Dim oXMLProxy

h t t p : / / w w w. i o p r o g r a m m o . i t
G 114/Novembre 2003
111-116 ADV Soap 4-10-2003 10:20 Pagina 115

Programmare il Web con i WebService ADVANCED EDITION

Set oXMLProxy = CreateObject( files : TStringArray;


“[Link]”) i : Integer;
[Link] Request, Response begin
%> [Link];
—MIME_boundaryB0R9532143182121— [Link];
attachManager:= GetIAttachmentsManager(
Si può osservare come, ancora una volta, il parame- false, [Link], HTTPRIO1);
tro fileToUpload di tipo TSOAPAttachment, cioè files:= [Link]([Link],
proprio il file che il client invia al server, sia a livello [Link]);
SOAP definito semplicemente come un link ed in [Link];
particolare come il link HTTP href=”cid: 2477FD62- for i:= 0 to Length(files) - 1 do
6EB3-4655-B6F2-D08AC06A26DA”. begin
Al termine dell’evenlope SOAP viene riportato pro- [Link](files[i]);
prio il file allegato in formato MIME multipart, ana- end;
logamente a quanto descritto in precedenza.
La risposta del server sarà un più banale:

<?xml version=”1.0”?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=
”[Link] xmlns:xsd=
”[Link] xmlns:xsi=
”[Link] xmlns:
SOAP-ENC=”[Link]
<SOAP-ENV:Body SOAP-ENC:encodingStyle=
”[Link]
<NS1:UploadFileResponse xmlns:NS1=”urn:
Fig. 3: Il client in azione.
RIFERIMENTI
AttachmentsManagerIntf-IAttachmentsManager”> RFC ufficiale della
specifica base64
<return xsi:type=”xsd:boolean”>true</return>
[Link]
</NS1:UploadFileResponse></SOAP-ENV:Body> Da notare come il web service, o meglio il suo proxy [Link]
</SOAP-ENV:Envelope> lato client, venga creato dalla funzione GetIAttach-
mentManager che è stata generata automatica- Documento w3c
In pratica un true o un false che indica la riuscita o mente da wizard di importazione lato client di ufficiale della specifica
meno dell’upload, come si poteva evincere dall’im- Delphi per i web service. L’elenco viene mostrato in SOAP con attachment
[Link]
plementazione Delphi del metodo UploadFile. Il una listbox e l’utente, semplicemente con un dop- SOAP-attachments
metodo GetFiles, invece, non presenta particolarità pio click sull’elemento desiderato, può richiedere il
interessanti ai fini dell’obiettivo di questo articolo, download di quel file (attraverso l’invocazione del Documento della
per cui per la sua consulatazione si rimanda al sor- metodo GetFile sull’evento DoubleClick della list- specifica DIME
gente allegato. box): [Link]
team/xml_wsspecs/dime/

procedure TForm1.ListBox1DblClick(Sender: TObject); [Link]


var com/article/0,1410,27301,
IL CLIENT attachManager : IAttachmentsManager; [Link]
soapAttach : TSOAPAttachment;
DEL NOSTRO begin
WEB FILE SERVER if [Link] <> - 1 then
Il progetto [Link] rappresen- begin
ta il client che consuma il nostro servizio. Per l’ag- attachManager:= GetIAttachmentsManager(
gancio e l’importazione di un web service da un false, [Link], HTTPRIO1);
client Delphi si rimanda alla documentazione speci- soapAttach:= [Link]([Link],
fica. Osserviamo come si presenta in Fig. 3. [Link], [Link][[Link]]);
Si tratta di una semplice applicazione Windows CreateDir(ExtractFileDir([Link])
scritta in Delphi che si connette al nostro web servi- + ‘\downloads’);
ce e richiede immediatamente l’elenco dei file pre- [Link](ExtractFileDir(
senti sul server attraverso il metodo GetFiles del web [Link]) + ‘\downloads\’ +
service: [Link][ [Link]]);
ShowMessage(‘Download riuscito!’);
var end;
attachManager : IAttachmentsManager; end;

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/115 G
111-116 ADV Soap 4-10-2003 10:20 Pagina 116

ADVANCED EDITION Programmare il Web con i WebService

Anche l’upload è altrettanto semplice: si sceglie da due eventi viene rediretto su due TMemo presenti
una finestra Common Dialog il file da inviare e lo si in un altro pannello del form del client di esempio,
invia. come mostrato in Fig. 4.
Eccone il codice: Osserviamone la semplice implementazione degli
event handler:
procedure [Link](Sender:TObject);
var procedure TForm1.HTTPRIO1AfterExecute(const
attachManager : IAttachmentsManager; MethodName: String; SOAPResponse: TStream);
soapAttach : TSOAPAttachment; var
begin Temp: TStringStream;
if [Link] <> ‘’ then begin
begin Temp := [Link](‘’);
attachManager:= GetIAttachmentsManager(false, try
[Link], HTTPRIO1); [Link](SOAPResponse, 0);
soapAttach:= [Link]; [Link] := [Link];
[Link]([Link]); finally
[Link]([Link], [Link];
[Link], ExtractFileName( end;
[Link]), soapAttach); end;
end procedure TForm1.HTTPRIO1BeforeExecute(const
L’AUTORE else MethodName: String; var SOAPRequest: WideString);
Vito Vessia è ShowMessage(‘File non definito!’); begin
cofondatore della
end; [Link](SOAPRequest);
codeBehind S.r.l.
end;
htttp://[Link] Una interessante possibilità offerta da BizSnap di
Delphi 7 è l’intercettazione della messaggistica
una software factory di SOAP che viene inviata e ricevuta dal server.
applicazioni enterprise, In pratica l’oggetto THTTPRIO, che funge da proxy CONCLUSIONI
web e mobile, dove
progetta e sviluppa
verso il web service, adesso espone quattro eventi Questo articolo ha introdotto e spiegato alcuni con-
applicazioni e che si scatenano quando viene inviata o ricevuta cetti legati alla gestione degli allegati della specifica
framework in .NET, una richiesta SOAP o quando viene inviato o ricevu- SOAP, almeno nella versione più antica ed ufficiale,
COM(+) e Delphi to un SOAP Attachment. Per l’esempio sono stati MIME multipart, che è stata scelta da Borland per la
occupandosi degli intercettati i primi due eventi di cui possiamo osser- sua implementazione nella libreria SOAP BizSnap
aspetti architetturali. È
autore del libro
vare i prototipi: presente in Delphi 7. Inoltre abbiamo creato un
“Programmare il esempio reale osservando la semplicità di fruizione
cellulare”, Hoepli, procedure HTTPRIO1AfterExecute(const MethodName: e di scrittura del codice per realizzare una funziona-
2002, sulla String; SOAPResponse: TStream); lità che, tutto sommato, non si può considerare
programmazione dei
procedure HTTPRIO1BeforeExecute(const banale. E abbiamo cercato di spiare cosa accadeva a
telefoni cellulari
MethodName: String; var SOAPRequest: WideString); basso livello cioè come quelle semplici istruzioni
connessi al PC con
protocollo standard Delphi venissero trasformate in messaggi SOAP che,
AT+. Può essere non dimentichiamoci, è un protocollo standard di
contattato tramite e- fruizione di servizi web da piattaforme eterogene
mail all’indirizzo basato sul protocollo HTTP per la comunicazione e
[Link]
su un xml governato da schemi standard per la
@[Link]. parte applicativa.
Ciò significa che avremmo potuto scrivere un client
che fruiva del servizio di file server anche in una
piattaforma diversa da Delphi, così come in Delphi
avremmo potuto scrivere un client in grado di con-
sumare un servizio SOAP che, tra i suoi parametri,
permetta di inviare o ricevere allegati, purchè di tipo
Fig. 4: La messaggistica SOAP “spiata” dal client.
MIME multipart. In soldoni: il server sarebbe potu-
to essere un host AS/400 con Web Sphere e, se non
Con il primo vengono intercettati i messaggi SOAP ci fosse stata di mezzo la diatriba tra MIME multi-
che il client invia al server, con il secondo invece le part e DIME, anche un server Windows con IIS e un
risposte del server. Grazie a questo due eventi è pos- web service .NET.
sibile spiare SOAP a livello più basso per capire Sembra un sogno che si trasforma in realtà…
come funziona davvero. Il contenuto ricevuto dai Vito Vessia

h t t p : / / w w w. i o p r o g r a m m o . i t
G 116/Novembre 2003
117-121 ADV API 4-10-2003 10:21 Pagina 117

Networking ADVANCED EDITION

Reperire la configurazione di una rete

Network API
in VB
Esistono diverse API che permettono di ottenere informazioni sulla
parte prima

nostra rete. E non solo…

S
appiamo tutti che i sistemi operativi Windows all’interno di questa DLL, è possibile recuperare
affidano la maggior parte dei compiti da svol- svariate informazioni ed effettuare diverse opera-
gere a programmi che si appoggiano a funzio- zioni che, altrimenti, diventerebbero complicate da
ni “preconfezionate” contenute, a loro volta, in li- gestire, specie per linguaggi come Visual Basic.
brerie dinamiche .DLL. E’ quasi ovvio pensare dun- Le varie tipologie di operazioni che possiamo com-
que che, tutto quello che Windows consente di fare, piere servendoci di questa libreria possono essere
dalla semplice gestione delle finestre, al recupero di così suddivise:
informazioni e quant’altro viene messo a dispo-
sizione dell’utente/amministratore, sia possibile • Recupero delle informazioni relative alla con-
ottenerlo nella medesima maniera, ossia affidando- figurazione di rete.
❏ CD ❏ WEB
[Link]
si alle centinaia di API fornite con il sistema operati-
[Link]
vo stesso. In realtà, un fondo di verità, relativamen- • Recupero di informazioni sul protocollo IP e
te a questa affermazione, esiste, poiché chi conosce ICMP.
questo “tipo” di programmazione, sa che le tantissi-
me funzioni messe a disposizione da Windows con- • Configurazione degli adattatori di rete.
sentono di effettuare operazioni spesso complicate
(se non impossibili) da ottenere con i mezzi classici • Configurazione delle interfacce di rete e degli
offerti dai più comuni linguaggi di programmazio- indirizzi IP.
ne. Le API di Windows, come già saprete, sono dav-
vero moltissime, spesso piuttosto complicate da ge- • Utilizzo di ARP.
stire, anche se consentono di ottenere risultati
straordinari. Un esempio immediato è la “banale” • Gestione delle notifiche di eventi riguardanti
funzione SendMessage(), attraverso la quale è possi- la rete.
bile inviare ad una qualunque finestra di Windows
un opportuno messaggio per notificarle il verificar- • Recupero informazioni sul protocollo TCP ed
si di un particolare evento o per “ordinarle” di com- UDP.
piere qualche azione. Questa volta ci occuperemo di
una particolare categoria di funzioni che si occupa Le funzioni appartenenti ad essa sono diverse deci-
di aiutare il programmatore nella risoluzione di pro- ne e si appoggiano, per la maggior parte dei casi, a
blemi legati alle reti e, di conseguenza, ai protocolli diverse strutture, spesso piuttosto complesse da uti-
che vi ruotano intorno (TCP/IP compreso, ovvia- lizzare, ma che alla fine ci consentono di ottenere
mente). moltissime informazioni. Di seguito ecco solo una
piccolissima parte delle funzioni che appartengono
a questa libreria (solo le prime in ordine alfabetico)
con una breve descrizione sul loro scopo:
LE IP HELPER API
Tra le tante librerie dinamiche rese disponibili da AddIPAddress: consente di aggiungere un indiriz-
Windows, sicuramente qualcuno si sarà accorto zo IP.
della presenza della [Link], una libreria dina-
mica il cui nome fa di certo subito sottointendere lo CancelIpChangeNotify: elimina l’invio di notifiche
scopo. Attraverso le tantissime funzioni presenti sul cambiamento di indirizzo IP e d’instradamento

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/117 G
117-121 ADV API 4-10-2003 10:21 Pagina 118

ADVANCED EDITION Networking

precedentemente richiesti attraverso NotifyAddr- molto utili i riferimenti a documentazione ed esem-


Change e NotifyRouteChange. pi reperibili direttamente dal sito della Microsoft o
altrove su Internet. Prima di passare oltre, è bene
CreateIpForwardEntry: crea una route all’interno rammentare che tutti gli esempi realizzati in questa
della route table. serie di articoli sono stati testati su Windows 2000
Professional e che il linguaggio utilizzato per la
CreateIpNetEntry: crea una nuova ARP entry. costruzione dei progetti è stato Visual Basic 6.0
Professional.
IP_ADDR_STRING
Next Long Puntatore alla successiva struttura IP_ADDR_STRING
IpAddress String * 16 IP Address
IpMask
Context
String * 16
Long
Subnet Mask
Network table entry (NTE).
LE FUNZIONI
DEL PROGETTO
FIXED_INFO Questo primo progetto in Visual Basic è, per certi
HostName String * MAX_HOSTNAME_LEN Nome HOST del PC aspetti, molto semplice. Esso, infatti, consente di
DomainName String * MAX_DOMAIN_NAME_LEN Nome del dominio di appartenenza
ottenere informazioni circa la configurazione della
CurrentDnsServer Long DNS Server primario
propria scheda di rete, sfruttando per questo soltan-
DnsServerList As IP_ADDR_STRING Lista linkata dei server DNS
to due delle tante funzioni appartenenti a questa
NodeType Long Node type del PC
ScopeId String * MAX_SCOPE_ID_LEN Netbios Scope ID categoria. Tuttavia, quest’esempio consente di
EnableRouting Long Routing abilitato/disabilitato approfondire anche altri aspetti legati alla program-
EnableProxy Long Proxy abilitato/disabilitato mazione che potrebbero tornare utili anche per un
EnableDns Long Risoluzione nomi con DNS altro genere di applicazioni. La prima funzione uti-
lizzata all’interno del progetto è la GetNetworkPa-
Tab. 1: Le strutture IP_ADDR_STRING e FIXED_INFO.
rams() la cui sintassi, così come dichiarata all’inter-
no di Visual Basic, è:
CreateProxyArpEntry: crea una nuova PARP entry
relativamente ad un certo IP address. Public Declare Function GetNetworkParams Lib “IPHlpApi”
(FixedInfo As Any, pOutBufLen As Long) As Long
DeleteIPAddress: cancella un indirizzo IP preceden-
temente creato con AddIPAddress. dove:

DeleteIpForwardEntry: elimina una route entry FixedInfo: rappresenta un puntatore ad una struttu-
all’interno della IP routing table. ra di tipo FIXED_INFO (mostrata in seguito) che non
fa altro che raccogliere i dati relativi alla configura-
DeleteIpNetEntry: elimina un’entry ARP. zione di rete del proprio PC. Il prefisso FIXED, da-
vanti al nome della struttura, non è affatto casuale
GLI DeleteProxyArpEntry: elimina una PARP entry. poiché, scopo di questa struttura, è proprio quello di
STRUMENTI memorizzare i dati di rete non strettamente legati ad
NECESSARI DisableMediaSense: disabilita la funzionalità di me- un particolare network adapter installato sul PC.
Tutti gli esempi dia sensing di una determinata interfaccia di rete. Alcune delle informazioni ritornate dalla funzione
realizzati in questa sono, ad esempio, il nome del dominio di apparte-
serie di articoli sono
stati testati su EnableRouter: abilita l’IP forwarding sul PC. nenza, il nome del PC, ecc.
Windows 2000
Professional FlushIpNetTable: elimina tutte le ARP entry pOutBufLen: questo valore Long specifica la dimen-
Il linguaggio utilizzato dall’ARP table. sione in byte della struttura precedente.
per la costruzione dei
progetti è stato Visual
Basic 6.0 Professional. GetAdapterIndex: ottiene l’indice di un adattatore Il valore di ritorno della funzione, in caso di succes-
di rete, partendo dal suo nome. so, è zero. Contrariamente, assume un valore diver-
so e corrispondente ai possibili tipi di errore che
GetAdapterOrderMap: ottiene il valore di priorità potrebbero occorrere. La seconda funzione utilizza-
per ciascuna interfaccia di rete. ta, invece, è la GetAdaptersInfo() la cui sintassi, così
come dichiarata all’interno di Visual Basic, è:
Ovviamente è impensabile poter disquisire su tutte
quante. Cercheremo invece di approfondire quelle Public Declare Function GetAdaptersInfo Lib “IPHlpApi”
che potrebbero risultare maggiormente utili, (IpAdapterInfo As Any, pOutBufLen As Long) As Long
lasciando a chiunque fosse interessato, l’onere di
approfondire l’argomento. A questo scopo sono in cui:

h t t p : / / w w w. i o p r o g r a m m o . i t
G 118/Novembre 2003
117-121 ADV API 4-10-2003 10:22 Pagina 119

Networking ADVANCED EDITION

IpAdapterInfo: questo parametro identifica un tipo STRING. Questa struttura, per alcuni aspetti molto
di dato molto particolare. Esso, infatti, rappresenta complicata, consente, tuttavia, di ottenere informa-
un puntatore ad un buffer di tipo IP_ADAPTER_ zioni circa ogni network adapter, ogni DNS, ogni
INFO (mostrato in seguito) che, attraverso un appo- gateway, ecc. senza che ci si debba preoccupare di
sito elemento della struttura stessa, consente di quanti gateway sono configurati o di quanti IP
“linkarsi” ad altre dello stesso tipo consentendoci di Address, ecc. Oltre a queste due funzioni apparte-
reperire le stesse informazioni per ogni apparato di nenti alle API [Link], il progetto VB ne sfrutta
rete installato. Naturalmente, nell’ipotesi classica un’altra, estremamente importante ed allo stesso
più banale, ossia quella di un PC con una sola sche- tempo, indispensabile per la gestione di queste
da di rete, questa struttura verrà sfruttata solo attra- informazioni: la funzione CopyMemory().
verso un’unica chiamata alla funzione. Essa appartiene alla libreria [Link] ed ha la
seguente sintassi:
pOutBufLen: analogamente a quanto visto per la
funzione precedente, questo valore fa riferimento Public Declare Sub CopyMemory Lib “kernel32” Alias
alla dimensione della struttura IP_ADAPTER_INFO. “RtlMoveMemory” (Destination As Any,
Source As Any, ByVal Length As Long)
Anche qui, analogamente a quanto visto per la fun-
zione precedente, il valore di ritorno, in caso di suc- in cui:
cesso, è zero. In caso contrario, invece, assume un
valore diverso e corrispondente ai possibili tipi di Destination: indirizzo finale di memoria ove copia-
errore che potrebbero occorrere. re il blocco dati.
Com’è possibile notare dai riquadri presenti, le
strutture a cui fanno riferimento le due funzioni so- Source: indirizzo iniziale di memoria facente riferi-
no molto “particolari”. La prima particolarità, come mento al blocco dati da copiare.
già accennato, riguarda il primo parametro della
funzione GetAdaptersInfo() ossia una struttura di Length: numero di byte da copiare.
tipo IP_ADAPTER_INFO.
Apparentemente una funzione siffatta può sembra-
re banale e, forse, inutile. Tuttavia è bene rammenta-
re che le due funzioni viste precedentemente resti-
tuiscono “semplicemente” un riferimento di memo-
ria ad una struttura che contiene i dati ricercati sot-
toforma di sequenza di byte che, in realtà, andreb-
bero letti secondo le specifiche viste prima.
A causa, quindi, della presenza di strutture linkate
all’interno di altre, contenenti le nostre informazio-
ni, è necessario riuscire a seguire questa catena di

Next Long
ComboIndex Long
AdapterName String * MAX_ADAPTER_NAME_LENGTH
Description String *
MAX_ADAPTER_DESCRIPTION_LENGTH
AddressLength Long
Address Byte
Fig. 1: La struttura IP_ADAPTER_INFO. (MAX_ADAPTER_ADDRESS_LENGTH - 1)
Index Long
Type Long
In prima “istanza” essa contiene i campi che memo- DhcpEnabled Long
rizzano i dati relativi ai parametri di rete del primo CurrentIpAddress Long
“network adapter” più un campo identificato con IpAddressList IP_ADDR_STRING
GatewayList IP_ADDR_STRING
l’etichetta Next che rappresenta il puntatore ad un’a-
DhcpServer IP_ADDR_STRING
naloga struttura per il secondo apparato e così via.
HaveWins Boolean
Questa lista linkata termina quando il valore Next è PrimaryWinsServer IP_ADDR_STRING
impostato a 0 nell’ultima struttura della catena. La SecondaryWinsServer IP_ADDR_STRING
seconda particolarità è quella che esistono degli ele- LeaseObtained Long
menti, all’interno delle due strutture principali, LeaseExpires Long
FIXED_INFO e IP_ADAPTER_INFO, che rappresen-
Tab. 2: La struttura IP_ADAPTER_INFO
tano, a loro volta, delle liste linkate di tipo IP_ADDR_

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/119 G
117-121 ADV API 4-10-2003 10:22 Pagina 120

ADVANCED EDITION Networking

strutture, “formattando” di volta in volta tali succes- [Link] e AdapterInfo


sioni di byte. Tanto per renderci conto di quanto .[Link] non fanno altro che restituir-
appena detto, diamo un’occhiata al seguente fram- ci proprio il primo indirizzo IP e la relativa subnet
mento di codice: mask configurati.
Naturalmente, dopo aver fatto ciò, quello che ci si
‘ Lista degli IP Address deve chiedere è appunto se esistono altri elementi
[Link] = [Link] + vbCrLf + della catena o se, come accade più spesso, l’indiriz-
“IP Address 1): “ & [Link] zo IP configurato è uno solo.
[Link] = [Link] + vbCrLf + Per ottenere quest’informazione, come già accen-
“Subnet Mask: “ & [Link] nato all’inizio, ci si serve dell’item Next della struttu-
‘ Altri IP Address? ra. Se questo elemento è pari a zero, ciò vuol dire
pAdapter = [Link] che la catena è terminata, altrimenti occorre acce-
NextItem = 2 dere alla struttura successiva. Il parametro Next, in
Do While pAdapter <> 0 questo caso, conterrà il riferimento al successivo
CopyMemory pADDRStr, ByVal pAdapter, elemento di questa catena.
LenB(pADDRStr) Adesso entra in gioco il ciclo DO… WHILE che con-
[Link] = [Link] + vbCrLf sente di effettuare, ricorsivamente, quest’operazio-
+ “IP Address “ & NextItem & “): ne. La prima istruzione utilizzata è, appunto, quella
“ & [Link] che lancia la funzione CopyMemory(). Il suo scopo è
[Link] = [Link] + vbCrLf quello di copiare una sequenza di byte pari alla lun-
+ “Subnet Mask: “ & [Link] ghezza di una generica struttura IP_ADDR_
pAdapter = [Link] STRING, partendo dall’indirizzo identificato dall’i-
NextItem = NextItem + 1 tem Next, in un’analoga struttura di tipo IP_ADDR_
Loop STRING. Così facendo, il risultato ottenuto sarà
stato proprio quello di “convertire” una sequenza di
Esso si occupa di recuperare dalla struttura Adap- byte “apparentemente illeggibile” in una forma
terInfo (di tipo IP_ADAPTER_INFO), valorizzata pre- “riconosciuta e gestibile”.
cedentemente con una chiamata alla funzione Get- A questo punto, recuperati nuovamente i dati relati-
AdaptersInfo(), la lista di tutti gli indirizzi IP configu- vi all’indirizzo IP ed alla subnet mask voluta, il di-
rati sulla propria scheda di rete. scorso di ripete ricorsivamente sino a quando il pa-
L’elemento IpAddressList rappresenta inizialmente rametro Next non mostra come valore zero.
la prima struttura di una catena di strutture di tipo
IP_ADDR_STRING e, di conseguenza, la lettura di

Next Puntatore al successivo adapter UNO SGUARDO


ComboIndex
AdapterName
Riservato
Nome dell’adattatore
ALL’ESEMPIO
Description Descrizione dell’adattatore Il progetto realizzato, come già accennato, è struttu-
AddressLength Lunghezza del MAC Address dell’adattatore rato in maniera molto semplice. Esso è formato da
Address MAC Address una sola form principale e da un modulo per la di-
Index Indice dell’adattatore rispetto alla lista degli adattatori chiarazione delle variabili, delle funzioni e delle
Type MIB_IF_TYPE_OTHER = 1 strutture utilizzate al suo interno.
MIB_IF_TYPE_ETHERNET = 6
MIB_IF_TYPE_TOKENRING = 9
All’avvio del form principale viene richiamata una
MIB_IF_TYPE_FDDI = 15 funzione, denominata GetNetworkInformation(),
MIB_IF_TYPE_PPP = 23 che si preoccupa di reperire tutte le informazioni
MIB_IF_TYPE_LOOPBACK = 24
MIB_IF_TYPE_SLIP = 28
necessarie per poi mostrarle opportunamente a vi-
DhcpEnabled Indica se abilitato il DHCP deo.
CurrentIpAddress Riservato La struttura di questa funzione è stata semplificata
IpAddressList Lista degli indirizzi IP per consentire una rapida lettura ed un più agevole
GatewayList IP Address del default gateway apprendimento del codice adottato. Sicuramente la
DhcpServer IP Address del DHCP strada migliore sarebbe stata quella di “spezzare” il
HaveWins Valore booleano che indica o meno l’utilizzo di WINS codice in sottofunzioni aventi il compito, ad esem-
PrimaryWinsServer WINS Server primario pio, di leggere strutture di tipo IP_ADDR_STRING o
SecondaryWinsServer WINS Server secondario gestire gli errori ritornati dalle funzioni, ma questo
LeaseObtained Lease Time
credo avrebbe reso sicuramente la lettura meno
LeaseExpires Expire Lease Time
scorrevole.
Tab. 3: La struttura IP_ADAPTER_INFO mantiene informazioni sugli adattatori di rete installati Una volta richiamata la funzione GetNetworkInfor-
sul PC. Ecco una descrizione sommaria sul significato di ogni campo.
mation(), vengono inizializzate diverse variabili, tra

h t t p : / / w w w. i o p r o g r a m m o . i t
G 120/Novembre 2003
117-121 ADV API 4-10-2003 10:22 Pagina 121

Networking ADVANCED EDITION

rizzano con la pOutBufLen la dimensione corretta.


Pertanto, la prima chiamata del tipo:

FixedInfoSize = 0
Errore = GetNetworkParams(ByVal 0&, FixedInfoSize)

permette proprio di ottenere questo risultato e,


successivamente, ci consente di richiamare la fun-
zione con i parametri corretti.
A parte questo “piccolo” dettaglio, il resto del pro-
gramma credo sia piuttosto semplice da com-
Fig. 2: L’interfaccia principale del programma.
prendere e non credo occorra dire nient’altro in
proposito.
le quali alcune strutture del tipo finora visto.
Un dettaglio importante e molto particolare circa AddIPAddress GetNumberOfInterfaces
l’implementazione adottata, è il modo nel quale CancelIpChangeNotify GetPerAdapterInfo
strutture di tipo IP_ADAPTER_INFO e FIXED_INFO CreateIpForwardEntry GetRTTAndHopCount
sono dimensionate e, successivamente valorizzate. CreateIpNetEntry GetTcpStatistics
Infatti, se riprendiamo per un attimo una delle due CreateProxyArpEntry GetTcpStatisticsEx
DeleteIPAddress GetTcpTable
API, ad esempio la GetNetworkParams(), ci accorge-
DeleteIpForwardEntry GetUdpStatistics
remo che la prima volta che essa è richiamata, il
DeleteIpNetEntry GetUdpStatisticsEx
codice è del tipo:
DeleteProxyArpEntry GetUdpTable
DisableMediaSense GetUniDirectionalAdapterInfo
‘ Ottieni I dati “FIXED” del PC. Scatena a questo proposito EnableRouter IcmpCloseHandle
‘ una chiamata “errata” che riporterà, come FlushIpNetTable Icmp6CreateFile
‘ conseguenza, la corretta dimensione della struttura GetAdapterIndex IcmpCreateFile
FixedInfoSize = 0 GetAdapterOrderMap IcmpParseReplies
Errore = GetNetworkParams(ByVal 0&, FixedInfoSize) GetAdapterAddresses Icmp6ParseReplies
GetAdapterInfo Icmp6SendEcho2
If Errore <> 0 Then GetBestInterface IcmpSendEcho
GetBestInterfaceEx IcmpSendEcho2
‘ Gestisci l’errore
GetBestRoute IpReleaseAddress
Select Case Errore
GetFriendlyIfIndex IpRenewAddress
‘Case ERROR_BUFFER_OVERFLOW: ‘…
GetIcmpStatistics NhpAllocateAndGetInterfaceInfoFromStack
‘Case ERROR_INVALID_PARAMETER: ‘…
GetIcmpStatisticsEx NotifyAddrChange
‘Case ERROR_NO_DATA: ‘… GetIfEntry NotifyRouteChange
‘Case ERROR_NOT_SUPPORTED: ‘… GetIfTable RestoreMediaSense
End Select GetInterfaceInfo SendARP
End If GetIpAddrTable SetIfEntry
GetIpErrorString SetIpForwardEntry
‘ Ridimensiona la struttura che conterrà i dati in GetIpForwardTable SetIpNetEntry
‘ maniera corretta GetIpNetTable SetIpStatistics
GetIpStatistics SetIpTTL
ReDim FixedInfoBuffer(FixedInfoSize - 1)
GetIpStatisticsEx SetTcpEntry
GetNetworkParams UnenableRouter
‘ Ricava i dati
Errore = GetNetworkParams(FixedInfoBuffer(0), Tab. 4: Ecco le funzioni che fanno parte della libreria [Link]
FixedInfoSize)

Contrariamente ad analoghe funzioni API, esse


necessitano, come secondo parametro, della cor-
retta dimensione della prima struttura, passata CONCLUSIONI
loro come primo parametro. A questo proposito, Le due funzioni appena viste ci consentono di re-
pertanto, si comportano in maniera molto parti- perire informazioni circa la configurazione della
colare ossia, quando vengono lanciate con un nostra rete in maniera molto semplice ed efficace.
parametro pOutBufLen contenente un valore La prossima volta avremo modo di analizzare altre
insufficiente ad identificare la dimensione della funzioni “particolari” facenti parte di questa libre-
prima struttura, esse ritornano un codice di erro- ria, che risulteranno senza ombra di dubbio al-
re identificato dalla costante simbolica ERROR_ trettanto utili ed interessanti.
BUFFER_OVERFLOW e, conseguentemente, valo- Francesco Lippo

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/121 G
122-125 ADV Aibo 4-10-2003 10:23 Pagina 122

ADVANCED EDITION Robot programming

La nuova frontiera dell’informatica: i robot

La programmazione
dei SONY AIBO
Vedere il risultato dei nostri programmi realmente funzionante, può
dare delle soddisfazioni. Ma vedere il nostro programma che si alza su
quattro zampe, scodinzola e se ne va, che sensazioni può suscitare?

P
robabilmente vi sarà capitato di vedere in te chiedendo, ma perché dovrebbero comunica-
TV, o su qualche rivista specializzata, le re con un PC? Beh, la risposta è semplice: il pezzo
foto di un grazioso cagnolino dall’aspetto forte di questi aggeggi (almeno dal punto di vista
“meccanico”. Un piccolo robot quadrupede che di noi programmatori :-) è proprio il fatto che
farebbe la gioia di qualsiasi bambino (e anche di sono programmabili! é cioè possibile, tramite
chi bambino non lo è più da un pezzo). Stiamo delle opportune API (Application Programming
parlando degli AIBO (Artificial Intelligence BOt) i Interface), scrivere del codice che permetta al
mini-robot prodotti dalla Sony per scopi di robot di compiere determinate azioni, magari
intrattenimento, che ben presto si sono rivelati sfruttando come input i segnali prodotti dai sen-
utilissimi nel campo della ricerca (ad es. in robo- sori, cosa che lo rende a tutti gli effetti un “agen-
tica) in quanto forniscono una piattaforma te autonomo”, secondo la definizione cara a chi
comune di sviluppo, ben supportata dal gigante si occupa di Intelligenza Artificiale; il robot
industriale giapponese e a costi accessibili (rela- diventa cioè in grado di prendere delle “decisio-
tivamente ai costi necessari per la progettazione ni” (per quanto semplici) senza alcun intervento
e costruzione di un robot “in proprio”, ovviamen- di tipo umano dall’esterno. La capacità elabora-
te...). Nonostante il loro aspetto da giocattolo, tiva è assicurata da un microprocessore interno
infatti, questi robot sono un vero e proprio con- di tipo MIPS (la cui frequenza varia a seconda del
AIBO centrato di tecnologia e possiedono al loro inter- modello), mentre la memoria di massa è costitui-
Nonostante il loro no, oltre ai motori necessari per il movimento ta da una schedina di memoria rimovibile (di
aspetto da giocattolo, della testa, della coda e delle zampe, anche una tipo MemoryStick, sempre prodotta da Sony) che
questi robot sono un
vero e proprio
serie di sensori per la “percezione” del mondo
concentrato di esterno, come ad esempio:
tecnologia e
possiedono al loro • una videocamera a colori montata sulla
interno, oltre ai motori punta del naso
necessari per il
movimento della testa,
• dei sensori di pressione sotto le zampe
della coda e delle • un sensore di distanza
zampe, anche una serie • sensori interni di accelerazione, vibrazione
di sensori per la e temperatura
“percezione” del • un microfono stereo.
mondo esterno.

Inoltre possono comunicare all’esterno tramite


particolari LED posti sulla testa (che simulano
degli occhi), nonché tramite un piccolo speaker
che permette loro di riprodurre dei suoni.
Una caratteristica molto interessante è costituita
dalla possibilità di montare sugli AIBO delle
schede di rete di tipo wireless (senza fili), per la
comunicazione con dei normali PC. Già, vi stare- Fig. 1: Il cane robot AIBO.

h t t p : / / w w w. i o p r o g r a m m o . i t
G 122/Novembre 2003
122-125 ADV Aibo 4-10-2003 10:23 Pagina 123

Robot programming ADVANCED EDITION

è destinata a contenere il codice sviluppato e i struttura dati opportunamente configurata). Se


dati necessari al funzionamento (ad es. file di l’oggetto B è pronto per leggere il messaggio, lo
testo, file sonori ecc.). Già ma come funziona legge, altrimenti il messaggio viene messo in una
tutto ciò? Come si usano queste API? Questo arti- coda dei messaggi e verrà letto in seguito, quan-
colo è fatto apposta per spiegarvelo! do B finirà di fare quello che sta facendo. In que-
sta situazione l’oggetto A è chiamato Subject,
mentre l’oggetto B è detto Observer. Ogni mes-
saggio contiene sostanzialmente due informa-
IL CANE E LE API zioni: una serie di dati e un numero intero detto
La programmabilità degli AIBO è assicurata da Selector. Il Selector specifica quale è la funzione
uno SDK (Software Development Kit) chiamato da attivare alla ricezione del messaggio, come
OPEN-R. OPEN-R è una piattaforma di sviluppo spiegato nel successivo punto. Alla funzione atti-
che costituisce un layer per la programmazione vata saranno passati come argomenti i dati del
dei robot, un po’ come, ad esempio, le librerie messaggio
OpenGL costituiscono una piattaforma per la
programmazione grafica sui comuni PC. OPEN- Un oggetto ha dei “punti di accesso” multipli
R si basa sul linguaggio C/C++ ed è liberamente Questo potrebbe sembrare un po’ ostico ma in
scaricabile dal sito che trovate nel box a lato, pre- realtà è una cosa molto semplice. I comuni pro-
via registrazione gratuita. grammi hanno (di solito) un unico punto di
Il fatto che si possa utilizzare un linguaggio di accesso, che è generalmente la funzione main().
tipo Object Oriented, rende ovviamente più faci- Quando al sistema operativo viene detto di lan-
le la vita allo sviluppatore, che può sfruttare tutti ciare un programma, esso comincia a eseguirlo
i vantaggi della programmazione a oggetti, partendo dalla prima istruzione di questa parti-
primo fra tutti la modularizzazione del software. colare funzione. Possiamo vedere un oggetto
Il concetto di modularizzazione è tuttavia, in OPEN-R come un programma che ha varie fun- ROBOCUP
questo ambito, ancora più accentuato, in quanto, zioni main() (ovviamente chiamate in maniera Uno degli utilizzi più
sviluppando con OPEN-R, non si ha il concetto diversa!) che possono attivare l’oggetto. Ad es. interessanti degli AIBO
è quello della ricerca
di “programma che utilizza degli oggetti”, quan- supponiamo di avere un oggetto con le due fun- scientifica in vari
to piuttosto quello di “oggetti indipendenti che zioni FaiPassoAvanti() e FaiPassoADestra() e che campi. Proprio a
comunicano tra loro”. Per visualizzare la situa- entrambe siano dei “punti di accesso”. Queste questo scopo, ogni
zione è utile pensare al funzionamento dei più funzioni potrebbero essere richiamate da altri anno, è organizzata
moderni sistemi operativi per PC (UNIX /Linux, oggetti mediante messaggi nella coda dei mes- una competizione
internazionale di cani-
Windows ecc.), i quali permettono l’esecuzione saggi (tramite il corrispondente Selector), in que- calciatori, chiamata
contemporanea di più programmi; i programmi sto caso verrebbe eseguita per prima la funzione RoboCup. In questa
in esecuzione vengono chiamati processi. In que- relativa al messaggio che si trova più avanti nella competizione gli AIBO
sto modo è possibile ad esempio utilizzare un coda. sono programmati per
giocare a pallone su un
word processor mentre si ascolta musica in mp3
campo di calcio in
e si scarica la posta elettronica, il tutto in con- miniatura e si
temporanea, col sistema operativo che gestisce affrontano, quattro
chi, e per quanto tempo, deve utilizzare le risorse CORE CLASSES contro quattro, nelle
del computer (CPU, memoria, disco rigido ecc.). Come di certo avrete capito, la definizione di squadre formate da
Negli AIBO la situazione è del tutto analoga e gli oggetto OPEN-R è sicuramente differente dalla varie università nel
mondo.
oggetti “vivono di vita propria” compiendo le definizione di oggetto in un linguaggio di pro- [Link].
loro azioni e comunicando tra loro. Possiamo grammazione Object Oriented. Un oggetto
pensare di schematizzare le caratteristiche OPEN-R è più vicino, come funzionamento, alla
salienti degli oggetti OPEN-R in questo modo: definizione di “programma vero e proprio” che
non a quella di “tipo di variabile personalizzato”.
Ogni oggetto funziona in maniera “concorren- Ma è così per tutti gli oggetti presenti nel softwa-
te” con altri oggetti - È quanto detto in prece- re che gira sugli AIBO? Tutti gli oggetti che defi-
denza: gli oggetti sono come dei “processi” che niamo, anche quelli che magari hanno pochi
funzionano in contemporanea, sono tutti attiva- campi e sono usati solo per rappresentare una
ti all’accensione del robot e distrutti al suo spe- semplice struttura dati, devono avere la dignità
gnimento. di “programma”?
Evidentemente non è così. È infatti possibile de-
Gli oggetti comunicano tra loro - Il sistema di finire tutte le classi che vogliamo e istanziare i
comunicazione è quello “a scambio di messag- relativi oggetti, senza che questi siano trattati co-
gi”: in pratica se l’oggetto A deve dire qualcosa me dei programmi autonomi; questo, ovviamen-
all’oggetto B, gli manda un messaggio (cioè una te, consente una notevole flessibilità e un rispar-

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/123 G
122-125 ADV Aibo 4-10-2003 10:23 Pagina 124

ADVANCED EDITION Robot programming

mio di risorse elaborative non indifferente. spensabili nella definizione di una CC, in quanto
Ma allora, come fare per distinguere gli oggetti definiscono la logica di comunicazione e la strut-
OPEN-R dai normali oggetti C++? Gli oggetti tura stessa di un oggetto di tipo CC. Il file def.h è
OPEN-R sono particolari istanze di quelle che un file standard, generato automaticamente
vengono chiamate Core Classes (CC = classi durante il (complicato) processo di compilazio-
nucleo) e hanno una serie di particolarità che li ne del software OPEN-R; esso contiene, tra le
rendono differenti dai normali oggetti C++. altre cose, le definizioni di:
Innanzitutto è possibile istanziare solo un ogget-
to per ogni singola CC. Inoltre un oggetto di una numOfSubject
CC deve: numOfObserver

essere derivato dalla classe OObject - Questa è cioè il numero di Subject e Observer con cui la
una classe predefinita che implementa lo sche- nostra CC avrà a che fare. I riferimenti a questi
DOVE ma della logica di funzionamento delle CC; oggetti esterni sono mantenuti nei due array
SCARICARE dinamici:
OPEN-R implementare quattro particolari funzioni -
È possibile scaricare Chiamate DoInit(), DoStart(), DoStop() e Do- subject[]
l’OPEN-R SDK Destroy(); observer[]
direttamente da
Internet, a partire dal
sito contenere i riferimenti agli oggetti Subject e e si potrà comunicare con tali oggetti invocando,
Observer - Con i quali andrà a comunicare; ad esempio, una funzione in questo modo:
[Link]/openr/ (eventualmente) definire delle funzioni “entry
point” invocabili dalle altre CC. Questo non è observer[[Link]()]->AssertReady();
Per accedere alla
sezione download è
obbligatorio ma è evidente che una CC che non
necessario registrarsi, riceve e non trasmette messaggi non è di grande in cui event è l’evento che ha determinato la
operazione del tutto utilità. chiamata (il parametro delle quattro funzioni
gratuita. I file da speciali), ObsIndex() restituisce il suo indice
scaricare sono: Lo “scheletro” del codice di una CC è quindi, all’interno del vettore dinamico e AssertReady() è
OPEN_R_SDK-(numero
pressappoco, il seguente: una funzione che comunica la disponibilità di un
versione).[Link] oggetto a ricevere messaggi. Ma a cosa servono
Il kit di sviluppo #include <OPENR/OObject.h> queste fantomatiche quattro funzioni speciali?
#include <OPENR/OSubject.h> Esse sono chiamate dal sistema operativo
OPEN_R_SDK-docE- #include <OPENR/OObserver.h> dell’AIBO in determinati momenti, e precisa-
(numero versione)
#include “def.h” mente:
.[Link]
La documentazione in class EsempioDiCC : public OObject
Inglese { DoInit() - È chiamata per tutti gli oggetti CC non
public: appena si accende il robot. Serve per contenere il
OPEN_R_SDK-sample- //Costruttore e distruttore codice di inizializzazione dell’oggetto.
(numero versione)
EsempioDiCC();
.[Link]
Alcuni file di esempio virtual ~EsempioDiCC() {} DoStart() - È chiamata per tutti gli oggetti CC
//Riferimenti agli oggetti Subject e Observer non appena sono finite tutte le chiamate a
Per potere compilare il OSubject* subject[numOfSubject]; DoInit(). In questo modo è possibile mettere in
software, è necessario OObserver* observer[numOfObserver]; questa funzione del codice, con la certezza che
avere installato il
virtual OStatus DoInit(const OSystemEvent& event); tutti gli altri oggetti siano stati già inizializzati.
compilatore gcc.
Mentre sotto virtual OStatus DoStart(const OSystemEvent& event);
UNIX/Linux questo virtual OStatus DoStop(const OSystemEvent& event); DoStop() - È l’opposto di DoStart() e viene invo-
dovrebbe esserci di virtual OStatus DoDestroy(const OSystemEvent& event); cata, per ogni oggetto, quando si preme il tasto di
default, sotto //Altre funzioni “entry point” spegnimento dell’AIBO.
Windows, di solito, è
//...
necessario installare
un suo porting. Sul sito private: DoDestroy() - È l’ultima funzione eseguita da
è disponibile per il //Funzioni e campi accessibili solo da *questa* CC ciascun oggetto CC. Essa viene invocata quando
download il famoso //... per tutti gli altri oggetti è stata invocata DoStop().
CygWin.
}; Può contenere del codice di finalizzazione, però
non può comunicare con gli altri oggetti, in
Vediamo di analizzare questo codice. I primi tre quanto non si è sicuri che questi siano ancora
file header importati, tramite la #include, sono “vivi”.
quelli relativi alle definizioni di oggetto OPEN-R
(OObject.h) e di Subject e Observer; sono indi- Una cosa interessante da notare è che, essendo

h t t p : / / w w w. i o p r o g r a m m o . i t
G 124/Novembre 2003
122-125 ADV Aibo 4-10-2003 10:23 Pagina 125

Robot programming ADVANCED EDITION

Una cosa che si può notare è che molto spesso,


nel codice sviluppato per gli AIBO, si fa uso di
parametri passati per riferimento (tramite l’ope-
ratore “&”) e in sola lettura (parola chiave
“const”), questo ovviamente è dovuto a motivi
legati all’efficienza di esecuzione del codice, su
una piattaforma hardware così ridotta come
quella degli AIBO: passare oggetti per riferimen-
to evita di copiare l’oggetto stesso in un’altra area
di memoria, risparmiando tempo e spazio pre-
ziosi.
Seguono nel corpo funzione due macro:

ENABLE_ALL_SUBJECT - Serve ad abilitare tutti i


Subject che fanno riferimento a questo oggetto.
Fig. 2: I mini AIBO impegnati in una competizione.
ASSERT_READY_TO_ALL_OBSERVER - Serve a
dare il segnale di “sono pronto” (ASSERT_
DoDestroy() l’ultima funzione invocata per cia- READY) a tutti gli Observer di questo oggetto
scun oggetto, il distruttore C++ dell’oggetto CC OPEN-R. Gli oggetti nella fase di comunicazione
stesso non verrà mai chiamato. Infatti, come si possono anche emettere un altro segnale, di
può vedere, il corpo funzione di tale distruttore è significato opposto: DEASSERT_READY, che
vuoto. Questo implicitamente vuol dire che ogni sostanzialmente dice all’oggetto cui si sta parlan-
oggetto OPEN-R non ha né la possibilità di ter- do: “ora sono impegnato” ACQUISTARE
minare un altro oggetto suo simile, né può “suici- AIBO
darsi”, interrompendo la sua esecuzione; in altre Infine, notiamo che viene restituito un valore di Il nome AIBO è
parole il ciclo di vita degli oggetti OPEN-R tipo Ostatus che, in questo caso, è oSUCCESS l'acronimo di
A(rtificial)
comincia con l’accensione del robot e finisce col (cioè: “operazione compiuta con successo”) ma I(ntelligence) (ro)BO(t)
suo spegnimento. Per quanto riguarda il codice che potrebbe essere anche un altro valore prede- e in giapponese
contenuto in queste funzioni si può dire che, finito (ad es. oFAIL per una operazione non por- significa compagno.
generalmente, esso non necessita di molta fanta- tata a termine in maniera corretta) oppure uno È possibile acquistare
sia per essere implementato, in quanto sono definito dal programmatore per particolari scopi. AIBO ad una “modica”
cifra che si aggira dai
disponibili delle macro che consentono di effet- 899,00 ai 2.199,00 Euro.
tuare tutte le inizializzazioni più comuni, che L’acquisto può essere
molto spesso sono anche le uniche ad essere inoltrato on-line
davvero necessarie al momento in cui vengono CONCLUSIONI visitando il sito web:
invocate le funzioni DoXXX(). Un tipico esempio In questo articolo, che è il primo di una serie di
[Link]
di implementazione può essere il seguente: due, abbiamo visto la struttura logica del funzio- [Link]
namento di un software per robot, scritto
Ostatus EsempioDiCC::DoStart(const OSystemEvent& mediante OPEN-R. Abbiamo visto come funzio-
event) nano gli oggetti CC e quali sono i meccanismi
{ che regolano la comunicazione e lo scambio di
ENABLE_ALL_SUBJECT; messaggi tra gli oggetti stessi. Questi passi sono
ASSERT_READY_TO_ALL_OBSERVER; fondamentali per potere capire il meccanismo
return oSUCCESS; utilizzato dalla piattaforma software, e possono
} risultare anche utili per chi si voglia cimentare
nella programmazione di sistema multi-process
Questa funzione, come del resto le altre tre di o multi-thread con il proprio PC, per realizzare
questa categoria, prende come parametro un comuni applicazioni. Dopo questa dose di teo-
riferimento a un oggetto di tipo OSystemEvent, ria, quindi, vedremo nella prossima puntata
che rappresenta un “evento” nel ciclo di vita di qualcosa di un po’ più pratico e anche, se volte,
un programma OPEN-R, un po’ come la pressio- divertente della programmazione degli AIBO.
ne di un pulsante su un’interfaccia grafica è un Non mancate quindi, e se avete suggerimenti,
“evento” per il programma che la gestisce. Tale consigli o critiche scrivete pure all’indirizzo
oggetto contiene delle informazioni utili, come [Link]@[Link] per espri-
ad esempio l’autore della chiamata alla funzione mere la vostra.
(in questo caso non è un altro oggetto, ma il siste- Alla prossima puntata dunque!
ma operativo stesso). Alfredo Marroccelli

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/125 G
126biblioteca 8-10-2003 17:47 Pagina 126

BIBLIOTECA I migliori testi scelti dalla redazione

ON LINE
MS OFFICE RESOURCE
Un sito, rivolto agli utilizzatori
dell’ambiente Office di
Biblioteca
Microsoft. JAVA - LA PROGRAMMAZIONE
Anteprime, tutorial, download, A OGGETTI
news, supporto tecnico e tanto Java è ormai diventato un vero e proprio status symbol tra gli sviluppato-
altro, a portata di click.
ri. I principali motivi per studiare un linguaggio di programmazione
come Java sono il suo stretto legame con Internet, la multimedialità e la
programmazione object oriented. Il libro si rivolge a tutti quegli utenti
che si avvicinano per la prima volta ad un linguaggio a oggetti utilizzan-
do un approccio semplice che guida all'apprendimento di concetti noto-
riamente tediosi: ereditarietà e polimorfismo in primis. Un'intera sezio-
ne viene dedicata allo sviluppo Web ed in particolare l'utilizzo degli
applet Java. Si tratta sicuramente di un testo che non può passare inos-
servato a colui che vuole cimentarsi nella programmazione Java, volendo
apprendere, da zero, tutti gli aspetti più salienti del linguaggio.
[Link]
[Link] Difficoltà: Bassa • Autore: P. Gallo - [Link] • Editore: Mondadori Informatica
[Link] • ISBN: 88-8331-522-7 • Anno di pubblicazione: 2003
Lingua: Italiano • Pagine: 288 • Prezzo: E 14,80

PROGRAMMING
TUTORIALS
Hai da sempre cercato un reposi-
tory di tutorial sui linguaggi di
EXPERT ONE-ON-ONE VISUAL BASIC
programmazione? Eccolo! .NET BUSINESS OBJECTS
Un sito esclusivamente dedicato
Rockford Lhotka, conosciuto per aver pubblicato numerosi testi a
ai tutorial per la quasi totalità
dei linguaggi di sviluppo. riguardo dello sviluppo di applicazioni distribuite, propone un nuovo
[Link] testo, questa volta focalizzando l'attenzione sulla nuova piattaforma
.NET. Il libro, suddiviso in tre diverse sezioni, analizza le architetture
logiche e fisiche di un'applicazione, esplorando gli effetti di scalability,
tolleranza di errori e prestazioni; l'attenzione viene focalizzata sugli
strumenti di Visual Basic .NET per la progettazione di applicazioni
distribuite; l'approccio è immediato, e grazie ad una serie di esempi
pratici, il lettore sarà subito in grado di capire ogni aspetto inerente
all’implementazione.

Difficoltà: Medio-Alta • Autore: R. Lhotka • Editore: Apress [Link]


ISBN: 1-59059-145-3 • Anno di pubblicazione: 2003 • Lingua: Italiano • Pagine: 725
Prezzo: $ 59.99
VISUAL BASIC
INTERNET
PROGRAMMING HTML & XML PASSO
Per gli amanti del linguaggio VB
un portate dedicato allo svilup- Un testo base per chi si accinge ad utilizzare Html muovendo i primi passi
po di applicazioni Internet. nel web. L’approccio all’argomento è basilare e la lettura risulta scorrevo-
Tutorial ed esempi pratici su
le anche per chi non ha alcuna nozione sull’argomento.
come realizzare software in
grado di interfacciarsi ad Nei primi capitoli sono affrontati i temi principali: struttura e sintassi di
Internet. una pagina Html, come inserire immagini, impostare lo stile del testo ed
effettuare collegamenti ipertestuali. La seconda parte del testo si occupa
di argomenti un po’ più avanzati, infine due capitoli sono dedicati rispet-
tivamente alle form ed al Dynamic Html.
Un ottimo manuale per chi non ha nozioni di Html e desidera iniziare a
conoscere questo linguaggio per realizzare il proprio, semplice, sito Web
per poi magari approfondire gli argomenti.

Difficoltà: Bassa • Autore: [Link] • Editore: Mondadori Informatica


[Link] [Link] • ISBN: 88-8331-485-9 • Anno di pubblicazione: 2003
Lingua: Italiano • Pagine: 288 • Prezzo: E 24,80

h t t p : / / w w w. i o p r o g r a m m o . i t
G 126/Novembre 2003
127-129 posta 4-10-2003 10:24 Pagina 127

Le risposte alle domande dei lettori INBOX

IN Box L’esperto risponde…


Estirpare il worm un personal firewall tipo ZoneAlarm o to da diversi siti in rete, viene raramente
Norton Internet Security affrontato tramite l'uso degli interrupt

S alve, prima di tutto vi faccio i


complimenti per la rivista e poi
passo subito al sodo... Nell'ultimo
come avviene nell'articolo da me redatto.

numero, quello di ottobre, ho letto con Reperibilità dei componenti


molto interesse l'articolo di Elia Florio elettronici Librerie TAPI e ISDN
"Fatti e misfatti di RPC". Purtroppo
oltre l'interesse non sono riuscito ad
andare, nel senso che non ho nessuna
dimestichezza con gli argomenti
R iguardo all'articolo (fantastico) di
A. Margarese "Un telecomando per
pilotare il PC", forse qualcuno ha
S alve, mi chiamo Claudio, leggo la
vostra rivista con interesse e la
trovo molto utile ed interessante,
trattati. Tuttavia il mio sistema (XP avuto il mio stesso problema: non anche per uno poco esperto di pro-
Home Edition) è afflitto, da qualche sono riuscito a trovare il ricevitore grammazione come me. Vengo al dun-
settimana, da un arresto di sistema integrato di infrarossi siemens SFH- que, è un po’ che mi diletto con VB e
iniziato da NT/authority\\system così 507-38. Così ho navigato qua e là in quando vedo sulla rivista alcune pro-
come viene anche illustrato da voi. Ora internet finché sono capitato sul sito poste mi cimento a farle da me, per
mi chiedevo se posso fare qualcosa per [Link] dove "uni- cercare di acquisire una maggiore
risolvere questo problema che mi dog" (che ringrazio) ha risposto ad un dimestichezza con il linguaggio. Sulla
affligge la maggior parte delle volte mio post sul forum che il sito ospita, rivista del mese scorso (n° 70), mi sono
che mi collego in rete. dicendomi di dare un'occhiata a cimentato nella realizzazione del pro-
Via e-mail [Link] In getto "Controlla il tuo PC dal
questa pagina c'è una lista di ricevitori Telefonino. Purtroppo, il programma
equivalenti, i componenti e lo schema non mi funziona a dovere in quanto il
Risponde Elia Florio per costruire il circuito di interfaccia modem che ho io è di tipo ISDN, per

C iao, ti ringrazio per i complimenti e


spero che la rivista continui sempre a
soddisfare le aspettative di voi lettori. La
con la porta parallela. Colgo l'occasio-
ne per fare i complimenti all'autore e
alla rivista in generale, i cui articoli
cui le informazioni contenute nel file
di Registro "Dim
ModemIDFromRegistry As Long..."
rubrica degli "exploit" si rivolge in genere mettono alla portata di tutti argomen- non rilevano il mio modem (Tipo
ti che credevo per soli "eletti". Hamlet ISDN). Vorrei sapere se cortese-
agli esperti di sicurezza, che conoscono le mente potreste darmi una dritta al
problematiche dei buffer overflow e dei Matteo, via e-mail riguardo.
bug scoperti ogni giorno nei software.
Tuttavia, anche senza approfondire il Risponde Amedeo Margarese Claudio, via e-mail
codice, gli articoli di questa rubrica sono
spesso interessanti da leggere, come nel S alve Matteo, purtroppo questo dipen-
de solo ed esclusivamente dai negozi di Risponde Elia Florio
tuo caso. Si tratta del worm "MSBlaster"
(anche conosciuto come LovSan). In prati-
ca quando ti connetti ad Internet, il tuo PC
elettronica ai quali ci si rivolge ed ahimé,
soprattutto nelle città più piccole può non
essere facile trovare alcuni componenti
P urtroppo le librerie TAPI utilizzate per
realizzare il progetto (ModemTools
della NetPoint) non funzionano corretta-
viene attaccato da qualche altro host infet- più ricercati. Nell'articolo viene indicata la mente con i modem ISDN, dispositivi che
to (connesso allo stesso provider) e riceve possibilità di utilizzare un qualsiasi ricevi- sono chiamati "modem" in maniera im-
un pacchetto RPC malformato, in grado di tore integrato di infrarossi che funzioni propria (in realtà sono dei TA, ossia dei
causare il riavvio forzato. Per rimuovere il intorno ai 36-38khz, rimandando però il "Terminal Adapter"). L'ISDN-TA è un ap-
problema devi: lettore alla ricerca di suddette liste di equi- parecchio che lavora su linee digitali,
valenza. Su molti siti, è possibile acquista- mentre il modem tradizionale è un con-
• aggiornare il tuo sistema WindowsXP re questi componenti on-line, anche se vertitore di segnale che lavora prettamen-
con la patch [Link] ordini di piccola entità possono rappre- te su linee analogiche. Di conseguenza le
.com/downloads/[Link]?display sentare un problema. librerie TAPI di Windows, per queste due
lang=it&FamilyID=2354406C-C5B6- Sul sito indicato dal forum si parla di un categorie di apparecchi, sono leggermente
44AC-9532-3DE40F69C074 oppure, ricevitore infrarossi per porta seriale, con diverse e spesso danno luogo a tali incom-
usando l'utility "[Link]" qualche differenza, quindi, da un ricevito- patibilità. Ti consiglio di testare il progetto
automatica re per porta parallela sia a livello circuitale con un qualsiasi altro modem analogico
• rimuovere il worm dal tuo sistema che software. Dal punto di vista del 56K; nelle nostre prove tutto ha funziona-
usando l'utility [Link] software di comando, il problema viene to per il meglio: la ricezione dei toni DTMF
[Link]/avcenter/venc/data/w trattato in maniera differente sia perché si avviene correttamente e viene gestita dal-
[Link] parla di un altro sistema operativo sia per- l'applicativo VB di esempio.
• proteggere la porta 135 del tuo PC con ché questo argomento, pur essendo tratta- Cordiali saluti.

h t t p : / / w w w. i o p r o g r a m m o . i t GGG
Novembre 2003/127 G
127-129 posta 4-10-2003 10:24 Pagina 128

INBOX I migliori Thread di ioProgrammo

Intercettare un tasto [Link]:='Inizio stampa"; 1234/[Link])


in una procedura [Link];
// "Quasi-Multitasking" trayicon presente in versione A
sleep(10000); // Operazione lunga: STAM-
S alve a tutti, Vivo a Trieste e
sono un programmatore di siti
Internet/intranet e di applicazioni
PA
[Link]:='Fine stampa";
([Link]
trayicon/[Link])
e versione C ([Link]
in Delphi 4. end; [Link]/java/trayicon/trayicon-
Ho un applicazione in cui in una [Link])
form lancio una stampa partico-
larmente complessa (lancio una Domandone da veri Personalmente ho usato Tray4J ed è
sere di elaborazioni nella proce- esperti relativamente facile e completo allo
dura Button1Click. Avrei bisogno stesso tempo, l'unico problema che
di intercettare un tasto (esempio
F3 o ESC) dopo aver premuto il
bottone per poter interrompere
H o iniziato la progettazione di
un client di posta elettronica
e ho ottenuto una prima bozza.
ho riscontrato è che nel codice (è
presente anche il sorgente java) c'è
un [Link] praticamente inutile
l'elaborazione. Vorrei fare in modo che la mia (credo sia un debug rimasto).
Ho provato così... applicazione avesse la possibilità Il problema lo puoi risolvere ricom-
di iconificarsi nel senso che essa, pilando il codice.
procedure TForm1.Button1KeyUp( quando viene iconificata, scompa- Naturalmente c'è da inserire una dll
Sender: TObject; var Key: Word; re lasciando traccia solamente con nella cartella bin del jdk usato, vici-
Shift: TShiftState); una piccola iconcina posta in no all'interprete java.
begin basso a destra (dove ci sono le Ciao!
if key = vk_f3 then icone attive: Volume, Java (per chi
begin ce l'ha)...
showmessage('Elaborazione interrotta Praticamente l'applicazione IP address
dall'utente! '); dovrebbe sempre essere attiva ma
close;

end;
end;
non visibile e per farla riapparire
dovrei cliccare sulla iconcina defi-
nita sopra. Non so se ho esposto
È possibile conoscere l'IP
address da VB (cioè da pro-
gramma) dopo aver effettuato
bene la specifica una connessione ad accesso remo-
Ma non funziona... lo intercetta Purtroppo non ho idea di come si to?
solo alla fine della procedura faccia!!! Grazie
Button1Click. Mi sapreste aiutare? pa_pier
Avete qualche idea? Per informazione, l' applicazione
Grazie estende un JFrame. La risposta di JBhemot
Raul • corwin56

La risposta di Salvatore Meschini


Grazie per l'aiuto.
carMAN C erto ;-) un modo può essere uti-
lizzando il componente Micro-
soft 'Winsock control'.

U tilizzando [Link]-
Messages rendi possibile l'ela-
borazione della coda dei messaggi
La risposta di kyakan

U sare un tray icon in java non è


molto facile, questo è dovuto al
Quest'ultimo possiede una pro-
prietà di nome 'LocalIP' che ti resti-
tuisce appunto il tuo indirizzo IP.
(e' quello che ti serve per non "bloc- fatto che non sempre una applica- Saluti.
care" l'applicazione)... Per opera- zione java si trova su sistemi win-
zioni lunghe conviene inserire una dows o comunque non è dette che ci
chiamata a tale metodo per "resti- sia sempre il tray! Client di posta in Java
tuire il controllo" all'utente. Per integrare questa funzionalità
Anche se secondo me la soluzione
migliore resta la creazione di un
nuovo thread per la stampa (come
bisogna ricorrere a programmi
scritti in C e quindi interfacciarsi
mediante una classe che dichiara
S alve, vorrei sapere da voi quali
api utilizzare per la gestione
della posta e se mi potreste forni-
fa per esempio Microsoft Word)! alcune funzioni native che fanno re qualche link utile sull'argomen-
Il metodo ProcessMessages e' riferimento alla libreria C. to, suggerire un tutorial...
descritto nella documentazione di Sul Web esistono diverse soluzioni Help!
Delphi. già implmentate che permettono di JBhemot
Esempio: gestire il tray icon su sistemi win-
dows, cercando su google io ho tro- La risposta di Carlo Pelliccia
procedure TForm1.Button1Click(Sender:

begin
TObject);
vato queste:

Tray4j ([Link]
L e API che fanno al caso tuo sono
[Link]
vamail/. È tempo che mi ripropongo

h t t p : / / w w w. i o p r o g r a m m o . i t
G 128/Novembre 2003
127-129 posta 4-10-2003 10:24 Pagina 129

I migliori Thread di ioProgrammo INBOX

anche io di scrivere un client e-mail notevolmente. Se ogni pixel ha un valore RGB, è


in Java. Anche io concordo sul fatto di sal- necessario valutare la trasforma-
Prima o poi lo farò, e pensavo anche vare nel db solo l'url dell'immagine zione da imporre.
di proporre un tutorial per ioPro- e quando vuoi visualizzarla fai inse- Ad esempio:
grammo sull'argomento. rire il percorso dell'immagine all'in-
Casomai confronteremo i nostri terno del tag img in questo modo: pixel(x1,y1) --> R(200),G(143),B(120)
risultati, ok? :-)
Ciao! <img src="<%=objRS( Vuoi valutare ogni singolo compo-
"CampoConPercorsoImmagine")%>"> nente del colore o tutti e tre insie-
me? Se uno di questi raggiunge il
Utilizzare i socket su massimo (255) gli altri vengono
rete con proxy …ma come bloccati? Una volta deciso questo
si stampa??? puoi applicare una semplice tra-

V orrei sapere com si puo' apri-


re e utilizzare una connessio-
ne via socket quando devo mette- S alve, ho questo seccantissimo
problema...che non so proprio
sformazione alla matrice che rap-
presenta l'immagine.
Alla fine puoi copiare l'immagine
re in comunicazione due PC come risolvere. modificata nello stesso controllo o
appartenenti a reti divise da un Dovrei stampare il contenuto di in un altro, oppure salvarla.
Server Proxy. un datatable ma non ho la più Detto così sembra semplice, ma non
Grazie pallida idea su come fare... lo è affatto (perlomeno dal mio
(Enrico Mi potreste aiutare?? punto di vista), poiché Visual Basic
Grazie 1000 ha delle serie limitazioni nella ge-
La risposta di Car1otta albadur stione della memoria.

M mm ... o ti fai aprire la porta


sul proxy dall'amministratore, La risposta di alip
Non è impossibile però.
Ti rimando ad un articolo esempio
o non c'e' possibilita' di riuscirci.
E' lo stesso problema che si ha
quando da una Intranet si vuole uti-
U sa DataEnviroment come data
source e DataReport per pre-
parare un Modello di report ( puoi
al seguente link:
[Link]
/gfx/[Link]
lizzare una chat ... usare anche il Drag and Drop) da CHEERS
Il problema puo essere aggirato se dataEnviroment a dataReport.... ov- Juppiter
su una delle due makkine c'e' un viamente devi prima preparare l'og-
web server (e tu ci puoi mettere getto Command nel DataEnviro-
mani) ed il proxy ha una porta http ment... Output DTS
aperta (di solito e' la 80) allora puoi
mascherare la comunicazione come
un flusso http ... Luminosità
di un'immagine
H o creato una DTS che mi fa
delle select all'interno di un
database. Come faccio a farmi
ritornare, all'esecuzione della
Come visualizzare
un'immagine S alve a tutti. Ho un piccolo pro-
blemino... dovrei salvare
un'immagine con una luminosità
query una griglia o un file con i
risultati?
jaco1982

S alve a tutti, ho un Db in
Access con una tabella che
diversa da quella originale, ma
non riesco a trovare niente che La risposta di mchim
contiene un campo in cui bisogna
inserire un'immagine.
Quest'img dovrà essere visualiz-
possa aiutarmi...
Se qualcuno può darmi una mano,
ne sarei molto felice.
N ella connessione di destinazio-
ne potresti inserire come DATA
SOURCE Microsoft excel 2000.
zata insieme agli altri campi in Ciao e grazie a tutti... In questo caso il risultato della que-
una pagina ASP. corkor ry viene inserito in excel in forma
Come posso fare? tabellare.
E soprattutto è meglio che l'im- La risposta di Juppiter
magine del DB sia di tipo OLE o
che sia solo testo?
Grazie a tutti
C iao corkor, il problema che poni
ha una soluzione semplice ma
di difficile programmazione.
PER CONTATTARCI
bianciuccio Fondamentalmente dovresti copia- e-mail: iopinbox@[Link]
re nella memoria l'immagine con la
Posta: Edizioni Master,
La risposta di danyw3b chiamata API BitBlt, Quindi devi
Via Cesare Correnti, 1 - 20123 Milano

E vita l'immagine di tipo OLE nel


db poichè le prestazioni calano
valutare pixel per pixel il filtro da
applicare.

h t t p : / / w w w. i o p r o g r a m m o . i t
Novembre 2003/129 G

Potrebbero piacerti anche