Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
INPRISE CONFIDENTIAL
April 15, 2002 6:49 pm (D:\Lavori\bcb6\DG\BCBonly\title.fm5)
Guida alla
programmazione
Borland Software Corporation, 100 Enterprise Way
Scotts Valley, CA 95066-3249
Borland
C
++
Builder
6
per Windows
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 15, 2002 6:49 pm (D:\Lavori\bcb6\DG\BCBonly\title.fm5)
Per una lista completa dei file che possibile distribuire in conformit allAccordo di Licenza e Garanzia Limitata di
C++Builder, fare riferimento al file DEPLOY.TXT situato nella directory principale di C++Builder 6.
Borland potrebbe avere brevetti e/o applicazioni in corso di brevetto relativamente ad argomenti trattati in questo
documento. La fornitura di questo documento non conferisce alcuna licenza relativamente a questi brevetti. Per un
elenco dei brevetti in vigore, fare riferimento al CD del prodotto oppure alla finestra di dialogo About.
COPYRIGHT 19832002 Borland Software Corporation. Tutti i diritti riservati. Tutti i marchi e i nomi dei prodotti
Borland sono marchi o marchi registrati di Borland Software Corporation negli Stati Uniti e negli altri paesi. Tutti gli
altri marchi citati sono di propriet dei rispettivi detentori.
Stampato in Irlanda
CPE1340WW21001 4E0R1001
0102030405-9 8 7 6 5 4 3 2 1
D3
i
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Capitolo 1
Introduzione 1-1
Contenuto del manuale . . . . . . . . . . . . . . 1-1
Convenzioni tipografiche . . . . . . . . . . . . . 1-3
Servizi di assistenza agli sviluppatori . . . . 1-3
Come ordinare la documentazione cartacea. 1-3
Parte I
Programmazione con C++Builder
Capitolo 2
Sviluppo di applicazioni
con C++Builder 2-1
Ambiente di sviluppo integrato . . . . . . . . . 2-1
Progettazione di applicazioni. . . . . . . . . . . 2-2
Creazione di progetti . . . . . . . . . . . . . . . 2-3
Editing del codice . . . . . . . . . . . . . . . . . 2-4
Compilazione di applicazioni . . . . . . . . . . 2-4
Debug di applicazioni . . . . . . . . . . . . . . . 2-5
Distribuzione di applicazioni . . . . . . . . . . . 2-5
Capitolo 3
Uso delle librerie di classi 3-1
Le librerie di classi . . . . . . . . . . . . . . . . . 3-1
Propriet, metodi ed eventi . . . . . . . . . . 3-2
Propriet . . . . . . . . . . . . . . . . . . . 3-2
Metodi . . . . . . . . . . . . . . . . . . . . 3-3
Eventi . . . . . . . . . . . . . . . . . . . . 3-3
Eventi utente . . . . . . . . . . . . . . . . 3-3
Eventi di sistema . . . . . . . . . . . . . . 3-3
Oggetti, componenti e controlli . . . . . . . . . 3-4
Il ramo TObject . . . . . . . . . . . . . . . . . 3-6
Il ramo TPersistent . . . . . . . . . . . . . . . 3-6
Il ramo TComponent. . . . . . . . . . . . . . 3-7
Il ramo TControl . . . . . . . . . . . . . . . . 3-8
Il ramo TWinControl/TWidgetControl . . . 3-9
Capitolo 4
Utilizzo di BaseCLX 4-1
Uso di stream. . . . . . . . . . . . . . . . . . . . 4-2
Uso di stream per leggere o scrivere dati . . 4-2
Metodi di stream per lettura e scrittura . 4-2
Lettura e scrittura di componenti . . . . . 4-3
Copia di dati da uno stream a un altro. . . . 4-3
Specifica della posizione e
della dimensione dello stream . . . . . . . . 4-3
Ricerca di una posizione specifica . . . . . 4-4
Utilizzo delle propriet Position e Size . . 4-4
Operazioni con i file . . . . . . . . . . . . . . . . 4-4
Approccio alle operazioni di I/O su file . . . 4-5
Uso degli stream di file . . . . . . . . . . . . . 4-5
Creazione e apertura di file
con stream di file . . . . . . . . . . . . . . 4-6
Uso dellhandle di file . . . . . . . . . . . . 4-7
Manipolazione dei file . . . . . . . . . . . . . 4-7
Cancellazione di un file . . . . . . . . . . . 4-7
Ricerca di un file . . . . . . . . . . . . . . . 4-8
Cambiamento del nome di un file . . . . . 4-9
Routine per data-ora. . . . . . . . . . . . . 4-9
Copia di un file. . . . . . . . . . . . . . . 4-10
Operazioni con file ini
e con il Registro di sistema . . . . . . . . . . . 4-10
Utilizzo di TIniFile e di TMemIniFile . . 4-11
Utilizzo di TRegistryIniFile. . . . . . . . 4-12
Uso di TRegistry . . . . . . . . . . . . . . 4-12
Operazioni con le liste . . . . . . . . . . . . . . 4-13
Operazioni comuni su elenchi . . . . . . . . 4-14
Aggiunta di elementi di un elenco. . . . 4-14
Cancellazione degli elementi
di un elenco. . . . . . . . . . . . . . . . 4-14
Accesso agli elementi di un elenco. . . . 4-15
Riordinamento degli elementi
di un elenco. . . . . . . . . . . . . . . . 4-15
Elenchi persistenti . . . . . . . . . . . . . . . 4-15
Operazioni con elenchi di stringhe . . . . . . . 4-16
Caricamento e salvataggio
di elenchi di stringhe . . . . . . . . . . . . 4-16
Creazione di un nuovo elenco di stringhe . 4-17
Elenchi di stringhe a breve termine . . . 4-17
Elenchi di stringhe a lungo termine . . . 4-18
Gestione di stringhe in un elenco . . . . . . 4-18
Conteggio di stringhe in un elenco . . . 4-19
Accesso ad una particolare stringa. . . . 4-19
Individuazione di elementi
in un elenco di stringhe . . . . . . . . . 4-19
Analisi sequenziale di stringhe
in un elenco. . . . . . . . . . . . . . . . 4-19
Aggiunta di una stringa a un elenco. . . 4-19
Spostamento di una stringa
allinterno di un elenco . . . . . . . . . 4-20
Indice generale
ii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Cancellazione di una stringa
da un elenco . . . . . . . . . . . . . . . . 4-20
Associazione di oggetti
ad un elenco di stringhe . . . . . . . . . 4-20
Operazioni con stringhe. . . . . . . . . . . . . . 4-21
Routine per wide character . . . . . . . . . . 4-21
Routine comunemente utilizzate
per AnsiStrings . . . . . . . . . . . . . . . . 4-22
Routine comunemente utilizzate
per stringhe terminate con null . . . . . . . 4-25
Stampa . . . . . . . . . . . . . . . . . . . . . . . 4-26
Conversione di misure . . . . . . . . . . . . . . 4-27
Esecuzione di conversioni . . . . . . . . . . . 4-27
Esecuzione di conversioni semplici . . . . 4-28
Esecuzione di conversioni complesse . . 4-28
Aggiunta di nuovi tipi di misura . . . . . . . 4-28
Creazione di una semplice famiglia di
conversione e aggiunta delle unit . . . . . 4-29
Dichiarazione delle variabili. . . . . . . . 4-29
Registrazione della famiglia
di conversione . . . . . . . . . . . . . . . 4-29
Registrazione delle unit di misura. . . . 4-29
Utilizzo delle nuove unit di misura . . . 4-30
Utilizzo di una funzione di conversione . . . 4-30
Dichiarazione delle variabili. . . . . . . . 4-30
Registrazione della famiglia
di conversione . . . . . . . . . . . . . . . 4-30
Registrazione dellunit di misura
di base . . . . . . . . . . . . . . . . . . . 4-31
Scrittura dei metodi per la conversione
in base allunit di misura di base. . . . 4-31
Registrazione delle altre unit di misura. 4-31
Utilizzo delle nuove unit di misura . . . 4-31
Utilizzo di una classe per gestire
le conversioni . . . . . . . . . . . . . . . . . 4-32
Creazione della classe di conversione . . 4-32
Dichiarazione delle variabili. . . . . . . . 4-33
Registrazione della famiglia
di conversione e delle altre unit . . . . 4-33
Utilizzo delle nuove unit di misura . . . 4-35
Creazione di spazi di disegno . . . . . . . . . . 4-35
Capitolo 5
Operazioni con componenti 5-1
Impostazione delle propriet dei componenti . 5-2
Impostazione delle propriet
in progettazione. . . . . . . . . . . . . . . . 5-2
Utilizzo di editor di propriet . . . . . . . 5-3
Impostazione di propriet in esecuzione . . 5-3
Chiamate a metodi . . . . . . . . . . . . . . . . . 5-3
Operazioni con eventi e gestori di evento . . . . 5-3
Generazione di nuovo gestore di evento . . . 5-4
Generazione di un gestore per levento
predefinito di un componente . . . . . . . . 5-4
Individuazione dei gestori di evento . . . . . 5-4
Associazione di un evento ad un gestore
di evento esistente . . . . . . . . . . . . . . . 5-5
Utilizzo del parametro Sender . . . . . . . 5-5
Visualizzazione e codifica di eventi
condivisi . . . . . . . . . . . . . . . . . . 5-5
Associazione di eventi di menu
a gestori di evento . . . . . . . . . . . . . . . 5-6
Cancellazione di gestori di evento. . . . . . . 5-6
Componenti multipiattaforma
e non multipiattaforma . . . . . . . . . . . . . . 5-7
Aggiunta di componenti custom alla
Component palette . . . . . . . . . . . . . . 5-9
Capitolo 6
Uso dei controlli 6-1
Implementazione del drag and drop
nei controlli . . . . . . . . . . . . . . . . . . . . 6-1
Inizio di unoperazione di trascinamento. . . 6-1
Accettazione degli elementi rilasciati . . . . . 6-2
Rilascio di elementi . . . . . . . . . . . . . . . 6-3
Fine di unoperazione di trascinamento . . . 6-3
Personalizzazione delle operazioni
di drag-and-drop con un oggetto drag . . . 6-4
Modifica del puntatore di trascinamento
del mouse. . . . . . . . . . . . . . . . . . . . 6-4
Implementazione del drag-and-dock
nei controlli . . . . . . . . . . . . . . . . . . . . 6-4
Trasformazione di un controllo con finestra
in una posizione di aggancio . . . . . . . . . 6-5
Trasformazione di un controllo
in un figlio agganciabile . . . . . . . . . . . 6-5
Controllo della modalit di aggancio dei
controlli figlio . . . . . . . . . . . . . . . . . 6-6
Controllo della modalit di sgancio
dei controlli figlio . . . . . . . . . . . . . . . 6-6
Controllo della modalit di risposta
dei controlli figlio alle operazioni
drag-and-dock . . . . . . . . . . . . . . . . . 6-7
Operazioni con testo nei controlli . . . . . . . . . 6-7
Impostazione dellallineamento del testo. . . 6-7
Aggiunta di barre di scorrimento
in fase di esecuzione. . . . . . . . . . . . . . 6-8
Aggiunta delloggetto clipboard. . . . . . . . 6-8
iii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Selezione del testo . . . . . . . . . . . . . . . 6-9
Selezione di tutto il testo. . . . . . . . . . . . 6-9
Operazione taglia, copia e incolla del testo . 6-9
Cancellazione del testo selezionato. . . . . . 6-10
Disattivazione delle voci di menu . . . . . . 6-10
Preparazione di un menu a comparsa . . . . 6-11
Gestione dellevento OnPopup . . . . . . . . 6-11
Aggiunta di grafici ai controlli . . . . . . . . . . 6-12
Come indicare che un controllo
owner-drawn . . . . . . . . . . . . . . . . 6-13
Aggiunta di oggetti grafici
ad un elenco di stringhe . . . . . . . . . . . 6-13
Aggiunta di immagini
ad unapplicazione . . . . . . . . . . . . 6-13
Aggiunta di immagini
a un elenco di stringhe . . . . . . . . . . 6-14
Disegno di elementi owner-draw. . . . . 6-15
Dimensionamento degli elementi
owner-draw. . . . . . . . . . . . . . . . . . 6-15
Disegno di elementi owner-draw. . . . . . . 6-16
Capitolo 7
Creazione di applicazioni,
componenti e librerie 7-1
Creazione di applicazioni . . . . . . . . . . . . . 7-1
Applicazioni GUI. . . . . . . . . . . . . . . . 7-1
Modelli di interfaccia utente. . . . . . . . 7-2
Applicazioni SDI . . . . . . . . . . . . . . 7-2
Applicazioni MDI. . . . . . . . . . . . . . 7-2
Impostazioni delle opzioni per lIDE, il
progetto e la compilazione . . . . . . . . 7-3
Modelli di programmazione . . . . . . . . . 7-3
Applicazioni per console . . . . . . . . . . . 7-4
Utilizzo di VCL e CLX in applicazioni
per console. . . . . . . . . . . . . . . . . 7-4
Applicazioni di servizio . . . . . . . . . . . . 7-4
Thread dei servizi. . . . . . . . . . . . . . 7-7
Propriet del nome del servizio . . . . . . 7-9
Debug delle applicazioni di servizio . . . 7-9
Creazione di package e di DLL. . . . . . . . . . 7-10
Quando usare i package e le DLL . . . . . . 7-11
Uso delle DLL in C++Builder. . . . . . . . . . . 7-11
Creazione di DLL in C++Builder. . . . . . . . . 7-12
Creazione di DLL contenenti
componenti VCL e CLX . . . . . . . . . . . . . 7-13
Collegamento delle DLL . . . . . . . . . . . . . 7-15
Scrittura di applicazioni database . . . . . . . . 7-16
Distribuzione di applicazioni database . . . 7-17
Creazione di applicazioni per Web server. . . . 7-17
Utilizzo di Web Broker . . . . . . . . . . . . 7-17
Creazione di applicazioni WebSnap. . . . . 7-18
Utilizzo di InternetExpress . . . . . . . . . . 7-19
Creazione di applicazioni Web Services . . 7-19
Scrittura di applicazioni con COM . . . . . . . 7-20
Utilizzo di COM e DCOM . . . . . . . . . . 7-20
Utilizzo di MTS e COM+ . . . . . . . . . . . 7-20
Utilizzo dei moduli dati . . . . . . . . . . . . . 7-21
Creazione e modifica
di moduli dati standard. . . . . . . . . . . 7-22
Attribuzione del nome a un modulo
dati e al relativo file unit . . . . . . . . 7-22
Posizionamento e assegnazione
del nome ai componenti . . . . . . . . . 7-23
Utilizzo delle propriet e degli eventi
dei componenti di un modulo dati. . . 7-24
Creazione di regole di gestione
in un modulo dati . . . . . . . . . . . . 7-24
Accesso a un modulo dati da una scheda. . 7-24
Aggiunta di un modulo dati remoto a un
progetto di application server . . . . . . . 7-25
Utilizzo dellObject Repository . . . . . . . . . 7-25
Condivisione di elementi
allinterno di un progetto . . . . . . . . . . 7-25
Aggiunta di elementi allObject Repository 7-26
Condivisione di oggetti
in un team di lavoro. . . . . . . . . . . . . 7-26
Utilizzo di un elemento
dellObject Repository in un progetto . . . 7-26
Copia di un elemento . . . . . . . . . . . 7-27
Ereditare un elemento. . . . . . . . . . . 7-27
Utilizzo di un elemento . . . . . . . . . . 7-27
Utilizzo di modelli di progetto. . . . . . . . 7-27
Modifica di elementi condivisi. . . . . . . . 7-28
Specifica di un progetto predefinito, di una
nuova scheda e della scheda principale. . 7-28
Attivazione dellHelp nelle applicazioni . . . . 7-28
Interfacce per il sistema di Help . . . . . . . 7-29
Implementazione di ICustomHelpViewer . 7-30
Comunicazione con Help Manager . . . . . 7-30
Richiesta di informazioni allHelp Manager 7-31
Visualizzazione di Help
in base a parole chiave . . . . . . . . . . . 7-31
Visualizzazione degli indici . . . . . . . . . 7-32
Implementazione IExtendedHelpViewer . . 7-33
Implementazione IHelpSelector . . . . . . . 7-34
Registrazione di oggetti di sistema di Help 7-34
Registrazione dei visualizzatori di Help 7-34
Registrazione dei selettori di Help. . . . 7-35
iv
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Utilizzo dellHelp in unapplicazione VCL . . . 7-35
In che modo TApplication
elabora lHelp VCL. . . . . . . . . . . . . . 7-35
In che modo i controlli VCL
elaborano lHelp . . . . . . . . . . . . . . . 7-36
Utilizzo dellHelp in unapplicazione CLX . . . 7-36
In che modo TApplication
elabora lHelp CLX . . . . . . . . . . . . . . 7-36
In che modo i controlli CLX
elaborano lHelp . . . . . . . . . . . . . . . 7-37
Chiamata diretta a un sistema di Help . . . . . 7-37
Utilizzo di IHelpSystem. . . . . . . . . . . . . . 7-37
Personalizzazione del sistema di Help dellIDE7-38
Capitolo 8
Sviluppo dellinterfaccia utente
dellapplicazione 8-1
Controllo del comportamento dellapplicazione 8-1
Il lavoro a livello di applicazione . . . . . . . 8-2
Gestione dello schermo . . . . . . . . . . . . 8-2
Impostazione delle schede . . . . . . . . . . . . 8-2
Uso della scheda principale . . . . . . . . . . 8-3
Occultamento della scheda principale . . . . 8-3
Aggiunta di schede. . . . . . . . . . . . . . . 8-3
Collegamento delle schede . . . . . . . . 8-3
Gestione del layout. . . . . . . . . . . . . . . 8-4
Uso delle schede . . . . . . . . . . . . . . . . . . 8-5
Controllo delle schede in memoria . . . . . . 8-5
Visualizzazione di una scheda
creata automaticamente . . . . . . . . . 8-6
Creazione dinamica delle schede . . . . . 8-6
Creazione di schede non modali
come finestre. . . . . . . . . . . . . . . . 8-7
Creazione di unistanza di scheda
mediante una variabile locale . . . . . . 8-7
Passaggio di altri argomenti alle schede . . . 8-8
Recupero dei dati dalle schede . . . . . . . . 8-9
Recupero dei dati da schede non modali. 8-9
Recupero dei dati da schede modali . . . 8-10
Riutilizzo di componenti
e gruppi di componenti . . . . . . . . . . . . . 8-12
Creazione e utilizzo di modelli di componenti . 8-13
Operazioni con i frame . . . . . . . . . . . . . . 8-14
Creazione di frame . . . . . . . . . . . . . . . 8-14
Aggiunta di frame alla Component palette . 8-15
Uso e modifica di frame . . . . . . . . . . . . 8-15
Condivisione di frame . . . . . . . . . . . . . 8-16
Sviluppo di finestre di dialogo . . . . . . . . . . 8-16
Utilizzo delle finestre di dialogo
di tipo Open . . . . . . . . . . . . . . . . . 8-17
Organizzazione delle azioni per barre e menu 8-17
Che cosa un azione . . . . . . . . . . . . . 8-19
Configurazione delle bande di azione . . . 8-20
Creazione di barre di strumenti e menu . . 8-20
Aggiunta di colori, motivi o immagini a
menu, pulsanti e barre di strumenti . . 8-22
Aggiunta di icone a menu e
barre di strumenti . . . . . . . . . . . . 8-23
Creazione di barre di strumenti e menu
personalizzabili dagli utenti . . . . . . 8-23
Occultamento di elementi e categorie
inutilizzate nelle bande di azioni . . . . 8-24
Uso delle liste di azioni. . . . . . . . . . . . . . 8-25
Configurazione delle liste di azioni . . . . . 8-25
Cosa accade quando si scatena unazione . 8-27
Risposta con eventi . . . . . . . . . . . . 8-27
Come le azioni trovano
le proprie destinazioni. . . . . . . . . . 8-28
Aggiornamento delle azioni . . . . . . . . . 8-29
Classi di azione predefinite. . . . . . . . . . 8-29
Scrittura di componenti azione . . . . . . . 8-30
Registrazione delle azioni . . . . . . . . . . 8-31
Creazione e gestione dei menu . . . . . . . . . 8-32
Apertura del Menu Designer . . . . . . . . 8-32
Costruzione di menu . . . . . . . . . . . . . 8-33
Assegnazione dei nomi dei menu . . . . 8-33
Assegnazione dei nomi
delle voci di menu . . . . . . . . . . . . 8-34
Aggiunta, inserimento e cancellazione
delle voci di menu . . . . . . . . . . . . 8-34
Aggiunta di barre separatrici . . . . . . . 8-36
Specifica dei tasti di scelta rapida e delle
scorciatoie di tastiera . . . . . . . . . . 8-36
Creazione di sottomenu . . . . . . . . . . . 8-37
Creazione di sottomenu
per retrocessione dei menu esistenti . . 8-38
Spostamento delle voci di menu . . . . . 8-38
Aggiunta di immagini alle voci di menu 8-38
Visualizzazione del menu. . . . . . . . . 8-39
Editing delle voci di menu
nellObject Inspector . . . . . . . . . . . . 8-39
Uso del menu contestuale Menu Designer . 8-40
I comandi del menu contestuale . . . . . 8-40
Passaggio da un menu allaltro
in fase di progettazione . . . . . . . . . 8-40
Uso dei modelli di menu . . . . . . . . . . . 8-41
Salvataggio di un menu come modello . . . 8-42
v
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Convenzioni per lassegnazione
dei nomi delle voci di menu
e dei gestori di evento di un modello . . 8-43
Manipolazione delle voci di menu
in fase di esecuzione . . . . . . . . . . . . . 8-44
Fusione dei menu . . . . . . . . . . . . . . . 8-44
Specifica del menu attivo:
propriet Menu . . . . . . . . . . . . . . 8-44
Determinazione dellordine delle voci
di menu fuse: propriet GroupIndex . . 8-44
Importazione dei file risorsa . . . . . . . . . 8-45
Progettazione di barre strumenti e di coolbar . 8-45
Aggiunta di una barra strumenti usando un
componente panel . . . . . . . . . . . . . . 8-47
Aggiunta di un pulsante di scelta
rapida a un pannello . . . . . . . . . . . 8-47
Assegnazione del glifo a un pulsante
di scelta rapida . . . . . . . . . . . . . . 8-47
Impostazione della condizione iniziale
di un pulsante di scelta rapida . . . . . 8-48
Creazione di un gruppo di pulsanti
di scelta rapida . . . . . . . . . . . . . . 8-48
Come consentire la commutazione
dei pulsanti . . . . . . . . . . . . . . . . 8-48
Aggiunta di una barra strumenti usando il
relativo componente . . . . . . . . . . . . . 8-49
Aggiunta di un pulsante strumento . . . 8-49
Assegnazione di immagini
ai pulsanti strumento . . . . . . . . . . . 8-50
Impostazione dellaspetto di un pulsante
strumento e delle condizioni iniziali . . 8-50
Creazione di gruppi
di pulsanti strumento. . . . . . . . . . . 8-50
Come consentire pulsanti
strumento commutati. . . . . . . . . . . 8-51
Aggiunta di un componente coolbar . . . . . 8-51
Impostazione dellaspetto della coolbar . 8-52
Risposta ai clic . . . . . . . . . . . . . . . . . 8-52
Assegnazione di un menu
a un pulsante strumento . . . . . . . . . 8-52
Aggiunta di barre strumenti nascoste . . . . 8-53
Come nascondere e mostrare
le barre strumenti . . . . . . . . . . . . . . . 8-53
Capitolo 9
Tipi di controlli 9-1
Controlli di testo . . . . . . . . . . . . . . . . . . 9-1
Controlli di editing. . . . . . . . . . . . . . . 9-2
Propriet dei controlli di editing . . . . . . . 9-3
Controlli memo e rich edit . . . . . . . . . 9-3
Controlli per la visualizzazione
del testo (solo per la CLX) . . . . . . . . . . 9-4
Etichette . . . . . . . . . . . . . . . . . . . . . 9-4
Controlli specializzati per linput . . . . . . . . . 9-5
Barre di scorrimento . . . . . . . . . . . . . . 9-5
Barre di regolazione. . . . . . . . . . . . . . . 9-5
Controlli up-down (solo VCL) . . . . . . . . . 9-6
Controlli spin edit (solo CLX) . . . . . . . . . 9-6
Controlli Hot key (solo VCL). . . . . . . . . . 9-6
Controlli splitter . . . . . . . . . . . . . . . . . 9-7
Pulsanti e controlli simili . . . . . . . . . . . . . . 9-7
Controlli pulsante . . . . . . . . . . . . . . . . 9-8
Pulsanti bitmap . . . . . . . . . . . . . . . . . 9-8
Pulsanti di scelta rapida . . . . . . . . . . . . 9-8
Caselle di controllo . . . . . . . . . . . . . . . 9-9
Pulsanti di opzione . . . . . . . . . . . . . . . 9-9
Barre strumenti . . . . . . . . . . . . . . . . . 9-9
Cool bar (solo VCL) . . . . . . . . . . . . . . 9-10
Controlli elenco . . . . . . . . . . . . . . . . . . 9-10
Caselle di riepilogo e
caselle di riepilogo con spunta . . . . . . . 9-11
Caselle combinate . . . . . . . . . . . . . . . 9-12
Viste ad albero . . . . . . . . . . . . . . . . . 9-12
Viste ad elenco . . . . . . . . . . . . . . . . . 9-13
Selettore data-ora e
calendari mensili (solo VCL) . . . . . . . . 9-13
Controlli di raggruppamento . . . . . . . . . . 9-14
Caselle di gruppo e
gruppi di pulsanti di opzione . . . . . . . 9-14
Pannelli . . . . . . . . . . . . . . . . . . . . . 9-14
Caselle a scorrimento . . . . . . . . . . . . . 9-15
Controlli separatore . . . . . . . . . . . . . . 9-15
Controlli pagina . . . . . . . . . . . . . . . . 9-16
Controlli intestazione . . . . . . . . . . . . . 9-16
Controlli di visualizzazione . . . . . . . . . . . 9-16
Barre di stato. . . . . . . . . . . . . . . . . . 9-16
Barre di avanzamento. . . . . . . . . . . . . 9-17
Propriet Help e Hint . . . . . . . . . . . . . 9-17
Griglie . . . . . . . . . . . . . . . . . . . . . . . 9-17
Griglie grafiche . . . . . . . . . . . . . . . . 9-18
Griglie per stringhe . . . . . . . . . . . . . . 9-18
Editor di liste di valori (solo VCL) . . . . . . . 9-18
Controlli grafici . . . . . . . . . . . . . . . . . . 9-19
Immagini . . . . . . . . . . . . . . . . . . . . 9-20
Forme . . . . . . . . . . . . . . . . . . . . . . 9-20
Linee smussate. . . . . . . . . . . . . . . . . 9-20
Caselle di disegno . . . . . . . . . . . . . . . 9-20
Controlli Animation (solo VCL) . . . . . . . 9-20
vi
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Capitolo 10
Operazioni con elementi
grafici e multimediali 10-1
Panoramica sulla programmazione dei grafici . 10-1
Aggiornamento dello schermo . . . . . . . . 10-2
Tipi di oggetti grafici . . . . . . . . . . . . . . 10-3
Propriet e metodi comuni
delloggetto Canvas . . . . . . . . . . . . . 10-4
Uso delle propriet delloggetto Canvas . . 10-5
Uso delle penne . . . . . . . . . . . . . . . 10-6
Uso dei pennelli . . . . . . . . . . . . . . . 10-8
Lettura e impostazione dei pixel . . . . 10-10
Uso dei metodi Canvas
per disegnare oggetti grafici. . . . . . . . 10-10
Disegno di linee e spezzate . . . . . . . 10-10
Disegno di figure . . . . . . . . . . . . . 10-11
Gestione di pi oggetti di disegno
in unapplicazione . . . . . . . . . . . . . 10-13
Come tenere la traccia dello strumento
di disegno da usare . . . . . . . . . . . 10-13
Modifica degli strumenti
con i pulsanti di scelta rapida . . . . . 10-14
Uso degli strumenti di disegno . . . . . 10-14
Disegno su un grafico . . . . . . . . . . . . 10-17
Come far scorrere i grafici . . . . . . . . 10-18
Aggiunta di un controllo immagine . . 10-18
Caricamento e salvataggio dei file grafici . 10-20
Caricamento di unimmagine da un file 10-20
Salvataggio di unimmagine in un file . 10-21
Sostituzione dellimmagine . . . . . . . 10-21
Uso della clipboard con i grafici . . . . . . 10-22
Operazioni di copia di grafici
nella clipboard. . . . . . . . . . . . . . 10-23
Operazioni di taglio di grafici
nella clipboard. . . . . . . . . . . . . . 10-23
Operazioni di incollaggio di grafici
dalla clipboard . . . . . . . . . . . . . 10-24
Esempio di effetto elastico. . . . . . . . . . 10-24
Risposta al mouse. . . . . . . . . . . . . 10-25
Risposta ad unazione mouse-down . . 10-26
Aggiunta di un campo
ad un oggetto scheda per tenere
traccia delle azioni del mouse . . . . . 10-27
Affinamento del disegno delle linee . . 10-29
Uso di componenti multimediali. . . . . . . . 10-30
Aggiunta di clip video senza suono
ad unapplicazione . . . . . . . . . . . . . 10-31
Esempio di aggiunta di clip video
senza suono . . . . . . . . . . . . . . . 10-32
Aggiunta di clip audio e/o video
a unapplicazione . . . . . . . . . . . . . 10-33
Esempio di aggiunta di clip audio
e/o video (solo VCL) . . . . . . . . . 10-34
Capitolo 11
Scrittura di applicazioni multi-thread 11-1
Definizione di oggetti thread . . . . . . . . . . 11-1
Inizializzazione del thread . . . . . . . . . . 11-3
Assegnazione di una priorit predefinita 11-3
Come indicare quando i thread
vengono rilasciati . . . . . . . . . . . . 11-4
Scrittura della funzione thread. . . . . . . . 11-4
Utilizzo del thread VCL/CLX principale 11-4
Uso di variabili locali al thread. . . . . . 11-5
Controllo del termine
da parte di altri thread. . . . . . . . . . 11-6
Gestione delle eccezioni
nella funzione di thread . . . . . . . . . 11-7
Scrittura del codice di pulizia . . . . . . . . 11-7
Coordinamento dei thread. . . . . . . . . . . . 11-7
Come evitare laccesso simultaneo . . . . . 11-8
Blocco di oggetti . . . . . . . . . . . . . . 11-8
Uso di sezioni critiche . . . . . . . . . . . 11-8
Uso del sincronizzatore multilettura a
scrittura esclusiva . . . . . . . . . . . . 11-9
Altre tecniche per la condivisione
della memoria . . . . . . . . . . . . . . 11-9
Attesa di altri thread . . . . . . . . . . . . .11-10
Attesa che un thread
termini lesecuzione . . . . . . . . . . .11-10
Attesa che venga completata
unoperazione . . . . . . . . . . . . . .11-10
Esecuzione di oggetti thread. . . . . . . . . . .11-12
Ridefinizione della priorit predefinita . . .11-12
Avvio e interruzione dei thread . . . . . . .11-12
Debug di applicazioni multi-thread . . . . . .11-13
Assegnazione di un nome al thread. . . . .11-13
Conversione di un thread senza nome
in uno con nome . . . . . . . . . . . . .11-13
Assegnazione di nomi differenti
a thread simili . . . . . . . . . . . . . .11-14
Capitolo 12
Gestione delle eccezioni 12-1
Gestione delle eccezioni C++ . . . . . . . . . . 12-1
Sintassi della gestione delle eccezioni . . . . 12-2
Il blocco try . . . . . . . . . . . . . . . . . 12-2
Listruzione throw . . . . . . . . . . . . . 12-2
vii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Listruzione catch . . . . . . . . . . . . . . 12-3
Risollevamento delle eccezioni . . . . . . . . 12-4
Specifica delle eccezioni . . . . . . . . . . . . 12-4
Rilascio delle eccezioni . . . . . . . . . . . . 12-5
Puntatori sicuri . . . . . . . . . . . . . . . 12-5
I costruttori nella gestione delle eccezioni . . 12-6
Gestione di eccezioni non intercettate
e inattese. . . . . . . . . . . . . . . . . . . . 12-6
Eccezioni strutturate in ambiente Win32 . . . . 12-7
Sintassi delle eccezioni strutturate . . . . . . 12-7
Gestione delle eccezioni strutturate . . . . . 12-8
Filtri delle eccezioni . . . . . . . . . . . . . . 12-9
Abbinamento di eccezioni
strutturate con C++. . . . . . . . . . . . . 12-10
Eccezioni basate su C
in un programma di esempio C++ . . 12-11
Definizione delle eccezioni . . . . . . . . . 12-12
Sollevamento delle eccezioni . . . . . . . . 12-13
Blocchi di terminazione . . . . . . . . . . . 12-13
Opzioni di C++Builder
per la gestione delle eccezioni. . . . . . . 12-15
Gestione delle eccezioni VCL/CLX . . . . . . 12-15
Differenze tra C++ e VCL/CLX
nella gestione delle eccezioni . . . . . . . 12-16
Gestione delle eccezioni
del sistema operativo. . . . . . . . . . . . 12-16
Gestione delle eccezioni
della VCL e della CLX . . . . . . . . . . . 12-17
Classi di eccezioni VCL e CLX . . . . . . . 12-17
Considerazioni sulla portabilit . . . . . . 12-19
Capitolo 13
Supporto del linguaggio C++
per la VCL e la CLX 13-1
Modelli di oggetti C++ e Object Pascal . . . . . 13-1
Eredit e interfacce . . . . . . . . . . . . . . . 13-2
Utilizzo delle interfacce invece
delleredit multipla . . . . . . . . . . . 13-2
Dichiarazione delle classi interfaccia . . . 13-2
IUnknown e IInterface . . . . . . . . . . . 13-3
Creazione di classi
che supportano IUnknown . . . . . . . 13-4
Classi interfacciate e gestione
del periodo di esistenza . . . . . . . . . 13-5
Identit e istanziazione di un oggetto . . . . 13-5
Distinzione tra i riferimenti in C++ e in
Object Pascal. . . . . . . . . . . . . . . . 13-6
Copia di oggetti . . . . . . . . . . . . . . . 13-6
Oggetti come argomenti di funzione . . . 13-8
Costruzione di oggetti per le classi
VCL\CLX di C++Builder . . . . . . . . . . 13-8
Costruzione di oggetti in C++ . . . . . . 13-8
Costruzione di oggetti in Object Pascal . 13-8
Costruzione di oggetti in C++Builder . . 13-8
Chiamata dei metodi virtuali
nei costruttori della classe base . . . . . 13-10
Modello Object Pascal . . . . . . . . . . .13-11
Modello C++ . . . . . . . . . . . . . . . .13-11
Modello C++Builder. . . . . . . . . . . .13-11
Esempio: chiamata dei metodi virtuali .13-11
Inizializzazione del costruttore dei
membri dati per le funzioni virtuali . 13-12
Distruzione di oggetti . . . . . . . . . . . . 13-13
Eccezioni sollevate dai costruttori . . . 13-14
Metodi virtuali chiamati dai distruttori 13-15
AfterConstruction e BeforeDestruction . . 13-15
Funzioni virtuali di classe . . . . . . . . . 13-15
Supporto per i tipi di dati Object Pascal e per le
strutture del linguaggio . . . . . . . . . . . 13-15
Typedef . . . . . . . . . . . . . . . . . . . . 13-16
Classi che supportano
il linguaggio Object Pascal . . . . . . . . 13-16
Equivalenti del linguaggio C++
presenti nel linguaggio Object Pascal . . 13-17
Parametri var . . . . . . . . . . . . . . . 13-17
Parametri senza tipo. . . . . . . . . . . 13-17
Open array . . . . . . . . . . . . . . . . . . 13-17
Calcolo del numero di elementi . . . . 13-18
Array temporanei . . . . . . . . . . . . 13-18
Array of const . . . . . . . . . . . . . . 13-19
Macro OPENARRAY . . . . . . . . . . 13-19
Macro EXISTINGARRAY . . . . . . . . 13-20
Funzioni C++ che accettano
argomenti di tipo open array . . . . . 13-20
Tipi definiti in altro modo . . . . . . . . . 13-20
Tipi di dati booleani . . . . . . . . . . . 13-20
Tipi di dati char . . . . . . . . . . . . . 13-21
Interfacce Delphi . . . . . . . . . . . . . . 13-21
Stringhe di risorse . . . . . . . . . . . . . . 13-21
Parametri predefiniti . . . . . . . . . . . . 13-22
Informazioni di tipo runtime. . . . . . . . 13-23
Tipi non mappati . . . . . . . . . . . . . . 13-24
Tipi real a 6 byte . . . . . . . . . . . . . 13-24
Arrays come tipi restituiti da funzioni 13-24
Estensioni di parole chiave . . . . . . . . . 13-24
__classid . . . . . . . . . . . . . . . . . 13-24
__closure . . . . . . . . . . . . . . . . . 13-25
__property . . . . . . . . . . . . . . . . 13-27
viii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
__published . . . . . . . . . . . . . . . . 13-28
Estensione della parola chiave __declspec. 13-29
__declspec(delphiclass) . . . . . . . . . 13-29
__declspec(delphireturn). . . . . . . . . 13-29
__declspec(delphirtti) . . . . . . . . . . 13-30
__declspec(dynamic) . . . . . . . . . . . 13-30
__declspec(hidesbase) . . . . . . . . . . 13-30
__declspec(package) . . . . . . . . . . . 13-30
__declspec(pascalimplementation) . . . 13-31
__declspec(uuid) . . . . . . . . . . . . . 13-31
Capitolo 14
Sviluppo di applicazioni
multipiattaforma 14-1
Creazione di applicazioni multipiattaforma . . 14-1
Porting di applicazioni Windows in Linux . . . 14-2
Tecniche di porting. . . . . . . . . . . . . . . 14-2
Porting specifico per una piattaforma . . 14-3
Porting per pi piattaforme . . . . . . . . 14-3
Porting in emulazione Windows . . . . . 14-3
Porting dellapplicazione . . . . . . . . . . . 14-3
CLX e VCL . . . . . . . . . . . . . . . . . . . 14-5
Differenze nella CLX. . . . . . . . . . . . . . 14-6
Aspetto. . . . . . . . . . . . . . . . . . . . 14-6
Stili . . . . . . . . . . . . . . . . . . . . . . 14-6
Variant . . . . . . . . . . . . . . . . . . . . 14-6
File di registro . . . . . . . . . . . . . . . . 14-7
Altre differenze . . . . . . . . . . . . . . . 14-7
Cosa manca nella CLX. . . . . . . . . . . . . 14-8
Funzioni di cui non possibile
fare il porting . . . . . . . . . . . . . . . . . 14-9
Confronto fra le unit CLX e VCL . . . . . . . 14-9
Differenze nei costruttori di oggetti CLX . 14-13
Gestione degli eventi di sistema
e di widget. . . . . . . . . . . . . . . . . . 14-13
Condivisione di file sorgente
tra Windows e Linux . . . . . . . . . . . . 14-14
Differenze di ambiente
fra Windows e Linux . . . . . . . . . . . . 14-14
Struttura delle directory su Linux . . . . . 14-16
Scrittura di codice portabile . . . . . . . . . 14-17
Utilizzo delle direttive condizionali . . 14-18
Emissione di messaggi . . . . . . . . . . 14-20
Inclusione di codice assembler in linea. 14-20
Differenze di programmazione in Linux. . 14-21
Applicazioni database multipiattaforma . . . 14-21
Differenze in dbExpress . . . . . . . . . . . 14-22
Differenze a livello di componenti . . . . . 14-23
Differenze a livello di interfaccia utente . . 14-24
Porting di applicazioni database in Linux 14-25
Aggiornamento dei dati
in applicazioni dbExpress . . . . . . . . 14-28
Applicazioni Internet multipiattaforma . . . 14-30
Porting di applicazioni Internet in Linux . 14-30
Capitolo 15
Uso di package e di componenti 15-1
Perch usare i package . . . . . . . . . . . . . . 15-2
Package e DLL standard . . . . . . . . . . . 15-2
Package di esecuzione . . . . . . . . . . . . . . 15-3
Uso dei package in unapplicazione. . . . . 15-3
Caricamento dinamico dei package . . . . . 15-4
Scelta di quali package di esecuzione usare 15-4
Package custom . . . . . . . . . . . . . . . . 15-5
Package di progettazione . . . . . . . . . . . . 15-5
Installazione di package di componenti . . 15-6
Creazione ed editing dei package . . . . . . . . 15-7
Creazione di un package . . . . . . . . . . . 15-7
Editing di un package esistente . . . . . . . 15-8
File sorgenti di package
e file di opzione di progetto . . . . . . . . 15-8
Packaging di componenti . . . . . . . . . 15-9
Struttura di un package. . . . . . . . . . . . 15-9
Assegnazione del nome ai package . . 15-10
Elenco Requires . . . . . . . . . . . . . 15-10
Elenco Contains . . . . . . . . . . . . . .15-11
Generazione di package . . . . . . . . . . .15-11
Direttive al compilatore
specifiche per il packaging . . . . . . 15-12
Uso del compilatore e del linker
dalla riga comandi . . . . . . . . . . . 15-13
File package creati
mediante generazione . . . . . . . . . 15-13
Distribuzione dei package . . . . . . . . . . . 15-14
Distribuzione di applicazioni
che usano package. . . . . . . . . . . . . 15-14
Distribuzione di package
ad altri sviluppatori . . . . . . . . . . . . 15-14
File di raccolta di package . . . . . . . . . 15-15
Capitolo 16
Creazione di applicazioni
internazionali 16-1
Internazionalizzazione e localizzazione . . . . 16-1
Internazionalizzazione . . . . . . . . . . . . 16-1
Localizzazione . . . . . . . . . . . . . . . . . 16-2
Internazionalizzazione delle applicazioni . . . 16-2
Abilitazione del codice dellapplicazione. . 16-2
ix
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Set di caratteri . . . . . . . . . . . . . . . . 16-2
Set di caratteri OEM e ANSI . . . . . . . . 16-3
Set di caratteri multibyte. . . . . . . . . . 16-3
Caratteri estesi . . . . . . . . . . . . . . . 16-3
Inclusione di funzionalit bidirezionali
nelle applicazioni . . . . . . . . . . . . . 16-4
Propriet BiDiMode . . . . . . . . . . . . 16-6
Funzioni specifiche della localit . . . . . 16-8
Progettazione di uninterfaccia utente . . . . 16-9
Testo . . . . . . . . . . . . . . . . . . . . . 16-9
Immagini. . . . . . . . . . . . . . . . . . 16-10
Formati e ordinamento. . . . . . . . . . 16-10
Configurazione della tastiera . . . . . . 16-10
Isolamento delle risorse . . . . . . . . . . . 16-10
Creazione di DLL di risorse . . . . . . . . . 16-11
Uso delle DLL di risorse . . . . . . . . . . . 16-11
Sostituzione dinamica delle DLL di risorse 16-12
Localizzazione delle applicazioni . . . . . . . 16-13
Localizzazione delle risorse . . . . . . . . . 16-13
Capitolo 17
Distribuzione di applicazioni 17-1
Distribuzione di applicazioni generiche. . . . . 17-1
Uso di programmi di installazione . . . . . . 17-2
Identificazione dei file dellapplicazione. 17-2
File di applicazione . . . . . . . . . . . . . 17-3
File package . . . . . . . . . . . . . . . . . 17-3
Moduli di fusione. . . . . . . . . . . . . . 17-3
Controlli ActiveX . . . . . . . . . . . . . . 17-5
Applicazioni di ausilio . . . . . . . . . . . 17-5
Ubicazione delle DLL . . . . . . . . . . . 17-6
Distribuzione di applicazioni CLX. . . . . . . . 17-6
Distribuzione di applicazioni database . . . . . 17-6
Distribuzione di applicazioni
database dbExpress. . . . . . . . . . . . . . 17-7
Distribuzione di applicazioni BDE . . . . . . 17-8
Borland Database Engine . . . . . . . . . 17-9
SQL Links . . . . . . . . . . . . . . . . . . 17-9
Distribuzione di applicazioni
database multi-tier (DataSnap) . . . . . . 17-10
Distribuzione di applicazioni Web. . . . . . . 17-10
Distribuzione su server Apache . . . . . . 17-11
Abilitazione dei moduli . . . . . . . . . 17-11
Applicazioni CGI . . . . . . . . . . . . . 17-12
Programmazione per ambienti
di destinazione diversi. . . . . . . . . . . . . 17-12
Risoluzione dello schermo
e numero di colori . . . . . . . . . . . . . 17-13
Considerazioni sul ridimensionamento
non dinamico . . . . . . . . . . . . . . 17-13
Considerazioni sul ridimensionamento
dinamico di schede e controlli . . . . 17-13
Regolazione in funzione
del numero di colori disponibili . . . 17-15
Font . . . . . . . . . . . . . . . . . . . . . . 17-15
Versioni del sistema operativo . . . . . . . 17-16
Requisiti per la licenza duso del software . . 17-16
DEPLOY . . . . . . . . . . . . . . . . . . . 17-16
README. . . . . . . . . . . . . . . . . . . 17-17
Accordo di licenza. . . . . . . . . . . . . . 17-17
Documentazione sui prodotti di terze parti 17-17
Parte II
Sviluppo di applicazioni database
Capitolo 18
Progettazione di applicazioni
database 18-1
Uso dei databases . . . . . . . . . . . . . . . . . 18-1
Tipi di database . . . . . . . . . . . . . . . . 18-3
Sicurezza del database . . . . . . . . . . . . 18-4
Transazioni . . . . . . . . . . . . . . . . . . . 18-5
Integrit referenziale, procedure registrate
e trigger . . . . . . . . . . . . . . . . . . . . 18-5
Architettura di un database . . . . . . . . . . . 18-6
Struttura generale . . . . . . . . . . . . . . . 18-6
La scheda dellinterfaccia utente . . . . . 18-6
Il modulo dati . . . . . . . . . . . . . . . 18-7
Connessione diretta a un server di database 18-8
Utilizzo di un file dedicato su disco. . . . . 18-9
Collegamento a un altro dataset . . . . . . 18-10
Connessione di un dataset client
a un altro dataset
nella stessa applicazione . . . . . . . 18-12
Utilizzo di unarchitettura multi-tier . 18-13
Combinazione dei vari approcci . . . . . . 18-15
Progettazione dellinterfaccia utente . . . . . 18-16
Analisi dei dati. . . . . . . . . . . . . . . . 18-16
Scrittura di report . . . . . . . . . . . . . . 18-17
Capitolo 19
Uso dei controlli dati 19-1
Uso delle funzioni comuni ai controlli dati . . 19-2
Associazione di un controllo
dati a un dataset . . . . . . . . . . . . . . . 19-3
x
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Modifica del dataset
associato in esecuzione . . . . . . . . . . 19-4
Attivazione e disattivazione
del datasource . . . . . . . . . . . . . . . 19-4
Risposta alle modifiche
mediate dal datasource. . . . . . . . . . 19-4
Modifica e aggiornamento dei dati . . . . . . 19-5
Abilitazione dellediting
nei controlli allatto
dellimmissione dati . . . . . . . . . . . 19-5
Modifica dei dati in un controllol . . . . . 19-5
Disabilitazione e abilitazione della
visualizzazione dei dati . . . . . . . . . . . 19-6
Aggiornamento della visualizzazione
dei dati . . . . . . . . . . . . . . . . . . . . . 19-7
Abilitazione degli eventi mouse,
tastiera e timer . . . . . . . . . . . . . . . . 19-7
Scelta del modo in cui organizzare i dati . . . . 19-8
Visualizzazione di un singolo record. . . . . 19-8
Visualizzazione dei dati come etichette . 19-8
Visualizzazione e modifica
di campi in una casella di testo . . . . . 19-9
Visualizzazione e modifica
del testo in un controllo memo l . . . . . 19-9
Visualizzazione e modifica
del testo in un controllo rich edit . . . 19-10
Visualizzazione e modifica
di campi grafici
in un controllo immagine . . . . . . . 19-10
Visualizzazione e modifica
di dati in caselle combinate
e di riepilogo. . . . . . . . . . . . . . . 19-11
Gestione dei valori di campo booleani
con le caselle di controllo. . . . . . . . 19-14
Restrizione dei valori del campo
con controlli di opzione . . . . . . . . 19-15
Visualizzazione di pi record . . . . . . . . 19-16
Visualizzazione e modifica dei dati
con TDBGrid . . . . . . . . . . . . . . . . . . 19-16
Uso di un controllo griglia
nel suo stato predefinito . . . . . . . . . . 19-17
Creazione di una griglia personalizzata . . 19-18
Caratteristiche delle colonne persistenti 19-19
Creazione di colonne persistenti . . . . 19-19
Cancellazione di colonne persistenti . . 19-21
Sistemazione dellordine
delle colonne persistenti . . . . . . . . 19-21
Impostazione delle propriet
di una colonna in progettazione. . . . 19-22
Definizione di una colonna
elenco di consultazione . . . . . . . . 19-23
Inserimento di un pulsante
in una colonna . . . . . . . . . . . . . 19-23
Ripristino dei valori predefiniti
in una colonna . . . . . . . . . . . . . 19-24
Visualizzazione dei campi ADT e array . 19-24
Impostazione delle opzioni per la griglia. 19-26
Editing nella griglia . . . . . . . . . . . . . 19-28
Controllo del disegno della griglia . . . . 19-28
Risposta alle azioni dellutente
in fase di esecuzione. . . . . . . . . . . . 19-29
Creazione di una griglia contenente
altri controlli associati ai dati . . . . . . . . 19-30
Spostamento e gestione dei record . . . . . . 19-31
Scelta dei pulsanti del navigatore
da visualizzare . . . . . . . . . . . . . . . 19-32
Visualizzazione e occultamento
dei pulsanti del navigatore
in fase di progettazione . . . . . . . . 19-33
Visualizzazione e occultamento
dei pulsanti del navigatore
in fase di esecuzione . . . . . . . . . . 19-33
Visualizzazione del fumetto guida . . . . 19-34
Uso di un singolo navigatore
per pi dataset . . . . . . . . . . . . . . . 19-34
Capitolo 20
Uso dei componenti
di supporto decisionale 20-1
Panoramica . . . . . . . . . . . . . . . . . . . . 20-1
I crosstab . . . . . . . . . . . . . . . . . . . . . . 20-2
Crosstab monodimensionali . . . . . . . . . 20-3
Crosstab multidimensionali . . . . . . . . . 20-3
Regole generali per luso dei componenti di
supporto decisionale . . . . . . . . . . . . . . 20-3
Uso dei dataset con i componenti
di supporto decisionale. . . . . . . . . . . . . 20-5
Creazione di dataset decisionali
con TQuery o TTable . . . . . . . . . . . . 20-5
Creazione di dataset decisionali
con leditor Decision Query . . . . . . . . 20-6
Uso dei cubi decisionali . . . . . . . . . . . . . 20-7
Propriet del cubo decisionale e eventi . . . 20-7
Uso di Decision Cube editor . . . . . . . . . 20-7
Visualizzazione e modifica delle
impostazioni delle dimensioni . . . . . 20-8
Impostazione del numero massimo di
dimensioni e di riepiloghi disponibili . 20-8
xi
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Visualizzazione e modifica
delle opzioni di progetto . . . . . . . . . 20-9
Uso delle sorgenti decisionali. . . . . . . . . . . 20-9
Propriet ed eventi . . . . . . . . . . . . . . . 20-9
Uso dei pivot decisionali . . . . . . . . . . . . 20-10
Propriet dei pivot decisionali . . . . . . . 20-10
Creazione e uso delle griglie decisionali . . . 20-11
Creazione di griglie decisionali . . . . . . . 20-11
Uso delle griglie decisionali . . . . . . . . . 20-11
Apertura e chiusura dei campi
della griglia decisionale . . . . . . . . 20-11
Riorganizzazione di righe
e colonne in griglie decisionali . . . . 20-12
Espansione dei dettagli
nelle griglie decisionali . . . . . . . . . 20-12
Limitazione della selezione
delle dimensioni
in griglie decisionali . . . . . . . . . . 20-12
Propriet della griglia decisionale . . . . . 20-12
Creazione e uso dei grafici decisionali. . . . . 20-13
Creazione di grafici decisionali . . . . . . . 20-14
Uso dei grafici decisionali . . . . . . . . . . 20-14
Visualizzazione del grafico decisionale . . 20-15
Personalizzazione dei grafici decisionali . 20-16
Impostazioni predefinite dei modelli
di grafico decisionale . . . . . . . . . . 20-17
Personalizzazione delle serie
del grafico decisionale . . . . . . . . . 20-18
Componenti di supporto decisionale
in esecuzione . . . . . . . . . . . . . . . . . . 20-19
Pivot decisionali in esecuzione . . . . . . . 20-19
Griglie decisionali in esecuzione . . . . . . 20-19
Grafici decisionali in esecuzione . . . . . . 20-20
Componenti di supporto decisionale
e controllo della memoria . . . . . . . . . . . 20-20
Impostazione dei valori massimi per
dimensioni, riepiloghi e celle . . . . . . . 20-20
Impostazione dello stato della dimensione 20-21
Utilizzo delle dimensioni paginate . . . . . 20-21
Capitolo 21
Connessione ai database 21-1
Uso di connessioni implicite . . . . . . . . . . . 21-2
Controllo delle connessioni . . . . . . . . . . . . 21-3
Connessione a un server di database. . . . . 21-3
Disconnessione da un server di database . . 21-4
Controllo del login al server . . . . . . . . . . . 21-4
Gestione delle transazioni. . . . . . . . . . . . . 21-6
Avvio di una transazione . . . . . . . . . . . 21-7
Chiusura di una transazione . . . . . . . . . 21-8
Chiusura di una transazione
andata a buon fine . . . . . . . . . . . . 21-8
Chiusura di una transazione
non andata a buon fine . . . . . . . . . 21-9
Specifica del livello di isolamento
delle transazioni . . . . . . . . . . . . . . 21-10
Invio di comandi al server . . . . . . . . . . . .21-11
Operazioni con i dataset associati . . . . . . . 21-13
Chiusura dei dataset
senza scollegarsi dal server. . . . . . . . 21-13
Scansione di tutti i dataset associati . . . . 21-13
Ottenimento di metadati . . . . . . . . . . . . 21-14
Elenco delle tabelle disponibili . . . . . . 21-14
Elenco dei campi in una tabella . . . . . . 21-14
Elenco delle procedure registrate
disponibili . . . . . . . . . . . . . . . . . 21-15
Elenco degli indici disponibili . . . . . . . 21-15
Elenco dei parametri
delle procedure registrate. . . . . . . . . 21-15
Capitolo 22
I dataset 22-1
Utilizzo dei discendenti di TDataSet . . . . . . 22-2
Determinazione degli stati del dataset . . . . . 22-3
Apertura e chiusura di dataset . . . . . . . . . 22-4
Spostamenti nei dataset . . . . . . . . . . . . . 22-5
Utilizzo dei metodi First e Last . . . . . . . 22-6
Utilizzo dei metodi Next e Prior . . . . . . . 22-7
Utilizzo del metodo MoveBy. . . . . . . . . 22-7
Utilizzo delle propriet Eof e Bof . . . . . . 22-8
Eof . . . . . . . . . . . . . . . . . . . . . . 22-8
Bof . . . . . . . . . . . . . . . . . . . . . . 22-9
Contrassegno e ritorno ai record. . . . . . . 22-9
La propriet Bookmark . . . . . . . . . 22-10
Il metodo GetBookmark. . . . . . . . . 22-10
I metodi GotoBookmark
e BookmarkValid. . . . . . . . . . . . 22-10
Il metodo CompareBookmarks. . . . . 22-10
Il metodo FreeBookmark . . . . . . . . 22-10
Un esempio di utilizzo dei segnalibri . 22-10
Ricerche nei dataset. . . . . . . . . . . . . . . .22-11
Uso di Locate . . . . . . . . . . . . . . . . .22-11
Uso di Lookup. . . . . . . . . . . . . . . . 22-12
Visualizzazione e modifica
di un sottoinsieme di dati usando i filtri . . 22-13
Attivazione e disattivazione dei filtri . . . 22-13
Creazione di filtri . . . . . . . . . . . . . . 22-14
Impostazione della propriet Filter . . 22-14
xii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Scrittura di un gestore
di eventi OnFilterRecord . . . . . . . . 22-16
Commutazione dei gestori evento
di filtro in esecuzione . . . . . . . . . . 22-16
Impostazione delle opzioni del filtro. . . . 22-16
Spostamento tra i record
in un dataset filtrato . . . . . . . . . . . . 22-17
Modifica dei dati . . . . . . . . . . . . . . . . . 22-17
Modifica dei record . . . . . . . . . . . . . 22-18
Aggiunta di nuovi record . . . . . . . . . . 22-19
Inserimento di record. . . . . . . . . . . 22-20
Aggiunta di record . . . . . . . . . . . . 22-20
Cancellazione dei record . . . . . . . . . . 22-20
Registrazione dei dati . . . . . . . . . . . . 22-21
Annullamento delle modifiche . . . . . . . 22-22
Modifica di interi record. . . . . . . . . . . 22-22
Calcolo dei campi . . . . . . . . . . . . . . . . 22-24
Tipi di dataset . . . . . . . . . . . . . . . . . . 22-24
Utilizzo dei dataset di tipo tabella . . . . . . . 22-26
Vantaggi dellutilizzo dei dataset
di tipo tabella . . . . . . . . . . . . . . . . 22-27
Ordinamento dei record con indici . . . . . 22-27
Ottenimento di informazioni
sugli indici . . . . . . . . . . . . . . . . 22-28
Specifica di un indice con IndexName . 22-28
Creazione di un indice
con IndexFieldNames . . . . . . . . . 22-28
Utilizzo di indici per la ricerca di record. . 22-29
Esecuzione di una ricerca
con metodi Goto. . . . . . . . . . . . . 22-30
Esecuzione di una ricerca
con metodi Find. . . . . . . . . . . . . 22-30
Specifica del record corrente
dopo una ricerca andata a buon fine . 22-31
Ricerca in base a chiavi parziali . . . . . 22-31
Ripetizione o ampliamento
di una ricerca . . . . . . . . . . . . . . 22-31
Limitazione dei record con gli intervalli . . 22-32
Differenze fra intervalli e filtri. . . . . . 22-32
Specifica degli intervalli . . . . . . . . . 22-32
Modifica di un intervallo. . . . . . . . . 22-35
Applicazione o annullamento
di un intervallo . . . . . . . . . . . . . 22-36
Creazione di relazioni master/detail. . . . 22-36
Trasformazione della tabella nella
tabella dettaglio di un altro dataset . . 22-37
Utilizzo di tabelle dettaglio annidate . . 22-38
Controllo dellaccesso alle tabelle
in lettura/scrittura . . . . . . . . . . . . . 22-39
Creazione e cancellazione di tabelle. . . . 22-40
Creazione di tabelle . . . . . . . . . . . 22-40
Cancellazione di tabelle . . . . . . . . . 22-42
Svuotamento di tabelle . . . . . . . . . . . 22-42
Sincronizzazione di tabelle . . . . . . . . . 22-43
Utilizzo di dataset di tipo query. . . . . . . . 22-43
Specifica della query . . . . . . . . . . . . 22-44
Specifica di una query utilizzando la
propriet SQL. . . . . . . . . . . . . . 22-45
Specifica di una query utilizzando la
propriet CommandText . . . . . . . 22-46
Utilizzo dei parametri nelle query. . . . . 22-46
Fornitura dei parametri
in progettazione . . . . . . . . . . . . 22-47
Fornitura dei parametri in esecuzione. 22-48
Impostazione di relazioni master/detail
mediante parametri . . . . . . . . . . . . 22-49
Preparazione di query . . . . . . . . . . . 22-50
Esecuzione di query che
non restituiscono un set risultato . . . . 22-50
Utilizzo di set risultato unidirezionali . . 22-51
Utilizzo di dataset di tipo
procedura registrata . . . . . . . . . . . . . 22-52
Operazioni con i parametri
delle procedure registrate. . . . . . . . . 22-53
Impostazione dei parametri
in progettazione . . . . . . . . . . . . 22-54
Utilizzo di parametri in esecuzione . . 22-55
Preparazione delle procedure registrate . 22-56
Esecuzione di procedure registrate che non
restituiscono un set risultato . . . . . . . 22-56
Prelievo di pi set risultato. . . . . . . . . 22-57
Capitolo 23
Operazioni
con i componenti campo 23-1
Componenti campo dinamici . . . . . . . . . . 23-2
Componenti campo persistenti . . . . . . . . . 23-3
Creazione di campi persistenti . . . . . . . . 23-4
Disposizione dei campi persistenti . . . . . 23-5
Definizione di nuovi campi persistenti . . . 23-5
Definizione di un campo dati. . . . . . . 23-7
Definizione di un campo calcolato. . . . 23-7
Programmazione di un campo calcolato 23-8
Definizione di un campo
di consultazione . . . . . . . . . . . . . 23-9
Definizione di un campo
di aggregazione . . . . . . . . . . . . 23-10
xiii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Cancellazione di componenti
campo persistenti . . . . . . . . . . . . . . 23-11
Impostazione di propriet ed eventi
dei campi persistenti . . . . . . . . . . . . 23-11
Impostazione delle propriet di
visualizzazione e di modifica
in progettazione . . . . . . . . . . . . . 23-12
Impostazione delle propriet del
componente campo in esecuzione. . . 23-13
Creazione di set di attributi
per i componenti campo . . . . . . . . 23-14
Associazione di set di attributi
ai componenti campo. . . . . . . . . . 23-14
Rimozione delle associazioni
degli attributi . . . . . . . . . . . . . . 23-15
Controllo e mascheratura dellinput . . 23-15
Uso dei formati predefiniti per i campi
numerici, data e ora. . . . . . . . . . . 23-16
Gestione degli eventi . . . . . . . . . . . 23-16
Operazioni con i metodi
del componente campo in esecuzione . . . . 23-17
Visualizzazione, conversione e accesso
ai valori di campo . . . . . . . . . . . . . . . 23-18
Visualizzazione dei valori dei componenti
campo nei controlli standard . . . . . . . 23-19
Conversione dei valori di campo . . . . . . 23-19
Accesso ai valori dei campi con la propriet
predefinita del dataset . . . . . . . . . . . 23-21
Accesso ai valori dei campi con la propriet
Fields di un dataset. . . . . . . . . . . . . 23-21
Accesso ai valori dei campi con il metodo
FieldByName di un dataset . . . . . . . . 23-21
Impostazione del valore predefinito
di un campo. . . . . . . . . . . . . . . . . . . 23-22
Utilizzo dei vincoli. . . . . . . . . . . . . . . . 23-22
Creazione di un vincolo custom . . . . . . 23-22
Uso dei vincoli del server . . . . . . . . . . 23-23
Uso dei campi oggetto. . . . . . . . . . . . . . 23-24
Visualizzazione di campi ADT e array. . . 23-24
Uso dei campi ADT . . . . . . . . . . . . . 23-25
Utilizzo di componenti campo
persistenti . . . . . . . . . . . . . . . . 23-25
Utilizzo del metodo FieldByName
del dataset . . . . . . . . . . . . . . . . 23-26
Utilizzo della propriet FieldValues
del dataset . . . . . . . . . . . . . . . . 23-26
Utilizzo della propriet FieldValues del
campo ADT . . . . . . . . . . . . . . . 23-26
Utilizzo della propriet Fields
del campo ADT. . . . . . . . . . . . . 23-26
Uso dei campi array. . . . . . . . . . . . . 23-26
Utilizzo di campi persistenti . . . . . . 23-27
Uso della propriet FieldValues
del campo array . . . . . . . . . . . . 23-27
Uso della propriet Fields
del campo array . . . . . . . . . . . . 23-27
Uso dei campi dataset. . . . . . . . . . . . 23-27
Visualizzazione dei campi dataset . . . 23-27
Accesso ai dati in un dataset annidato 23-28
Uso dei campi riferimento . . . . . . . . . 23-28
Visualizzazione
dei campi riferimento . . . . . . . . . 23-28
Accesso ai dati
di un campo riferimento . . . . . . . 23-29
Capitolo 24
Uso di Borland Database Engine 24-1
Larchitettura BDE . . . . . . . . . . . . . . . . 24-1
Impiego di dataset per BDE . . . . . . . . . 24-2
Associazione di un dataset
a connessioni di database e di sessione 24-3
Cache dei BLOB . . . . . . . . . . . . . . 24-4
Ottenimento degli handle BDE. . . . . . 24-4
Utilizzo di TTable . . . . . . . . . . . . . . . 24-5
Specifica del tipo di tabella
per tabelle locali . . . . . . . . . . . . . 24-5
Controllo dellaccesso a tabelle locali in
lettura/scrittura . . . . . . . . . . . . . 24-6
Specifica di file indice dBASE . . . . . . 24-6
Come rinominare tabelle locali . . . . . . 24-8
Importazione di dati da altre tabelle. . . 24-8
Utilizzo di TQuery . . . . . . . . . . . . . . 24-9
Creazione di query eterogenee . . . . . . 24-9
Ottenimento di un set risultato
modificabile. . . . . . . . . . . . . . . 24-10
Aggiornamento di set risultato
a sola lettura . . . . . . . . . . . . . . .24-11
Utilizzo di TStoredProc . . . . . . . . . . . 24-12
Inglobamento dei parametri . . . . . . 24-12
Operazioni con procedure registrate
ridefinite di Oracle . . . . . . . . . . . 24-13
Collegamento ai database
tramite TDatabase . . . . . . . . . . . . . 24-13
Associazione di un componente
database a una sessione . . . . . . . . 24-13
Interazioni tra il componente
Session e i database . . . . . . . . . . 24-14
xiv
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Identificazione del database . . . . . . . 24-14
Apertura di una connessione
utilizzando TDatabase . . . . . . . . . 24-16
Impiego di componenti
database nei moduli dati . . . . . . . . 24-17
Gestione delle sessioni di database. . . . . 24-17
Attivazione di una sessione . . . . . . . 24-18
Specifica del comportamento predefinito
della connessione al database . . . . . 24-19
Gestione delle connessioni
con il database. . . . . . . . . . . . . . 24-20
Operazioni con tabelle Paradox e dBASE
protette da password . . . . . . . . . . 24-22
Specifica delle ubicazioni
delle directory di Paradox . . . . . . . 24-25
Operazioni con gli alias BDE . . . . . . 24-25
Reperimento di informazioni
su una sessione . . . . . . . . . . . . . 24-27
Creazione di sessioni supplementari . . 24-28
Attribuzione del nome a una sessione . 24-29
Gestione di sessioni multiple . . . . . . 24-29
Utilizzo delle transazioni con BDE. . . . . . . 24-31
Utilizzo di passthrough SQL . . . . . . . . 24-32
Utilizzo delle transazioni locali . . . . . . . 24-33
Utilizzo di BDE per gli aggiornamenti
in cache . . . . . . . . . . . . . . . . . . . . . 24-33
Attivazione degli aggiornamenti
in cache con BDE . . . . . . . . . . . . . . 24-35
Applicazione degli aggiornamenti in cache
basati su BDE . . . . . . . . . . . . . . . . 24-35
Applicazione degli aggiornamenti nella
cache mediante un database . . . . . . 24-36
Applicazione degli aggiornamenti
in cache con i metodi
dei componenti dataset. . . . . . . . . 24-37
Creazione di un gestore di evento
OnUpdateRecord . . . . . . . . . . . . 24-38
Gestione degli errori di aggiornamento 24-39
Aggiornamento di dataset
mediante oggetti update. . . . . . . . . . 24-41
Creazione di istruzioni SQL
per componenti update. . . . . . . . . 24-42
Utilizzo di pi oggetti update . . . . . . 24-46
Esecuzione delle istruzioni SQL. . . . . 24-47
Utilizzo di TBatchMove . . . . . . . . . . . . . 24-50
Creazione di un componente batch move . 24-50
Specifica della modalit
di un componente batch move . . . . . . 24-51
Aggiunta di record . . . . . . . . . . . . 24-52
Aggiornamento di record . . . . . . . . 24-52
Aggiunta e aggiornamento di record . 24-52
Copia di dataset . . . . . . . . . . . . . 24-52
Cancellazione di record . . . . . . . . . 24-53
Mappatura dei tipi di dati . . . . . . . . . 24-53
Esecuzione di unoperazione batch move 24-54
Gestione degli errori
delle operazioni batch move . . . . . . . 24-54
Il Data Dictionary . . . . . . . . . . . . . . . . 24-55
Strumenti per operare con BDE . . . . . . . . 24-56
Capitolo 25
Operazioni con componenti ADO 25-1
Panoramica dei componenti ADO . . . . . . . 25-1
Connessione a datastore ADO. . . . . . . . . . 25-2
Connessione a un datastore
mediante TADOConnection . . . . . . . . 25-3
Accesso alloggetto connessione . . . . . 25-4
Messa a punto di una connessione . . . . . 25-5
Come forzare connessioni asincrone. . . 25-5
Controllo dei timeout . . . . . . . . . . . 25-5
Indicazione dei tipi di operazione che la
connessione supporta . . . . . . . . . . 25-6
Come specificare se la connessione
avvia in automatico le transazioni . . . 25-6
Accesso ai comandi della connessione . . . 25-7
Eventi di connessione ADO . . . . . . . . . 25-7
Eventi allo stabilirsi di una connessione 25-8
Eventi alla chiusura del collegamento. . 25-8
Eventi durante la gestione
delle transazioni . . . . . . . . . . . . . 25-8
Altri eventi . . . . . . . . . . . . . . . . . 25-8
Uso di dataset ADO . . . . . . . . . . . . . . . 25-9
Connessione di un dataset
ADO a un datastore . . . . . . . . . . 25-10
Operazioni con set di record . . . . . . 25-10
Filtraggio di record mediante segnalibri 25-11
Prelievo di record in modalit asincrona25-11
Uso di aggiornamenti batch . . . . . . 25-12
Caricamento e salvataggio
di dati su file . . . . . . . . . . . . . . 25-15
Utilizzo di TADODataSet. . . . . . . . . . 25-16
Utilizzo di oggetti Command . . . . . . . . . 25-17
Specifica del comando . . . . . . . . . . . 25-18
Utilizzo del metodo Execute . . . . . . . . 25-18
Annullamento di comandi . . . . . . . . . 25-19
Reperimento di set risultato con comandi 25-19
Gestione dei parametri di comando. . . . 25-20
xv
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Capitolo 26
Uso di dataset unidirezionali 26-1
Tipi di dataset unidirezionali . . . . . . . . . . . 26-2
Connessione al server di database . . . . . . . . 26-2
Impostazione di TSQLConnection . . . . . . 26-3
Identificazione del driver . . . . . . . . . 26-3
Specifica dei parametri di connessione. . 26-4
Assegnazione di un nome
a una descrizione della connessione . . 26-4
Utilizzo di Connection Editor . . . . . . . 26-5
Specifica dei dati da visualizzare. . . . . . . . . 26-6
Rappresentazione dei risultati di una query 26-6
Rappresentazione dei record in una tabella . 26-7
Rappresentazione di una tabella
mediante TSQLDataSet. . . . . . . . . . 26-7
Rappresentazione di una tabella
mediante TSQLTable . . . . . . . . . . . 26-7
Rappresentazione dei risultati
di una procedura registrata . . . . . . . . . 26-8
Reperimento dei dati . . . . . . . . . . . . . . . 26-8
Preparazione del dataset. . . . . . . . . . . . 26-9
Reperimento di pi dataset . . . . . . . . . . 26-9
Esecuzione di comandi
che non restituiscono record . . . . . . . . . . 26-9
Specifica del comando da eseguire . . . . . 26-10
Esecuzione del comando . . . . . . . . . . 26-10
Creazione e modifica
dei metadati del server. . . . . . . . . . . 26-11
Configurazione di cursor
master/detail collegati . . . . . . . . . . . . 26-12
Accesso a informazioni di schema . . . . . . . 26-12
Prelievo di metadati
in un dataset unidirezionale. . . . . . . . 26-13
Ottenimento dei dati
dopo aver utilizzato il dataset
per i metadati . . . . . . . . . . . . . . 26-14
La struttura dei dataset di metadati . . 26-14
Debug di applicazioni dbExpress . . . . . . . 26-18
Utilizzo di TSQLMonitor per controllare i
comandi SQL . . . . . . . . . . . . . . . . 26-18
Utilizzo di una callback per controllare i
comandi SQL . . . . . . . . . . . . . . . . 26-19
Capitolo 27
Utilizzo dei dataset client 27-1
Utilizzo dei dati tramite un dataset client . . . . 27-2
Come spostarsi tra i dati nei dataset client . 27-2
Come limitare i record da visualizzare. . . . 27-2
Editing di dati. . . . . . . . . . . . . . . . . . 27-5
Annullamento delle modifiche . . . . . . 27-6
Salvataggio delle modifiche . . . . . . . 27-7
Definizione dei vincoli dei valori dati. . . . 27-7
Specifica di vincoli custom . . . . . . . . 27-8
Ordinamento e indicizzazione . . . . . . . . 27-8
Aggiunta di un nuovo indice. . . . . . . 27-9
Cancellazione e cambio degli indici . . 27-10
Uso degli indici
per il raggruppamento dei dati . . . . 27-10
Rappresentazione dei valori calcolati . . . .27-11
Uso di campi calcolati internamente
nei dataset client . . . . . . . . . . . . .27-11
Uso delle aggregazioni di manutenzione . 27-12
Specifica delle aggregazioni . . . . . . 27-12
Aggregazione di gruppi di record . . . 27-13
Ottenimento dei valori di aggregazione 27-14
Copia di dati da un altro dataset. . . . . . 27-15
Assegnazione diretta dei dati. . . . . . 27-15
Clonazione di un cursor
di un dataset client . . . . . . . . . . . 27-16
Aggiunta di informazioni specifiche per
lapplicazione ai dati . . . . . . . . . . . 27-16
Utilizzo di un dataset client
per registrare in cache gli aggiornamenti . . 27-17
Panoramica sullutilizzo
degli aggiornamenti in cache. . . . . . . 27-18
Scelta del tipo di dataset
per gli aggiornamenti in cache . . . . . . 27-19
Indicazione dei record modificati . . . . . 27-20
Aggiornamento dei record . . . . . . . . . 27-21
Applicazione degli aggiornamenti. . . 27-22
Interventi durante lapplicazione
degli aggiornamenti . . . . . . . . . . 27-23
Riconciliazione degli errori
di aggiornamento . . . . . . . . . . . 27-25
Uso di un dataset client
con un provider di dati . . . . . . . . . . . . 27-26
Specifica di un provider . . . . . . . . . . 27-27
Richiesta di dati da un dataset sorgente
o da un documento . . . . . . . . . . . . 27-28
Recupero incrementale . . . . . . . . . 27-28
Recupero in automatico . . . . . . . . . 27-29
Ottenimento dei parametri
dal dataset sorgente . . . . . . . . . . . . 27-29
Passaggio di parametri al dataset sorgente 27-30
Invio dei parametri di una query
o di una procedura registrata . . . . . 27-31
Limitazione dei record mediante
parametri . . . . . . . . . . . . . . . . 27-31
xvi
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Gestione dei vincoli dal server . . . . . . . 27-32
Rinnovo dei record. . . . . . . . . . . . . . 27-33
Comunicazione con i provider
tramite eventi custom . . . . . . . . . . . 27-33
Ridefinizione del dataset sorgente . . . . . 27-34
Uso di un dataset client con dati basati su file 27-35
Creazione di un nuovo dataset . . . . . . . 27-35
Caricamento dei dati da un file
o da uno stream. . . . . . . . . . . . . . . 27-36
Fusione delle modifiche nei dati . . . . . . 27-36
Salvataggio dei dati in un file
o in uno stream . . . . . . . . . . . . . . . 27-37
Capitolo 28
Uso di componenti provider 28-1
Individuazione della sorgente dati. . . . . . . . 28-2
Uso di un dataset come sorgente dati . . . . 28-2
Uso di un documento XML
come sorgente dati . . . . . . . . . . . . . . 28-2
Comunicazione con il dataset clientt . . . . . . 28-3
Come applicare gli aggiornamenti
usando un provider di dataset . . . . . . . . . 28-4
Controllo delle informazioni
incluse nei pacchetti dati . . . . . . . . . . . . 28-4
Specifica dei campi inclusi
in un pacchetto dati . . . . . . . . . . . . . 28-5
Impostazione di opzioni che influenzano i
pacchetti dati . . . . . . . . . . . . . . . . . 28-5
Aggiunta di informazioni personali
ai pacchetti dati . . . . . . . . . . . . . . . . 28-7
Risposta alle richieste di dati del client . . . . . 28-8
Risposta alle richieste di aggiornamento
del client. . . . . . . . . . . . . . . . . . . . . . 28-8
Modifica dei pacchetti delta prima
dellaggiornamento del database . . . . . . 28-9
Come influenzare la modalit
di applicazione degli aggiornamenti . . . 28-10
Vaglio dei singoli aggiornamenti . . . . . . 28-11
Risoluzione degli errori di aggiornamento
sul provider . . . . . . . . . . . . . . . . . 28-12
Applicazione di aggiornamenti
a dataset che non rappresentano
una singola tabella . . . . . . . . . . . . . 28-12
Risposta agli eventi generati dal client . . . . 28-13
Gestione dei vincoli del server . . . . . . . . . 28-13
Capitolo 29
Creazione di applicazioni multi-tier 29-1
Vantaggi di un modello database multi-tier . . 29-2
Applicazioni multi-tier basate su provider. . . 29-2
Panoramica di unapplicazione three-tier . 29-3
Struttura dellapplicazione client . . . . . . 29-4
La struttura dellapplication server . . . . . 29-5
Contenuti del modulo dati remoto. . . . 29-6
Uso di moduli dati transazionali . . . . . 29-7
Centralizzazione di moduli dati remoti . 29-8
Scelta di un protocollo di connessione . . . 29-9
Uso di connessioni DCOM . . . . . . . 29-10
Uso delle connessioni socket . . . . . . 29-10
Uso di connessioni . . . . . . . . . . . . .29-11
Utilizzo di connessioni SOAP . . . . . .29-11
Creazione di unapplicazione multi-tier . . . 29-12
Creazione dellapplication server . . . . . . . 29-12
Impostazione del modulo dati remoto . . 29-14
Configurazione del modulo dati
remoto nel caso non sia transazionale 29-14
Configurazione di un modulo
dati remoto transazionale . . . . . . . 29-15
Configurazione di TSoapDataModule. 29-16
Estensione dellinterfaccia
dellapplication server . . . . . . . . . . 29-17
Aggiunta di callback allinterfaccia
dellapplication server . . . . . . . . . 29-18
Estensione dellinterfaccia
transazionale di un application server 29-18
Gestione delle transazioni
nelle applicazioni multi-tiered . . . . . . 29-18
Supporto delle relazioni master/detail . . 29-19
Supporto delle informazioni di stato
nei moduli dati remoti . . . . . . . . . . 29-20
Uso di pi moduli dati remoti . . . . . . . 29-21
Registrazione dellapplication server . . . . . 29-22
Creazione dellapplicazione client . . . . . . 29-23
Connessione allapplication server . . . . 29-24
Specifica di una connessione
con DCOM . . . . . . . . . . . . . . . 29-24
Specifica di una connessione
con i socket . . . . . . . . . . . . . . . 29-25
Specifica di una connessione con HTTP 29-26
Specifica di una connessione con SOAP 29-26
Brokering delle connessioni . . . . . . 29-27
Gestione delle connessioni al server. . . . 29-27
Connessione al server . . . . . . . . . . 29-28
Abbandono o modifica
di una connessione a un server . . . . 29-28
Chiamata delle interfacce del server . . . 29-29
Connessione a un application server
che utilizza pi moduli dati . . . . . . . 29-30
xvii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Scrittura di applicazioni client basate su Web 29-31
Distribuzione di unapplicazione
client come controllo ActiveX . . . . . . . 29-32
Creazione di una Active Form per
lapplicazione client. . . . . . . . . . . 29-32
Creazione di applicazioni
Web con InternetExpress. . . . . . . . . . 29-33
Creazione di unapplicazione
InternetExpress . . . . . . . . . . . . . . . 29-34
Uso delle librerie javascript . . . . . . . 29-35
Concessione dei permessi per laccesso e
lavvio dellapplication server . . . . . 29-35
Uso di un broker XML . . . . . . . . . . . . 29-36
Recupero di pacchetti dati XML. . . . . 29-36
Applicazione degli aggiornamenti da
pacchetti delta XML . . . . . . . . . . 29-37
Creazione di pagine web con produttori di
pagine InternetExpress. . . . . . . . . . . 29-39
Utilizzo di Web page editor . . . . . . . 29-39
Impostazione delle propriet
degli elementi Web . . . . . . . . . . . 29-40
Personalizzazione del modello del
produttore di pagine InternetExpress. 29-41
Capitolo 30
Uso di XML
nelle applicazioni database 30-1
Definizione della trasformazione . . . . . . . . 30-1
Mappatura tra nodi XML e campi di un
pacchetto dati . . . . . . . . . . . . . . . . . 30-2
Utilizzo di XMLMapper . . . . . . . . . . . . 30-4
Caricamento di uno schema XML
o di un pacchetto dati. . . . . . . . . . . 30-4
Definizione delle mappature . . . . . . . 30-5
Generazione dei file di trasformazione. . 30-6
Conversione di documenti XML
in pacchetti dati . . . . . . . . . . . . . . . . . 30-6
Specifica del documento XML di origine . . 30-6
Specifica della trasformazione . . . . . . . . 30-7
Ottenimento del pacchetto dati risultante . . 30-7
Conversione dei nodi definiti dallutente . . 30-7
Impiego di un documento XML
come origine di un provider . . . . . . . . . . 30-8
Utilizzo di documenti XML
come client di un provider . . . . . . . . . . . 30-9
Prelievo di un documento XML
da un provider . . . . . . . . . . . . . . . . 30-9
Applicazione degli aggiornamenti da un
documento XML a un provider . . . . . . 30-10
Parte III
Creazione di applicazioni Internet
Capitolo 31
Scrittura di applicazioni CORBA 31-1
Panoramica di unapplicazione CORBA . . . . 31-1
Gli stub e gli skeleton . . . . . . . . . . . . . 31-2
Utilizzo di Smart Agent. . . . . . . . . . . . 31-3
Attivazione delle applicazioni server . . . . 31-4
Binding dinamico
delle chiamate alle interfacce. . . . . . . . 31-4
Scrittura di server CORBA. . . . . . . . . . . . 31-4
Definizione delle interfacce delloggetto . . 31-5
Utilizzo del CORBA Server Wizard . . . . . 31-5
Generazione di stub e skeleton
da un file IDL . . . . . . . . . . . . . . . . 31-6
Uso del Wizard
CORBA Object Implementation . . . . . . 31-7
Istanze di oggetti CORBA. . . . . . . . . 31-8
Uso del modello di delega . . . . . . . . 31-8
Visualizzazione e modifica
dei cambiamenti . . . . . . . . . . . . . 31-9
Implementazione degli oggetti CORBA . 31-10
Protezione da conflitti di thread . . . . 31-12
Modifica delle interfacce CORBA . . . . . 31-13
Registrazione delle interfacce del server . 31-13
Scrittura di client CORBA . . . . . . . . . . . 31-14
Uso di stub . . . . . . . . . . . . . . . . . . 31-15
Utilizzo dellinterfaccia
di chiamata dinamica . . . . . . . . . . . 31-16
Collaudo di server CORBA . . . . . . . . . . 31-17
Configurazione dello strumento
di collaudo . . . . . . . . . . . . . . . . . 31-18
Registrazione ed esecuzione
di script di collaudo . . . . . . . . . . . . 31-18
Capitolo 32
Creazione di applicazioni server
per Internet 32-1
Web Broker e WebSnap. . . . . . . . . . . . . . 32-1
Terminologia e standard . . . . . . . . . . . . . 32-3
Parti di uno Uniform Resource Locator. . . 32-4
URI e. URL . . . . . . . . . . . . . . . . . 32-4
Informazioni dellheader
della richiesta HTTP. . . . . . . . . . . . . 32-4
Attivit di un server HTTP . . . . . . . . . . . 32-5
Composizione delle richieste del client . . . 32-5
Soddisfacimento delle richieste del client . 32-6
xviii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Risposta alle richieste del client. . . . . . . . 32-6
Tipi di applicazioni per server Web . . . . . . . 32-7
ISAPI e NSAPI . . . . . . . . . . . . . . . 32-7
CGI indipendente. . . . . . . . . . . . . . 32-7
Win-CGI indipendente . . . . . . . . . . . 32-7
Apache . . . . . . . . . . . . . . . . . . . . 32-7
Web App Debugger. . . . . . . . . . . . . 32-8
Conversione del tipo di destinazione per
applicazioni Web server . . . . . . . . . . . 32-9
Debug di applicazioni server . . . . . . . . . . . 32-9
Utilizzo di Web Application Debugger . . 32-10
Avvio dellapplicazione
con Web Application Debugger . . . . 32-10
Conversione dellapplicazione
in un altro tipo di applicazione
per Web server. . . . . . . . . . . . . . 32-11
Debug di applicazioni Web
sotto forma di DLL . . . . . . . . . . . . . 32-11
Diritti utente necessari
per il debug di DLL. . . . . . . . . . . 32-12
Capitolo 33
Utilizzo di Web Broker 33-1
Creazione di applicazioni per Web server
con Web Broker. . . . . . . . . . . . . . . . . . 33-1
Il modulo Web . . . . . . . . . . . . . . . . . 33-2
Loggetto Application Web . . . . . . . . . . 33-3
Struttura delle applicazioni Web Broker. . . . . 33-3
Il dispatcher Web. . . . . . . . . . . . . . . . . . 33-4
Aggiunta di azioni al dispatcher . . . . . . . 33-5
Dispatch dei messaggi di richiesta . . . . . . 33-5
Elementi di azione . . . . . . . . . . . . . . . . . 33-6
Determinazione dellattivazione
degli elementi di azione . . . . . . . . . . . 33-6
LURL di destinazione . . . . . . . . . . . 33-6
La propriet Method Type . . . . . . . . . 33-7
Attivazione e disattivazione
di elementi di azione . . . . . . . . . . . 33-7
Scelta di un elemento
di azione predefinito . . . . . . . . . . . 33-7
Risposta a messaggi di richiesta
mediante elementi di azione . . . . . . . . 33-8
Invio della risposta . . . . . . . . . . . . . 33-8
Utilizzo di pi elementi di azione. . . . . 33-9
Accesso alle informazioni
della richiesta client . . . . . . . . . . . . . . . 33-9
Propriet contenenti informazioni
dello header della richiesta . . . . . . . . . 33-9
Propriet che identificano
la destinazione . . . . . . . . . . . . . . 33-9
Propriet che descrivono il client Web. 33-10
Propriet che identificano
lo scopo della richiesta . . . . . . . . 33-10
Propriet che descrivono
la risposta prevista . . . . . . . . . . . 33-10
Propriet che descrivono il contenuto . .33-11
Il contenuto dei messaggi
di richiesta HTTP . . . . . . . . . . . . . .33-11
Creazione di messaggi di risposta HTTP. . . .33-11
Compilazione dellintestazione
della risposta . . . . . . . . . . . . . . . . .33-11
Indicazione dello stato della risposta . 33-12
Indicazione della necessit
di azione da parte del client. . . . . . 33-12
Descrizione dellapplicazione server . 33-12
Descrizione del contenuto . . . . . . . 33-13
Impostazione del contenuto della risposta 33-13
Invio della risposta . . . . . . . . . . . . . 33-13
Generazione del contenuto
dei messaggi di risposta . . . . . . . . . . . 33-14
Utilizzo di componenti
produttori di pagine. . . . . . . . . . . . 33-14
Modelli HTML . . . . . . . . . . . . . . 33-14
Specifica del modello HTML . . . . . . 33-15
Conversione dei tag HTML trasparenti 33-16
Utilizzo dei produttori di pagine da un
elemento di azione . . . . . . . . . . . 33-16
Concatenamento di
produttori di pagine . . . . . . . . . . 33-17
Utilizzo nelle risposte
di informazioni di database . . . . . . . . . 33-18
Aggiunta di una sessione
a un modulo Web . . . . . . . . . . . . . 33-18
Rappresentazione di informazioni
di database in HTML . . . . . . . . . . . 33-19
Utilizzo dei produttori
di pagine di dataset . . . . . . . . . . 33-19
Utilizzo di produttori di tabelle . . . . 33-19
Specifica degli attributi di tabella . . . 33-20
Specifica degli attributi di riga . . . . . 33-20
Specifica delle colonne . . . . . . . . . 33-20
Inserimento di tabelle
nei documenti HTML . . . . . . . . . 33-21
Impostazione di un produttore
di tabelle di dataset . . . . . . . . . . 33-21
Impostazione di un produttore
di tabelle di query . . . . . . . . . . . 33-21
xix
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Capitolo 34
Creazione di applicazioni
Web Server con WebSnap 34-1
Componenti fondamentali di WebSnap . . . . . 34-2
Moduli Web . . . . . . . . . . . . . . . . . . . 34-2
Tipi di modulo Web application. . . . . . 34-3
Moduli pagina Web. . . . . . . . . . . . . 34-4
Moduli dati Web . . . . . . . . . . . . . . 34-5
Adattatori . . . . . . . . . . . . . . . . . . . . 34-5
Campi . . . . . . . . . . . . . . . . . . . . 34-6
Azioni . . . . . . . . . . . . . . . . . . . . 34-6
Errori . . . . . . . . . . . . . . . . . . . . . 34-6
Record . . . . . . . . . . . . . . . . . . . . 34-6
Produttori di pagina . . . . . . . . . . . . . . 34-7
Creazione di applicazioni per Web server
con WebSnap . . . . . . . . . . . . . . . . . . . 34-8
Selezione di un tipo server . . . . . . . . . . 34-9
Specifica dei componenti
del modulo applicazione. . . . . . . . . . . 34-9
Selezione delle opzioni
del modulo Web application . . . . . . . 34-11
Esercitazione WebSnap . . . . . . . . . . . . . 34-12
Creazione della nuova applicazione . . . . 34-12
Fase 1. Avvio di WebSnap
application wizard . . . . . . . . . . . 34-12
Fase 2. Salvataggio dei file generati
e del progetto . . . . . . . . . . . . . . 34-12
Fase 3. Specifica del titolo
dellapplicazione . . . . . . . . . . . . 34-13
Creazione di una pagina CountryTable . . 34-13
Fase 1. Aggiunta di un nuovo
modulo pagina Web . . . . . . . . . . 34-13
Fase 2. Salvataggio del nuovo
modulo pagina Web . . . . . . . . . . 34-14
Aggiunta dei componenti dati
al modulo CountryTable . . . . . . . . . . 34-14
Fase 1. Aggiunta di componenti
data-aware . . . . . . . . . . . . . . . . 34-15
Fase 2. Specifica di un campo chiave . . 34-15
Fase 3. Aggiunta di un
componente adapter . . . . . . . . . . 34-16
Creazione di una griglia
per visualizzare i dati . . . . . . . . . . . 34-16
Fase 1. Aggiunta di una griglia . . . . . 34-16
Fase 2. Aggiunta alla griglia
di comandi per lediting . . . . . . . . 34-18
Aggiunta di una scheda per lediting . . . 34-19
Fase 1. Aggiunta di un nuovo
modulo pagina Web . . . . . . . . . . 34-19
Fase 2. Salvataggio del nuovo modulo 34-20
Fase 3. Come rendere CountryTableU
accessibile al nuovo modulo . . . . . 34-20
Fase 4. Aggiunta dei campi
di immissione. . . . . . . . . . . . . . 34-20
Fase 5. Aggiunta di pulsanti . . . . . . 34-21
Fase 6. Collegamento di azioni
della scheda con la pagina
della griglia . . . . . . . . . . . . . . . 34-22
Fase 7. Collegamento delle azioni
della griglia con la pagina
della scheda. . . . . . . . . . . . . . . 34-22
Esecuzione dellapplicazione ultimata . . 34-23
Aggiunta della notifica degli errori . . . . 34-23
Fase 1. Aggiunta alla griglia
del supporto per gli errori. . . . . . . 34-23
Fase 2. Aggiunta alla scheda
del supporto per gli errori. . . . . . . 34-24
Fase 3. Verifica del meccanismo di
segnalazione errori. . . . . . . . . . . 34-24
Progettazione HTML evoluta . . . . . . . . . 34-25
Trattamento dello script lato server
nei file HTML . . . . . . . . . . . . . . . 34-26
Supporto per il login . . . . . . . . . . . . . . 34-26
Aggiunta del supporto per il login . . . . 34-27
Utilizzo del servizio per le sessioni . . . . 34-28
Pagine di login. . . . . . . . . . . . . . . . 34-28
Impostazione delle pagine in modo che
richiedano il login . . . . . . . . . . . . . 34-30
Diritti di accesso degli utenti . . . . . . . . 34-31
Visualizzazione dinamica di campi
come caselle di testo o di modifica . . 34-31
Occultamento dei campi
e del loro contenuto . . . . . . . . . . 34-32
Come evitare laccesso alla pagina. . . 34-32
Scripting lato server in WebSnap . . . . . . . 34-33
Active scripting . . . . . . . . . . . . . . . 34-34
Motore di script . . . . . . . . . . . . . . . 34-34
Blocchi di script . . . . . . . . . . . . . . . 34-34
Creazione di script . . . . . . . . . . . . . 34-35
Modelli di wizard . . . . . . . . . . . . 34-35
TAdapterPageProducer . . . . . . . . . 34-35
Modifica e visualizzazione di script . . . . 34-35
Inclusione di script in una pagina . . . . . 34-35
Oggetti script . . . . . . . . . . . . . . . . 34-35
Indirizzamento di richieste e risposte . . . . 34-36
Componenti dispatcher. . . . . . . . . . . 34-37
Operazioni delladapter dispatcher . . . . 34-37
xx
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Utilizzo di componenti adapter
per generare contenuti . . . . . . . . . 34-37
Ricezione di richieste delladapter e
generazione delle risposte . . . . . . . 34-38
Richiesta di immagine . . . . . . . . . . 34-40
Risposta di immagine . . . . . . . . . . 34-40
Indirizzamento degli elementi di azione . 34-41
Operazione del dispatcher di pagine. . . . 34-42
Capitolo 35
Operazioni con documenti XML 35-1
Utilizzo del Document Object Model . . . . . . 35-2
Operazioni con i componenti XML . . . . . . . 35-3
Utilizzo di TXMLDocument. . . . . . . . . . 35-3
Operazioni con i nodi XML . . . . . . . . . . 35-4
Operazioni con il valore di un nodo . . . 35-5
Operazioni con gli attributi di un nodo . 35-5
Aggiunta e cancellazione di nodi figlio . 35-5
Astrazione di documenti XML
con Data Binding wizard . . . . . . . . . . . . 35-6
Utilizzo di XML Data Binding wizard . . . . 35-7
Utilizzo del codice generato da XML Data
Binding wizard . . . . . . . . . . . . . . . . 35-9
Capitolo 36
Utilizzo dei Web Services 36-1
Le interfacce richiamabili . . . . . . . . . . . . . 36-2
Utilizzo di tipi non scalari
nelle interfacce richiamabili . . . . . . . . . 36-4
Registrazione di tipi non scalari. . . . . . 36-5
Registrazione di tipi dichiarati
con typedef e di tipi enumerati . . . . . 36-6
Utilizzo di oggetti remotable . . . . . . . 36-7
Esempio di oggetto Remotable . . . . . . 36-9
Scrittura di server che supportano
i Web Services . . . . . . . . . . . . . . . . . 36-10
Creazione di un server Web Service . . . . 36-10
Utilizzo di SOAP application wizard . . . 36-11
Aggiunta di nuovi Web Services . . . . . . 36-12
Editing del codice generato . . . . . . . 36-13
Utilizzo di una classe di base differente 36-13
Utilizzo di Web Services Importer . . . . . 36-14
Creazione di classi di eccezione custom
per Web Services . . . . . . . . . . . . . . 36-15
Generazione di documenti WSDL per
unapplicazione Web Service . . . . . . . 36-16
Scrittura di client per Web Services . . . . . . 36-17
Importazione di documenti WSDL. . . . . 36-17
Chiamata a interfacce richiamabili . . . . . 36-17
Capitolo 37
Operazioni con i socket 37-1
Implementazione dei servizi. . . . . . . . . . . 37-1
I protocolli di servizio. . . . . . . . . . . . . 37-2
Comunicare con le applicazioni . . . . . 37-2
Servizi e porte . . . . . . . . . . . . . . . . . 37-2
Tipi di connessioni socket . . . . . . . . . . . . 37-2
Connessioni client . . . . . . . . . . . . . . . 37-3
Connessioni di ascolto . . . . . . . . . . . . 37-3
Connessioni server . . . . . . . . . . . . . . 37-3
Descrizione dei socket . . . . . . . . . . . . . . 37-3
Descrizione dellhost . . . . . . . . . . . . . 37-4
Scelta tra un nome di host
e un indirizzo IP . . . . . . . . . . . . . 37-5
Uso delle porte. . . . . . . . . . . . . . . . . 37-5
Utilizzo dei componenti socket . . . . . . . . . 37-5
Ottenimento di informazioni
sulla connessione . . . . . . . . . . . . . . 37-6
Utilizzo di socket client . . . . . . . . . . . . 37-6
Specifica del server desiderato . . . . . . 37-6
Formazione della connessione . . . . . . 37-7
Ottenimento di informazioni
sulla connessione. . . . . . . . . . . . . 37-7
Chiusura della connessione. . . . . . . . 37-7
Uso dei socket server . . . . . . . . . . . . . 37-7
Specifica della porta . . . . . . . . . . . . 37-7
Ascolto delle richieste
provenienti da client . . . . . . . . . . . 37-8
Connessione con i client. . . . . . . . . . 37-8
Chiusura delle connessioni server . . . . 37-8
Risposta agli eventi socket . . . . . . . . . . . . 37-8
Eventi di errore . . . . . . . . . . . . . . . . 37-8
Eventi del client . . . . . . . . . . . . . . . . 37-9
Eventi del server. . . . . . . . . . . . . . . . 37-9
Eventi durante lascolto . . . . . . . . . . 37-9
Eventi con connessioni client . . . . . . . 37-9
Lettura e scrittura sulle connessioni socket . 37-10
Connessioni non bloccanti . . . . . . . . . 37-10
Eventi di lettura e scrittura . . . . . . . 37-10
Connessioni bloccanti . . . . . . . . . . . . .37-11
Parte IV
Sviluppo di applicazioni COM
Capitolo 38
Panoramica sulle tecnologie COM 38-1
COM come specifica
e implementazione. . . . . . . . . . . . 38-1
xxi
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Estensioni COM. . . . . . . . . . . . . . . 38-2
Parti di unapplicazione COM . . . . . . . . . . 38-3
Interfacce COM. . . . . . . . . . . . . . . . . 38-3
Linterfaccia COM fondamentale,
IUnknown . . . . . . . . . . . . . . . . . 38-4
Puntatori di interfaccia COM . . . . . . . 38-5
Server COM. . . . . . . . . . . . . . . . . . . 38-5
CoClass e class factory . . . . . . . . . . . 38-6
Server in-process, out-of-process
e remoti. . . . . . . . . . . . . . . . . . . 38-6
Il meccanismo di smistamento . . . . . . 38-8
Aggregazione . . . . . . . . . . . . . . . . 38-9
Client COM . . . . . . . . . . . . . . . . . . 38-10
Estensioni COM . . . . . . . . . . . . . . . . . 38-10
Server Automation . . . . . . . . . . . . . . 38-13
Active Server Pages . . . . . . . . . . . . . 38-14
Controlli ActiveX. . . . . . . . . . . . . . . 38-14
Active Documents . . . . . . . . . . . . . . 38-15
Oggetti transazionali . . . . . . . . . . . . . 38-15
Oggetti evento COM+
e subscriber di eventi. . . . . . . . . . . . 38-16
Librerie di tipi. . . . . . . . . . . . . . . . . 38-17
Contenuto delle librerie di tipi . . . . . 38-17
Creazione di librerie di tipi . . . . . . . 38-18
Quando usare le librerie di tipi . . . . . 38-18
Accesso alle librerie di tipi . . . . . . . . 38-19
Vantaggi delluso delle librerie di tipi . 38-19
Uso degli strumenti della libreria di tipi 38-20
Implementazione di oggetti COM
con i wizard. . . . . . . . . . . . . . . . . . . 38-20
Codice generato dai wizard . . . . . . . . . 38-23
Capitolo 39
Funzionamento delle librerie di tipi 39-1
Type Library editor . . . . . . . . . . . . . . . . 39-2
Elementi del Type Library editor . . . . . . . 39-3
Barra strumenti . . . . . . . . . . . . . . . 39-3
Pannello Object list . . . . . . . . . . . . . 39-5
Barra di stato . . . . . . . . . . . . . . . . 39-5
Pagine di informazioni di tipo. . . . . . . 39-6
Elementi del Type Library editor . . . . . . . 39-8
Interfacce. . . . . . . . . . . . . . . . . . . 39-9
Dispinterface . . . . . . . . . . . . . . . 39-10
CoClass . . . . . . . . . . . . . . . . . . 39-10
Definizioni di tipo . . . . . . . . . . . . 39-10
Moduli . . . . . . . . . . . . . . . . . . . 39-11
Uso del Type Library editor . . . . . . . . . 39-11
Tipi consentiti . . . . . . . . . . . . . . . 39-12
Creazione di una nuova libreria di tipi . 39-13
Apertura di una libreria di tipi esistente39-14
Aggiunta di uninterfaccia
alla libreria di tipi . . . . . . . . . . . 39-14
Modifica di uninterfaccia
con il Type Library editor . . . . . . . 39-15
Aggiunta di propriet e metodi ad una
interface o dispinterface . . . . . . . . 39-15
Aggiunta di CoClass alla libreria di tipi 39-16
Aggiunta di uninterfaccia
a una CoClass. . . . . . . . . . . . . . 39-17
Aggiunta di una Enumeration
alla libreria di tipi . . . . . . . . . . . 39-17
Aggiunta di un alias alla libreria di tipi 39-18
Aggiunta di un record o di una union
alla libreria di tipi . . . . . . . . . . . 39-18
Aggiunta di un modulo
alla libreria di tipi . . . . . . . . . . . 39-18
Salvataggio e registrazione delle
informazioni della libreria di tipi. . . 39-19
Salvataggio di una libreria di tipi . . . 39-19
Aggiornamento della libreria di tipi . . 39-19
Registrazione della libreria di tipi . . . 39-20
Esportazione di un file IDL . . . . . . . 39-20
Distribuzione delle librerie di tipi . . . . . . . 39-20
Capitolo 40
Creazione di client COM 40-1
Importazione di informazioni
della libreria di tipi . . . . . . . . . . . . . . . 40-2
Uso della finestra di dialogo
Import Type Library. . . . . . . . . . . . . 40-3
Uso della finestra di dialogo
Import ActiveX . . . . . . . . . . . . . . . 40-4
Codice generato durante limportazione
delle informazioni di una libreria di tipi . 40-5
Controllo di un oggetto importato . . . . . . . 40-7
Uso di wrapper di componenti . . . . . . . 40-7
Wrapper ActiveX. . . . . . . . . . . . . . 40-7
Wrapper di oggetti Automation . . . . . 40-8
Uso di controlli ActiveX associati ai dati . . 40-9
Esempio: stampa di un documento con
Microsoft Word . . . . . . . . . . . . . . .40-11
Fase 1: preparazione di C++Builder
per lesempio . . . . . . . . . . . . . . .40-11
Fase 2: importazione della libreria
di tipi di Word . . . . . . . . . . . . . .40-11
Fase 3: uso di un oggetto interfaccia
VTable o dispatch per il controllo di
Microsoft Word. . . . . . . . . . . . . 40-12
xxii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Fase 4: ripristino dello stato originario . 40-13
Scrittura del codice del client in base alle
definizioni della libreria di tipi . . . . . . 40-13
Connessione a un server . . . . . . . . . 40-13
Controllo di un server Automation
usando uninterfaccia duale . . . . . . 40-14
Controllo di un server Automation
usando uninterfaccia dispatch . . . . 40-14
Gestione degli eventi
in un controller Automation . . . . . . 40-15
Creazione di client per server
che non hanno una libreria di tipi . . . . . . 40-17
Capitolo 41
Creazione di semplici server COM 41-1
Panoramica sulla creazione
di un oggetto COM . . . . . . . . . . . . . . . 41-2
Progettazione di un oggetto COM . . . . . . . . 41-2
Utilizzo di COM object wizard. . . . . . . . . . 41-3
Uso di Automation object wizard . . . . . . . . 41-4
Scelta di una modello di threadingl . . . . . 41-5
Scrittura di un oggetto che supporta il
modello free threading . . . . . . . . . . 41-7
Scrittura di un oggetto che supporta il
modello apartment threading . . . . . . 41-8
Scrittura di un oggetto che supporta il
modello di threading neutral . . . . . . 41-8
Specifica di opzioni ATL . . . . . . . . . . . . . 41-9
Definizione dellinterfaccia di un oggetto COM41-9
Aggiunta di una propriet
allinterfaccia delloggetto . . . . . . . . . 41-10
Aggiunta di un metodo
allinterfaccia delloggetto . . . . . . . . . 41-10
Esposizione di eventi ai client. . . . . . . . 41-11
Gestione degli eventi
nelloggetto Automation . . . . . . . . 41-12
Interfacce di Automation . . . . . . . . . . . . 41-13
Interfacce duali . . . . . . . . . . . . . . . . 41-13
Interfacce di dispatch . . . . . . . . . . . . 41-14
Interfacce custom. . . . . . . . . . . . . . . 41-15
Marshaling dei dati . . . . . . . . . . . . . . . 41-15
Tipi compatibili con Automation . . . . . 41-16
Restrizioni di tipo
per il marshaling automatico . . . . . . . 41-16
Marshaling personalizzato . . . . . . . . . 41-17
Registrazione di un oggetto COM . . . . . . . 41-17
Registrazione di un server in-process . . . 41-17
Registrazione di un server out-of-process . 41-17
Verifica e debug dellapplicazione . . . . . . . 41-18
Capitolo 42
Creazione di Active Server Page 42-1
Creazione di Active Server Object . . . . . . . 42-2
Utilizzo degli intrinsics di ASP . . . . . . . 42-3
Application . . . . . . . . . . . . . . . . . 42-4
Request . . . . . . . . . . . . . . . . . . . 42-4
Response . . . . . . . . . . . . . . . . . . 42-5
Session . . . . . . . . . . . . . . . . . . . 42-6
Server . . . . . . . . . . . . . . . . . . . . 42-7
Creazione di ASP per server in-process
o out-of-process . . . . . . . . . . . . . . . 42-7
Registrazione di Active Server Object . . . . . 42-8
Registrazione di un server in-process . . . . 42-8
Registrazione di un server out-of-process . 42-8
Collaudo e debug
dellapplicazione Active Server Page . . . . . 42-8
Capitolo 43
Creazione di un controllo ActiveX 43-1
Panoramica sulla creazione
di controlli ActiveX . . . . . . . . . . . . . . . 43-2
Elementi di un controllo ActiveX . . . . . . 43-2
Il controllo VCL . . . . . . . . . . . . . . 43-3
Wrapper ActiveX. . . . . . . . . . . . . . 43-3
La libreria di tipi . . . . . . . . . . . . . . 43-3
Pagina di propriet . . . . . . . . . . . . 43-3
Progettazione di un controllo ActiveX . . . . . 43-4
Generazione di un controllo ActiveX da un
controllo VCL . . . . . . . . . . . . . . . . . . 43-4
Generazione di un controllo ActiveX
basato su una scheda VCL . . . . . . . . . . . 43-6
Concessione in licenza di controlli ActiveX . . 43-7
Personalizzazione dellinterfaccia
del controllo ActiveX . . . . . . . . . . . . . . 43-8
Aggiunta di ulteriori propriet,
metodi ed eventi . . . . . . . . . . . . . . . 43-9
Aggiunta di propriet e metodi . . . . . 43-9
Aggiunta di eventi . . . . . . . . . . . . .43-11
Attivazione dellassociazione
di dati semplici con la libreria di tipi . . 43-12
Creazione di una pagina di propriet per un
controllo ActiveX . . . . . . . . . . . . . . . 43-14
Creazione di una nuova pagina
di propriet. . . . . . . . . . . . . . . . . 43-14
Aggiunta di controlli
ad una pagina di propriet . . . . . . . . 43-15
Associazione dei controlli di una pagina di
propriet alle propriet del
controllo ActiveX . . . . . . . . . . . . . 43-15
xxiii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Aggiornamento
della pagina di propriet . . . . . . . . 43-15
Aggiornamento delloggetto. . . . . . . 43-16
Collegamento di una pagina
di propriet ad un controllo ActiveX. . . 43-16
Registrazione di un controllo ActiveX. . . . . 43-16
Collaudo di un controllo ActiveX . . . . . . . 43-17
Distribuzione di un controllo ActiveX su Web 43-17
Impostazione delle opzioni . . . . . . . . . 43-18
Capitolo 44
Creazione di oggetti MTS o COM+ 44-1
Gli oggetti transazionali . . . . . . . . . . . . . . 44-2
Requisiti di un oggetto transazionale . . . . 44-3
Gestione delle risorse . . . . . . . . . . . . . . . 44-3
Accesso al contesto delloggetto . . . . . . . 44-4
Attivazione just-in-time . . . . . . . . . . . . 44-5
Condivisione delle risorse. . . . . . . . . . . 44-6
Distributori di risorse di database . . . . 44-6
Shared property manager . . . . . . . . . 44-7
Rilascio delle risorse . . . . . . . . . . . . 44-9
Condivisione degli oggetti . . . . . . . . . 44-10
Supporto delle transazioni MTS e COM+. . . 44-10
Attributi di transazione . . . . . . . . . . . 44-12
Impostazione dellattributo
di transazione . . . . . . . . . . . . . . 44-12
Oggetti con e senza stato . . . . . . . . . . 44-13
Come influenzare la modalit
di completamento delle transazioni . . . 44-13
Inizio di transazioni . . . . . . . . . . . . . 44-14
Impostazione di un oggetto
transazionale sul lato client . . . . . . 44-15
Impostazione di un oggetto
transazionale sul lato server . . . . . . 44-16
Durata della transazione. . . . . . . . . . . 44-17
Sicurezza basata sul ruolo. . . . . . . . . . . . 44-17
Panoramica sulla creazione
di oggetti transazionali . . . . . . . . . . . . 44-18
Uso di Transactional Object wizard . . . . . . 44-18
Scelta di un modello di threading
per un oggetto transazionale . . . . . . . 44-19
Attivit . . . . . . . . . . . . . . . . . . . 44-20
Generazione di eventi in ambiente COM+ . . 44-22
Uso di Event Object wizard . . . . . . . . . 44-24
Uso di COM+ Event Subscription
object wizard . . . . . . . . . . . . . . . . 44-25
Attivazione di eventi utilizzando
un oggetto evento di COM+. . . . . . . . 44-26
Passaggio di riferimenti a oggetti . . . . . . . 44-27
Uso del metodo SafeRef . . . . . . . . . 44-27
Callback. . . . . . . . . . . . . . . . . . 44-28
Debug e collaudo di oggetti transazionali . . 44-28
Installazione di oggetti transazionali . . . . . 44-29
Amministrazione di oggetti transazionali . . 44-30
Parte V
Creazione di componenti custom
Capitolo 45
Introduzione alla creazione
di componenti 45-1
Librerie di classi . . . . . . . . . . . . . . . . . . 45-1
Componenti e classi . . . . . . . . . . . . . . . 45-2
Creazione di componenti . . . . . . . . . . . . 45-2
Modifica di controlli esistenti . . . . . . . . 45-3
Creazione di controlli con finestra. . . . . . 45-4
Creazione di controlli grafici . . . . . . . . . 45-4
Derivazioni di sottoclassi
da controlli Windows . . . . . . . . . . . . 45-4
Creazione di componenti non visuali . . . . 45-5
Cosa mettere in un componente. . . . . . . . . 45-5
Rimozione delle dipendenze. . . . . . . . . 45-5
Impostazione di propriet, metodi ed eventi45-6
Propriet . . . . . . . . . . . . . . . . . . 45-6
Eventi . . . . . . . . . . . . . . . . . . . . 45-7
Metodi. . . . . . . . . . . . . . . . . . . . 45-7
Incapsulamento della grafica. . . . . . . . . 45-7
Registrazione di componenti. . . . . . . . . 45-8
Creazione di un nuovo componente . . . . . . 45-8
Creazione di un componente
con Component wizard . . . . . . . . . . . 45-9
Creazione manuale di un componente . . 45-12
Creazione di un unit file . . . . . . . . 45-12
Derivazione del componente . . . . . . 45-13
Dichiarazione di un nuovo costruttore 45-13
Registrazione del componente . . . . . 45-14
Creazione di una bitmap
per un componente . . . . . . . . . . . . 45-15
Verifica di componenti non installati . . . . . 45-17
Collaudo di componenti installati. . . . . . . 45-19
Installazione di un componente
sulla Component palette . . . . . . . . . . . 45-20
Rendere disponibili i file sorgente. . . . . 45-20
Aggiunta del componente . . . . . . . . . 45-20
xxiv
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Capitolo 46
Programmazione object-oriented
per gli scrittori di componenti 46-1
Definizione di nuove classi . . . . . . . . . . . . 46-1
Derivazione di nuove classi . . . . . . . . . . 46-2
Modificare le impostazioni predefinite
della classe per evitare ripetizioni . . . . 46-2
Aggiungere nuove capacit a una classe . 46-2
Dichiarazione di una nuova classe
di componente . . . . . . . . . . . . . . . . 46-3
Antenati, discendenti e gerarchie della classe . 46-3
Controllo dellaccesso . . . . . . . . . . . . . . . 46-4
Occultamento dei dettagli implementativi . 46-5
Definizione dellinterfaccia
per lo scrittore di componenti . . . . . . . . 46-7
Definizione dellinterfaccia di esecuzione . . 46-7
Definizione dellinterfaccia di progettazione46-8
Dispatch dei metodi . . . . . . . . . . . . . . . . 46-8
Metodi regolari . . . . . . . . . . . . . . . . . 46-9
Metodi virtuali . . . . . . . . . . . . . . . . . 46-9
Ridefinizione dei metodi . . . . . . . . . 46-10
Membri astratti di classi. . . . . . . . . . . . . 46-10
Classi e puntatori . . . . . . . . . . . . . . . . 46-11
Capitolo 47
Creazione di propriet 47-1
Perch creare le propriet . . . . . . . . . . . . . 47-1
Tipi di propriet . . . . . . . . . . . . . . . . . . 47-2
Pubblicazione di propriet ereditate. . . . . . . 47-3
Definizione delle propriet . . . . . . . . . . . . 47-3
Dichiarazione della propriet . . . . . . . . . 47-4
Memorizzazione interna dei dati . . . . . . . 47-4
Accesso diretto . . . . . . . . . . . . . . . . . 47-5
Access methods. . . . . . . . . . . . . . . . . 47-5
Il metodo read. . . . . . . . . . . . . . . . 47-7
Il metodo write . . . . . . . . . . . . . . . 47-7
Valori predefiniti delle propriet . . . . . . . 47-7
Specifica di una propriet
senza valore predefinito . . . . . . . . . 47-8
Creazione di propriet array . . . . . . . . . . . 47-8
Creazione di propriet per i sottocomponenti 47-10
Registrazione e caricamento delle propriet . 47-11
Uso del meccanismo di registrazione
e di caricamento . . . . . . . . . . . . . . 47-12
Specifica di valori predefiniti . . . . . . . . 47-12
Determinazione di che cosa registrare . . . 47-13
Inizializzazione dopo il caricamento. . . . 47-14
Registrazione e caricamento
di propriet non pubbliche . . . . . . . . 47-14
Creazione di metodi per memorizzare e
caricare i valori delle propriet . . . . 47-14
Ridefinizione del metodo
DefineProperties . . . . . . . . . . . . 47-15
Capitolo 48
Creazione di eventi 48-1
Cos un evento . . . . . . . . . . . . . . . . . . 48-1
Gli eventi sono closure . . . . . . . . . . . . 48-2
Gli eventi sono propriet . . . . . . . . . . . 48-2
I tipi degli eventi sono tipi closure . . . . . 48-3
Il tipo restituito
dai gestori di evento void . . . . . . . 48-3
I gestori di evento sono facoltativi. . . . . . 48-4
Implementazione degli eventi standard . . . . 48-4
Identificazione degli eventi standard . . . . 48-4
Eventi standard di tutti i controlli . . . . 48-5
Gli eventi standard
dei controlli standard . . . . . . . . . . 48-5
Visibilit degli eventi . . . . . . . . . . . . . 48-5
Modifica della gestione
standard degli eventi . . . . . . . . . . . . 48-6
Definizione di eventi personalizzati . . . . . . 48-6
Attivazione dellevento . . . . . . . . . . . . 48-7
Due tipi di eventi . . . . . . . . . . . . . 48-7
Definizione del tipo di gestore . . . . . . . . 48-7
Notifica semplice. . . . . . . . . . . . . . 48-7
Gestori che dipendono dallevento . . . 48-8
Restituzione di informazioni
da parte del gestore . . . . . . . . . . . 48-8
Dichiarazione dellevento . . . . . . . . . . 48-8
I nomi degli eventi cominciano con On48-8
Chiamata dellevento . . . . . . . . . . . . . 48-9
Capitolo 49
Creazione di metodi 49-1
Eliminazione delle dipendenze . . . . . . . . . 49-1
Assegnazione del nome ai metodi . . . . . . . 49-2
Protezione dei metodi . . . . . . . . . . . . . . 49-3
Metodi che devono essere pubblici . . . . . 49-3
Metodi che devono essere protetti. . . . . . 49-3
Utilizzo dei metodi virtual . . . . . . . . . . . . 49-4
Dichiarazione dei metodi . . . . . . . . . . . . 49-4
Capitolo 50
Uso della grafica nei componenti 50-1
Introduzione alla grafica . . . . . . . . . . . . . 50-1
xxv
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Utilizzo del canvas. . . . . . . . . . . . . . . . . 50-3
Operazioni con le immagini . . . . . . . . . . . 50-3
Uso di classi picture, graphic o canvas. . . . 50-4
Caricamento e memorizzazione di grafici . . 50-4
Gestione delle tavolozze. . . . . . . . . . . . 50-5
Specifica di una tavolozza
per un controllo . . . . . . . . . . . . . . 50-5
Le bitmap fuori schermo . . . . . . . . . . . . . 50-6
Creazione e gestione di bitmap
fuori schermo . . . . . . . . . . . . . . . . . 50-6
Copia di immagini bitmap . . . . . . . . . . 50-7
Risposta alle modifiche . . . . . . . . . . . . . . 50-7
Capitolo 51
Gestione dei messaggi
e delle notifiche di sistema 51-1
Il sistema di gestione dei messaggi . . . . . . . 51-1
Cosa contiene un messaggio di Windows? . 51-2
Smistamento dei messaggi . . . . . . . . . . 51-3
Il flusso dei messaggi. . . . . . . . . . . . 51-3
Modifica della gestione dei messaggi . . . . . . 51-4
Ridefinizione del metodo di gestione . . . . 51-4
Uso dei parametri del messagio . . . . . . . 51-5
Intercettazione dei messaggi . . . . . . . . . 51-5
Creazione di nuovi gestori di messaggio . . . . 51-6
Definizione di un proprio messaggio . . . . 51-6
Dichiarazione di un identificatore
di messaggio. . . . . . . . . . . . . . . . 51-7
Dichiarazione di un tipo di struttura
di messaggio. . . . . . . . . . . . . . . . 51-7
Dichiarazione di un nuovo metodo
di gestione messaggi . . . . . . . . . . . . . 51-8
Invio di messaggi. . . . . . . . . . . . . . . . 51-8
Trasmissione di un messaggio a tutti i
controlli in una scheda . . . . . . . . . . 51-9
Chiamata diretta del gestore
del messaggio di un controllo . . . . . . 51-9
Invio di un messaggio utilizzando
la coda dei messaggi Windows . . . . 51-10
Invio di un messaggio che non
viene eseguito immediatamente. . . . 51-10
Risposta alle notifiche di sistema
utilizzando la CLX . . . . . . . . . . . . . . . 51-11
Risposta ai segnali . . . . . . . . . . . . . . 51-11
Assegnazione dei gestori
di segnale custom. . . . . . . . . . . . 51-12
Risposta a eventi di sistema . . . . . . . . . 51-13
Eventi comunemente utilizzati . . . . . 51-13
Ridefinizione del metodo EventFilter . 51-15
Generazione di eventi Qt . . . . . . . . 51-15
Capitolo 52
Come rendere disponibili
i componenti in fase di progetto 52-1
Registrazione di componenti . . . . . . . . . . 52-1
Dichiarazione della funzione Register . . . 52-2
Scrittura della funzione Register. . . . . . . 52-2
Specifica dei componenti . . . . . . . . . 52-2
Specifica della pagina della tavolozza. . 52-3
Uso della funzione
RegisterComponents . . . . . . . . . . 52-3
Aggiunta di bitmap alla tavolozza . . . . . . . 52-4
Preparazione di un file di Guida
per il componente . . . . . . . . . . . . . . . . 52-4
Creazione del file di Guida. . . . . . . . . . 52-5
Creazione delle voci . . . . . . . . . . . . 52-5
Come rendere sensibile al contesto
la guida del componente . . . . . . . . 52-6
Aggiunta di file di Guida al componente 52-7
Aggiunta di editor di propriet . . . . . . . . . 52-7
Derivazione di una classe
editor di propriet . . . . . . . . . . . . . . 52-8
Modifica della propriet come testo. . . . . 52-9
Visualizzazione del valore
della propriet . . . . . . . . . . . . . . 52-9
Impostazione del valore della propriet 52-10
Modifica globale della propriet. . . . . . 52-10
Specifica degli attributi delleditor . . . . .52-11
Registrazione delleditor di propriet. . . 52-12
Categorie di propriet . . . . . . . . . . . . . 52-13
Registrazione di una propriet alla volta . 52-13
Registrazione contemporanea
di pi propriet . . . . . . . . . . . . . . 52-14
Specifica delle categorie di propriet . . . 52-15
Utilizzo della funzione
IsPropertyInCategory . . . . . . . . . . . 52-15
Aggiunta di editor di componenti . . . . . . 52-16
Aggiunta di voci al menu contestuale. . . 52-17
Specifica delle voci di menu . . . . . . 52-17
Implementazione dei comandi . . . . . 52-17
Modifica del comportamento
del doppio clic . . . . . . . . . . . . . . . 52-18
Aggiunta di formati nella clipboard. . . . 52-19
Registrazione delleditor di componente . 52-19
Compilazione dei componenti in package . . 52-20
Risoluzione dei problemi
con componenti custom . . . . . . . . . . . 52-20
xxvi
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Capitolo 53
Modifica di un componente
esistente 53-1
Creazione e registrazione del componente . . . 53-1
Modifica della classe del componente . . . . . . 53-3
Ridefinizione del costruttore . . . . . . . . . 53-3
Specifica del nuovo valore
predefinito di una propriet. . . . . . . . . 53-4
Capitolo 54
Creazione di un controllo grafico 54-1
Creazione e registrazione del componente . . . 54-1
Pubblicazione delle propriet ereditate . . . . . 54-3
Aggiunta di funzionalit grafiche . . . . . . . . 54-3
Determinazione di cosa disegnare . . . . . . 54-4
Dichiarzione del tipo della propriet . . . 54-4
Dichiarazione della propriet . . . . . . . 54-4
Scrittura del metodo di implementazione54-5
Ridefinizione del costruttore
e del distruttore . . . . . . . . . . . . . . . . 54-5
Cambiamento dei valori predefiniti
delle propriet. . . . . . . . . . . . . . . 54-5
Pubblicazione di penna e pennello . . . . . . 54-6
Dichiarazione dei membri dati
della classe . . . . . . . . . . . . . . . . . 54-6
Dichiarazione delle propriet di accesso . 54-7
Inizializzazione delle classi possedute . . 54-7
Impostazione delle propriet
delle classi possedute. . . . . . . . . . . 54-8
Disegno dellimmagine del componente . . 54-9
Perfezionamento del disegno della figura . 54-10
Capitolo 55
Personalizzazione di una griglia 55-1
Creazione e registrazione del componente . . . 55-1
Come rendere pubbliche le propriet ereditate. 55-3
Cambiamento dei valori iniziali . . . . . . . . . 55-3
Ridimensionamento delle celle. . . . . . . . . . 55-4
Riempimento delle celle. . . . . . . . . . . . . . 55-6
Registrazione della data . . . . . . . . . . . . 55-6
Registrazione della data interna. . . . . . 55-7
Accesso a giorno, mese e anno . . . . . . 55-8
Generazione dei numeri dei giorni . . . . 55-9
Selezione del giorno corrente . . . . . . 55-11
Scorrimento di mesi e anni . . . . . . . . . . . 55-11
Scorrimento dei giorni. . . . . . . . . . . . . . 55-12
Spostamento della selezione . . . . . . . . 55-13
Preparazione di un evento OnChange . . . 55-13
Esclusione delle celle vuote . . . . . . . . 55-14
Capitolo 56
Creazione di un controllo
di accesso ai dati 56-1
Creazione di un controllo per lesame dei dati 56-1
Creazione e registrazione del componente . 56-2
Costruzione del controllo a sola lettura. . . 56-3
Aggiunta della propriet ReadOnly . . . 56-3
Permettere gli aggiornamenti necessari . 56-4
Aggiunta di un datalink . . . . . . . . . . . 56-5
Dichiarazione del membro dati . . . . . 56-5
Dichiarzione delle propriet di accesso . 56-6
Un esempio di dichiarazione
delle propriet di accesso . . . . . . . . 56-6
Inizializzazione del datalink . . . . . . . 56-7
Risposta alle modifiche dei dati . . . . . . . 56-7
Creazione di un controllo per lediting dei dati 56-8
Modifica del valore predefinito
di FReadOnly . . . . . . . . . . . . . . . . 56-9
Gestione dei messaggi
mouse-down e key-down. . . . . . . . . . 56-9
Risposta ai messaggi mouse-down . . . 56-9
Risposta a messaggi key-down. . . . . 56-10
Modifica della classe datalink del campo. .56-11
Modifica del metodo Change . . . . . . . 56-12
Aggiornamento del dataset . . . . . . . . 56-13
Capitolo 57
Trasformazione di una finestra
di dialogo in un componente 57-1
Definizione dellinterfaccia del componente. . 57-2
Creazione e registrazione del componente. . . 57-2
Creazione dellinterfaccia del componente. . . 57-3
Inclusione dei file unit della scheda . . . . . 57-4
Aggiunta delle propriet di interfaccia . . . 57-4
Aggiunta del metodo Execute . . . . . . . . 57-5
Verifica del componente . . . . . . . . . . . . . 57-7
Capitolo 58
Estensione dellIDE 58-1
Panoramica sugli strumenti API . . . . . . . . 58-2
Scrittura di una classe wizard . . . . . . . . . . 58-3
Implementazione delle interfacce wizard . 58-4
Semplificazione dellimplementazione
delle interfacce . . . . . . . . . . . . . . . . 58-6
Installazione del package del wizard . . . . 58-7
Ottenimento dei servizi delle API Tools . . . . 58-8
xxvii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
Utilizzo di oggetti nativi dellIDE . . . . . . 58-9
Utilizzo dellinterfaccia INTAServices . . 58-9
Aggiunta di unimmagine
alla lista delle immagini . . . . . . . . . 58-9
Aggiunta di unazione
allelenco di azioni . . . . . . . . . . . 58-10
Cancellazione di pulsanti
dalla barra strumenti . . . . . . . . . . 58-10
Debug di un wizard . . . . . . . . . . . . . 58-11
Numeri di versione dellinterfaccia . . . . 58-12
Operazioni con file ed editor . . . . . . . . . . 58-13
Utilizzo delle interfacce di modulo. . . . . 58-13
Utilizzo delle interfacce degli editor . . . . 58-14
Creazione di schede e di progetti . . . . . . . 58-14
Creazione dei moduli . . . . . . . . . . . . 58-15
Notifica a un wizard di eventi dellIDE . . . . 58-19
Installazione della DLL di un wizard . . . . . 58-23
Utilizzo di una DLL
senza package di esecuzione . . . . . . . 58-24
Appendice A
Normativa ANSI per le
implementazioni specifiche A-1
Appendice B
Guida di riferimento
agli script lato server di WebSnap B-1
Tipi di oggetto . . . . . . . . . . . . . . . . . . . B-2
Tipo Adapter . . . . . . . . . . . . . . . . . . B-2
Propriet . . . . . . . . . . . . . . . . . . . B-3
Tipo AdapterAction . . . . . . . . . . . . . . B-4
Propriet . . . . . . . . . . . . . . . . . . . B-4
Metodi . . . . . . . . . . . . . . . . . . . . B-6
Tipo AdapterErrors . . . . . . . . . . . . . . B-6
Propriet . . . . . . . . . . . . . . . . . . . B-6
Tipo AdapterField type . . . . . . . . . . . . B-7
Propriet . . . . . . . . . . . . . . . . . . . B-7
Metodo. . . . . . . . . . . . . . . . . . . .B-10
Tipo AdapterFieldValues . . . . . . . . . . .B-10
Propriet . . . . . . . . . . . . . . . . . . .B-10
Metodi . . . . . . . . . . . . . . . . . . . .B-10
Tipo AdapterFieldValuesList . . . . . . . . .B-11
Propriet . . . . . . . . . . . . . . . . . . .B-11
Metodi . . . . . . . . . . . . . . . . . . . .B-11
Tipo AdapterHiddenFields . . . . . . . . . .B-12
Propriet . . . . . . . . . . . . . . . . . . .B-12
Metodi . . . . . . . . . . . . . . . . . . . .B-12
Tipo AdapterImage . . . . . . . . . . . . . .B-12
Propriet . . . . . . . . . . . . . . . . . . B-12
Tipo di modulo . . . . . . . . . . . . . . . . B-12
Propriet . . . . . . . . . . . . . . . . . . B-12
Tipo Page . . . . . . . . . . . . . . . . . . . . B-13
Propriet . . . . . . . . . . . . . . . . . . B-13
Oggetti globali. . . . . . . . . . . . . . . . . . . B-14
Oggetto Application . . . . . . . . . . . . . B-15
Propriet . . . . . . . . . . . . . . . . . . B-15
Metodi. . . . . . . . . . . . . . . . . . . . B-16
Oggetto EndUser . . . . . . . . . . . . . . . B-16
Propriet . . . . . . . . . . . . . . . . . . B-16
Oggetto Modules . . . . . . . . . . . . . . . B-16
Oggetto Page. . . . . . . . . . . . . . . . . . B-17
Oggetto Pages . . . . . . . . . . . . . . . . . B-17
Oggetto Producer . . . . . . . . . . . . . . . B-17
Propriet . . . . . . . . . . . . . . . . . . B-17
Metodi. . . . . . . . . . . . . . . . . . . . B-17
Oggetto Request . . . . . . . . . . . . . . . . B-18
Propriet . . . . . . . . . . . . . . . . . . B-18
Oggetto Response . . . . . . . . . . . . . . . B-18
Propriet . . . . . . . . . . . . . . . . . . B-18
Metodi. . . . . . . . . . . . . . . . . . . . B-18
Oggetto Session . . . . . . . . . . . . . . . . B-19
Propriet . . . . . . . . . . . . . . . . . . B-19
Esempi JScript . . . . . . . . . . . . . . . . . . . B-19
Esempio 1 . . . . . . . . . . . . . . . . . . . B-20
Esempio 2 . . . . . . . . . . . . . . . . . . . B-21
Esempio 3 . . . . . . . . . . . . . . . . . . . B-21
Esempio 4 . . . . . . . . . . . . . . . . . . . B-21
Esempio 5 . . . . . . . . . . . . . . . . . . . B-22
Esempio 6 . . . . . . . . . . . . . . . . . . . B-22
Esempio 7 . . . . . . . . . . . . . . . . . . . B-23
Esempio 8 . . . . . . . . . . . . . . . . . . . B-23
Esempio 9 . . . . . . . . . . . . . . . . . . . B-24
Esempio 10 . . . . . . . . . . . . . . . . . . . B-25
Esempio 11 . . . . . . . . . . . . . . . . . . . B-26
Esempio 12 . . . . . . . . . . . . . . . . . . . B-28
Esempio 13 . . . . . . . . . . . . . . . . . . . B-28
Esempio 14 . . . . . . . . . . . . . . . . . . . B-29
Esempio 15 . . . . . . . . . . . . . . . . . . . B-31
Esempio 16 . . . . . . . . . . . . . . . . . . . B-32
Esempio 17 . . . . . . . . . . . . . . . . . . . B-34
Esempio 18 . . . . . . . . . . . . . . . . . . . B-35
Esempio 19 . . . . . . . . . . . . . . . . . . . B-35
Esempio 20 . . . . . . . . . . . . . . . . . . . B-36
Esempio 21 . . . . . . . . . . . . . . . . . . . B-36
Esempio 22 . . . . . . . . . . . . . . . . . . . B-37
Indice I-1
xxviii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:21 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.toc)
xxix
1.1 Caratteri tipografici e simboli . . . . . . . 1-3
3.1 Classi di base importanti . . . . . . . . . . 3-5
4.1 Modalit Open . . . . . . . . . . . . . . . . 4-6
4.2 Modalit Share . . . . . . . . . . . . . . . . 4-6
4.3 Modalit shared disponibili
per ogni modalit open . . . . . . . . . . . 4-7
4.4 Costanti di attributo e valori . . . . . . . . 4-8
4.5 Classi per la gestione di elenchi . . . . . . 4-13
4.6 Routine per il confronto delle stringhe . . 4-23
4.7 Routine di conversione
maiuscole/minuscole . . . . . . . . . . . . 4-24
4.8 Routine per la modifica di stringhe . . . . 4-24
4.9 Routine per le sottostringhe . . . . . . . . 4-24
4.10 Routine di confronto
per stringhe terminate con null . . . . . . 4-25
4.11 Routine di conversione
maiuscole/minuscole
per stringhe terminate con null . . . . . . 4-25
4.12 Routine per la modifica di stringhe . . . . 4-26
4.13 Routine per le sottostringhe . . . . . . . . 4-26
4.14 Routine per la copia di stringhe . . . . . . 4-26
5.1 Pagine della Component palette . . . . . 5-7
6.1 Propriet del testo selezionato . . . . . . . 6-9
6.2 Confronto dello stile owner-draw
fixed con quello variable . . . . . . . . . . 6-13
7.1 Direttive al compilatore per le librerie. . . 7-11
7.2 Pagine di database
sulla Component palette . . . . . . . . . . 7-16
7.3 Applicazioni per Web server . . . . . . . . 7-18
7.4 Opzioni del menu contestuale
dei moduli dati . . . . . . . . . . . . . . . 7-22
7.5 Metodi Help in TApplication . . . . . . . 7-35
8.1 Terminologia per la configurazione
delle azioni . . . . . . . . . . . . . . . . . . 8-18
8.2 Valori predefiniti della propriet
PrioritySchedule del gestore di azioni. . . 8-25
8.3 Classi di azioni . . . . . . . . . . . . . . . . 8-29
8.4 Esempi di caption e loro nomi derivati . . 8-34
8.5 Comandi del menu contestuale
Menu Designer. . . . . . . . . . . . . . . . 8-40
8.6 Impostazione dellaspetto
di pulsanti scelta rapid a . . . . . . . . . . 8-48
8.7 Impostazione dellaspetto
di pulsanti strumento . . . . . . . . . . . . 8-50
8.8 Impostazione dellaspetto
di un pulsante cool . . . . . . . . . . . . . 8-52
9.1 Propriet dei controlli di testo . . . . . . . 9-3
10.1 Tipi di oggetti grafici . . . . . . . . . . . . 10-3
10.2 Propriet comuni delloggetto Canvas . . 10-4
10.3 Metodi comuni delloggetto Canvas . . . 10-4
10.4 Tipi MIME e costanti della CLX . . . . 10-23
10.5 Parametri degli eventi mouse . . . . . 10-25
10.6 Tipi di dispositivi multimediali
e loro funzioni . . . . . . . . . . . . . . 10-34
11.1 Priorit del thread . . . . . . . . . . . . . 11-3
11.2 Valori di ritorno di Waifor . . . . . . . . . 11-11
12.1 Opzioni del compilatore
per la gestione delle eccezioni . . . . . . 12-15
12.2 Classi di eccezione selezionate . . . . . 12-18
13.1 Confronto dei modelli degli oggetti . . 13-10
13.2 Confronto delluguaglianza !A == !B di
variabili BOOL . . . . . . . . . . . . . . 13-21
13.3 Esempi di correlazioni RTTI
da Object Pascal a C++. . . . . . . . . . 13-23
14.1 Tecniche di porting . . . . . . . . . . . . . 14-2
14.2 Sezioni della CLX. . . . . . . . . . . . . . 14-5
14.3 Funzionalit modificate o differenti . . . 14-9
14.4 Unit nella VCL
ed equivalenti nella CLX. . . . . . . . . 14-10
14.5 Unit solo nella CLX. . . . . . . . . . . . 14-10
14.6 Unit solo nella VCL. . . . . . . . . . . . .14-11
14.7 Differenze fra gli ambienti operativi
Linux e Windows . . . . . . . . . . . . . 14-14
14.8 Directory Linux comuni . . . . . . . . 14-16
14.9 Componenti paragonabili
per laccesso ai dati . . . . . . . . . . . . 14-23
14.10Propriet , metodi ed eventi degli
aggiornamenti in cache . . . . . . . . . 14-29
15.1 File package . . . . . . . . . . . . . . . . . 15-2
15.2 Direttive al compilatore
specifiche per il packaging. . . . . . . . 15-12
15.3 Opzioni del linker della riga comandi
specifiche per i package . . . . . . . . . 15-13
15.4 File distribuiti con un package . . . . . 15-14
16.1 Oggetti VCL che supportano BiDi . . . . 16-4
16.2 Metodi della VCL che supportano BiDi . 16-8
16.3 Lunghezza stimata delle stringhe. . . . . 16-9
17.1 File di applicazione . . . . . . . . . . . . 17-3
17.2 Moduli di fusione
e rispettive dipendenze . . . . . . . . . . 17-4
17.3 Distribuzione di dbExpress
come eseguibile indipendente . . . . . . 17-7
17.4 Distribuzione dbExpress
con DLL di driver . . . . . . . . . . . . . 17-8
Tabelle
xxx
17.5 File software del client di database . . . . 17-9
19.1 Controllo dati . . . . . . . . . . . . . . . . 19-2
19.2 Propriet di Columns . . . . . . . . . . . 19-22
19.3 Propriet Title del TColumn espanso . . 19-23
19.4 Propriet che influiscono
sulla modalit di visualizazione dei campi compositi
19-26
19.5 Propriet Options espansa
di TBDGrid . . . . . . . . . . . . . . . . 19-27
19.6 Eventi di controllo della griglia . . . . . 19-29
19.7 Propriet del controllo griglia
per database selezionato . . . . . . . . . 19-31
19.8 Pulsanti di TDBNavigator . . . . . . . . 19-32
21.1 Componenti di connessione
del database . . . . . . . . . . . . . . . . . 21-1
22.1 Valori della propriet State
di un dataset . . . . . . . . . . . . . . . . . 22-3
22.2 Metodi di navigazione dei dataset . . . . . 22-5
22.3 Propriet di navigazione dei dataset . . . 22-6
22.4 Operatori logici e di confronto
che possono apparire in un filtro . . . . 22-15
22.5 Valori di FilterOptions . . . . . . . . . . 22-16
22.6 Metodi di navigazione
nei dataset filtrati . . . . . . . . . . . . . 22-17
22.7 Metodi dei dataset per inserire,
aggiornare e cancellare dati. . . . . . . . 22-18
22.8 Metodi che funzionano
con interi record . . . . . . . . . . . . . . 22-22
22.9 Metodi di ricerca basati sugli indici . . . 22-29
23.1 Propriet di TFloatField
che influenzano la visualizzazione
dei dati . . . . . . . . . . . . . . . . . . . . 23-1
23.2 Tipi di campi persistenti particolari . . . . 23-6
23.3 Propriet dei componenti campo . . . . 23-12
23.4 Routine di formattazione
dei componenti campo . . . . . . . . . . 23-16
23.5 Eventi dei componenti campo . . . . . 23-17
23.6 Altri metodi dei componenti campo. . . 23-18
23.7 Risultati speciali di conversioni . . . . . 23-20
23.8 Tipi di componenti campo oggetto . . . 23-24
23.9 Propriet comuni dei discendenti
dei campi oggetto . . . . . . . . . . . . . 23-24
24.1 Tipi di tabella riconosciuti da BDE
in base allestensione del file . . . . . . . . 24-5
24.2 Valori di TableType . . . . . . . . . . . . . 24-6
24.3 Modalit di importazione
di BatchMove . . . . . . . . . . . . . . . . 24-8
24.4 Metodi informativi correlati
al database dei componenti session . . . 24-27
24.5 Propriet e metodi di TSessionList . . 24-30
24.6 Propriet , metodi ed eventi degli
aggiornamenti in cache . . . . . . . . . 24-34
24.7 Valori di UpdateKind . . . . . . . . . . 24-40
24.8 Modalit di un componente
batch move . . . . . . . . . . . . . . . . 24-51
24.9 Interfaccia del Data Dictionary . . . . 24-56
25.1 Componenti ADO . . . . . . . . . . . . . 25-2
25.2 Modalit di connessione ADO . . . . . . 25-6
25.3 Opzioni di esecuzione dei dataset ADO 25-12
25.4 Confronto tra gli aggiornamenti
in cache di ADO e gli aggiornamenti
in cache nel dataset client . . . . . . . . 25-12
26.1 Colonne nelle tabelle di metadati
che elencano tabelle . . . . . . . . . . . 26-14
26.2 Colonne nelle tabelle di metadati
che elencano procedure registrate . . . 26-15
26.3 Colonne nelle tabelle di metadati
che elencano campi . . . . . . . . . . . . 26-16
26.4 Colonne nelle tabelle di metadati
che elencano indici . . . . . . . . . . . . 26-17
26.5 Colonne nelle tabelle di metadati
che elencano parametri. . . . . . . . . . 26-17
27.1 Supporto per i filtri nei dataset client . . 27-3
27.2 Operatori di riepilogo per le
aggregazioni di manutenzione . . . . . 27-13
27.3 Dataset client specializzati per gli
aggiornamenti in cache . . . . . . . . . 27-19
28.1 Membri dellinterfaccia AppServer . . . . 28-3
28.2 Opzione del provider. . . . . . . . . . . . 28-5
28.3 Valori di UpdateStatus . . . . . . . . . . 28-9
28.4 Valori di UpdateMode . . . . . . . . . . 28-10
28.5 Valori di ProviderFlags . . . . . . . . . .28-11
29.1 Componenti usati nelle
applicazioni multi-tier . . . . . . . . . . . 29-3
29.2 Componenti connection . . . . . . . . . . 29-5
29.3 Librerie javascript. . . . . . . . . . . . . 29-35
32.1 Web Broker e WebSnap. . . . . . . . . . . 32-2
33.1 Valori di MethodType . . . . . . . . . . . 33-7
34.1 Tipi di modulo Web application. . . . . . 34-3
34.2 Tipi di applicazione per Web server . . . 34-9
34.3 Componenti Web application . . . . . . 34-10
34.4 Oggetti script . . . . . . . . . . . . . . . 34-36
34.5 Informazioni di richiesta presenti nelle
richieste di azioni . . . . . . . . . . . . 34-39
36.1 Classi Remotable . . . . . . . . . . . . . . 36-8
38.1 Requisiti degli oggetti COM. . . . . . . 38-12
xxxi
38.2 Wizard di C++Builder per
limplementazione di oggetti COM,
Automation e ActiveX . . . . . . . . . . 38-22
39.1 File di Type Library editor . . . . . . . . . 39-2
39.2 Parti di Type Library editor. . . . . . . . . 39-3
39.3 Pagine del Type Library editor . . . . . . . 39-6
41.1 Modelli di threading
per gli oggetti COM. . . . . . . . . . . . . 41-6
42.1 Membri dellinterfaccia
IApplicationObject . . . . . . . . . . . . . 42-4
42.2 Membri dellinterfaccia IRequest . . . . . 42-4
42.3 Membri dellinterfaccia IResponse . . . . 42-5
42.4 Membri dellinterfaccia ISessionObject . . 42-6
42.5 Membri dellinterfaccia IServer . . . . . . 42-7
44.1 Metodi IObjectContext
per il supporto delle transazioni . . . . . 44-14
44.2 Modelli di threading
per oggetti transazionali . . . . . . . . . 44-20
44.3 Opzioni di sincronizzazione
della chiamata . . . . . . . . . . . . . . . 44-21
44.4 Codici di ritorno dei publisher
di evento . . . . . . . . . . . . . . . . . . 44-26
45.1 Punti di partenza per la creazione
di componenti . . . . . . . . . . . . . . . . 45-3
46.1 Livelli di visibilit allinterno
di un oggetto . . . . . . . . . . . . . . . . 46-4
47.1 Come appaiono le propriet nellObject
Inspector . . . . . . . . . . . . . . . . . . 47-2
50.1 Riepilogo delle capacit del canvas. . . . 50-3
50.2 Metodi per la copia di immagini . . . . . 50-7
51.1 Metodi protetti di TWidgetControl
per la risposta ad eventi di sistema . . 51-14
51.2 Metodi protetti di TWidgetControl per la
risposta ad eventi dai controlli . . . . . 51-14
52.1 Tipi di editor di propriet predefiniti. . . 52-8
52.2 Metodi per leggere e scrivere
i valori delle propriet . . . . . . . . . . . 52-9
52.3 Flag attributi di un editor di propriet . .52-11
52.4 Categorie di propriet . . . . . . . . . . 52-15
58.1 I quattro tipi di wizard . . . . . . . . . . 58-3
58.2 Interfacce di servizi Tools API. . . . . . . 58-8
58.3 Le interfacce notifier . . . . . . . . . . . 58-19
A.1 Opzioni necessarie per assicurare
il rispetto delle norme ANSI. . . . . . . . A-1
A.2 Identificazione dei diagnostici in C++ . . A-3
B.1 Tipi di oggetto di WebSnap . . . . . . . . . B-2
B.2 Oggetti globali WebSnap. . . . . . . . . . B-14
B.3 Esempi JScript di scripting lato server . . B-19
xxxii
xxxiii
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:34 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.lof)
3.1 Oggetti, componenti e controlli . . . . . . 3-4
3.2 Un diagramma semplificato
della gerarchia . . . . . . . . . . . . . . . . 3-5
8.1 Un frame con controlli data-aware e un
componente datasource. . . . . . . . . . . 8-16
8.3 Terminologia dei menu . . . . . . . . . . . 8-32
8.4 Componenti MainMenu e PopupMenu. . 8-32
8.6 Aggiunta di voci di menu
a un menu principale . . . . . . . . . . . . 8-36
8.7 Strutture di menu annidate. . . . . . . . . 8-37
9.2 Una barra di avanzamento . . . . . . . . . 9-17
10.1 Finestra di dialogo
Bitmap Dimension dalla unit BMPDlg . 10-22
13.1 Sequenza di costruzione
degli oggetti in stile VCL . . . . . . . . . . 13-9
16.1 TListBox impostato a bdLeftToRight . . . 16-6
16.2 TListBox impostato a bdRightToLeft . . . 16-7
16.3 TListBox impostato a
bdRightToLeftNoAlign . . . . . . . . . . . 16-7
16.4 TListBox impostato a
bdRightToLeftReadingOnly . . . . . . . . 16-7
18.1 Architettura generale di un database . . . 18-6
18.2 Connessione diretta
a un server di database . . . . . . . . . . . 18-8
18.3 Unapplicazione database basata su file. 18-10
18.4 Architettura che combina
un dataset client e un altro dataset. . . . 18-12
18.5 Architettura multi-tier di un database. . 18-14
19.1 Controllo TDBGrid . . . . . . . . . . . . 19-17
19.2 Controllo TDBGrid
con ObjectView impostato a false . . . . 19-25
19.3 Controllo TDBGrid
con Expanded impostato a false . . . . . 19-26
19.4 Controllo TDBGrid
con Expanded impostato a true . . . . . 19-26
19.5 TDBCtrlGrid in fase di progettazione . . 19-31
19.6 Pulsanti del controllo TDBNavigator . . 19-32
20.1 Componenti di supporto decisionale
in progettazione . . . . . . . . . . . . . . . 20-2
20.2 Un crosstab mono-dimensionale. . . . . . 20-3
20.3 Crosstab tridimensionale . . . . . . . . . . 20-3
20.4 Grafici decisionali collegati a sorgenti
decisionali diverse . . . . . . . . . . . . . 20-15
24.1 Componenti in unapplicazione BDE. . . 24-2
29.1 Applicazione database multi-tier
basata su Web . . . . . . . . . . . . . . . 29-31
31.1 Struttura di unapplicazione CORBA. . . 31-2
32.1 Parti di uno Uniform Resource Locator . 32-4
33.1 Struttura di unapplicazione server. . . . 33-4
34.5 Pagina CountryTable Preview. . . . . . 34-17
34.6 Pagina CountryTable HTML Script . . . 34-18
34.7 CountryTable Preview
dopo avere aggiunto
i comandi di editing . . . . . . . . . . . 34-19
34.10Finestra di dialogo
Web App Components
con le opzioni per supporto
del login selezionate . . . . . . . . . . . 34-27
34.11 Un esempio di pagina di login visto
nelleditor della pagina web. . . . . . . 34-30
34.12 Generazione
del flusso dei contenuti . . . . . . . . . 34-38
34.13Action request e response . . . . . . . . 34-40
34.14 Risposta di immagine a una richiesta . 34-41
34.15 Indirizzamento di una pagina . . . . . 34-42
38.1 Uninterfaccia COM . . . . . . . . . . . . 38-3
38.2 Vtable dellinterfaccia . . . . . . . . . . . 38-5
38.3 Server in-process . . . . . . . . . . . . . . 38-7
38.4 Server out-of-process e remoti. . . . . . . 38-8
38.5 Tecnologie basate su COM. . . . . . . . 38-12
38.6 Una semplice interfacia
per un oggetto COM . . . . . . . . . . . 38-21
38.7 Interfaccia di un oggetto Automation . 38-21
38.8 Interfaccia di un oggetto ActiveX. . . . 38-21
39.1 Type Library editor . . . . . . . . . . . . . 39-3
39.2 Pannello Object list . . . . . . . . . . . . . 39-5
41.1 VTable di uninterfaccia duale. . . . . . 41-14
43.1 La pagina di propriet Mask Edit
in modalit progetto . . . . . . . . . . . 43-15
44.1 Il sistema a eventi di COM+. . . . . . . 44-24
45.1 La gerarchia di classi
della Visual Component Library . . . . . 45-2
45.2 Component wizard. . . . . . . . . . . . 45-10
51.1 Instradamento del segnale. . . . . . . . .51-11
51.2 Instradamento dellevento di sistema . 51-13
Figure
xxxiv
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 7:34 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.lof)
I n t r o d u z i o n e 1-1
C a p i t o l o
1
Capitolo1Introduzione
Il manuale Guida alla programmazione descrive gli argomenti, intermedi e evoluti,
quali la costruzione di database client/server, la scrittura di componenti custom, la
creazione di applicazioni per Web server Internet e linclusione del supporto per
specifiche standard come SOAP, TCP/IP, COM e ActiveX. La maggior parte delle
funzioni evolute che supportano lo sviluppo per Web, le tecnologie evolute XML e lo
sviluppo di database richiedono componenti o wizard che non sono disponibili in
tutte le versioni di C++Builder
Il manuale Guida alla programmazione presuppone una certa familiarit con luso di
C++Builder e la conoscenza delle tecniche fondamentali di programmazione in
C++Builder. Per una introduzione alla programmazione in C++Builder e
allambiente di sviluppo integrato (IDE), consultare il manuale Per iniziare e la Guida
in linea.
Contenuto del manuale
Questo manuale costituito da cinque parti:
La Parte I, Programmazione con C++Builder, descrive come costruire
applicazioni C++Builder per scopi generici. Vi vengono fornite informazioni
dettagliate sulle tecniche di programmazione, utilizzabili in qualsiasi applicazione
C++Builder. Per esempio, vi viene descritto l+uso di oggetti della Visual
Component Library (VCL) comuni o della Component Library for Cross-platform
(CLX), che semplificano la programmazione dellinterfaccia utente, per aspetti
quali la gestione delle stringhe, la manipolazione del testo, limplementazione
delle finestre di dialogo comuni di Windows, le operazioni con elementi grafici, la
gestione degli errori e delle eccezioni, luso di DLL, di Ole Automation e la
scrittura di applicazioni internazionali.
Capita di rado che una libreria VCL di C++Builder sia scritta in Object Pascal.
Tuttavia, ci sono casi in cui ci vale anche per programmi C++Builder. Un capitolo
sul supporto del linguaggio C++ e sulle librerie VCL descrive alcuni argomenti
1-2 G u i d a a l l a p r o g r a mma z i o n e
C o n t e n u t o d e l m a n u a l e
relativi al linguaggio quali le diverse modalit con cui si istanzia una classe C++
quando si utilizzano le classi VCL o le estensioni del linguaggio C++ aggiunte per
supportare il modello di programmazione componente-propriet-evento di
C++Builder.
Un capitolo descrive come utilizzare gli oggetti inclusi nella Borland Component
Library for Cross-Platform (CLX) per lo sviluppo di applicazioni che possono
essere compilate ed eseguite su piattaforme Windows o Linux.
Il capitolo sulla distribuzione illustra dettagliatamente le operazioni connesse alla
distribuzione delle applicazioni agli utenti. Per esempio, include informazioni
sulle opzioni del compilatore, sulluso di InstallShield Express, sulla concessione
delle licenze e su come determinare quali package, DLL e altre librerie utilizzare
per generare una versione della propria applicazione da immettere sul mercato.
La Parte II, Sviluppo di applicazioni database, descrive come costruire
applicazioni database utilizzando strumenti e componenti database. C++Builder
permette di accedere a molti tipi di database, inclusi i database locali come
Paradox e dBASE e database SQL server per rete come InterBase, Oracle e Sybase.
possibile scegliere fra vari meccanismi per laccesso di dati, fra cui dbExpress,
Borland Database Engine, InterBaseExpress e ActiveX Data Objects (ADO). Per
implementare applicazioni database client/server pi evolute, sono necessarie
funzionalit di C++Builder che non sono disponibili in tutte le edizioni.
La Parte III, Creazione di applicazioni Internet, descrive come creare
applicazioni da distribuire in Internet. C++Builder include una vasta gamma di
strumenti per la scrittura di applicazioni per Web server, fra cui Web Broker,
unarchitettura che permette di creare applicazioni server per pi piattaforme,
WebSnap, che permette di progettare pagine web in un ambiente GUI, il supporto
per operazioni con documenti XML, e BizSnap, unarchitettura per lutilizzo di
Servizi Web basati su SOAP.
Questa parte contiene anche un capitolo sui componenti socket di C++Builder che
permettono di creare applicazioni in grado di comunicare con altri sistemi tramite
TCP/IP e i protocolli correlati. I socket forniscono connessioni basate sul
protocollo TCP/IP, ma sufficientemente generiche da consentire di lavorare con
protocolli correlati come Xerox Network System (XNS), DECnet di Digital o la
famiglia IPX/SPX di Novell.
La Parte IV, Sviluppo di applicazioni COM, descrive come costruire
applicazioni in grado di interagire con altri oggetti API basati su COM.
C++Builder supporta le applicazioni COM basate sui wizard ATL (Active
Template Library) e un Type Library editor per semplificare lo sviluppo di server
COM, oltre a uno strumento di importazione che consente di creare rapidamente
applicazioni client. Il supporto per i client COM previsto in tutte le versioni di
C++Builder. Il supporto per i server COM non disponibile in tutte le versioni di
C++Builder.
La Parte V, Creazione di componenti custom, descrive come progettare e
implementare componenti personali e come renderli disponibili nella Component
palette dellIDE. Un componente pu essere un qualsiasi elemento di programma
che si desidera gestire in fase di progettazione. Limplementazione di componenti
I n t r o d u z i o n e 1-3
C o n v e n z i o n i t i p o g r a f i c h e
personalizzati implica la derivazione di una nuova classe a partire da uno dei tipi
di classe presenti nelle librerie di classi VCL o CLX.
Convenzioni tipografiche
Il presente manuale utilizza i caratteri e i simboli descritti nella Tabella 1.1 per
indicare un testo speciale.
Servizi di assistenza agli sviluppatori
Borland offre diverse opzioni di supporto. Tra queste vi sono servizi gratuiti su
Internet, dove si possono fare ricerche in unampia base di informazioni o collegarsi
con altri utenti dei prodotti Borland. Inoltre, possibile scegliere tra varie categorie di
supporto, che vanno dal supporto allinstallazione del prodotto Borland al supporto
a livello di consulenza e allassistenza estesa non gratuiti.
Per ottenere informazioni sui costi dei servizi Borland di assistenza agli sviluppatori,
visitare il sito Web di Borland, allindirizzo http://www.borland.com/devsupport/
bcppbuilder, oppure allindirizzo htpp://www.borland.it (seguire i collegamenti a
Borland Assist), oppure contattare telefonicamente Borland Assist al numero
0542.34058. I clienti non residenti negli Stati Uniti dAmerica possono anche
consultare il sito web di Borland allindirizzo http://www.borland.com/bww/
intlcust.html.
Quando si contatta il supporto tecnico, bene avere sotto mano tutte le informazioni
relative allambiente, alla versione del prodotto utilizzato e una descrizione
dettagliata del problema.
Come ordinare la documentazione cartacea
Per ordinare la documentazione aggiuntiva, visitare il sito http://shop.borland.com.
Tabella 1.1 Caratteri tipografici e simboli
Carattere o simbolo Significato
.s,i.i Il carattere monospaziato viene utilizzato per rappresentare un testo cos
come appare sullo schermo o nel codice C++. Rappresenta, inoltre, tutto ci
che deve essere immesso da tastiera.
[ ] Le parentesi quadre nel testo o nei listati sintattici racchiudono elementi
facolativi. Un testo di questo tipo non deve essere scritto letteralmente.
Grassetto Le parole in grassetto nel testo o nei listati di codice rappresentano parole
riservate di C++ oppure opzioni del compilatore.
Corsivo Le parole in corsivo nel testo rappresentano identificatori di C++, come i
nomi di variabili o di tipi. Il corsivo viene anche utilizzato per mettere in
evidenza determinate parole, come i nuovi termini.
Keycaps Questo carattere indica un tasto sulla tastiera. Ad esempio, Premere Esc
per uscire dal menu.
1-4 G u i d a a l l a p r o g r a mma z i o n e
C o n v e n z i o n i t i p o g r a f i c h e
P r o g r a mma z i o n e c o n C + + B u i l d e r
P a r t e
I
ParteIProgrammazione con C++Builder
I capitoli inclusi nella sezione Programmazione con C++Builder illustrano i
concetti di base e le nozioni necessarie per creare applicazioni C++Builder con
qualunque edizione del prodotto.
S v i l u p p o d i a p p l i c a z i o n i c o n C + + B u i l d e r 2-1
C a p i t o l o
2
Capitolo2Sviluppo di applicazioni con
C++Builder
Borland C++Builder un ambiente di programmazione visuale orientato agli oggetti
per lo sviluppo di applicazioni a 32-bit da distribuire in ambiente Windows e Linux.
Con C++Builder possibile creare applicazioni ad elevata efficienza scrivendo
pochissime righe di codice.
C++Builder mette a disposizione una suite di strumenti di progettazione RAD
(Rapid Application Development) che include wizard per la programmazione oltre a
modelli di applicazioni e schede, e supporta la programmazione orientata agli
oggetti grazie a una completa libreria di classi:
la Visual Component Library (VCL), che include oggetti che, oltre alle API di
Windows, incapsulano molte altre utili tecniche di programmazione (Windows).
la Borland Component Library for Cross-Platform (CLX), che include oggetti che
incapsulano la libreria Qt (Windows o Linux).
Questo capitolo descrive in breve lambiente di sviluppo di C++Builder e come esso
si adatta perfettamente al ciclo di sviluppo di un progetto. Nella parte rimanente di
questo manuale vengono forniti dettagli tecnici sullo sviluppo di applicazioni
generiche, di applicazioni database, di applicazioni Internet e Intranet, oltre che sulla
scrittura di controlli ActiveX e COM e di componenti personali.
Ambiente di sviluppo integrato
Quando si avvia C++Builder, ci si trova immediatamente allinterno dellambiente di
sviluppo integrato, detto anche IDE. Questo ambiente fornisce tutti gli strumenti
necessari per progettare, sviluppare, collaudare, correggere e distribuire le
applicazioni, consentendo cos la creazione rapida di prototipi e labbreviazione dei
tempi del ciclo di sviluppo.
2-2 G u i d a a l l a p r o g r a mma z i o n e
P r o g e t t a z i o n e d i a p p l i c a z i o n i
LIDE include tutti gli strumenti necessari per iniziare la progettazione di
applicazioni, quali:
Form Designer, una finestra vuota, detta anche scheda, in cui progettare
linterfaccia utente (UI) dellapplicazione.
Component palette per la visualizzazione di componenti visuali e non, che
possibile utilizzare per progettare linterfaccia utente.
Object Inspector per esaminare e modificare le propriet e gli eventi degli oggetti.
Object TreeView per visualizzare e modificare le relazioni di un componente.
Code editor per la stesura e la modifca della logica sottostante di un programma.
Project Manager per gestire i file che costituiscono uno o pi progetti.
Debugger integrato per ricercare e corregere gli errori nel codice.
Molti altri strumenti, come gli editor di propriet per modificare i valori delle
properiet di un oggetto.
Strumenti per la riga comandi che comprendono compilatori, linker e altri
programmi di utilit.
Complete librerie di classi con moltissimi oggetti riutilizzabili. La maggior parte
degli oggetti forniti nella libreria di classi sono accessibili nellIDE dalla
Component palette. Per convenzione, i nomi degli oggetti nella libreria di classi
iniziano con una T, come TStatusBar.
Alcuni strumenti potrebbero non essere inclusi in tutte le edizioni del prodotto.
Nel manuale Per iniziare, incluso nel prodotto, viene presentata una panoramica pi
completa sullambiente di sviluppo. Inoltre, il sistema di Guida in linea contiene la
descrizione completa dei menu, delle finestre di dialogo e delle finestre
dellapplicazione.
Progettazione di applicazioni
C++Builder pu essere usato per progettare qualsiasi tipo di applicazione a 32 bit
dai programmi di utilit per scopi generici ai sofisticati programmi di accesso ai dati
o applicazioni distribuite.
Quando si progetta in modo visuale linterfaccia utente per lapplicazione,
C++Builder genera il codice C++ sottostante. Quando si selezionano e si modificano
le propriet di componenti e schede, i risultati di queste modifiche vengono
visualizzati automaticamente nel codice sorgente e viceversa. possibile modificare i
file sorgente direttamente con qualsiasi editor di testo, compreso il Code editor
integrato. Le modifiche apportate vengono immediatamente riportate nellambiente
visuale.
In C++Builder possibile creare dei propri componenti. La maggior parte dei
componenti forniti scritta in Object Pascal. possibile aggiungere alla Component
palette i propri componenti oppure personalizzarla in base alle proprie preferenze
inserendo, ad esempio, nuove pagine.
Utilizzando la libreria CLX possibile anche utilizzare C++Builder per lo sviluppo di
applicazioni eseguibili su entrambe le piattaforme Linux e Windows. CLX contiene
un insieme di classi che, se utilizzate al posto di quelle incluse nella VCL, permettono
di eseguire il porting del programma tra Windows e Linux. Per i dettagli sulla
S v i l u p p o d i a p p l i c a z i o n i c o n C + + B u i l d e r 2-3
C r e a z i o n e d i p r o g e t t i
programmazione per pi piattaforme e per le differenze fra gli ambienti Windows e
Linux, fare riferimento al Capitolo 14, Sviluppo di applicazioni multipiattaforma.
Il Capitolo 7, Creazione di applicazioni, componenti e librerie, presenta i supporti
forniti da C++Builder per i diversi tipi di applicazioni.
Creazione di progetti
In C++Builder, tutte le attivit relative allo sviluppo di applicazioni ruotano intorno
ai progetti. Quando si crea unapplicazione in C++Builder si crea un progetto. Un
progetto una raccolta di file che compongono unapplicazione. Alcuni di questi file
sono creati in fase di progettazione. Gli altri vengono generati automaticamente
quando si compila il codice sorgente del progetto.
possibile visualizzare il contenuto di un progetto in uno strumento per la gestione
dei progetti di nome Project Manager. Il Project Manager elenca, in una vista
gerarchica, i nomi delle unit, le schede contenute nella unit (nel caso ve ne siano) e
mostra i percorsi dei file nel progetto. Bench sia possibile modificare direttamente la
maggior parte di questi file, spesso pi semplice e affidabile utilizzare gli strumenti
visuali di C++Builder.
In cima alla gerarchia del progetto, vi un file di gruppo. possibile combinare pi
progetti in un gruppo di progetti.Ci permette di aprire nel Project Manager pi di
un progetto per volta. I gruppi di progetti permettono organizzare e operare su
progetti correlati, come le applicazioni che funzione in combinazione fra di loro o che
fanno parte di unapplicazione multi-tier. Se si lavora su un solo progetto, per creare
unapplicazione non necessario un file di gruppo di progetti.
I file di progetto, che descrivono i singoli progetti, i file e le opzioni associate, hanno
lestensione .bpr. I file di progetto contengono indicazioni per la generazione di
unapplicazione o di un oggetto condiviso. Quando si aggiungono e rimuovono file
utilizzando il Project Manager, il file di progetto viene aggiornato. Le opzioni di
progetto vengono specificate utilizzando una finestra di dialogo, Project Options,
contenente varie pagine per i diversi aspetti del progetto come le schede,
lapplicazione o il compilatore. Queste opzioni di progetto vengono memorizzate nel
file di progetto assieme al progetto.
Le unit e le schede sono i componenti di base di unapplicazione in C++Builder. Un
progetto pu condividere tutti i file form e unit esistenti, inclusi quelli che risiedono
esternamente allalbero delle directory di progetto. Questo include le procedure e le
funzioni custom che sono state scritte come routine indipendenti.
Se si aggiunge a un progetto un file condiviso, bene rendersi conto che il file non
viene copiato nella directory del progetto corrente; rimane nella sua ubicazione
attuale. Laggiunta al progetto corrente di un file condiviso registra il nome del file e
il percorso nel file di progetto. C++Builder gestisce automaticamente questa
operazione non appena si aggiungono delle unit a un progetto.
Quando si compila un progetto, non importate la posizione in cui risiedono i file
che compongono il progetto. Il compilatore tratta i file condivisi esattamente come
quelli creati dal progetto stesso.
2-4 G u i d a a l l a p r o g r a mma z i o n e
E d i t i n g d e l c o d i c e
Editing del codice
Il Code editor di C++Builder un editor ASCII completo di ogni funzione. Se si
utilizza lambiente di programmazione visuale, viene visualizzata automaticamente
una scheda come parte di un nuovo progetto. possibile cominciare a progettare
linterfaccia dellapplicazione collocando oggetti sulla scheda e modificandone il
funzionamento con lObject Inspector. Altre attivit di programmazione, invece,
come la scrittura dei gestori di evento degli oggetti, devono essere fatte immettendo
il codice.
I contenuti della scheda, tutte le sue propriet, i suoi componenti e le rispettive
propriet possono essere visualizzati e modificati sotto forma di testo nel Code
Editor. Nel Code Editor possibile adattare il codice generato e aggiungervi altri
componenti dallinterno delleditor scrivendo il codice opportuno. Man mano che si
scrive il codice nelleditor, il compilatore scandisce costantemente ogni modifica e
aggiorna la scheda con il nuovo layout. possibile quindi ritornare alla scheda,
visualizzarla e verificare le modifiche apportate nelleditor, e quindi continuarne la
messa a punto.
I sistemi di generazione del codice e di esposizione delle propriet di C++Builder
possono essere ispezionati completamente. Il codice sorgente per tutto ci che
incluso nel file eseguibile finalevale a dire tutti gli oggetti VCL, tutti gli oggetti
CLX, i sorgenti RTL e tutti i file di progetto-possono essere visualizzati e modificati
nel Code editor.
Compilazione di applicazioni
Una volta terminata la progettazione sulla scheda dellinterfaccia dellapplicazione e
la scrittura di tutto il codice aggiuntivo, in modo che lapplicazione faccia ci che ci si
era prefissi, possibile compilare il progetto dallIDE o dalla riga comandi.
Tutti i progetti hanno come destinazione un singolo file eseguibile distribuibile.
possibile visualizzare o provare lapplicazione a diversi stadi dello sviluppo
compilandola, rigenerandola o mandandola in esecuzione:
Quando si compila, vengono ricompilate solo le unit che sono state modificate
rispetto allultima compilazione.
Quando si rigenera lapplicazione, vengono ricompilate tutte le unit nel progetto,
indipendentemente dal fatto che siano state modificate o meno rispetto allultima
compilazione. importante utilizzare il comando Build anche quando si sono
modificate le direttive globali del compilatore, in modo da accertarsi che tutto il
codice venga compilato in base alle impostazioni appropriate. importante anche
eseguire la rigenerazione del progetto una volta modificate tutte le direttive
globali del compilatore per accertarsi che tutto il codice venga compilato nello
stato opportuno. anche possibile verificare la validit del codice sorgente senza
tentare di compilare il progetto.
S v i l u p p o d i a p p l i c a z i o n i c o n C + + B u i l d e r 2-5
D e b u g d i a p p l i c a z i o n i
Quando si esegue lapplicazione, lapplicazione viene compilata e quindi eseguita.
Se si modificato il codice sorgente rispetto allultima compilazione, il
compilatore ricompila i moduli modificati e ne riesegue il link allapplicazione.
Nel caso si siano raggruppati pi progetti, possibile compilare o rigenerare in una
sola volta tutti i progetti in un singolo gruppo di progetti. Dopo aver selezionato nel
Project Manager il gruppo di progetti, scegliere il comando Project|Compile All
Projects o Project|Build All Projects.
Non ancora disponibile unapplicazione C++ per Linux per compilare
unapplicazione CLX in Linux, ma possibile cominciare a sviluppare da ora le
proprie applicazioni con C++Builder.
Debug di applicazioni
C++Builder fornisce un debugger integrato che consente di trovare e di correggere
gli errori presenti nelle applicazioni. Il debugger integrato permette di controllare
lesecuzione del programma, di tenere sotto controllo i valori delle variabili e gli
elementi delle strutture di dati, oltre che di modificare i valori dei dati durante la fase
di debug.
Il debugger integrato pu tracciare sia gli errori di esecuzione sia gli errori di logica.
Eseguendo il programma fino a determinati punti ed esaminando i valori delle
variabili, le funzioni nello stack delle chiamate e loutput del programma, possibile
controllare il comportamento del programma e trovare le aree in cui il
comportamento non quello progettato. Il debugger descritto nella Guida in linea.
anche possibile usare la gestione delle eccezioni per riconoscere, individuare e
trattare gli errori. In C++Builder le eccezioni sono classi, identiche alle altre classi di
C++Builder, tranne per il fatto che, per convenzione, il loro nome inizia con una E
invece che con una T. Per maggiori informazioni sulla gestione delle eccezioni,
consultare il Capitolo 12, Gestione delle eccezioni.
Distribuzione di applicazioni
C++Builder include strumenti aggiuntivi che consentono la distribuzione delle
applicazioni. Ad esempio, InstallShield Express (non disponibile in tutte le edizioni)
aiuta a creare un package per linstallazione dellapplicazione, che include tutti i file
necessari per lesecuzione di unapplicazione distribuita. disponibile anche il
software TeamSource (non disponibile in tutte le edizioni) per tenere traccia degli
aggiornamenti apportati alle applicazioni.
_
Non tutte le edizioni di C++Builder consentono la distribuzione di applicazioni.
Non ancora disponibile unapplicazione C++ per Linux per distribuire
unapplicazione CLX in Linux, ma possibile cominciare a sviluppare da ora le
proprie applicazioni con C++Builder.
2-6 G u i d a a l l a p r o g r a mma z i o n e
D i s t r i b u z i o n e d i a p p l i c a z i o n i
Per informazioni specifiche sulla distribuzione, consultare il Capitolo 17,
Distribuzione di applicazioni,.
U s o d e l l e l i b r e r i e d i c l a s s i 3-1
C a p i t o l o
3
Capitolo3Uso delle librerie di classi
Questo capitolo presenta una panoramica delle librerie di componenti e presenta
alcuni oggetti che possibile utilizzare durante lo sviluppo di applicazioni.
C++Builder include sia la Visual Component Library (VCL) che la Borland
Component Library for Cross-Platform (CLX). La VCL per lo sviluppo in Windows
e la CLX per lo sviluppo multipiattaforma in Windows e in Linux. Sono due librerie
di classi diverse ma hanno molte somiglianze.
Le librerie di classi
VCL e CLX sono librerie di classi composte da oggetti che si utilizzano durante lo
sviluppo di applicazioni. Le librerie sono fra loro simili e contengono entrambe quasi
tutti gli stessi oggetti. Alcuni oggetti nella VCL implementano funzioni che sono
disponibili solo in Windows, come gli oggetti che vengono visualizzati sulle pagine
ADO, BDE, QReport, COM+ e Server della Component palette. Potenzialmente tutti
gli oggetti CLX sono disponibili sia in Windows che in Linux.
Tutti gli oggetti della VCL e della CLX discendono da TObject, una classe astratta i cui
metodi ne definiscono il comportamento di base come la costruzione, la distruzione e
la gestione dei messaggi. Quando si scrivono personalmente delle classi, dovrebbero
discendere da TObject incluso nella libreria di classi che si intende utilizzare.
I componenti sono un sottoinsieme della VCL o della CLX e discendono dalla classe
astratta TComponent. I componenti sono oggetti che possono essere collocati su una
scheda o in un modulo dati e trattare in fase di progettazione. La maggior parte dei
componenti sono visuali o non visuali, a seconda del fatto che siano visibili o meno in
esecuzione. Alcuni componenti vengono visualizzati nella Component palette.
I componenti visuali, come TForm e TSpeedButton, sono detti controlli e discendono
da TControl. TControl fornisce le propriet che specificano gli attributi visuali dei
controlli, come la loro altezza e ampiezza.
3-2 G u i d a a l l a p r o g r a mma z i o n e
L e l i b r e r i e d i c l a s s i
I componenti non visuali vengono usati per una vasta gamma di compiti. Ad
esempio, se si sta scrivendo unapplicazione che si connete a un database, possibile
collocare sulla scheda un componente TDataSource per collegarsi a un controllo e un
componente dataset usato dal controllo. Questa connessione non visibile allutente,
pertanto TDataSource non visuale. In progettazione, i componenti non visuali
vengono rappresentati da unicona. Ci consente di manipolarne le propriet e gli
eventi esattamente come se si trattasse di un controllo visuale.
Durante la programmazione, possibile accedere alla Guida in linea che contiene la
documentazione di riferimento molto dettagliata su tutti gli oggetti della VCL e della
CLX. Dallinterno del Code editor, collocare il cursore sulloggetto e premere F1 per
visualizzare la Guida sui componenti della topic . Gli oggetti, le propriet, i metodi e
gli eventi che sono inclusi nella VCL sono contrassegnati come VCL Reference,
mentre quelli inclusi nella CLX come CLX Reference.
Propriet, metodi ed eventi
Sia la VCL che la CLX sono gerarchie di oggetti legate allIDE di Delphi, in cui
possibile sviluppare rapidamente applicazioni. Gli ogggetti in entrambe le librerie di
componenti si basano su propriet, metodi ed eventi. Ogni oggetto include i membri
dati (le propriet), le funzioni che operano sui dati (i metodi) e un modo per
interagire con gli utenti della classe (gli eventi). La VCL e la CLX sono scritte in
Object Pascal, anche se la VCL si basa sulle API di Windows API e la CLX si basa
sulla libreria di widget Qt.
Propriet
Le propriet sono le caratteristiche di un oggetto che influiscono o sul comportamento
visibile o sulle operazioni delloggetto. Ad esempio, la propriet Visible determina se
un oggetto pu essere visualizzato o meno nellinterfaccia dellapplicazione.
Propriet ben progettate consentono di semplificare lutilizzo del componente da
parte di altri programmatori e la manutenzione da parte di chi lha progettato.
Di seguito sono riportare alcune utili caratteristiche delle propriet:
A differenza dei metodi, che sono disponibili solo in esecuzione, possibile vedere
e modificare le propriet nellIDE in fase di progettazione e ottenere un immediato
riscontro visivo dei cambiamenti apportati.
possibile accedere alle propriet tramite lObject Inspector, che consente di
modificare visivamente i valori delloggetto. Limpostazione delle propriet in
fase di progettazione pi semplice della scrittura del codice e rende il codice pi
semplice da gestire.
Poich i dati sono incapsulati, risultano protetti e privati allinterno delloggetto.
Le chiamate volte a ottenere e a impostare i valori sono metodi, rendendo pertanto
invisibili allutente delloggetto particolari elaborazioni. Ad esempio, i dati
potrebbero risiedere in una tabella, ma potrebbero apparire al programmatore
come normali membri dati.
U s o d e l l e l i b r e r i e d i c l a s s i 3-3
L e l i b r e r i e d i c l a s s i
possibile implementare la logica che innesca eventi o modifica altri dati durante
laccesso alla propriet. Ad esempio, la modifica del valore di una propriet
potrebbe richiedere la modifica di unaltra. possibile modificare i metodi creati
per la propriet.
Le propriet possono essere virtuali.
Una propriet non limitata a un singolo oggetto. La modifica di una propriet di
un oggetto potrebbe ripercuotersi su numerosi oggetti. Ad esempio,
limpostazione della propriet Checked su un pulsante di opzione influenza tutti i
pulsanti di opzione nel gruppo.
Metodi
Un metodo una funzione che memebro di una classe. I metodi definiscono il
comportamento di un oggetto. I metodi di classe possono accedere a tutte le
propriet pubbliche, protette e private e ai membri dati della classe e sono
comunemente menzionati come funzioni membro. Consulatre Controllo
dellaccesso a pagina 46-4.
Eventi
Un evento unazione o un accadimento rilevato da un programma. Molte
applicazioni moderne vengono definite event-driven, perch sono progettate per
rispondere agli eventi. In un programma, il programmatore non ha alcun modo di
prevedere la sequenza esatta di azioni che sar eseguita dallutente. Lutente ad
esempio potr scegliere una voce di menu, fare clic su un pulsante o selezionare del
testo. Il programmatore potr scrivere il codice per gestire gli eventi che ritiene
importanti, invece di scrivere del codice che sar eseguito sempre secondo lo stesso
ordine limitato.
Indipendentemente da come stato chiamato levento, C++Builder cerca di
individuare se stato predisposto un qualsiasi codice per gestire quel determinato
evento. Nel caso sia stato predisposto, quel codice viene eseguito; altrimenti, ha
luogo il comportamento predefinito di gestione dellevento.
I tipi di eventi che possono verificarsi possono essere suddivisi in due categorie
principali:
Eventi utente
Eventi di sistema
Eventi utente
Gli eventi utente sono azioni che vengono iniziate dallutente. Esempi di eventi
utente sono OnClick (lutente ha fatto clic col mouse), OnKeyPress (lutente ha
premuto un tasto sulla tastiera), e OnDblClick (lutente ha fatto doppio clic su un
pulsante del mouse).
Eventi di sistema
Gli eventi di sistema sono eventi generati automaticamente dal sistema operativo. Ad
esempio, levento OnTimer (il componente TTimer genera uno di questi eventi ogni
3-4 G u i d a a l l a p r o g r a mma z i o n e
O g g e t t i , c o m p o n e n t i e c o n t r o l l i
volta che trascorso un intervallo temporale predefinito), levento OnCreate (il
componente sta per essere creato), levento OnPaint (un componente o una window
devono essere ridisegnati), e cos via. Di solito, gli eventi di sistema non vengono
avviati direttamente da unazione dellutente.
Oggetti, componenti e controlli
La Figura 3.1 mostra in modo molto semplificato la gerarchia dellereditariet che
illustra le relazioni esistenti tra oggetti, componenti e controlli.
Figura 3.1 Oggetti, componenti e controlli
Ogni oggetto eredita da TObject, e molti oggetti ereditano da TComponent. I controlli,
che ereditano da TControl, hanno la capacit di visualizzare s stessi in fase di
esecuzione. Un controllo come TCheckBox eredita tutta le funzionalit di TObject, di
TComponent e di TControl e aggiunge proprie capacit specializzate.
La Figura 3.2 una panoramica della Visual Component Library (VCL) che mostra i
rami principali dellalbero dellereditariet. A questo livello, la Borland Component
Library for Cross-Platform (CLX) molto simile, ma TWinControl sostituito da
TWidgetControl.
TForm TButton TCheckBox TListBox
TObject
TComponent
TControl
U s o d e l l e l i b r e r i e d i c l a s s i 3-5
O g g e t t i , c o m p o n e n t i e c o n t r o l l i
Figura 3.2 Un diagramma semplificato della gerarchia
Nella figura vengono visualizzate diverse importanti classi base che sono descritte
nella tabella seguente:
Le prossime sezioni presentano una descrizione generale dei tipi di classi conytenuti
in ogni ramo. Per una panoramica completa della gerarchia degli oggetti della VCL e
della CLX, fare riferimento ai diagramma VCL Object Hierarchy e CLX Object
Hierarchy inclusi nel prodotto.
Tabella 3.1 Classi di base importanti
Classe Descrizione
TObject Indica la classe di base e lantenato pi remoto di tutto ci che incluso nella
VCL o nella CLX. TObject incapsula il comportamento fondamentale comune
a tutti gli oggetti della VCL/CLX introducendo i metodi che eseguono le
funzioni di base come la creazione, la gestione e la distruzione di unistanza
di un oggetto.
Exception Specifica la classe di base di tutte le classi correlate alle eccezioni. La classe
Exception fornisce uninterfaccia coerente per le condizioni di errore e
permette alle applicazioni di gestire le condizioni di errore in modo elegante.
TPersistent Specifica la classe di base per tutti gli oggetti che implementano propriet. Le
classi sotto TPersistent si occupano dellinvio di dati agli stream e permettono
lassegnazione di classi.
TComponent Specifica la classe di base per tutti i componenti non visuali come
TApplication. TComponent lantenato comune di tutti i componenti. Questa
classe permette a un componente di essere visualizzato sulla Component
palette, consente a un componente di possedere altri componenti, e consente
di trattare il componente direttamente su una scheda.
TControl Rappresenta la classe di base per tutti i controlli visibili in fase di esecuzione.
TControl lantenato comune di tutti i componenti visuali e fornisce ai
controlli propriet standard come posizione e cursore. Questa classe fornisce
anche gli eventi che rispondono alle azioni del mouse.
TWinControl Specifica la classe di base di tutti gli oggetti dellinterfaccia utente. I controlli
sotto TWinControl sono controlli basati su finestre in grado di catturare
linput da tastiera. In CLX, questi vengono chiamati widget, e TWidgetControl
sostituisce TWinControl.
TObject
TGraphicControl
Exception
TComponent TControl TWinControl TPersistent
[Objects]
[Objects]
[Objects]
[Objects] [Objects] [Objects]
3-6 G u i d a a l l a p r o g r a mma z i o n e
O g g e t t i , c o m p o n e n t i e c o n t r o l l i
Il ramo TObject
Il ramo TObject include tutti gli oggetti VCL e CLX che discendono da TObject ma
non da TPersistent. Molte potenti capacit degli oggetti della VCL e della CLX
derivano dai metodi introdotti da TObject. TObject incapsula il comportamento di
base comune a tutti gli oggetti della VCL e della CLX, introducendo metodi che
forniscono:
La capacit di rispondere quando gli oggetti vengono creati o distrutti.
Tipo della classe e informazioni sullistanza relativamente a un oggetto, e
informazioni di tipo in esecuzione (RTTI) relativamente alle propriet rese
pubbliche.
Supporto per la gestione di messaggi (VCL) oppure per gli eventi di sistema
(CLX).
TObject lantenato diretto di molte classi semplici. Le classi allinterno del ramo
TObject hanno unimportante caratteristica comune: sono transitorie. Ci significa
che queste classi non hanno un metodo per salvare lo stato in cui sono prima di
essere distrutte, vale a dire che non sono persistenti.
Uno dei gruppi principali delle classi in questo ramo la classe Exception. Questa
classe fornisce una vasta serie di classi di eccezioni predefinite per gestire
automaticamente errori di divisione per zero, errori di I/O su file, conversioni di tipo
non valide e molte altre condizioni di eccezione.
Un altro tipo di classe nel ramo TObject sono le classi che incapsulano strutture dati,
come:
TBits, una classe che memorizza un array di valori booleani.
TList, una classe di lista collegata.
TStack, una classe che mantiene un array di puntatori di tipo last-in-first-out.
TQueue, una classe che mantiene un array di puntatori di tipo first-in first-out.
Nella VCL possibile anche trovare dei wrapper per oggetti esterni come TPrinter,
che incapsula linterfaccia per la stampante Windows e TRegistry, un wrapper a basso
livello per il file di registro di sistema e per le funzioni che operano sul file di registro.
Queste sono specifiche per lambiente Windows.
TStream un buon esempio di un altro tipo di classi in questo ramo. TStream il tipo
di classe base per oggetti stream che sono in grado di leggere o scrivere su vari tipi di
supporto, come file su disco, memoria dinamica, e cos via.
Pertanto, questo ramo include molti tipi di classi differenti che risultano molto utili
agli sviluppatori.
Il ramo TPersistent
Il ramo TPersistent include tutti gli oggetti VCL e CLX che discendono da TPersistent
ma non da TComponent. La persistenza determina che cosa viene salvato con un file
form o con un modulo dati e che cosa viene caricato nella scheda o nel modulo dati
quando li si ricupera dalla memoria.
U s o d e l l e l i b r e r i e d i c l a s s i 3-7
O g g e t t i , c o m p o n e n t i e c o n t r o l l i
Gli oggetti in questo ramo implementano le propriet per i componenti. Le propriet
vengono caricate e salvate con una scheda solo se hanno un possessore. Il possessore
deve essere qualche componente. Questo ramo introduce la funzione GetOwner che
permette di determinare il possessore della propriet.
Gli oggetti in questo ramo sono anche i primi a includere una sezione published in
cui possibile caricare e salvare automaticamente le propriet. Il metodo
DefineProperties permette anche di indicare come caricare e salvare le propriet.
Di seguito sono elencate alcune altre classi incluse nel ramo TPersistent della
gerarchia:
TGraphicsObject, una classe base astratta per oggetti grafici, come TBrush, TFont, e
TPen.
TGraphic, una classe base astratta per oggetti come TBitmap e TIcon ,in grado di
memorizzare e visualizzare immagini.
TStrings, una classe base per oggetti che rappresentano un elenco di stringhe.
TClipboard, una classe in grado di contenere testo o immagini grafiche tagliate o
copiate da unapplicazione.
TCollection, TOwnedCollection, e TCollectionItem, classi che contengono raccolte
indicizzate di elementi definiti in modo particolare.
Il ramo TComponent
Il ramo TComponent contiene oggetti che scendono da TComponent ma non da
TControl. Gli oggetti in questo ramo sono componenti che possibile manipolare
sulle schede in fase di progettazione. Essi sono oggetti persistenti che possono fare
quanto segue:
Essere visualizzati sulla Component palette e modificati nel Form designer.
Possedere e gestire altri componenti.
Caricare e salvare se stessi.
Diversi metodi in TComponent regolano il comportamento dei componenti in fase di
progettazione e quali informazioni vengono salvate con il componente. In questo
ramo della CLX viene introdotto il concetto di stream. C gestisce automaticamente la
maggior parte delle operazioni che coinvolgono gli stream. Le propriet sono
persistenti se sono state rese pubbliche e le propriet rese pubbliche sono
automaticamente soggette allo stream.
La classe TComponent introduce anche il concetto di possesso che propagato in tutta
la VCL e la CLX. Due propriet supportano il possesso: Owner e Components. Ogni
componente ha una propriet Owner che fa riferimento a un altro componente come
possessore. Un componente pu possedere altri componenti. In questo caso, tutti i
componenti posseduti sono referenziati nella propriet Array del componente.
Il costruttore di un componente richiede un singolo parametro che utilizzato per
specificare il possessore del nuovo componente. Se il possessore che viene passato
esiste, il nuovo componente viene aggiunto alla lista Components del possessore. Oltre
allutilizzo della lista Components per referenziare i componenti posseduti, questa
propriet consente anche la distruzione automatica dei componenti posseduti. Finch
3-8 G u i d a a l l a p r o g r a mma z i o n e
O g g e t t i , c o m p o n e n t i e c o n t r o l l i
il componente ha un possessore, sar distrutto al momento della distruzione del
possessore. Ad esempio, poich TForm un discendente di TComponent, quando si
distrugger la scheda saranno distrutti tutti i componenti posseduti dalla scheda e la
memoria allocata sar liberata. In questo caso si parte dallassunto che tutti i
componenti sulla scheda siano in grado di far pulizia di s stessi correttamente nel
momento in cui vengono chiamati i rispettivi distruttori.
Se un tipo di propriet un TComponent o un discendente, il sistema di streaming
crea unistanza di quel tipo al momento della sua lettura. Se un tipo di propriet
TPersistent ma non TComponent, il sistema di streaming utilizza listanza esistente
disponibile attraverso la propriet e legge i valori delle propriet di quellistanza.
Quando si crea un file form (un file utilizzato per memorizzare le informazioni
relative ai componenti sulla scheda), il Form designer analizza ciclicamente la sua
matrice di componenti e salva tutti i componenti sulla scheda. Ogni componente sa
come scrivere nello stream (in questo caso, un file di testo) le propriet che sono state
modificate. Al contrario, quando si caricano le propriet dei componenti nel file di
scheda, il Form designer analizza ciclicamente la sua matrice di componenti e carica
ogni componente.
I tipi di classi che troverai in questo ramo includono:
TActionList, una classe che conserva un elenco di azioni utilizzate con componenti
e controlli, come elementi di menu e pulsanti.
TMainMenu, una classe che fornisce alle schede una barra di menu e i relativi
menu a discesa.
TOpenDialog, TSaveDialog, TFontDialog, TFindDialog, TColorDialog e cos via, sono
classi che rendono disponibili le finestre di dialogo utilizzate pi di frequente.
TScreen, una classe che tiene traccia di quali schede e moduli dati sono stati
istanziati dallapplicazione, qual scheda attiva, qual il controllo attivo
allinterno di quella scheda, le dimensioni e la risoluzione dello schermo, e i
cursori e i font disponibile utilizzabili dallapplicazione.
Componenti che non hanno bisogno di uninterfaccia visuale possono essere derivati
direttamente da TComponent. Per creare uno strumento come un dispositivo TTimer,
possibile derivarlo da TComponent. Questo tipo di componente risiede nella
Component palette, ma esegue funzioni interne a cui si accede mediante codice e non
viene visualizzato nellinterfaccia utente in fase di esecuzione.
Nella CLX, il ramo TComponent include anche THandleComponent. Questa la classe
di base per i componenti non visuali che richiedono un handle per un oggetto Qt
sottostante, come le finestre di dialogo e i menu.
Per i dettagli sullimpostazione delle propriet, sulla chiamata ai metodi e sulle
operazioni con gli eventi dei componenti, consultare il Capitolo 5, Operazioni con
componenti.
Il ramo TControl
Il ramo TControl formato da componenti che discendono da TControl ma non da
TWinControl (TWidgetControl nella CLX). Gli oggetti in questo ramo sono controlli
che sono oggetti visuali che lutente dllapplicazione pu vedere e manipolare in
U s o d e l l e l i b r e r i e d i c l a s s i 3-9
O g g e t t i , c o m p o n e n t i e c o n t r o l l i
esecuzione. Tutti i controlli hanno propriet, metodi ed eventi in comune che sono
correlati allaspetto del controllo, come la posizione, il cursore associato alla finestra
del controllo (al widget nella CLX), i metodi per colorare o spostare il controllo e gli
eventi per rispondere alle azioni del mouse. I controlli non possono mai ricevere
linput da tastiera.
Mentre TComponent definisce il comportamento di tutti i componenti, TControl
definisce il comportamento per tutti i controlli visuali. Ci comprende le routine di
disegno, gli eventi standard e le relazioni contenuto-contenitore.
Tutti i controlli visuali condividono alcune propriet. Bench queste propriet siano
ereditate da TControl, esse vengo rese pubbliche, e appaiono pertanto nellObject
Inspector, solo per quei componenti per cui sono applicabili. Ad esempio, il
componente TImage non pubblica la propriet Color, poich il suo colore
determinato dallimmagine grafica visualizzata.
Ci sono due tipi di controlli:
Quelli che hanno una propria finestra (o un widget.
Quelli che utilizzano la finestra (o il widget) del proprio genitore.
I controlli che hanno una propria finestra sono detti controlli con finestra (VCL) o
controlli basati su widget (CLX) e discendono da TWinControl (TWidgetControl in
CLX). I pulsanti e le caselle di controllo rientrano in questa categoria.
I controlli che utilizzano la finestra (o il widget) del genitore sono definiti controlli
grafici e discendono da TGraphicControl. I controlli immagine ed etichetta rientrano
in questa categoria. I controlli grafici non posseggono un handle e non possono
ricevere il fuoco. Poich un controllo grafico non necessita di un handle, utilizza
meno risorse di sistema. I controlli grafici devono tracciare s stessi e non possono
essere genitori di altri controlli.
Per informazioni sugli altri controlli grafici, vedere Controlli grafici a pagina 9-19,
e per i dettagli sui diversi tipi di controlli consultare il Capitolo 9, Tipi di controlli.
Per informazioni su come interagire con i controlli in esecuzione, consultare il
Capitolo 6, Uso dei controlli.
Il ramo TWinControl/TWidgetControl
Nella VCL, il ramo TWinControl include tutti i controlli che discendono da
TWinControl. TWinControl la classe di base per tutti i controlli con finestra, che
sono elementi che si utilizzeranno nellinterfaccia utente di unapplicazione. I
controlli con finestra sono wrapper di controlli Windows.
In CLX, TWidgetControl, che sostituisce TWinControl, la classe base per tutti i
controlli widget, che sono wrappers di widget.
I controlli con finestra e i widget:
Possono ricevere il fuoco durante la fase di esecuzione di unapplicazione, il che
significa che possono ricevere linput da tastiera da parte dellutente
dellapplicazione. A confronto, altri controlli possono solo visualizzare dati.
Possono essere genitori di uno o pi controlli figlio.
3-10 G u i d a a l l a p r o g r a mma z i o n e
O g g e t t i , c o m p o n e n t i e c o n t r o l l i
Hanno un handle, o un identificatore univoco.
Il ramo TWinControl/TwidgetControl include sia i controlli che vengono tracciati
automaticamente (inclusi TEdit, TListBox, TComboBox, TPageControl, e cos via) sia i
controlli custom che devono essere tracciati da C++Builder come TDBNavigator,
TMediaPlayer (solo nella VCL), TGauge (solo nella VCL). Di solito i discendenti diretti
di TWinControl/TWidgetControl implementano controlli standard, come i campi di
editing, le caselle combinate, le caselle di riepilogo o i controlli pagina e, pertanto,
sanno gi come tracciarsi.
La classe TCustomControl viene fornita per quei componenti che richiedono un
handle di finestra ma non incapsulano un controllo standard che include la capacit
di tracciarsi. Non necessario preoccuparsi di come i controlli vengono tracciati o di
come rispondono agli eventi. C++Buider incapsula completamente e
automaticamnete questo comportamento.
4-1 G u i d a a l l a p r o g r a mma z i o n e
C a p i t o l o
4
Capitolo4Utilizzo di BaseCLX
Vi sono molte unit comuni sia alla VCL che alla CLX che forniscono il supporto
sottostante per entrambe le librerie di componenti. Collettivamente, queste unit
vengono chiamate BaseCLX. BaseCLX non include nessuno dei componenti
visualizzati sulla Component palette. Include invece moltissime classi e routine
globali che vengono usate dai componenti che vengono visualizzati sulla Component
palette. Queste classi e queste routine sono utilizzabili anche nel codice delle proprie
applicazioni o durante la scrittura delle proprie classi.
_
Le routine globali che compongono la BaseCLX sono anche dette libreria di
esecuzione. Non confondere queste routine con la libreria di esecuzione del C++.
Molte di queste eseguono funzioni simili a quelle nella libreria di esecuzione del
C++, ma possono essere distinte in quanto i nomi delle funzioni iniziano con una
lettera maiuscola e vengono dichiarate nello header di una unit.
Le sezioni seguenti trattano molte classi e routine che compongono BaseCLX e ne
illustrano i possibili utilizzi. Fra questi vi sono:
Uso di stream
Operazioni con i file
Operazioni con i file .ini
Operazioni con le liste
Operazioni con elenchi di stringhe
Operazioni con stringhe
Conversione di misure
Creazione di spazi di disegno
_
Questo elenco di attivit non esaustivo. La libreria di esecuzione in BaseCLX
contiene molte routine in grado di eseguire compiti non citati in questa trattazione.
Fra qyesti vi sono una serie di funzioni matematiche (definite nella unit Math), varie
routine per operare con valori di data/ora (definiti nelle unit SysUtils e DateUtils) e
routine per operare con i Variant di Object Pascal (definite nella unit Variants).
4-2 G u i d a a l l a p r o g r a mma z i o n e
U s o d i s t r e a m
Uso di stream
Gli stream sono classi che permettono di leggere e scrivere dati. Essi forniscono
uninterfaccia comune per la lettura e la scrittura su svariati supporti come memoria,
stringhe, socket e campi BLOB nei database. Esistono numerose classi stream, che
discendono tutte da TStream. Ogni classe stream specifica per un tipo di supporto.
Ad esempio, TMemoryStream legge o scrive su unimmagine in memoria, TFileStream
legge o scrive su un file.
Uso di stream per leggere o scrivere dati
Le classi stream condividono tutte svariati metodi per la lettura e la scrittura di dati.
Questi metodi sono distinguibili per il fatto che compiono quanto segue:
Restituiscono il numero di byte letti o scritti.
Richiedono che sia noto il numero di byte.
Generano uneccezione sullerrore.
Metodi di stream per lettura e scrittura
Il metodo Read legge dallo stream un numero specificato di byte, iniziando dalla sua
posizione corrente (Position), caricandoli in un buffer. La lettura quindi sposta la
posizione corrente del numero di byte effettivamente trasferiti. Il prototipo per Read
vIttaaI Iat __?aatcaII ci.veIi ..c, Iat ,
Read utile quando il numero di byte del file non noto. Read restituisce il numero di
byte effettivamente trasferiti, che pu essere minore di Count se lo stream non
conteneva Count byte di dati precedenti alla posizione corrente.
Write una funzione che scrive Count byte dal buffer nel file associato allo stream,
partendo dalla Position corrente. Il prototipo per Write :
vIttaaI Iat __?aatcaII cceaat veIi ..c, Iat ,
Dopo la scrittura nel file, Write sposta la posizione corrente del numero di byte scritti,
e restituisce il numero di byte effettivamente scritti, che pu essere minore di Count
se incontra la fine del buffer oppure se lo stream non pu accettare pi byte.
Le procedure complementari sono ReadBuffer e WriteBuffer che, a differenza di Read e
Write, non restituiscono il numero di byte letti o scritti. Queste procedure sono utili
nei casi in cui il numero di byte noto e sono necessarie, per esempio, per la lettura
delle strutture. ReadBuffer e WriteBuffer generano uneccezione (EReadError e
EWriteError) se il Count byte non corrisponde esattamente. Ci in contrasto con i
metodi Read e Write, che possono restituire un numero di byte diverso dal valore
chiesto. I prototipi per ReadBuffer e WriteBuffer sono:
vIttaaI Iat __?aatcaII ci...cveIi ..c, Iat ,
vIttaaI Iat __?aatcaII c..cceaat veIi ..c, Iat ,
Questi metodi chiamano i metodi Read e Write, per eseguire una lettura e una
scrittura effettive.
4-3 G u i d a a l l a p r o g r a mma z i o n e
U s o d i s t r e a m
Lettura e scrittura di componenti
TStream definisce metodi specializzati, ReadComponent e WriteComponent, per la
lettura e la scrittura di componenti. possibile utilizzarli nelle applicazioni come un
modo per salvare i componenti e le rispettive propriet quando li si crea o li si
modifica in fase di esecuzione.
ReadComponent e WriteComponent sono i metodi che lIDE utilizza per leggere o
scrivere i componenti nei file scheda. Durante la lettura o la scrittura da o in un file
scheda, le classi stream operano con le classi TFiler, TReader e TWriter, per leggere
oggetti dal file scheda o per scriverli su disco. Per ulteriori informazioni sulluso del
sistema di streaming dei componenti, consultare nella guida di riferimento in linea le
classi TStream, TFiler, TReader, TWriter, e TComponent.
Copia di dati da uno stream a un altro
Quando si copiano dati da uno stream a un altro, non necessario leggere
esplicitamente e poi scrivere i dati. possibile invece utilizzare il metodo CopyFrom,
come illustrato nellesempio seguente.
Lapplicazione include due controlli di testo (From e To) e un pulsante Copy File.
veIi __?aatcaII .,cc.ccc .c.c
__?IaaII,
ieIete sci..,
__?IaaII,
ieIete sci.,
I? ..cx.ciccc
icc>i, .ciccc>.i.c - ' s ' - L..ciccc..c - ' ccs
s.c',
eIae
.sc.ciccc,
_
Nelle applicazioni multipiattaforma, tutti i nomi di percorso scritti direttamente nel
codice vanno sostituiti con il percorso corretto per il sistema, oppure si devono
utilizzare variabili di ambiente per rappresentare tali percorsi (sulla pagina
Environment Variables selezionare il comando Tools| Environment Options.
Cambiamento del nome di un file
Per modificare un nome file, utilizzare la funzione RenameFile:
exteta .~~ beeI __?aatcaII ci.ccceaat ~s. ..i.c, ceaat ~s.
.c..i.c,
RenameFile cambia il nome, identificato da OldFileName, con il nome specificato da
NewFileName. Se loperazione ha successo, RenameFile restituisce true. Se non
possibile rinominare il file, (ad esempio, se un file chiamato NewFileName esiste gi),
RenameFile restituisce false. Ad esempio:
I? ci.cc'.~..','..~..'
.s' ci. .c',
impossibile rinominare (spostare) un file nelle unit usando RenameFile. Prima
bisogna copiare il file e poi cancellare il vecchio.
_
RenameFile nella libreria runtime BaseCLX un wrapper per la funzione MoveFile
delle API di Windows, e pertanto nemmeno MoveFile funzioner sulle varie unit.
Routine per data-ora
Le routine FileAge, FileGetDate e FileSetDate operano sui valori data-ora del sistema
operativo. FileAge restituisce la data e lora di registrazione di un file, o -1 se il file non
esiste. FileSetDate imposta la data e lora di registrazione per un determinato file, e
restituisce zero se lesito positivo, o un codice di errore se lesito negativo.
4-10 G u i d a a l l a p r o g r a mma z i o n e
O p e r a z i o n i c o n f i l e i n i e c o n i l R e g i s t r o d i s i s t e m a
FileGetDate restituisce la data e lora di registrazione per il file specificato o -1 se
lhandle non corretto.
Analogamente a molte altre routine per il trattamento dei file, FileAge utilizza un
nome di file di tipo string. FileGetDate e FileSetDate, tuttavia, utilizzano un parametro
integer che accetta un handle di file. Per ottenere lhandle di file possibile
Utilizzare la funzione FileOpen o FileCreate per creare un nuovo file o aprire un file
esistente. Sia FileOpen che FileCreate restituiscono un handle di file.
Istanziare TFileStream per creare o aprire un file. Quindi utilizzarne la propriet
Handle. Per ulteriori informazioni, vedere Uso degli stream di file a pagina 4-5.
Copia di un file
La libreria runtime non fornisce tutte le routine per copiare un file. Comunque, se si
stanno scrivendo applicazioni per lambiente Windows, per chiamare un file,
possibile chiamare direttamente la funzione API CopyFile di Windows. Come la
maggior parte delle routine della libreria runtime , CopyFile accetta un nome di file
come parametro, e non un handle di file. Quando si copia un file, occorre fare
attenzione che nel nuovo file vengano copiati gli attributi del file esistente, ma non
quelli relativi alla sicurezza. CopyFile utile anche nello spostamento dei file nelle
unit, perch n la funzione RenameFile n la funzione API MoveFile possono
rinominare oppure spostare i file nelle unit. Per ulteriori informazioni, consultare la
Guida in linea di Microsoft Windows.
Operazioni con file ini e con il Registro di sistema
Molte applicazioni utilizzano i file ini per memorizzare le informazioni di
configurazione. BaseCLX include due classi per le operazioni con i file ini: TIniFile e
TMemIniFile. Lutilizzo dei file ini ha il vantaggio che possono essere utilizzati in
applicazioni multipiattaforma e sono semplici da leggere e da modificare. Per
informazioni su queste classi, vedere Utilizzo di TIniFile e di TMemIniFile a
pagina 4-11 per ulteriori informazioni.
Molte applicazioni Windows sostituiscono lutilizzo di file ini con il Registro di
sistema. Il file di registro di sistema di Windows un database gerarchico che agisce
come uno spazio di memoria centralizzato per informazioni di configurazione . La
VCL include classi per operare con il Registro di sistema. Bench dal punto di vista
tecnico non facciano parte di BaseCLX (poich essi sono disponibili solo in
Windows), due di queste classi, TRegistryIniFile e TRegistry, sono trattati in questa
sezione grazie alla loro somiglianza con le classi usate per operare con i file ini.
TRegistryIniFile utile per applicazioni multipiattaforma, poich condivide un
antenato comune (TCustomIniFile) con le classi che operano con file ini. Se ci si limita
ad utilizzare i metodi dellantenato comune (TCustomIniFile) lapplicazione pu
funzionare su entrambe le applicazioni con pochissimo codice condizionale.
TRegistryIniFile trattato in Utilizzo di TRegistryIniFile a pagina 4-12.
Nel caso di applicazioni che non sono multipiattaforma, possibile utilizzare la
classe TRegistry. Le propriet e i metodi di TRegistry hanno nomi che corrispondono
4-11 G u i d a a l l a p r o g r a mma z i o n e
O p e r a z i o n i c o n f i l e i n i e c o n i l R e g i s t r o d i s i s t e m a
pi direttamente al modo in cui organizzato il Registro di sistema, in quanto non
necessario che siano compatibili con le classi per i file ini. TRegistry trattato in Uso
di TRegistry a pagina 4-12.
Utilizzo di TIniFile e di TMemIniFile
Il formato dei file ini ancora molto diffuso, e molti file di configurazione (come il
file DSK delle impostazioni del Desktop) sono in questo formato. Questo formato
particolarmente utile in applicazioni multipiattaforma, in cui impossibile fare
affidamento su un Registro di sistema per la memorizzazione delle informazioni di
configurazione. BaseCLX fornisce due classi, TIniFile e TMemIniFile, per semplificare
le operazioni di lettura e di scrittura con i file ini.
In Linux, TMemIniFile e TIniFile sono identiche. Su Windows, TIniFile opera
direttamente sul file ini su disco mentre TMemIniFile registra tutte le modifiche in
memoria e non le scrive sul disco finch non si chiama il metodo UpdateFile.
Quando si crea unistanza delloggetto TIniFile oppure TMemIniFile , si passa al
costruttore il nome del file INI come parametro. Se il file non esiste, viene creato
automaticamente. Sar quindi possibile leggere i valori utilizzando metodi di lettura
come ReadString,ReadDate ReadInteger o ReadBool. In alternativa, se si desidera leggere
unintera sezione del file ini, possibile utilizzare il metodo ReadSection.
Analogamente, possibile scrivere valori utilizzando metodi come WriteBool,
WriteInteger, o WriteString.
Di seguito riportato un esempio di lettura da un file ini delle informazioni di
configurazione nel costruttore di una scheda e di scrittura dei valori nel gestore di
evento OnClose.
__?aatcaII ...,c .c ..c
Lc ,
aev Lc iccx ~,,ci>xc.i.c, 'L.L' ,
, >ci.Lcc '.', ',', ,
c. >ci.Lcc '.', 'c.', ,
i, >ci.. '.', 'i,',
'c.i i,' ,
>ci. '.', 'L.ix', ?aIae
...ic .s.ix..c.
...ic .s..i,
ieIete ,
Lc ,
aev Lciccx ~,,ci>xc.i.c, 'L.L' ,
>cLcc '.', ',', , ,
>cLcc '.', 'c.', c. ,
>c. '.', 'i,', i, ,
>c '.', 'L.ix',
...ic .s.ix..c. ,
4-12 G u i d a a l l a p r o g r a mma z i o n e
O p e r a z i o n i c o n f i l e i n i e c o n i l R e g i s t r o d i s i s t e m a
ieIete ,
Ognuna delle routine Read accetta tre parametri. Il primo parametro identifica la
sezione del file ini. Il secondo parametro identifica il valore che si desidera leggere e
il terzo un valore predefinito nel caso la sezione o il valore non esista nel file ini.
Esattamente come i metodi Read gestiscono le situazioni in cui una sezione o un
valore non esistono, le routine Write creano la sezione e/o il valore nel caso esse non
esistano. La prima volta che viene eseguito, il codice di esempio crea un file INI
simile al seguente:
,.
,
c..
i,c.i i,
L.ix
Alle successive esecuzioni dellapplicazione, i valori del file ini saranno letti al
momento della creazione della scheda, e riscritti nel file nellevento OnClose.
Utilizzo di TRegistryIniFile
La maggior parte delle applicazioni a 32-bit memorizzano le proprie informazioni nel
file di registro invece che nel file ini poich il file di registro gerarchico e non
soggetto ai limiti sulle dimensione dei file ini. Se si abituati ad utilizzare i file ini e si
vogliono spostare invece le informazioni di configurazione nel file di registro,
possibile utilizzare la classe TRegistryIniFile. Si potrebbe anche volere utilizzare
TRegistryIniFile in applicazioni multipiattaforma nel caso si voglia utilizzare il
Registro di sistema in Windows e un file ini in Linux. possibile scrivere la maggior
parte dellapplicazione in modo che utilizzi il tipo TCustomIniFile. necessario solo
condizionare il codice che crea unistanza di TRegistryIniFile (in Windows) o
TMemIniFile (in Linux) e assegnarla al TCustomIniFile utilizzato dallapplicazione.
TRegistryIniFile progettata per far s che le voci del file di registro assomiglino alle
voci del file INI. Tutti i metodi di TIniFile e di TMemIniFile (lettura e scrittura)
esistono in TRegistryIniFile.
Quando si costruisce un oggetto TRegistryIniFile , il parametro che si passa (il nome
file per un oggetto IniFile oppure un oggetto TmemIniFile) diventa un valore di
chiave nelle chiavi utente nel file di registro e tutte le sezioni e i valori dipendono da
quella radice. Tutte le sezioni e i valori sono ramificazioni di quella radice.
TRegistryIniFile semplifica notevolmente linterfaccia del file di registro, tanto che lo
si utilizzer al posto del componente di TRegistry, anche se non si sta convertendo del
codice esistente o scrivendo unapplicazione cross-platform.
Uso di TRegistry
Se si sta scrivendo unapplicazione solamente per Windows e la struttura del
Registro di sistema familiare, possibile utilizzare TRegistry. A differenza di
TRegistryIniFile, che utilizza le stesse propriet e metodi degli altri componenti per
file ini, le propriet e i metodi di TRegistry corrispondono pi direttamente alla
struttura del Registro di sistema. Ad esempio, TRegistry permette di specificare sia la
U t i l i z z o d i B a s e C L X 4-13
O p e r a z i o n i c o n l e l i s t e
chiave radice che la sottochiave, mentre TRegistry assume HKEY_CURRENT_USER
come chiave radice. Oltre ai metodi per aprire, chiudere, salvare, spostare, copiare e
cancellare chiavi, TRegistry permette di specificare il livello di accesso che si desidera
utilizzare.
_
TRegistry non utilizzabile per programmi multipiattaforma.
Lesempio seguente recupera un valore da una voce del file di registro:
-c.c cs,,>
~s. ccsic~s. c.i.c
~s. .,
cs cs aev cs_~,
tt,
cs>c -_~_.~-L.,
isc cccisc .c . .i ccic . .cs cxs
cs>,ccc.i.c,.isc,
. cs>ci..'~',
__?IaaII,
ieIete cs,
tetata .,
__?IaaII,
ieIete c.,s, .cs c s ccc
4-18 G u i d a a l l a p r o g r a mma z i o n e
O p e r a z i o n i c o n e l e n c h i d i s t r i n g h e
Elenchi di stringhe a lungo termine
Se un elenco di stringhe deve essere disponibile in un qualunque momento durante
lesecuzione dellapplicazione, costruire lelenco allavvio dellapplicazione e
distruggerlo prima che lapplicazione termini.
1 Nel file unit della scheda principale dellapplicazione, aggiungere un campo di
tipo TStrings alla dichiarazione della scheda.
2 Scrivere un costruttore per la scheda principale che viene eseguito prima che la
scheda appaia. Dovrebbe creare un elenco di stringhe e dovrebbe assegnarlo al
campo dichiarato al punto precedente.
3 Scrivere un gestore di evento che liberi lelenco di stringhe nellevento OnClose
della scheda.
Questo esempio utilizza un elenco di stringhe a lungo termine per registrare i clic che
lutente fa con il mouse sulla scheda principale, quindi salva lelenco in un file prima
del termine dellapplicazione.
-c.c c>
-,i.i .s,
-c.c ''
-,i.i ,ic.ics.i_
-,i.i cscc '...'
. .,
__?aatcaII ...,c .c
..c
c.s>.icciccx~,,ci>xc.i.c, '',.ic c s
ieIete c.s,
icc , .,,
c.s>~...i'c. i `., `.',,~~.L. ,i.. i s c s
.c . .c,
cc cc.,.,.>.ic. .,.>.ic-c .,
.>cc,
?et Iat , .c.>cs>, --
.>iis>cx.,. -
.>iis>cx-c.c.>cs>.s,,
.c.>cs>.s,,
.>iis>s> cic.,
.>iis>i.ccc,
.>.c,
tetata ~ic . ,
tetata ~ic - .,
tetata ~ic .,
tetata ~ic - .,
tetata.~ic ic, .,
Il problema che questo approccio richiede dei parametri aggiuntivi per la funzione
di conversione, il che significa che impossibile semplicemente registrare la stessa
funzione per ogni valuta europea. Per evitare di dovere scrivere due nuove funzioni
di conversione per ogni valuta europea, possibile utilizzare le stesse due funzioni
trasformandole in membri di una classe.
Creazione della classe di conversione
La classe deve essere un discendente di TConvTypeFactor. TConvTypeFactor definisce
due metodi, ToCommon e FromCommon, per la conversione in entrambi i sensi delle
unit di misura di base di una famiglia di conversione (in questo caso, da e in Euro).
Come nel caso delle funzioni che si utilizzano direttamente quando si registra
ununit di conversione, questi metodi non hanno alcun parametro aggiuntivo e
pertanto necessario fornire, sotto forma di membri privati della classe di
conversione, il numero di cifre per larrotondamento e il fattore di conversione. Lo si
pu vedere nellesempio EuroConv nella directory demos\ConvertIt (vedere
euroconv.pas):
cIaaa tscL:xtLsxsx:::ox ,cic pabIIc s,cic
ptIvate
U t i l i z z o d i B a s e C L X 4-33
C o n v e r s i o n e d i m i s u r e
.ic .,
pabIIc
__?aatcaII ,cicceaat i. ~i.,
ceaat ~s. ~csc,, ceaat ieabIe ~ic, ceaat .ic ~.,
,cic~i., ~csc,, ~ic,
vIttaaI ieabIe ..ceaat ieabIe ~ic,
vIttaaI ieabIe ...ceaat ieabIe ~ic,
. ~.,
iis>.c> cc,
iis>.c , ,
iis>c , ,
iis>s> cicc,
iis>>.i.c '~i',
iis>cx iis>.c.sx, iis>.c.s,'s s c c. . c c' ,
c,i,
I? .cc. .i . c. c ,cssc.
I? .cc>Lcs.__cIaaaIicsx
~ccc, ttae,
U s o d e i c o n t r o l l i 6-3
I m p l e m e n t a z i o n e d e l d r a g a n d d r o p n e i c o n t r o l l i
Rilascio di elementi
Se un controllo indica che pu accettare un elemento trascinato, necessario gestire
lelemento che viene rilasciato su di esso. Per gestire gli elementi rilasciati, si deve
collegare un gestore allevento OnDragDrop del controllo che accetta lelemento
rilasciato. Come levento drag-over, levento drag-and-drop indica la sorgente
dellelemento trascinato e le coordinate del cursore del mouse sul controllo
accettante. Lultimo parametro consente di monitorare il percorso compiuto da un
oggetto durante il trascinamento; ad esempio, si potrebbe utilizzare questa
informazione per modificare il colore dei componenti, man mano che loggetto passa
sopra di essi.
Nellesempio che segue, una vista ad albero della directory,che accetta elementi
trascinati da una casella di riepilogo di file, risponde spostando i file nella directory
su cui questi vengono rilasciati.
veIi __?aatcaII .ccc.i,ccc .c.c, ccc .cc,
Iat ., Iat
I? .cc>Lcs.__cIaaaIicsx
I? ic
csx>,.ic,
,
6-4 G u i d a a l l a p r o g r a mma z i o n e
I m p l e m e n t a z i o n e d e l d r a g - a n d - d o c k n e i c o n t r o l l i
Personalizzazione delle operazioni di drag-and-drop con un oggetto
drag
Per personalizzare il comportamento drag-and-drop delloggetto possibile usare un
discendente di TDragObject. Per impostazione predefinita, gli eventi drag-over e
drag-and-drop indicano la sorgente dellelemento trascinato e le coordinate del
cursore del mouse sul controllo accettante. Per ottenere altre informazioni dello stato,
derivare da TDragObject o da TDragObjectEx(solo per VCL) un oggetto drag custom e
ridefinirne i metodi virtuali. Creare loggetto drag custom nellevento OnStartDrag.
Di solito, il parametro sorgente degli eventi drag-over e drag-and-drop il controllo
che inizia loperazione di trascinamento. Se unoperazione che coinvolge gli stessi
tipi di dati pu essere iniziata da tipi di controllo differenti, il sorgente deve
supportare ciascun tipo di controllo. Comunque, se si utilizza un discendente di
TDragObject, il sorgente lo stesso oggetto drag; se ogni controllo crea lo stesso tipo
di oggetto drag nel proprio evento OnStartDrag, il controllo di destinazione deve
essere in grado di gestire un solo tipo di oggetto. Gli eventi drag-over e drag-and-
drop possono riferire se il sorgente un oggetto drag, invece del controllo,
chiamando la funzione IsDragObject.
I discendenti di TDragObjectEx (solo per VCL) vengono liberati automaticamente al
contrario dei discendenti di TDragObject. Se si hanno discendenti di TDragObject che
non vengono liberati esplicitamente, possibile modificarli in modo che discendano
invece da TDragObjectEx in modo da evitare perdite di memoria.
Gli oggetti drag consentono di trascinare elementi fra una scheda implementata nel
file EXE principale dellapplicazione e una scheda implementata utilizzando una
DLL, o fra schede implementate utilizzando DLL differenti.
Modifica del puntatore di trascinamento del mouse
Impostando la propriet DragCursor del componente sorgente possibile
personalizzare laspetto del puntatore del mouse durante le operazioni di
trascinamento).
Implementazione del drag-and-dock nei controlli
I discendenti di TWinControl possono agire come posizioni di aggancio e i
discendenti di TControl possono, invece, comportarsi come finestre figlio che
vengono agganciate alle posizioni specificate. Per esempio, per fornire una posizione
di aggancio al margine sinistro di una finestra scheda, si deve allineare un riquadro
al margine sinistro della scheda e renderlo una posizione di aggancio. Quando i
controlli agganciabili vengono trascinati nel riquadro e vengono rilasciati, diventano
controlli figlio del riquadro.
Trasformazione di un controllo con finestra in una posizione di aggancio
Trasformazione di un controllo in un figlio agganciabile
Controllo della modalit di aggancio dei controlli figlio
U s o d e i c o n t r o l l i 6-5
I m p l e m e n t a z i o n e d e l d r a g - a n d - d o c k n e i c o n t r o l l i
Controllo della modalit di sgancio dei controlli figlio
Controllo della modalit di risposta dei controlli figlio alle operazioni drag-and-
dock
_
Le propriet drag-and-dock sono disponibili nella VCL ma non in CLX.
Trasformazione di un controllo con finestra in una posizione di
aggancio
Per rendere un controllo finestra una posizione di aggancio:
1 Impostare la propriet DockSite a true.
2 Se loggetto della posizione di aggancio non deve apparire se non contiene un
client agganciato, impostare la sua propriet AutoSize a true. Quando AutoSize
true, la posizione di aggancio ha come dimensione 0 finch non accetta un
controllo figlio per laggancio. Quindi, viene ridimensionata in modo tra trovare
posto intorno al controllo figlio.
Trasformazione di un controllo in un figlio agganciabile
Per trasformare un controllo in un figlio agganciabile:
1 Impostare la sua propriet DragKind a dkDock. Quando DragKind dkDock, il
trascinamento del controllo lo sposta in una nuova posizione di aggancio o sgancia
il controllo in modo che diventi una finestra mobile. Quando DragKind dkDrag
(impostazione predefinita), il trascinamento del controllo avvia unoperazione
drag-and-drop che deve essere implementata usando gli eventi OnDragOver,
OnEndDrag e OnDragDrop.
2 Impostare la sua propriet DragMode a dmAutomatic. Quando DragMode
dmAutomatic, il trascinamento (per loperazione drag-and-drop o di aggancio, in
funzione di DragKind) viene iniziato automaticamente quando lutente avvia il
trascinamento del controllo con il mouse. Quando DragMode dmManual, ancora
possibile iniziare unoperazione drag-and-dock (o drag-and-drop) chiamando il
metodo BeginDrag.
3 Impostare la sua propriet FloatingDockSiteClass per indicare il discendente
TWinControl che ospiter il controllo quando sar sganciato e lasciato come
finestra mobile. Quando il controllo viene rilasciato in una posizione diversa da
quella di aggancio, viene creato dinamicamente un controllo finestra di questa
classe, che diventa il genitore del figlio agganciabile. Se il controllo del figlio
agganciabile un discendente di TWinControl, non necessario creare una distinta
posizione di aggancio mobile per ospitare il controllo, anche se pu essere
opportuno specificare una scheda per ottenere un bordo e una barra del titolo. Per
omettere una finestra contenitore dinamica, si deve impostare
FloatingDockSiteClass alla stessa classe del controllo; in questo modo diventer una
finestra mobile senza alcun genitore.
6-6 G u i d a a l l a p r o g r a mma z i o n e
I m p l e m e n t a z i o n e d e l d r a g - a n d - d o c k n e i c o n t r o l l i
Controllo della modalit di aggancio dei controlli figlio
Un posizione di aggancio accetta automaticamente i controlli figlio quando vi
vengono rilasciati sopra. Per la maggior parte dei controlli il primo figlio viene
agganciato per riempire larea client, il secondo la divide in due regioni distinte, e
cos via. I controlli pagina agganciano i figli in nuovi fogli di tabulazione (o fondono i
fogli di tabulazione se il figlio un altro controllo pagina).
Tre eventi consentono alle posizioni di aggancio di limitare ulteriormente il modo in
cui vengono agganciati i controlli figlio:
__ptepett, c.cL.c c.cL. teaic.cL., vtItec.cL.,
t,peie? veIi __?aatcaII __cIeaate c.cL.c.sc.ccc .c.c,
c.c, ..scc L.ccccc, ceaat ..s. .sc.s, beeI ic.,
OnGetSiteInfo si verifica nella posizione di aggancio quando lutente trascina un figlio
agganciabile sul controllo. Questo evento consente alla posizione di indicare se
accetter o meno il controllo specificato dal parametro DockClient come figlio, e in
caso di risposta positiva, dove deve essere agganciato il figlio. Quando si verifica
OnGetSiteInfo, InfluenceRect viene inizializzato alle coordinate dello schermo della
posizione di aggancio, e CanDock viene inizializzato a true. Modificando
InfluenceRect, pu essere creata una regione di aggancio pi limitata, mentre il figlio
pu essere rifiutato impostando CanDock a false.
__ptepett, c.cc c.c teaic.c, vtItec.c,
t,peie? veIi __?aatcaII __cIeaate c.cc.sc.ccc .c.c,
ic.ccc .cc, Iat ., Iat , i.ic .ic, beeI ~ccc,,
OnDockOver si verifica nella posizione di aggancio quando lutente trascina sul
controllo un figlio agganciabile. Corrisponde allevento OnDragOver in una normale
operazione drag-and-drop. Deve essere utilizzato per segnalare che il figlio pu
essere rilasciato dalla posizione di aggancio, impostando il parametro Accept. Se il
controllo agganciabile stato rifiutato dal gestore di evento OnGetSiteInfo (forse
perch il tipo di controllo era errato), levento OnDockOver non verr attivato.
__ptepett, c.,c c., teaic.,, vtItec.,,
t,peie? veIi __?aatcaII __cIeaate c.,c.sc.ccc .c.c,
ic.ccc .cc, Iat ., Iat ,
OnDockDrop si verifica nella posizione di aggancio quando lutente rilascia un figlio
agganciabile sul controllo. Corrisponde allevento OnDragDrop in una normale
operazione drag-and-drop. Deve essere utilizzato per eseguire un adattamento
necessario per accettare il controllo come controllo figlio. Laccesso al controllo figlio
pu essere ottenuto usando la propriet Control del TDockObject specificato dal
parametro Source.
Controllo della modalit di sgancio dei controlli figlio
Una posizione di controllo consente automaticamente ai controlli figlio di essere
sganciati quando vengono trascinati ed hanno la propriet DragMode impostata a
dmAutomatic. Le posizioni di aggancio possono rispondere quando i controlli figlio
U s o d e i c o n t r o l l i 6-7
O p e r a z i o n i c o n t e s t o n e i c o n t r o l l i
vengono trascinati fuori, e possono anche impedire lo sganciamento in un gestore di
evento OnUnDock:
__ptepett, c.c c. teaic., vtItec.,
t,peie? veIi __?aatcaII __cIeaate c.c.sc.ccc .c.c,
c, .c.ic, beeI ~.,
Il parametro Client indica il controllo figlio che sta tentando lo sganciamento, mentre
il parametro Allow consente alla posizione di aggancio (Sender) di rifiutare lo
sganciamento. Quando si implementa un gestore di evento OnUnDock, pu risultare
utile conoscere quali altri figli (eventuali) sono al momento agganciati. Queste
informazioni sono disponibili nella propriet a sola lettura DockClients, che un array
indicizzato di TControl. Il numero di client agganciati viene indicato dalla propriet a
sola lettura DockClientCount.
Controllo della modalit di risposta dei controlli figlio alle operazioni
drag-and-dock
I controlli figlio agganciabili hanno due eventi che si verificano durante le operazioni
drag-and-dock: OnStartDock, analogo allevento OnStartDrag di unoperazione drag-
and-drop, consente al controllo figlio agganciabile di creare un oggetto
trascinamento personalizzato. OnEndDock, analogamente allevento OnEndDrag, si
verifica al termine del trascinamento.
Operazioni con testo nei controlli
Le sezioni seguenti spiegano come utilizzare le varie funzioni dei controlli RichEdit e
Memo. Alcune funzioni qui descritte valgono anche per i controlli di editing.
Impostazione dellallineamento del testo
Aggiunta di barre di scorrimento in fase di esecuzione
Aggiunta delloggetto clipboard
Selezione di testo
Selezione di tutto il testo
Operazioni taglia, copia e incolla del testo
Cancellazione del testo selezionato
Disattivazione delle voci di menu
Preparazione di un menu a comparsa
Gestione dellevento OnPopup
Impostazione dellallineamento del testo
In un componente RichEdit o Memo, il testo pu essere allineato a sinistra, a destra o
al centro. Per cambiare lallineamento del testo, impostare la propriet Alignment del
componente di editing. Lallineamento ha effetto solo se la propriet WordWrap
true; se lallineamento alla riga successiva disattivato, non esiste alcun margine
rispetto al quale effettuare lallineamento.
6-8 G u i d a a l l a p r o g r a mma z i o n e
O p e r a z i o n i c o n t e s t o n e i c o n t r o l l i
Ad esempio, il codice seguente tratto dallesempio RichEdit imposta lallineamento a
seconda del pulsante scelto:
avItcaIatc.>.iii,>~.c
c.>ci.ccc,
Iat ~..c.L.cx,
caat c.i.c,1 '~',
?et ci c ~, c ., c-- i ,sscc .cs
c.i.c, c,
avItca cc,cc.i.c
I? Iatc ~ c.s. cc .c
cs>Lc.L.cx ~..c.L.cx, c .i.c i c cc s c.
U s o d e i c o n t r o l l i 6-15
A g g i u n t a d i g r a f i c i a i c o n t r o l l i
Disegno di elementi owner-draw
Le viste elenco e i controlli pagina hanno una propriet di nome OwnerDraw che
attiva o disattiva il tracciamento predefinito. Invece, il sistema operativo genera
eventi per ciascun elemento visibile del controllo. Lapplicazione gestisce gli eventi
per disegnare gli elementi.
Per disegnare gli elementi in un controllo owner-draw, occorre fare quanto descritto
qui di seguito per ciascun elemento visibile del controllo. Si deve usare un unico
gestore di evento per tutti gli elementi.
1 Dimensionare, se necessario, lelemento.
Gli elementi con le stesse dimensioni (per esempio, con uno stile casella di
riepilogo di lsOwnerDrawFixed), non richiedono alcun dimensionamento.
2 Disegno dellelemento.
Dimensionamento degli elementi owner-draw
Prima di dare allapplicazione la possibilit di disegnare tutti gli elementi di un
controllo owner-draw variabile, il sistema operativo genera un evento a misura di
elemento. Questo evento comunica allapplicazione dove lelemento appare sul
controllo.
C++Builder determina le dimensioni dellelemento (generalmente, sono grandi a
sufficienza per visualizzare il testo dellelemento con il font corrente). Lapplicazione
pu gestire levento e modificare il rettangolo scelto. Per esempio, se si prevede di
sostituire una bitmap per il testo dellelemento, bene modificare il rettangolo in
modo che abbia le dimensioni del bitmap. Se si desidera un bitmap e il testo, si deve
regolare il rettangolo in modo che sia abbastanza grande per entrambi.
Per modificare le dimensioni di un elemento owner-draw, occorre collegare un
gestore allevento a misura di elemento nel controllo owner-draw. Il nome
dellevento varia in funzione del controllo. Le caselle di riepilogo e quelle combinate
usano OnMeasureItem. Le griglie non hanno alcun evento a misura di elemento.
Il dimensionamento di un evento ha due importanti parametri: il numero di indice
dellelemento e le dimensioni dellelemento stesso. Le dimensioni sono variabili:
lapplicazione pu crearle pi piccole o pi grandi. Le posizioni degli elementi
successivi dipendono dalle dimensioni di quelli precedenti.
Per esempio, in una casella di riepilogo owner-draw variabile, se lapplicazione
imposta laltezza del primo elemento a cinque pixel, il secondo elemento dister sei
pixel, e cos via. Sia nelle caselle di riepilogo sia in quelle combinate lunico aspetto
dellelemento che lapplicazione pu cambiare laltezza. La larghezza sempre
quella del controllo.
Le griglie owner-draw non possono modificare le dimensioni delle loro celle quando
disegnano. Le dimensioni di ciascuna riga e di ciascuna colonna vengono impostate
prima di disegnare dalle propriet ColWidths e RowHeights.
6-16 G u i d a a l l a p r o g r a mma z i o n e
A g g i u n t a d i g r a f i c i a i c o n t r o l l i
Il seguente codice, collegato allevento OnMeasureItem di una casella di riepilogo
owner-draw, aumenta laltezza di ciascun elemento dellelenco per contenere la sua
bitmap associata.
veIi __?aatcaII .sx.ciscLc. , Iat L.cx,
Iat -c c i -c s ,issc. c c.cccc
_
Occorre convertire gli elementi dalla propriet Objects nellelenco di stringhe. Objects
una propriet di tipo TObject che pertanto pu contenere qualsiasi tipo di oggetto.
Quando si recuperano gli oggetti dallarray, occorre riconvertirli nel tipo effettivo
degli elementi.
Disegno di elementi owner-draw
Quando unapplicazione ha bisogno di disegnare o di ridisegnare un controllo
owner-draw, il sistema operativo genera eventi draw-item per ciascun elemento
visibile del controllo. A seconda del controllo, lelemento pu anche ricevere gli
eventi di tracciamento per lelemento nel suo complesso o per i singoli sottoelementi.
Per disegnare un elemento di un controllo owner-draw, si deve collegare un gestore
allevento draw-item per quel controllo.
I nomi degli eventi per il disegno personalizzato di solito iniziano con uno dei
seguenti modi:
OnDraw, come OnDrawItem o OnDrawCell
OnCustomDraw, come OnCustomDrawItem
OnAdvancedCustomDraw, come OnAdvancedCustomDrawItem
Levento draw-item contiene i parametri che indentificano lelemento da disegnare, il
rettangolo in cui disegnare e solitamente alcune informazioni sullo stato
dellelemento (per esempio, se lelemento ha il fuoco). Lapplicazione gestisce ciascun
evento rappresentando lelemento appropriato nel rettangolo dato.
Per esempio, il codice seguente mostra come disegnare gli elementi in una casella di
riepilogo che ha delle bitmap associate a ciascuna stringa. Il codice collega questo
gestore allevento OnDrawItem per la casella di riepilogo:
veIi __?aatcaII .sxi.Lc. , Iat L.cx,
cc cc, .ci..ic .ic
.i, .i, .i, sx>Lc.s>cccs,L.cx,
sx>iis>i.c., , - ., .i,, .i. c c.i,
sx>iis>cxc. - .i,>. - ., , - .,
sx>Lc.s>.s,L.cx, i. .c c cx s
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-1
C a p i t o l o
7
Capitolo7Creazione di applicazioni,
componenti e librerie
In questo capitolo viene fornita una panoramica sulluso di C++Builder per la
creazione di applicazioni, librerie e componenti.
Creazione di applicazioni
C++Builder usato principalmente per la progettazione e la costruzione dei seguenti
tipi di applicazioni:
Applicazioni GUI
Applicazioni per console
Applicazioni di servizio (solo per applicazioni Windows)
Package e DLL
Generalmente, le applicazioni GUI hanno uninterfaccia di facile impiego. Le
applicazioni per console vengono eseguite da una finestra della console. Le
applicazioni di servizio sono eseguite come servizi Windows. Questi tipi di
applicazioni vengono compilati come eseguibili con codice di avvio.
Si possono creare altri tipi di progetto, come package e DLL, che portano alla
realizzazione di package o di librerie collegabili dinamicamente. Queste applicazioni
producono un codice eseguibile senza codice di avvio. Fare riferimento al paragrafo
Creazione di package e di DLL on page 7-10.
Applicazioni GUI
Unapplicazione con interfaccia utente grafica (GUI) viene progettata utilizzando
funzionalit grafiche come finestre, menu, finestre di dialogo e altre funzionalit che
la rendono facile da usare. Quando si compila unapplicazione GUI, viene generato
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-2
C r e a z i o n e d i a p p l i c a z i o n i
un file eseguibile con codice di avvio. Leseguibile generalmente fornisce la
funzionalit di base del programma, tanto che i programmi pi semplici sono
costituiti esclusivamente da un file. possibile estendere lapplicazione chiamando le
DLL, i package e gli altri file di supporto dalleseguibile.
C++Builder offre due modelli di applicazione UI:
Single document interface (SDI)
Multiple document interface (MDI)
Oltre che con il modello di implementazione delle applicazioni, il comportamento
del progetto in fase di progettazione e di esecuzione dellapplicazione pu essere
modificato tramite le opzioni di progetto dellIDE.
Modelli di interfaccia utente
Le schede possono essere implementate come schede MDI (Multiple document
interface) o SDI (Single document interface). In unapplicazione MDI possibile
aprire allinterno di ununica finestra genitore pi di un documento o finestra figlio.
Ci vale per applicazioni come i fogli di lavoro o gli elaboratori testo.
Unapplicazione SDI, invece, generalmente contiene ununica vista del documento.
Per rendere una scheda unapplicazione SDI, occorre impostare la propriet
FormStyle delloggetto Form a fsNormal.
Per ulteriori informazioni sullo sviluppo dellinterfaccia utente per unapplicazione,
consultare il Capitolo 8, Sviluppo dellinterfaccia utente dellapplicazione.
Applicazioni SDI
Per creare una nuova applicazione SDI:
1 Selezionare File|New|Other per richiamare la finestra di dialogo New Items.
2 Fare clic sulla pagina Projects e fare doppio clic su SDI Application.
3 Fare clic su OK.
Per impostazione predefinita, la propriet FormStyle delloggetto Form fsNormal,
chioschi C++Builder presuppone che tutte le nuove applicazioni siano di tipo SDI.
Applicazioni MDI
Per creare una nuova applicazione MDI:
1 Selezionare File|New|Other per richiamare la finestra di dialogo New Items.
2 Fare clic sulla pagina Projects e fare doppio clic su MDI Application.
3 Fare clic su OK.
Le applicazioni MDI richiedono una maggiore pianificazione e sono in un certo senso
pi complesse da progettare di quelle SDI. Le applicazioni MDI generano finestre
figlio che risiedono allinterno della finestra client; la scheda principale contiene le
schede figlio. Per specificare se una scheda figlio (fsMDIForm) o la scheda principale
(fsMDIChild), occorre impostare la propriet FormStyle delloggetto TForm.
consigliabile definire una classe base per le schede figlio e derivare ogni scheda figlio
da questa classe, per evitare di dover ridefinire le propriet della scheda figlio.
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-3
C r e a z i o n e d i a p p l i c a z i o n i
Le applicazioni MDI spesso includono sul menu principale una finestra popup che
contiene elementi quali Cascade e Tile per la visualizzazione di pi finestre in
modalit differenti. Quando una finestra figlio viene ridotta a icona, la sua icona
situata nella scheda MDI genitore.
Per riassumere ci che necessario fare per creare le finestre per lapplicazione MDI:
1 Creare la scheda della finestra principale o finestra MDI genitore. Impostare la sua
propriet FormStyle a fsMDIForm.
2 Creare un menu per la finestra principale che include File|Open, File|Save e
Window che abbia gli elementi Cascade, Tile e Arrange All.
3 Creare le schede MDI figlio e impostare le loro propriet FormStyle a fsMDIChild.
Impostazioni delle opzioni per lIDE, il progetto e la compilazione
Per specificare le diverse opzioni per il progetto, utilizzare il comando Project|
Options. Per maggiori informazioni, consultare la Guida in linea.
Impostazione delle opzioni predefinite del progetto
Per cambiare le opzioni predefinite che valgono per tutti i progetti, si deve ricorrere
alla finestra di dialogo Project Options e contrassegnare la casella Default nellangolo
in basso a destra. Per impostazione predefinita, tutti i nuovi progetti utilizzeranno le
opzioni correnti selezionate.
Modelli di programmazione
I modelli di programmazione sono scheletri di strutture comunemente utilizzate, che
possibile aggiungere al codice sorgente e quindi completare. In C++Builder sono
inclusi alcuni modelli di codice standard, come quelli per gli array, per le classi, per
la dichiarazioni di funzioni, nonch molte istruzioni.
possibile anche scrivere dei modelli propri per codificare delle strutture di impiego
frequente. Ad esempio, se si desidera utilizzare nel codice un ciclo for, si pu inserire
il seguente modello:
?et , ,
Per inserire un modello di codice nel Code editor, premere Ctrl-j e selezionare il
modello di codice che si intende utilizzare. A questa raccolta possibile aggiungere
anche dei propri modelli. Per aggiungere un modello:
1 Scegliere il comando Tools|Editor Options.
2 Fare clic sul separatore Code Insight.
3 Nei sezione Template, fare clic su Add.
4 Dopo Shortcut name scrivere un nome per il modello, immettere una breve
descrizione del nuovo modello e fare clic su OK.
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-4
C r e a z i o n e d i a p p l i c a z i o n i
5 Aggiungere il codice del modello nella casella di testo Code.
6 Fare clic su OK.
Applicazioni per console
Le applicazioni per console sono programmi a 32-bit che vengono eseguiti senza
uninterfaccia grafica, solitamente in una finestra per console. Queste applicazioni di
solito non richiedono uninterazione con lutente ed eseguono un numero limitato di
funzioni.
Per creare una nuova applicazione per console:
1 Selezionare lopzione di menu File|New|Other ,quindi nella finestra di dialogo
New Items selezionare lopzione Console Wizard.
2 Nella finestra di dialogo Console Wizard, selezionare lopzione Console
Application, scegliere il tipo di file sorgente (C o C++) per il modulo principale del
progetto, o specificare un file esistente che contenga una funzione main o
winmain, quindi fare clic sul pulsante OK.
C++Builder creer un file di progetto per questo tipo di file sorgente e visualizzer il
Code editor.
Utilizzo di VCL e CLX in applicazioni per console
_
Quando si crea una nuova applicazione per console, lIDE non crea una nuova
scheda. Viene visualizzato solo il Code editor.
Nelle applicazioni per console possibile tuttavia utilizzare la VCL e la CLX. Per fare
ci occorre indicare nel Console Wizard che si intende utilizzare la VCL o la CLX
(selezionare lopzione Use VCL oppure Use CLX). Se nel Wizard non si indica che si
vuole utilizzare la VCL o la CLX, in seguito non sar pi possibile utilizzare alcuna
classe della VCL o della CLX in quella applicazione. Se si tenta di farlo, il linker
generer una serie di errori.
Le applicazioni per console dovrebbero gestire tutte le eccezioni per impedire alle
finestre di visualizzare una finestra di dialogo durante la sua esecuzione.
Applicazioni di servizio
Le applicazioni di servizio accettano richieste dalle applicazioni client, elaborano tali
richieste e restituiscono informazioni allapplicazione client. Solitamente vengono
eseguite in background, con poca o nulla interazione con lutente. Esempi di
applicazioni di servizio sono i server Web, i server FTP o di posta.
Per creare unapplicazione che implementi un servizio Win32:
1 Scegliere File|New|Other e fare doppio clic su Service Application nella finestra di
dialogo New Items. In questo modo si aggiunge una variabile di nome Application
al progetto, che di tipo TServiceApplication.
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-5
C r e a z i o n e d i a p p l i c a z i o n i
2 Apparir una finestra Service che corrisponde a un servizio (TService). Per
implementare il servizio, occorre impostarne le propriet e i gestori di evento
nellObject Inspector.
3 Scegliendo File|New|Other e selezionando Service dalla finestra di dialogo New
Items, possibile aggiungere ulteriori servizi allapplicazione del server. Non
possibile aggiungere servizi ad unapplicazione che non sia di servizio. Anche se
possibile aggiungere un oggetto TService, lapplicazione non generer gli eventi
necessari, n effettuer le chiamate appropriate ad Windows a favore del servizio.
4 Una volta creata l applicazione di servizio, possibile installarne i servizi con
Service Control Manager (SCM). Le altre applicazioni potranno quindi attivare tali
servizi inviando delle richieste a SCM.
Per installare i servizi dellapplicazione, eseguire il programma utilizzando lopzione
/INSTALL. Lapplicazione installer i suoi servizi e terminer, emettendo un
messaggio di conferma dellavvenuta installazione dei servizi. Se si esegue
lapplicazioni di servizio utilizzando lopzione /SILENT possibile evitare la
visualizzazione del messaggio di conferma.
Per disinstallare i servizi, eseguire lapplicazione dalla riga comandi utilizzando
lopzione /UNINSTALL. ( possibile utilizzare anche lopzione /SILENT per
sopprimere il messaggio di conferma emesso in fase di disinstallazione).
Esempio Questo servizio ha un TServerSocket la cui porta impostata a 80. Questa la porta
predefinita dei browser Web per effettuare richieste ai server Web e dei server Web
per fornire risposte ai browser. Questo particolare esempio produce un documento
di testo di nome WebLogxxx.log (dove xxx ThreadID) nella directory C:\Temp. Ci
deve essere un unico server in ascolto nella porta stabilita, in modo che, se c un
server Web, si avr la certezza che non sta ascoltando (il servizio viene interrotto).
Per vedere il risultato: aprire un browser Web sulla macchina locale e immettere
localhost (senza virgolette) per lindirizzo. Probabilmente il browser si disattiver,
ma a questo punto sar disponibile un file di nome Weblogxxx.log nella directory
C:\Temp.
1 Per creare lesempio, scegliere il comando File|New |Other e selezionare nella
finestra di dialogo New Items lopzione Service Application. Appare la finestra
Service1.
2 Aggiungere alla finestra del servizio (Service1) un componente ServerSocket
prelevandolo dalla pagina Internet della Component palette).
3 Aggiungere alla classe TService1 un membro dati privato di tipo TMemoryStream.
L intestazione della unit dovrebbe assomigliare al seguente:
-I?aie? -
-ie?Iae -
-IacIaie .ss,,>
-IacIaie isscs,,>
-IacIaie .c.,,>
-IacIaie .c..,,,>
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-6
C r e a z i o n e d i a p p l i c a z i o n i
cIaaa .ccc pabIIc .ccc
-eaiI?
4 Selezionare ServerSocket 1, il componente aggiunto al passo 1. Fare doppio clic
sullevento OnClientRead nellObject Inspector ed aggiungere il seguente gestore di
evento:
veIi __?aatcaII .ccc.cc.c.ccci.ccc .c.c,
s..c.c .c.c
caat ..c .,
c .c.c>ccccc,
vaIIe c >
tt,
..c caat .icc,
.c.c>cccc.veIi ..c, c,
.ci.>c..c, c,
__?IaaII,
.cc..c,
.ci.>.cc., s.c,
~s. c 'c.,cc',
c c - L..cccci.>ci.L - '',
.ci.>.iccc,
5 Infine, selezionare Service1 facendo clic nellarea del client della finestra (non sul
ServiceSocket). Fare doppio clic sullevento OnExecute nellObject Inspector ed
aggiungere il seguente gestore di evento:
veIi __?aatcaII .ccc.cccxccc.ccc .c.c
ptIvate
ptetectei
veIi __?aatcaII xccc,
pabIIc
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-8
C r e a z i o n e d i a p p l i c a z i o n i
__?aatcaII .,i.ci.beeI cic.s,c.c.,
,
3 Nel file .cpp della unit, creare una variabile globale per unistanza di
TSparkyThread:
.,i.ci. .,i.ci.,
4 Aggiungere il codice seguente al file .cpp del costruttore TSparkyThread:
__?aatcaII .,i.ci..,i.ci.beeI cic.s,c.c.
ci.cic.s,c.c.
5 Aggiungere il codice seguente al file .cpp del metodo Execute di TSparkyThread (la
funzione di thread):
veIi __?aatcaII .,i.ci.xccc
.c c.ic.
cc,,
.cc,,
6 Selezionare la finestra del servizio (Service1), e fare doppio clic sullevento OnStart
nellObject Inspector. Aggiungere il seguente gestore di evento OnStart:
veIi __?aatcaII .ccc.ccc.i.ccc .c.c, beeI .ic.
.,i.ci.>cs.c,
c. ttae,
.,i.ci.>.s,c.,
.isc. ttae,
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-9
C r e a z i o n e d i a p p l i c a z i o n i
.,i.ci.>c.ic,
.,,c. ttae,
tetata ic ic,
,
ieabIe i.icieabIe ic
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-13
C r e a z i o n e d i D L L c o n t e n e n t i c o m p o n e n t i V C L e C L X
tetata ic .,
Nel codice precedente viene esportata la funzione changeValue, che viene resa
pertanto disponibile alle applicazioni che la chiamano. Le funzioni dblValue e
halfValue sono interne, per cui non possono essere chiamate dallesterno della DLL.
Ulteriori informazioni sulla creazione di DLL si trovano in Microsoft Win32 SDK
Reference.
Creazione di DLL contenenti componenti VCL e CLX
Uno dei punti di forza delle DLL il fatto che una DLL creata con un determinato
strumento di sviluppo pu spesso essere utilizzata da unapplicazione scritta con
uno strumento di sviluppo differente. Quando la DLL contiene dei componenti VCL
(per esempio, delle schede) che devono essere utilizzate dallapplicazione chiamante,
bisogna preparare delle routine di interfaccia esportate che utilizzino le convenzioni
di chiamata standard, evitare il mangling dei nomi di C++, mentre non richiesto che
lapplicazione chiamante supporti la libreria VCL o CLX per poter funzionare. Per
creare componenti VCL o CLX che possano essere esportati, utilizzare i package di
runtime. Per ulteriori informazioni, consultare il Capitolo 15, Uso di package e di
componenti.
Si supponga, per esempio, di voler creare una DLL per visualizzare questa semplice
finestra di dialogo:
Il codice della DLL della finestra di dialogo il seguente:
.~L.-
-..c. ..i-
-.c.c ..i-
-c.c isscs,,>
-c.c cs,,>
-c.c c..s,,>
-c.c c.s,,>
7-14 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i D L L c o n t e n e n t i c o m p o n e n t i V C L e C L X
__pabIIaaei L.iic. .,cs
icc icccx,
cs,
.,
veIi __?aatcaII csc.ccc .c.c,
veIi __?aatcaII .c.ccc .c.c,
ptIvate sc .cciis
beeI cic,
pabIIc sc .cciis
vIttaaI __?aatcaII cs.i.,c .c,
beeI __?aatcaII ccic,
,
cx,c. c.icc .c
exteta '' __iecIapec .cx, beeI L.ccs.i,
-c..
.~L...
-c.c cc>
-,i.i .s,
-c.c '..i'
__?aatcaII cs.ics.i.,c .c
..c
cic ?aIae,
cic ttae,
sc,
cic ?aIae,
sc,
c cic,
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-15
C o l l e g a m e n t o d e l l e D L L
cx,c. si.i. -- c.icc .c i cis
beeI L.ccs.i
beeI cic,
cs.i cs.i aev cs.i.,
cs.i>....i,
cic cs.i>ccic,
ieIete cs.i,
tetata cic,
I contesti numerici di aiuto sono la forma standard delle richieste di Help nelle
applicazioni eseguite in ambiente Windows che utilizzano il sistema WinHelp;
bench supportate dalla CLX, se ne sconsiglia lutilizzo nelle applicazioni CLX
perch la maggior parte dei sistemi di Help di Linux non sono in grado di
comprenderle.
Alle implementazioni di ICustomHelpViewer viene richiesto di fornire il supporto per
richieste di aiuto in base a una parola chiave, mentre alle implementazioni
IExtendedHelpViewer viene richiesto il supporto per le richieste di aiuto in base al
contesto.
ICustomHelpViewer fornisce tre metodi per la gestione di aiuto in base a una parola
chiave:
UnderstandsKeyword
GetHelpStrings
ShowHelp
7-32 G u i d a a l l a p r o g r a mma z i o n e
A t t i v a z i o n e d e l l H e l p n e l l e a p p l i c a z i o n i
Iat__?aatcaII Ls.-c,c.c.csi.sc..ceaat ~s. -c,.
il primo dei tre metodi chiamati dallHelp Manager, il quale chiamer ogni
visualizzatore di Help registrato passandogli la stessa stringa per chiedergli se in
grado di fornire un aiuto per quella stringa; il visualizzatore dovrebbe risponde con
un valore integer che indica quante differenti pagine della guida pu visualizzare in
risposta a quella richiesta di Help. Per determinare tale valore, il visualizzatore pu
utilizzare un qualsiasi metodo- allinterno dellIDE il visualizzatore HyperHelp
gestisce il proprio indice e lo utilizza per la ricerca. Se il visualizzatore non in grado
di fornire un aiuto per questa parola chiave dovrebbe restituire zero. I numeri
negativi vengono interpretati come se fossero zero, ma questo comportamento non
garantito nelle versioni successive.
cIaaaea:sttIaLIat__?aatcaII Ls.-c,c.cc-c,.sceaat ~s.
-c,.
viene chiamato dallHelp Manager nel caso vi sia pi di un visualizzatore in grado di
fornire un aiuto su un argomento. Il visualizzatore dovrebbe restituire uno
TStringList liberato dallHelp Manager. Le stringhe nella lista restituita dovrebbero
corrispondere alle pagine disponibili per quella parola chiave, ma le caratteristiche di
quella mappatura possono essere determinate dal visualizzatore. Nel caso del
visualizzatore WinHelp in Windows e del visualizzatore HyperHelp in Linux,
lelenco di stringhe contiene sempre esattamente una voce. HyperHelp fornisce una
propria indicizzazione e la sua duplicazione in unaltra posizione produrrebbe una
duplicazione senza puntatore. Nel caso del visualizzatore Man page (Linux), la lista
di stringhe formata da stringhe multiple, una per ogni sezione del manuale che
contiene una pagina per quella parola chiave.
veIi__?aatcaII Ls.-c,c.c..-c,ceaat ~s. -c,.
viene chiamato dallHelp Manager nel caso abbia bisogno che il visualizzatore di
Help visualizzi un aiuto per una particolare parola chiave. Questa lultima
chiamata a metodo delloperazione; il sistema garantisce che non sar mai chiamato a
meno che prima non venga chiamato il metodo UnderstandsKeyword.
Visualizzazione degli indici
ICustomHelpViewer fornisce due metodi relativi alla visualizzazione degli indici:
CanShowTableOfContents
ShowTableOfContents
Il meccanismo del loro funzionamento simile a quello delle operazioni di richiesta
di help in base a una parola chiave: per prima cosa lHelp Manager interroga tutti i
visualizzatori di Help chiamando ICustomHelpViewer::CanShowTableOfContents() e
successivamente richiama un particolare visualizzatore di Help chiamando
ICustomHelpViewer::ShowTableOfContents().
perfettamente normale che un particolare visualizzatore si rifiuti di supportare
richieste per la visualizzazione di un indice. Questo il caso, ad esempio, del
visualizzatore Man page, perch il concetto di indice non si addice alla modalit di
funzionamento di Man page; il visualizzatore HyperHelp, invece, supporta un indice
passando la richiesta di visualizzare lindice direttamente a HyperHelp su Linux e a
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-33
A t t i v a z i o n e d e l l H e l p n e l l e a p p l i c a z i o n i
WinHelp su Windows. Non normale, tuttavia, che unimplementazione di
ICustomHelpViewer risponda a una richiesta che perviene da CanShowTableOfContents
con true e poi ignori le richieste che pervengono da ShowTableOfContents.
Implementazione IExtendedHelpViewer
ICustomHelpViewer fornisce solo un supporto diretto per Help basati su parole
chiave. Alcuni sistemi di Help (specialmente WinHelp) funzionano associando
numeri (conosciuti come ID di contesto) a parole chiave in un modo interno al
sistema di Help e quindi non visibile allapplicazione. Tali sistemi richiedono che
lapplicazione supporti lHelp in base al contesto, vale a dire lapplicazione richiama
il sistema Help con quel contesto, invece che con una stringa, e il sistema di Help
traduca tale numero.
Le applicazioni scritte nella CLX e nella CLX possono dialogare con sistemi che
richiedono un Help in base al contesto estendendo loggetto che implementa
ICustomHelpViewer in modo che implementi anche IExtendedHelpViewer.
IExtendedHelpViewer fornisce anche un supporto per dialogare con sistemi di Help
che permettono di passare direttamente ad argomenti di livello pi alto invece di
utilizzare ricerche per parole chiave. Il visualizzatore natico WinHelp compie
loperazione automaticamente.
IExtendedHelpViewer espone quattro funzioni. Due di esse - UnderstandsContext e
DisplayHelpByContext - sono utilizzate per supportare gli Help in base al contesto; le
altre due - UnderstandsTopic and DisplayTopic - sono utilizzate per supportare gli
argomenti.
Quando un utente dellapplicazione preme il tasto F1, lHelp Manager chiama
Iat__?aatcaII Lxc.c.-c,c.c.csi.scxceaat Iat cxL, ~s.
-c,c.i.c
e il controllo attivato attualmente supporta un Help in base al contesto invece che
basato su parola chiave. Come nel caso di ICustomHelpViewer::UnderstandsKeyword,
lHelp Manager interroga in sequenza tutti i visualizzatori di Help registrati. A
differenza del caso con ICustomHelpViewer::UnderstandsKeyword(), per, se pi di un
visualizzatore supporta un determinato contesto, viene attivato il primo
visualizzatore registrato che supporta quel certo contesto.
LHelp Manager chiama
veIi__?aatcaII Lxc.c.-c,c.cs,i-c,cxceaat Iat cxL, ~s.
-c,c.i.c
dopo aver eseguito la scansione ciclica dei visualizzatori di Help registrati.
Le funzioni per il supporto degli argomenti operano in modo analogo:
beeI__?aatcaII Lxc.c.-c,c.c.csi.s,cceaat ~s. ,c
viene utilizzata per eseguire la scansione ciclica dei visualizzatori di Help e chiedere
se supportano un argomento;
veIi__?aatcaII Lxc.c.-c,c.cs,i,cceaat ~s. ,c
7-34 G u i d a a l l a p r o g r a mma z i o n e
A t t i v a z i o n e d e l l H e l p n e l l e a p p l i c a z i o n i
viene utilizzata per richiamare il primo visualizzatore registrato che riferisce di
essere in grado di fornire laiuto per quellargomento.
Implementazione IHelpSelector
IHelpSelector viene utilizzato in combinazione con ICustomHelpViewer. Quando
esistono pi visualizzatori di Help che sostengono di essere in grado di fornire un
supporto per una certa parola chiave, per un contesto o per un determinato
argomento, o di essere in grado di fornire un indice, lHelp Manager deve effettuare
una scelta. Nel caso di contesti o di argomenti, lHelp Manager seleziona sempre il
primo visualizzatore di Help che sostiene di essere in grado di fornire il supporto.
Nel caso delle parole chiave o dellindice, per impostazione predefinita lHelp
Manager selezioner il primo visualizzatore Help. Questo comportamento pu
essere ridefinito da unapplicazione.
Per ridefinire la decisione dellHelp Manager in questi casi, lapplicazione deve
registrare una classe che fornisca unimplementazione dellinterfaccia
IHelpSelector.IHelpSelector esporta due funzioni: SelectKeyword, e TableOfContents.
Entrambe accettano come argomento un TStrings contenente, ad uno ad uno, o le
possibili corrispondenze con la parola chiave o i nomi dei visualizzatori che
sostengono di essere in grado di fornire un indice. Chi implementa la funzione deve
restituire lindice (in TStringList) che rappresenta la stringa selezionata, TStringList
viene quindi liberata dallHelp Manager.
_
LHelp Manager potrebbe fare confusione se le stringhe vengono riorganizzate; si
consiglia a chi implementa IHelpSelector di astenersi dal fare ci. Il sistema di Help
supporta un solo HelpSelector; quando si registrano nuovi selettori, qualsiasi selettore
precedentemente esistente viene scollegato.
Registrazione di oggetti di sistema di Help
Affinch lHelp Manager possa comunicare con loro, gli oggetti che implementano
ICustomHelpViewer, IExtendedHelpViewer, ISpecialWinHelpViewer e IHelpSelector
devono essere registrati con lHelp Manager.
Per registrare con lHelp Manager oggetti di sistema di Help, necessario:
Registrare il visualizzatore di Help.
Registrare il selettore di Help.
Registrazione dei visualizzatori di Help
La unit che contiene limplementazione di oggetto deve utilizzare HelpIntfs. Nel file
header della unit che lo implementa si deve dichiarare unistanza delloggetto.
La unit implementante deve includere una direttiva di avvio pragma che chiama un
metodo che assegna la variabile di istanza e la passa alla funzione RegisterViewer.
RegisterViewer una funzione esportata da HelpIntfs.pas che accetta come argomento
uno ICustomHelpViewer e restituisce uno IHelpManager. Lo IHelpManager dovrebbe
essere memorizzato per un successivo utilizzo.
C r e a z i o n e d i a p p l i c a z i o n i , c o mp o n e n t i e l i b r e r i e 7-35
U t i l i z z o d e l l H e l p i n u n a p p l i c a z i o n e V C L
Il file .cpp corrispondente contiene il codice per registrare linterfaccia. Per
linterfaccia descritta sopra, il codice di registrazione assomiglia al seguente:
veIi L.cccs
-c,L.,c.c ciiss,
ci .i.c_cisLs.-c,c.c>ciiss,
ci>~..c.,
-c,L.scscc.cci, ciiss>.iic,
css.>....i,
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-7
U s o d e l l e s c h e d e
css. aev css.taIa,
css.>....i,
ieIete css.,
Il gestore di evento dellesempio cancella la scheda dopo averla chiusa, in modo che
non occorrer ricrearla se occorrer usare ResultsForm in qualche altro punto
dellapplicazione. Se la scheda fosse visualizzata usando Show, non potrebbe essere
cancellata allinterno del gestore di evento, perch Show termina mentre la scheda
ancora aperta.
_
Se si crea una scheda usando loperatore new, bisogna ricordarsi di controllare che
non sia nellelenco Auto-create forms della pagina Project Options|Forms. Nello
specifico, se la nuova scheda viene creata senza cancellare la scheda omonima
dallelenco, C++Builder crea la scheda in fase di avvio e questo gestore di evento crea
una nuova istanza della scheda, sovrascrivendo il riferimento allistanza creata
automaticamente. Questa istanza esiste ancora, ma lapplicazione non pu pi
accedervi. Dopo che il gestore di evento ha terminato lesecuzione, la variabile
globale non punta pi a una scheda valida. Qualsiasi tentativo di dereferenziare la
variabile globale bloccher probabilmente lapplicazione.
Creazione di schede non modali come finestre
Occorre garantire che le variabili di riferimento per le schede non modali esistano
finch la scheda in uso. Questo vuol dire che queste variabili devono avere un
campo dazione globale. Nella maggior parte dei casi si usa la variabile globale di
riferimento creata insieme alla scheda (il nome della variabile che corrisponde alla
propriet name della scheda). Se l applicazione richiede altre istanze della scheda,
occorre dichiarare variabili globali distinte (di tipo puntatore alla classe form) una
per ciascuna istanza.
Creazione di unistanza di scheda mediante una variabile locale
Un modo pi sicuro per creare unistanza univoca di una scheda modale consiste
nellusare una variabile locale nel gestore di evento come riferimento a una nuova
istanza. Se si usa una variabile locale, non importa se ResultsForm stata creata
automaticamente o meno. Il codice nel gestore di evento non fa alcun riferimento alla
variabile globale della scheda. Per esempio:
veIi __?aatcaII .i..sc.ccc .c.c
Si noti che listanza globale della scheda non viene mai usata in questa versione del
gestore di evento.
Normalmente, le applicazioni usano le istanze globali delle schede. Tuttavia, se
occorre una nuova istanza di una scheda modale, e si usa quella scheda in una
sezione limitata dellapplicazione, come una singola funzione, unistanza locale
solitamente il modo pi sicuro ed efficace per lavorare con la scheda.
8-8 G u i d a a l l a p r o g r a mma z i o n e
U s o d e l l e s c h e d e
Naturalmente, non possibile usare le variabili locali nei gestori di evento per le
schede non modali, perch devono avere un campo dazione globale per garantire
che le schede esistano finch sono utilizzate. Show termina non appena si apre la
scheda, quindi se stata usata una variabile locale, questa variabile uscir
immediatamente dal campo dazione.
Passaggio di altri argomenti alle schede
Normalmente, le schede per lapplicazione vengono create dallinterno dellIDE.
Quando vengono create in questo modo, le schede hanno un costruttore che accetta
un argomento, Owner, che il proprietario della scheda da creare. (Il proprietario
loggetto applicazione o scheda chiamante). Owner pu essere NULL.
Per passare alla scheda altri argomenti, si deve creare un altro costruttore e istanziare
la scheda usando l operatore new. La classe della scheda di esempio sotto riportata
mostra un costruttore aggiuntivo, con un ulteriore argomento whichButton. Questo
nuovo costruttore viene aggiunto manualmente alla classe della scheda.
cIaaa css. pabIIc .
avItca .c
caae
cssicc>i, ' ,c.c. c .s c',
bteak,
caae .
cssicc>i, ' ,c.c. c scc. c',
bteak,
caae
cssicc>i, ' ,c.c. c . c',
8-10 G u i d a a l l a p r o g r a mma z i o n e
U s o d e l l e s c h e d e
eIae c scccc.
c '',
veIi .sc. s
c s,
I? . c. . cxss
. s .>c,
. s.c . c c i.c s
Per prima cosa il gestore di evento verifica che ColorForm esista controllando se il
puntatore NULL. Quindi, riceve il valore della propriet CurrentColor di ColorForm.
La richiesta del CurrentColor chiama la sua funzione getter getColor mostrata di
seguito:
. .c
tetata c,
c s,
c '',
Notare che il gestore di evento memorizza il nome del colore selezionato nella stringa
address che stata passata al costruttore.
Per usare efficacemente ColorForm, la scheda chiamante deve passare il costruttore a
un puntatore a una stringa esistente. Per esempio, si supponga che ColorForm stata
istanziata da una scheda chiamata ResultsForm in risposta a un clic su un pulsante
chiamato UpdateButton di ResultsForm. Il gestore di evento dovrebbe essere simile al
seguente codice:
veIi __?aatcaII css.,.icc.ccc .c.c
. s,
cs,
I? s ''
. s.c . c c i.c s
eIae
. s.c csc cccisc c .is ,c.c.
veIi css.c. s
c cis sc
i>scc i>scc,
possibile fornire un gestore di evento che risponda a uno dei tre diversi livelli:
lazione, la lista di azioni o lapplicazione. Ci si deve occupare di ci solo se si utilizza
una nuova azione generica invece di unazione standard predefinita. Se si utilizzano
le azioni standard non ce ne si deve occupare, perch le azioni standard hanno un
comportamento incorporato che viene eseguito quando si verificano questi eventi.
I gestori di evento risponderanno agli eventi in base al seguente ordine:
Lista di azioni
Applicazione
Azione
Quando lutente fa clic su un controllo client, C++Builder chiama il metodo Execute
dellazione che dapprima rimanda alla lista di azioni, quindi alloggetto Application,
quindi allazione stessa nel caso non venga gestita n dalla lista di azioni n
dalloggetto Application. Per essere pi precisi, C++Builder segue questa sequenza
di smistamento quando cerca un modo per rispondere allazione di un utente:
1 Se si fornisce un gestore di evento OnExecute per la lista di azioni e tale gestore in
grado di gestire lazione, lapplicazione procede.
Il gestore di evento della lista di azioni ha un parametro di nome Handled, che, per
impostazione predefinita, restituisce false. Se il gestore stato assegnato ed in
grado di gestire levento restituisce true, e la sequenza di elaborazione termina a
questo punto. Per esempio:
veIi __?aatcaII .~csxccc~cisc~c ~c, beeI -i.c.
-i.c. ttae,
Se non si imposta Handled a true nel gestore di evento della lista di azioni, allora
lelaborazione continua.
2 Se non stato preparato un gestore di evento OnExecute per la lista di azioni
oppure se il gestore di evento non in grado di gestire lazione, viene scatenato il
8-28 G u i d a a l l a p r o g r a mma z i o n e
U s o d e l l e l i s t e d i a z i o n i
gestore di evento OnActionExecute dellapplicazione. Se gestisce lazione,
lapplicazione procede.
Loggetto globale Application riceve un evento OnActionExecute nel caso nessuna
delle liste di azioni dellapplicazione sia in grado di gestire un evento. Come il
gestore di evento OnExecute dellelenco di azioni, il gestore di OnActionExecute ha
un parametro Handled che, per impostazione predefinita, restituisce false. Se un
gestore di evento stato assegnato ed in grado di gestire levento, restituisce true
e la sequenza di elaborazioni termina a questo punto. Per esempio:
veIi __?aatcaII .~,,cixccc~cisc~c ~c, beeI -i.c.
j
Non aggiungere al gestore di evento OnUpdate codice con lunghi tempi di
esecuzione. Questa operazione viene eseguita ogniqualvolta lapplicazione inattiva.
Se il gestore di evento impiega troppo tempo, influenzer negativamente le
prestazioni dellintera applicazione.
Classi di azione predefinite
possibile aggiungere allapplicazione azioni predefinite facendo clic destro
sullAction Manager e selezionando il comando New Standard Action. Verr
visualizzata la finestra di dialogo New Standard Action Classes che elenca le classi di
azione predefinite e le azioni standard associate. Queste sono azioni gi incluse in
C++Builder e sono oggetti che eseguono automaticamente determinate azioni. Le
azioni predefinite sono organizzate nelle seguenti classi:
Tabella 8.3 Classi di azioni
Classe Descrizione
Edit Azioni standard di editing: Utilizzate con controlli di editing come
destinazione. TEditAction la classe di base dei discendenti, ognuno dei
quali ridefinisce individualmente il metodo ExecuteTarget in modo da
implementare le attivit di copia, taglia e incolla utilizzando la clipboard.
Format Azioni standard di formattazione: Utilizzate con controlli rich text per
impostare opzioni di formattazione del testo come grassetto, corsivo,
sottolineato, barrato, e cos via.TRichEditAction la classe di base dei
discendenti, ognuno dei quali ridefinisce individualmente i metodi
ExecuteTarget e UpdateTarget in modo da implementare le attivit di
formattazione della destinazione.
Help Azioni standard di Help: Utilizzate con qualsiasi destinazione.
THelpAction la classe di base dei discendenti, ognuno dei quali
ridefinisce individualmente il metodo ExecuteTarget in modo da passare
il comando a un sistema di Help.
Window Azioni standard di finestra: Utilizzate con schede come destinazioni in
unapplicazione MDI. TWindowAction la classe di base dei discendenti,
ognuno dei quali ridefinisce individualmente il metodo ExecuteTarget in
modo da implementare le attivit di disposizione, sovrapposizione,
chiusura o affiancamento di finestre figlio in applicazioni MDI.
8-30 G u i d a a l l a p r o g r a mma z i o n e
U s o d e l l e l i s t e d i a z i o n i
Tutti gli oggetti azione sono descritti nella Guida di riferimento in linea. Per i dettagli
sul loro funzionamento, consultare la Guida in linea.
Scrittura di componenti azione
possibile anche creare proprie classi di azione predefinite. Quando si scrivono
proprie classi di azione, possibile incorporare la capacit di essere eseguite su
alcune classi di oggetti di destinazione. A questo punto, sar possibile utilizzare le
azioni custom in modo analogo a quello utilizzato per le classi di azione predefinite.
Vale a dire, se lazione in grado di individuare e di applicare se stessa a una classe
di destinazione, possibile assegnare semplicemente lazione a un controllo client, ed
essa agir sulla destinazione che sia necessario scrivere un gestore di evento.
Gli scrittori di componenti possono utilizzare le classi nelle unit QStdActns e
DBActns come esempi per derivare le proprie classi di azione per implementare
comportamenti specifici per alcuni controlli o componenti. Le classi di base di queste
azioni specializzate (TEditAction, TWindowAction, e cos via) di solito ridefiniscono
File Azioni su file: Utilizzate per operazioni su file come File Open, File Run
o File Exit.
Search Azioni di ricerca: Utilizzato con opzioni di ricerca. TSearchAction
implementa il comportamento comune per quelle azioni che
visualizzano una finestra di dialogo non modale in cui lutente pu
immettere una stringa di ricerca per effettuare ricerche in un controllo di
editing.
Tab Azioni per controlli multipagina: Utilizzate per spostarsi fra le varie
pagine di un controllo multipagina, come per i pulsanti Prev e Next di
un wizard.
List Azioni per controlli elenco: Utilizzate per la gestione degli elementi in un
controllo list view.
Dialog Azioni per finestre di dialogo: Utilizzato con componenti finestra di
dialogo. TDialogAction implementa il comportamento comune per quelle
azioni che, quando eseguite, visualizzano una finestra di dialogo. Ogni
classe discendente rappresenta una finestra di dialogo specifica.
Internet Azioni Internet: Utilizzato per funzioni quali la navigazione in Internet,
lo scaricamento di file e linvio di posta.
DataSet Azioni DataSet: Utilizzato con componenti dataset come destinazione.
TDataSetAction la classe di base dei discendenti, ognuno dei quali
ridefinisce individualmente i metodi ExecuteTarget e UpdateTarget in
modo da implementare le attivit di navigazione ed editing della
destinazione.
TDataSetAction introduce una propriet DataSource che garantisce che le
azioni vengano eseguite su quel dataset. Se DataSource NULL, viene
usato il controllo associato ai dati che in quel momento ha il fuoco.
Tools Strumenti: Strumenti aggiuntivi come TCustomizeActionBars per la
visualizzazione automatica della finestra di dialogo di personalizzazione
delle bande di azioni.
Tabella 8.3 Classi di azioni
Classe Descrizione
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-31
U s o d e l l e l i s t e d i a z i o n i
HandlesTarget, UpdateTarget e altri metodi in modo da limitare la destinazione
dellazione a una determinata classe di oggetti. Normalmente, le classi discendenti
ridefiniscono ExecuteTarget per eseguire un compito specialistico. Questi metodi sono
descritti nella tabella seguente :
Registrazione delle azioni
Quando si scrivono le proprie azioni, possibile registrarle in modo da consentirne la
visualizzazione nellAction List editor. Le azioni vengono registrate e de-registrate
utilizzando le routine globali nella unit Actnlist:
exteta tckss veIi __?aatcaII csc~csceaat ~s. ic.i.c, .ciiss
ceaat ~isscs, ceaat Iat ~isscs_..c, :xetacIaaa cscc),
exteta tckss veIi __?aatcaII csc~cs.ciiss ceaat ~isscs, ceaat Iat
~isscs_..c,
Quando si chiama RegisterActions, le azioni che si registrano vengono visualizzate
nellAction List editor in modo che siano utilizzabili da parte delle applicazioni.
possibile indicare un nome di categoria per organizzare le azioni, oltre a un
parametro Resource che permette di indicare i valori predefiniti delle propriet.
Per esempio, il seguente codice registra con lIDE le azioni standard nella unit
MyAction:
aaeeapace .~c
Metodo Descrizione
HandlesTarget Chiamato automaticamente quando lutente richiama un oggetto (come un
pulsante di una barra pulsanti o una voce di menu) collegato con lazione. Il
metodo HandlesTarget permette alloggetto action di indicare se opportuna
o meno lesecuzione, utilizzando come destinazione loggetto specificato
dal parametro Target. Per i dettagli, consultare Come le azioni trovano le
proprie destinazioni a pagina 8-28.
UpdateTarget Chiamato automaticamente quando lapplicazione inattiva in modo che le
azioni si possano aggiornare in funzione delle condizioni. Utilizzare al posto
di OnUpdateAction. Per i dettagli, consultare Aggiornamento delle azioni a
pagina 8-29.
ExecuteTarget Chiamato automaticamente al posto di OnExecute quando lazione viene
scatenata in risposta allazione di un utente (ad esempio, quando lutente
seleziona una voce di menu o preme un pulsante strumento collegato con
questa azione). Per i dettagli, consultare Cosa accade quando si scatena
unazione a pagina 8-27.
8-32 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e g e s t i o n e d e i m e n u
Quando si chiama UnRegisterActions, le azioni non vengono pi visualizzate
nellAction List editor.
Creazione e gestione dei menu
I menu forniscono agli utenti un modo facile per eseguire comandi raggruppati
logicamente. Il Menu Designer di Delphi consente di aggiungere facilmente un
menu, gi progettato o confezionato su misura, alla scheda. sufficiente aggiungere
un componente menu alla scheda, aprire il Menu Designer e scrivere le voci menu
direttamente nella finestra del Menu Designer. possibile aggiungere o cancellare le
voci di menu, o trascinarle e rilasciarle per risistemarle in fase di progettazione.
Non occorre neanche eseguire il programma per vedere i risultatila progettazione
immediatamente visibile nella scheda, che appare proprio come apparir in fase di
esecuzione. Il codice pu modificare i menu anche in fase di esecuzione, per fornire
ulteriori informazioni o opzioni allutente.
Questo capitolo spiega come usare il Menu Designer per progettare barre di menu e
menu (locali) a comparsa. Esso tratta i seguenti modi di lavorare con i menu in fase di
progettazione e in fase di esecuzione:
Apertura del Menu Designer.
Costruzione di menu.
Editing delle voci di menu nellObject Inspector.
Uso del menu contestuale Menu Designer.
Uso dei modelli di menu.
Salvataggio di un menu come modello.
Aggiunta di immagini alle voci di menu.
Figura 8.3 Terminologia dei menu
Apertura del Menu Designer
I menu vengono progettati utilizzando il Menu Designer. Prima di iniziare a usare il
Menu Designer, necessario aggiungere alla scheda un componente TMainMenu o
TPopupMenu. Entrambi i componenti menu sono collocati sulla pagina Standard
della Component palette.
Figura 8.4 Componenti MainMenu e PopupMenu
Acceleratore di
tastiera
Separatore
Voci di menu sulla barra dei menu
Voci di menu in un elenco di menu
Scorciatoia di tastiera
Componente MainMenu
Componente PopupMenu
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-33
C r e a z i o n e e g e s t i o n e d e i m e n u
Un componente MainMenu crea un menu che viene collegato alla barra del titolo
della scheda. Un componente PopupMenu crea un menu che appare quando lutente
fa clic con il tasto destro nella scheda. I menu a comparsa non hanno una barra di
menu.
Per aprire il Menu Designer, selezionare un componente menu sulla scheda, e quindi
scegliere:
Fare doppio clic sul componente menu.
oppure
Dalla pagina Properties dellObject Inspector, selezionare la propriet Items, e
quindi fare doppio clic [Menu] nella colonna Value, oppure fare clic sul pulsante
ellissi (...).
Il Menu Designer viene visualizzato, con la prima voce di menu (vuota)
evidenziata nel Designer, e la propriet Caption selezionata nellObject Inspector.
Figura 8.5 Menu Designer per un menu principale
Costruzione di menu
Si aggiunga un componente menu alla scheda, o alle schede, per ogni menu da
includere nellapplicazione. possibile costruire ciascuna struttura di menu
completamente ex-novo, o iniziare da uno dei modelli di menu predefiniti.
Questa sezione illustra i principi per la creazioni di un menu in fase di progettazione.
Per ulteriori informazioni sui modelli di menu, consultare Uso dei modelli di menu
a pagina 8-41.
Assegnazione dei nomi dei menu
Come tutti i componenti, quando alla scheda viene aggiunto un componente menu,
C++Builder gli d un nome predefinito; per esempio, MainMenu1. possibile dare al
menu un nome pi significativo.
C++Builder aggiunge il nome del menu alla dichiarazione di tipo della scheda, e
quindi questo nome appare nel Component list.
Segnaposto per la
voce di menu
8-34 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e g e s t i o n e d e i m e n u
Assegnazione dei nomi delle voci di menu
Al contrario del componente menu stesso, occorre dare esplicitamente un nome alle
voci di menu via via che vengono aggiunte alla scheda. possibile farlo in due modi:
Scrivere direttamente il valore per la propriet Name.
Scrivere prima il valore per la propriet Caption, e lasciare a C++Builder il compito
di derivare la propriet Name dal caption.
Per esempio, se viene data a una voce di menu una valore della propriet Caption
di File, C++Builder assegna alla voce di menu una propriet Name di File1. Se viene
compilata la propriet Name prima di compilare la propriet Caption, C++Builder
lascia la propriet Caption vuota finch non viene scritto un valore.
_
Se vengono immessi nella propriet Caption caratteri non validi per gli
identificatori C++, C++Builder modifica conseguentemente la propriet Name. Per
esempio, se si desidera che il caption inizi con un numero, C++Builder fa
precedere il numero con un carattere per derivare la propriet Name.
La seguente tabella mostra alcuni esempi di ci, presupponendo che tutte le voci
di menu mostrate appaiano nella stessa barra di menu.
Come il componente menu, C++Builder aggiunge qualsiasi nome di voce di menu
alla dichiarazione di tipo della scheda, e quei nomi quindi appaiono nella
Component list.
Aggiunta, inserimento e cancellazione delle voci di menu
Le seguenti procedure descrivono come eseguire i principali compiti coinvolti nella
costruzione della struttura del menu. Ciascuna procedura assume che sia aperta la
finestra Menu Designer.
Per aggiungere voci di menu in fase di progettazione:
1 Selezionare la posizione in cui creare la voce di menu.
Se il Menu Designer stato appena aperto, la prima posizione sulla barra di menu
gi selezionata.
Tabella 8.4 Esempi di caption e loro nomi derivati
Caption del
componente Nome derivato Spiegazione
&File File1 Rimuove la e commerciale
&File (2nd occurrence) File2 Ordina numericamente le voci duplicate
1234 N12341 Aggiunge una lettera prima e lordine numerico
1234 (2nd occurrence) N12342 Aggiungi un numero per eliminare lambiguit al
nome derivato
$@@@# N1 Rimuove tutti i caratteri non standard, aggiungendo
una lettere prima e lordine numerico
- (hyphen) N2 Ordinamento numerico della seconda occorrenza di
caption senza alcun carattere standard
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-35
C r e a z i o n e e g e s t i o n e d e i m e n u
2 Iniziare a scrivere per immettere il caption. O immettere prima la propriet Name
collocando specificamente il cursore nellObject Inspector e immettendo un valore.
In questo caso, occorre allora selezionare di nuovo la propriet Caption ed
immettere un valore.
3 Premere Invio.
Viene selezionato il successivo placeholder per una voce di menu.
Se prima viene immessa la propriet Caption, usare i tasti cursore per ritornare alla
voce di menu appena immessa. C++Builder visualizzer di aver compilato la
propriet Name in base al valore immesso per il caption. (Consultare il paragrafo
Assegnazione dei nomi delle voci di menu a pagina 8-34.)
4 Continuare limmissione dei valori per le propriet Name e Caption per ciascuna
nuova voce da creare, o premere Esc per ritornare alla barra dei menu.
Usare i tasti cursore per spostarsi dalla barra dei menu nel menu, e quindi
spostarsi tra le voci dellelenco; premere Invio per completare unazione. Per
ritornare alla barra dei menu, premere Esc.
Per inserire una nuova voce di menu vuota:
1 Collocare il cursore su una voce di menu.
2 Premere Ins.
Le voci di menu vengono inserite a sinistra della voce selezionata sulla barra dei
menu, e sopra la voce selezionata nellelenco del menu.
Per cancellare una voce di menu o comando:
1 Collocare il cursore sulla voce di menu da cancellare.
2 Premere Del.
_
Non possibile cancellare il placeholder predefinito che appare sotto lultima voce
immessa nellelenco del menu, o vicino allultima voce sulla barra dei menu. Questo
placeholder non appare nel menu in fase di esecuzione.
8-36 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e g e s t i o n e d e i m e n u
Figura 8.6 Aggiunta di voci di menu a un menu principale
Aggiunta di barre separatrici
Le barre separatrici inseriscono una riga tra le voci di menu. possibile usare queste
barre per indicare raggruppamenti allinterno dellelenco del menu, o semplicemente
per fornire uninterruzione visuale di un elenco.
Per rendere la voce di menu una barra separatrice, scrivere un trattino () per il
caption.
Specifica dei tasti di scelta rapida e delle scorciatoie di tastiera
I tasti di scelta rapida consentono allutente di accedere ad comando di menu dalla
tastiera premendo Alt+ la lettera appropriata, indicata nel codice dalla e commerciale
precedente. Nel menu, la lettera dopo la e commerciale appare sottolineata.
C++Builder controlla automaticamente lesistenza di tasti di scelta rapida duplicati e
li corregge in fase di esecuzione. Questo comportamento garantisce che tutti i menu
generati dinamicamente in fase di esecuzione non contengano tasti di scelta rapida
duplicati e che tutti gli elementi di menu abbiano un tasto di scelta rapida. possibile
disattivare questo controllo automatico impostando la propriet AutoHotkeys di un
elemento di menu a maManual.
Per specificare un tasti di scelta rapida:
Aggiungere una e commerciale davanti alla lettera appropriata.
Per esempio, per aggiungere un comando di menu Save con la S come tasto
acceleratore, scrivere .ic.
Le scorciatoie di tastiera consentono allutente di eseguire lazione senza accedere
direttamente al menu, scrivendo la combinazione di tasti della scorciatoia.
Per specificare una scorciatoia di tastiera:
Le funzionalit WYSIWYG del Menu Designer mostrano le
voci di menu man mano che il menu viene creato.
Viene creato un oggetto TMenuItem e la
propriet Name viene impostata alla propriet
Caption specificata (eliminando eventuali
caratteri non ammessi e aggiungendo un
suffisso numerico).
Segnaposto per
la voce di menu
Barra del menu
Barra del titolo (mostra la propriet
Name per un componente Menu)
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-37
C r e a z i o n e e g e s t i o n e d e i m e n u
Usare lObject Inspector per immettere un valore per la propriet ShortCut, o
selezionare una combinazione di tasti dallelenco a discesa.
Questo elenco solo un sottoinsieme delle combinazioni valide che possono essere
scritte.
Quando viene aggiunta una scorciatoia, essa appare vicino al titolo della voce di
menu.
j
Le scorciatoie di tastiera, a differenza degli acceleratori, non sono soggette al
controllo automatico per lesistenza di duplicati. Il controllo di univocit deve essere
eseguito manualmente.
Creazione di sottomenu
Molti menu di applicazioni contengono elenchi a discesa che appaiono vicino a una
voce di menu per fornire ulteriori comandi collegati. Tali elenchi vengono indicati da
una freccia a destra della voce di menu. C++Builder supporta tutti i livelli di
sottomenu desiderati.
Organizzando la struttura dei menu in questo modo, si pu salvare lo spazio
verticale dello schermo. Tuttavia, per progettazioni ottimali forse meglio non usare
pi di due o tre livelli nella progettazione dellinterfaccia. (Per i menu popup,
potrebbe essere opportuno usare un solo sottomenu.)
Figura 8.7 Strutture di menu annidate
Per creare un sottomenu:
1 Selezionare la voce di menu sotto cui si desidera creare un sottomenu.
2 Premere Ctrl per creare il primo segnaposto, o fare clic con il tasto destro e
scegliere Create Submenu.
3 Scrivere un nome per la voce del sottomenu, o trascinare una voce di menu
esistente su questo segnaposto.
4 Premere Invio, o , per creare il successivo segnaposto.
5 Ripetere i punti 3 e 4 per ciascuna voce da creare nel sottomenu.
6 Premere Esc per ritornare al precedente livello di menu.
Voci di menu sulla
barra dei menu
Voci di menu in
una lista di menu
Voci di menu
annidate
8-38 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e g e s t i o n e d e i m e n u
Creazione di sottomenu per retrocessione dei menu esistenti
possibile creare un sottomenu inserendo una voce dalla barra dei menu (o da un
modello di menu) tra le voci di menu di un elenco. Quando un menu viene spostato
in una struttura di menu esistente, tutte le voci associate lo seguono, creando un
menu completamente intatto. Questo vale anche per i sottomenu. Spostando una
voce di menu in un sottomenu esistente si crea solo un altro livello di annidamento.
Spostamento delle voci di menu
In fase di progettazione, per spostare le voci di menu basta semplicemente trascinare
e rilasciare. possibile spostare le voci della barra dei menu, o in un altro posto
dellelenco del menu, o in un menu completamente diverso.
Lunica eccezione a ci di tipo gerarchico: non possibile degradare una voce dalla
barra dei menu nel suo stesso menu; n possibile spostare una voce di menu nel suo
stesso sottomenu. Per, si pu spostare qualsiasi voce in un altro menu,
indipendentemente dalla sua posizione originaria.
Durante il trascinamento, il cursore cambia forma per indicare se possibile
rilasciare la voce di menu nella nuova locazione. Quando viene spostata una voce di
menu, si sposta anche qualsiasi voce al di sotto di essa.
Per spostare una voce di menu lungo la barra dei men:,
1 Trascinare la voce lungo la barra dei menu finch la punta della freccia del cursore
di trascinamento punta alla nuova locazione.
2 Rilasciare il pulsante del mouse per abbandonare la voce di menu nella nuova
locazione.
Per spostare una voce in un elenco di menu:
1 Trascinare la voce lungo la barra dei menu finch la punta della freccia del cursore
di trascinamento punta al nuovo menu.
Questo obbliga il menu ad aprirsi, consentendo di trascinare la voce nella sua
nuova locazione.
2 Trascinare la voce di menu nellelenco, rilasciando il pulsante del mouse per
abbandonare la voce di menu nella nuova locazione.
Aggiunta di immagini alle voci di menu
Le immagini possono aiutare gli utenti a navigare nei menu facendo corrispondere
glyph e immagini allazione della voce di menu, in modo analogo alle immagini della
barra strumenti. possibile aggiungere singole bitmap alle voci di menu oppure
possibile organizzare le immagini per lapplicazione in una lista di immagini e
aggiungerle a un menu prelevandole dalla lista di immagini. Se nellapplicazione si
utilizzano numerose bitmap delle stesse dimensioni, utile collocarle in una lista di
immagini.
Per aggiungere una singola immagine a un menu o a una voce di menu, impostarne
la propriet Bitmap in modo che faccia riferimento al nome della bitmap che sar
utilizzata sul menu o sulla voce di menu.
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-39
C r e a z i o n e e g e s t i o n e d e i m e n u
Per aggiungere unimmagine a una voce di menu utilizzando una lista di immagini:
1 Rilasciare un oggetto TMainMenu o TPopupMenu su una scheda.
2 Rilasciare un oggetto TImageList sulla scheda.
3 Aprire lImageList editor facendo doppio clic sulloggetto TImageList.
4 Fare clic su Add per selezionare la bitmap o il gruppo di bitmap da usare nel
menu. Fare clic su OK.
5 Impostare la propriet Images delloggetto TMainMenu o TPopupMenu allImageList
appena creato.
6 Creare le voci di menu e di sottomenu come precedentemente descritto.
7 Selezionare la voce di menu per la quale si desidera unimmagine nellObject
Inspector e impostare la propriet ImageIndex al corrispondente numero
dellimmagine nellImageList (il valore predefinito per ImageIndex 1, che non
visualizza alcuna immagine).
_
Usare immagini 16 per 16 pixel per una visualizzazione corretta nel menu. Anche se
possibile usare altre dimensioni, quando si usano immagini pi grandi o pi piccole
potrebbero nascere problemi di allineamento e di coerenza.
Visualizzazione del menu
In fase di progettazione, possibile visualizzare il menu nella scheda senza prima
eseguire il codice del programma. (I menu del componente a comparsa sono visibili
nella scheda in fase di progettazione, ma ci non succede per gli stessi menu a
comparsa. Usare il Menu Designer per visualizzare un menu a comparsa in fase di
progettazione.)
Per visualizzare il menu:
1 Se la scheda visibile, fare clic sulla scheda, o dal menu View, scegliere la scheda
di cui si vuole visualizzare il menu.
2 Se la scheda ha pi di un menu, selezionare il menu desiderato dallelenco a
discesa della propriet Menu della scheda.
Il menu appare nella scheda esattamente come apparir quando il programma
viene eseguito.
Editing delle voci di menu nellObject Inspector
Questa sezione ha trattato come impostare alcune propriet per le voci di menuper
esempio, le propriet Name e Captionusando il Menu Designer.
La sezione ha anche descritto come impostare le propriet di una voce di menu, come
ShortCut, direttamente nellObject Inspector, proprio come si farebbe per qualsiasi
componente selezionato nella scheda.
Quando si modifica una voce di menu usando il Menu Designer, le sue propriet
vengono ancora visualizzate nellObject Inspector. Si pu passare il fuoco allObject
Inspector e continuare l lediting delle propriet della voce di menu. Oppure si pu
8-40 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e g e s t i o n e d e i m e n u
selezionare la voce di menu dal Component list nellObject Inspector e modificarne le
propriet senza aprire sempre il Menu Designer.
Per chiudere il Menu Designer e continuare la modifica delle voci di menu:
1 Passare il fuoco dalla finestra Menu Designer allObject Inspector facendo clic
sulla pagina Properties dellObject Inspector.
2 Chiudere il Menu Designer coma al solito.
Il fuoco rimane nellObject Inspector, dove possibile continuare lediting delle
propriet per la voce di menu selezionata. Per modificare unaltra voce di menu,
selezionarla dal Component list.
Uso del menu contestuale Menu Designer
Il menu contestuale di Menu Designer fornisce un rapido accesso ai comandi pi
usati del Menu Designer, e alle opzioni relative ai modelli di menu. Per ulteriori
informazioni sui modelli di menu, consultare Uso dei modelli di menu a
pagina 8-41.)
Per visualizzare il menu contestuale, fare clic con il tasto destro sulla finestra Menu
Designer, o premere Alt+F10 mentre il cursore si trova nella finestra.
I comandi del menu contestuale
La seguente tabella riporta i comandi del menu contestuale Menu Designer.
Passaggio da un menu allaltro in fase di progettazione
Se per la scheda occorre creare molti menu, si pu usare il menu contestuale Menu
Designer o lObject Inspector per selezionare e spostarsi facilmente dalluno allaltro.
Tabella 8.5 Comandi del menu contestuale Menu Designer
Comando Azione
Insert Inserisce un placeholder sopra o a sinistra del cursore.
Delete Cancella la voce di menu selezionata (e tutti i suoi sottoelementi, se ne
esistono).
Create Submenu Crea un placeholder a un livello annidato e aggiunge una freccia alla
destra della voce di menu selezionata.
Select Menu Apre un elenco di menu nella scheda corrente. Facendo doppio clic su un
nome di menu si apre la finestra designer per il menu.
Save As Template Apre la finestra di dialogo Save Template, dove possibile salvare un
menu che potrebbe essere utile in futuro.
Insert From
Template
Apre la finestra di dialogo Insert Template, dove possibile selezionare
un modello da riutilizzare.
Delete Templates Apre la finestra di dialogo Delete Templates, dove possibile cancellare
un qualsiasi modello esistente.
Insert From
Resource
Apre la finestra di dialogo Insert Menu from file Resource, dove
possibile scegliere un file .rc oppure .mnu da aprire nella scheda corrente.
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-41
C r e a z i o n e e g e s t i o n e d e i m e n u
Per usare il menu contestuale per passare da un menu allaltro di una scheda:
1 Fare clic destro nel Menu Designer e scegliere Select Menu.
Viene visualizzata la finestra di dialogo Select Menu.
Figura 8.8 Finestra di dialogo Select Menu
Questa finestra di dialogo elenca tutti i menu associati alla scheda il cui menu
attualmente aperto nel Menu Designer.
2 Dallelenco della finestra di dialogo Select Menu, scegliere il menu da visualizzare
o modificare.
Per usare Object Inspector to switch between menus in a form:
1 Passare il fuoco sulla scheda da cui scegliere i menu.
2 Dal Component list, selezionare il menu da modificare.
3 Sulla pagina Properties dellObject Inspector, selezionare la propriet Items per
questo menu, e quindi fare clic sul pulsante ellissi o doppio clic su [Menu].
Uso dei modelli di menu
C++Builder fornisce molti menu gi progettati, o modelli di menu, che contengono i
comandi usati pi frequentemente. possibile usare questi menu nella applicazioni
senza modificarli (a parte la scrittura del codice), o come punto di partenza,
personalizzandoli come si farebbe con un proprio menu progettato in precedenza. I
modelli di menu non contengono qualsiasi codice di gestore di evento.
I modelli di menu forniti con C++Builder sono memorizzati nella sottodirectory BIN
di uninstallazione predefinita. Questi file hanno estensione .dmt (modelli di menu di
C++Builder.
Inoltre, possibile salvare un modello di qualsiasi menu progettato usando Menu
Designer. Dopo aver salvato un menu come modello, possibile usarlo come
qualsiasi menu gi progettato. Quando un particolare modello di menu non serve
pi, possibile cancellarlo dallelenco.
Per aggiungere un modello di menu allapplicazione:
1 Fare clic con il tasto destro sul Menu Designer e scegliere Insert From Template.
8-42 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e g e s t i o n e d e i m e n u
(Se non ci sono modelli, lopzione Insert From Template nel menu contestuale
appare attenuata.)
Viene aperta la finestra di dialogo Insert Template, con un elenco di modelli di
menu disponibili.
Figura 8.9 Esempio di finestra di dialogo Insert Template per i menu
2 Selezionare il modello di menu da inserire, quindi premere Invio o scegliere OK.
Questa operazione inserisce il menu nella scheda alla posizione del cursore. Per
esempio, se il cursore su una voce di menu di un elenco, il modello di menu
viene inserito sopra la voce selezionata. Se il cursore sulla barra dei menu, il
modello viene inserito a sinistra del cursore.
Per cancellare un modello di menu:
1 Fare clic con il tasto destro sul Menu Designer e scegliere Delete Templates.
(Se non ci sono modelli, lopzione Delete Templates del menu contestuale appare
attenuata.)
Viene aperta la finestra di dialogo Delete Templates, con un elenco di modelli
disponibili.
2 Selezionare il modello di menu da cancellare, e premere Del.
C++Builder cancella il modello dallelenco e dal disco rigido.
Salvataggio di un menu come modello
Qualsiasi menu progettato pu essere salvato come modello, in modo da poterlo di
nuovo. I modelli di menu possono essere usati per fornire alle applicazioni un
aspetto armonioso, o come punto di partenza per ulteriori personalizzazioni.
I modelli di menu salvati vengono memorizzati nella sottodirectory BIN come file
.dmt.
Per salvare un menu come modello:
1 Progettare il menu da riutilizzare.
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-43
C r e a z i o n e e g e s t i o n e d e i m e n u
Questo menu pu contenere tutte le voci, i comandi e i sottomenu preferiti; tutto
ci che si trova nella finestra Menu Designer attiva verr salvato come menu
riutilizzabile.
2 Fare clic con il tasto destro sul Menu Designer e scegliere Save As Template.
Viene visualizzata la finestra di dialogo Save Template.
Figura 8.10 Finestra di dialogo Save Template per menu
3 Nella casella di modifica Template Description, scrivere una breve descrizione per
questo menu, e quindi scegliere OK.
La finestra di dialogo Save Template si chiude, salvando il progetto del menu e
ritornando alla finestra Menu Designer.
_
La descrizione immessa viene visualizzata solo nelle finestre di dialogo Save
Template, Insert Template e Delete Templates. Non collegata alla propriet Name o
Caption per il menu.
Convenzioni per lassegnazione dei nomi delle voci di menu e dei gestori di
evento di un modello
Quando si salva un menu come modello, C++Builder non salva la sua propriet
Name, poich ogni menu deve avere un nome caratteristico allinterno del campo
dazione del suo proprietario (la scheda). Tuttavia, quando in una scheda viene
inserito il menu come modello usando il Menu Designer, allora C++Builder genera
nuovi nomi per il menu stesso e per tutte le sue voci.
Per esempio, si supponga di salvare un menu File come modello. Nel menu originale,
questo menu stato chiamato MyFile. Se tale menu viene inserito come modello in un
nuovo menu, C++Builder gli assegna il nome File1. Se il menu viene inserito in un
menu con una voce di menu chiamata File1, C++Builder gli assegna il nome File2.
C++Builder non salva neanche tutti i gestori di evento OnClick associata a un menu
salvato come modello, poich non c alcun modo per verificare se il codice valido
nella nuova scheda. Quando viene generato un nuovo gestore di evento per la voce
di menu di un modello, C++Builder genera ancora il nome del gestore di evento.
8-44 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e g e s t i o n e d e i m e n u
possibile associare facilmente le voci del modello di menu ai gestori di evento
OnClick esistenti nella scheda.
Manipolazione delle voci di menu in fase di esecuzione
Qualche volta, potrebbe essere necessario aggiungere delle voci di menu a una
struttura di menu esistente mentre lapplicazione in esecuzione, in modo da fornire
ulteriori informazioni o opzioni allutente. possibile inserire una voce di menu
usando il metodo Add o Insert della voce di menu, o in alternativa nascondere e
mostrare le voci di un menu cambiando la loro propriet Visible. La proprietVisible
determina se la voce viene visualizzata nel menu. Per attenuare una voce di menu
senza nasconderla, usare la propriet Enabled.
Per esempi che usano le propriet Visible e Enabled della voce di menu, consultare
Disattivazione delle voci di menu a pagina 6-10.
Nelle applicazioni MDI (Multiple Document Interface) e OLE (Object Linking and
Embedding), possibile anche fondere le voci contenute in una barra di menu
esistente. La seguente sezione tratta questo argomento in dettaglio.
Fusione dei menu
Per le applicazioni MDI, come unapplicazione di esempio di editor di testi, e per le
applicazioni client OLE, il menu principale dellapplicazione deve essere in grado di
ricevere voci di menu da unaltra scheda o dalloggetto server OLE. Spesso, ci viene
chiamato fusione di menu. bene ricordare che la tecnologia OLE utilizzabile solo in
applicazioni Windows e non disponibile per lo sviluppo di applicazioni
multipiattaforma.
I menu da fondere vengono preparati specificando i valori di due propriet:
Menu, una propriet della scheda
GroupIndex, una propriet delle voci del menu
Specifica del menu attivo: propriet Menu
La propriet Menu specifica il menu attivo per la scheda. Le operazioni per la fusione
dei menu valgono solo per il menu attivo. Se la scheda contiene pi di un
componente menu, possibile cambiare il menu attivo in fase di esecuzione
impostando la propriet Menu nel codice. Per esempio,
.>.c .cc..c,
Determinazione dellordine delle voci di menu fuse: propriet GroupIndex
La propriet GroupIndex determina lordine in cui le voci di menu fuse appaiono nella
barra dei menu condivisa. Le voci di menu della fusione possono sostituire quelle
sulla barra del menu principale, o essere mischiate.
Il valore predefinito per GroupIndex 0. Quando si specifica un valore per GroupIndex
si devono applicare diverse regole:
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-45
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
I numeri pi bassi appaiono prima (pi a sinistra) nel menu.
Per esempio, impostare la propriet GroupIndex a 0 (zero) per un menu che debba
essere sempre il primo a sinistra, come un menu File. Analogamente, specificare
un numero alto (non necessariamente in sequenza) per un menu che debba essere
sempre il primo a destra, come un menu Help.
Per sostituire le voci del menu principale, dare alle voci sul menu figlio lo stesso
valore GroupIndex.
Questa regola applicabile ai raggruppamenti e alle singole voci. Per esempio, se
la scheda principale ha una voce di menu Edit con un valore GroupIndex di 1,
possibile sostituirla con una o pi voci dal menu della scheda figlia dando anche a
questa un valore GroupIndex di 1.
Fornendo alle stesse voci del menu figlio lo stesso valore GroupIndex si tiene il loro
ordine intatto quando vengono fuse nel menu principale.
Per inserire le voci senza sostituire quelle del menu principale, lasciare spazio
nellintervallo numerico delle voci del menu principale e inserire i numeri dalla
scheda figlia.
Per esempio, numerare le voci del menu principale 0 e 5, e inserire le voci del
menu figlio numerandole 1, 2, 3 e 4.
Importazione dei file risorsa
C++Builder supporta menu costruiti con altre applicazioni, purch siano nel formato
file risorsa standard (.RC) di Windows. Tali menu possono essere importati
direttamente nel progetto C++Builder, risparmiando il tempo e la fatica di costruire
di nuovo i menu che sono stati creati altrove.
Per caricare i file menu .RC esistenti:
1 Nel Menu Designer, collocare il cursore nel punto in cui far apparire il menu.
Il menu importato pu far parte di un menu in costruzione, o essere un menu
completo.
2 Fare clic con il tasto destro e scegliere Insert From Resource.
Viene visualizzata la finestra di dialogo Insert Menu From Resource.
3 Nella finestra di dialogo, selezionare il file risorsa da caricare e scegliere OK.
Il menu appare nella finestra Menu Designer.
_
Se il file risorsa contiene pi di un menu, occorre prima salvare ciascun menu come
un file risorsa distinto prima di importarlo.
Progettazione di barre strumenti e di coolbar
Una barra strumenti un pannello, solitamente nella parte superiore di una scheda
(sotto la barra dei menu), che contiene pulsanti e altri controlli. Una coolbar (chiamata
8-46 G u i d a a l l a p r o g r a mma z i o n e
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
anche rebar) una particolare barra strumenti che visualizza i controlli su bande
mobili e ridimensionabili. Se vi sono pi pannelli allineati al bordo superiore della
scheda, essi vengono impilati in verticale, in base alla sequenza con cui sono stati
aggiunti.
_
Le coolbar non sono disponibili in CLX per applicazioni multipiattaforma.
Su una barra strumenti possono essere messi controlli di qualsiasi tipo. Oltre ai
pulsanti, potrebbe essere opportuno mettere griglie per luso dei colori, barre di
scorrimento, etichette, e cos via.
Esistono molti modi per aggiungere una barra strumenti a una scheda:
Collocare un pannello (TPanel) sulla scheda e aggiungervi i controlli (di solito
pulsanti di scelta rapida).
Usare un componente barra strumenti (TToolBar) invece di TPanel, e aggiungervi i
controlli. TToolBar gestisce i pulsanti e altri controlli, sistemandoli in righe e
regolandone automaticamente dimensioni e posizioni. Se sulla barra strumenti
vengono usati controlli pulsante di strumento (TToolButton), TToolBar facilita il
raggruppamento dei pulsanti per funzione e fornisce altre opzioni di
visualizzazione.
Usare un componente coolbar (TCoolBar) e aggiungervi i controlli. La coolbar
visualizza i controlli su bande mobili e ridimensionabili indipendenti.
Il modo in cui implementare la barra strumenti dipende dallapplicazione. Il
vantaggio di usare il componente Panel sta nel fatto che si ha il controllo totale
dellaspetto della barra strumenti.
Usando componenti barra strumenti e coolbar, si garantisce allapplicazione di avere
laspetto di unapplicazione Windows, poich vengono usati i controlli Windows
nativi. Se questi controlli del sistema operativo in futuro cambiano, anche
lapplicazione potrebbe cambiarli. Inoltre, dal momento che la barra strumenti e la
coolbar fa affidamento sui componenti standard di Windows, lapplicazione richiede
COMCTL32.DLL. Le barre strumenti e le coolbar non vengono supportate dalle
applicazioni WinNT 3.51.
Nelle sezioni seguenti viene descritta la procedura per:
Aggiungere una barra strumenti e i corrispondenti controlli pulsante di scelta
rapida usando il componente barra strumenti.
Aggiungere una barra strumenti e i corrispondenti controlli pulsante strumento
usando il componente barra strumenti.
Aggiungere una coolbar usando il componente coolbar.
Rispondere ai clic.
Aggiungere barre strumenti e coolbar nascoste.
Nascondere e mostrare barre strumenti e coolbar.
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-47
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
Aggiunta di una barra strumenti usando un componente panel
Per aggiungere una barra strumenti a una scheda usando il componente panel:
1 Aggiungere alla scheda un componente panel (dalla pagina Standard della
Component palette).
2 Impostare la propriet Align del pannello a alTop. Quando allineato alla parte
superiore della scheda, il pannello conserva laltezza, ma adegua la sua larghezza
a quella dellarea client della scheda, anche se la finestra cambia dimensioni.
3 Aggiungere i pulsanti di scelta rapida o altri controlli al pannello.
I pulsanti di scelta rapida sono progettati per lavorare sui pannelli della barra
strumenti. Un pulsante di scelta rapida, normalmente, non ha alcun caption, ma solo
un piccolo grafico (chiamato glyph), che rappresenta la funzione del pulsante.
I pulsanti di scelta rapida hanno tre possibili modi di funzionamento. Essi possono
Agire come normali pulsanti a pressione
Attivare e disattivare quando vi si fa clic sopra
Agire come un insieme di pulsanti radio
Per implementare i pulsanti di scelta rapida sulle barre strumenti:
Aggiungere un pulsante di scelta rapida a un pannello della barra strumenti.
Assegnare un glyph al pulsante di scelta rapida.
Impostare la condizione iniziale di un pulsante di scelta rapida.
Creare un gruppo di pulsanti di scelta rapida.
Consentire la commutazione dei pulsanti.
Aggiunta di un pulsante di scelta rapida a un pannello
Per aggiungere un pulsante di scelta rapida a un pannello della barra strumenti,
collocare il componente pulsante di scelta rapida (dalla pagina Additional della
Component palette) sul pannello.
Il pannello, e non la scheda, possiede il pulsante di scelta rapida, in modo che
spostando o nascondendo il pannello si sposta o si nasconde anche il pulsante di
scelta rapida.
Laltezza predefinita del pannello 41, mentre quella dei pulsanti di scelta rapida
25. Se la propriet Top di ciascun pulsante viene impostata a 8, essi verranno centrati
verticalmente. Limpostazione predefinita della griglia blocca automaticamente il
pulsante di scelta rapida in quella posizione verticale.
Assegnazione del glifo a un pulsante di scelta rapida
Ogni pulsante di scelta rapida ha bisogno di unimmagine grafica, detta anche glifo,
per indicare allutente la funzione svolta. Se viene fornita solo unimmagine, il
pulsante di scelta rapida manipola quellimmagine per indicare che stato premuto,
non premuto, selezionato o disattivato. Se si preferisce, possibile fornire anche
specifiche immagini distinte per ciascuno stato.
8-48 G u i d a a l l a p r o g r a mma z i o n e
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
Normalmente, i glifi vengono assegnati ai pulsanti di scelta rapida in fase di
progettazione, anche se possibile assegnare glifi differenti in fase di esecuzione.
Per assegnare un glifo a un pulsante di scelta rapida in fase di progettazione:
1 Selezionare il pulsante di scelta rapida.
2 NellObject Inspector, selezionare la propriet Glyph.
3 Fare doppio clic sulla colonna Value a fianco di Glyph per aprire il Picture Editor e
selezionare la bitmap desiderato.
Impostazione della condizione iniziale di un pulsante di scelta rapida
I pulsanti di scelta rapida sfruttano il proprio aspetto per dare allutente indizi
relativi al loro stato e alla loro funzione. Poich non hanno alcuna etichetta,
importante usare le parti visuali corrette per aiutare gli utenti.
La Tabella 8.6 elenca alcune azioni che possibile impostare per cambiare laspetto di
un pulsante di scelta rapida:
Se lapplicazione ha uno strumento di disegno predefinito, essere certi che il suo
pulsante sulla barra strumenti premuto quando lapplicazione viene avviata. Per
eseguire questa operazione, impostare la sua propriet GroupIndex a un valore
diverso da zero e la sua propriet Down a true.
Creazione di un gruppo di pulsanti di scelta rapida
Spesso, una serie di pulsanti di scelta rapida rappresenta un insieme di scelte che si
escludono a vicenda. In questo caso, occorre riunire i pulsanti in un gruppo, in modo
che il clic su un qualsiasi pulsante del gruppo obblighi gli altri pulsanti a risalire.
Per associare un qualsiasi numero di pulsanti di scelta rapida in un gruppo,
assegnare lo stesso numero a ciascuna propriet GroupIndex del pulsante di scelta
rapida.
Il modo pi facile per compiere questa operazione quello di selezionare tutti i
pulsanti desiderati nel gruppo, e, con lintero gruppo selezionato, impostare
GroupIndex a un valore caratteristico.
Come consentire la commutazione dei pulsanti
Qualche volta, si vuole avere la possibilit di fare clic su un pulsante gi premuto di
un gruppo e riportarlo su, non lasciando nel gruppo alcun pulsante premuto. Un tale
pulsante viene chiamato commutatore. Usare AllowAllUp per creare un pulsante di
Tabella 8.6 Impostazione dellaspetto di pulsanti scelta rapid a
Per fare in modo che un pulsante di
scelta rapida: Nella barra strumenti, impostare:
Appaia premuto La propriet GroupIndex a un valore diverso da zero e la
sua propriet Down a true.
Appaia disattivato La propriet Enabled a false.
Abbia un margine sinistro La propriet Indent a una valore maggiore di 0.
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-49
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
gruppo che agisce come un commutatore: facendo clic su esso una prima volta,
rimane gi; facendo clic di nuovo, ritorna su.
Perch un pulsante di scelta rapida di gruppo diventi un commutatore, impostare la
sua propriet AllowAllUp a true.
Impostando AllowAllUp a true per tutti i pulsanti di scelta rapida di un gruppo, si
imposta automaticamente lo stesso valore di propriet per tutti i pulsanti del gruppo.
Ci consente al gruppo di agire come un normale gruppo, con un solo pulsante
premuto alla volta, ma consente anche ai pulsanti di essere contemporaneamente
tutti su.
Aggiunta di una barra strumenti usando il relativo componente
Il componente barra strumenti (TToolBar) offre caratteristiche di gestione e di
visualizzazione dei pulsanti che i componenti pannello non hanno. Per aggiungere
una barra strumenti a una scheda usando questo componente:
1 Aggiungere alla scheda un componente barra strumenti (dalla pagina Win32 della
Component palette). La barra strumenti viene allineata automaticamente alla
parte superiore della scheda.
2 Aggiungere alla barra i pulsanti strumento o altri controlli.
I pulsanti strumento sono progettati per lavorare sui componenti barra strumenti.
Come i pulsanti di scelta rapida, i pulsanti strumento possono:
Agire come normali pulsanti a pressione.
Attivare e disattivare quando vi si fa clic sopra.
Agire come un insieme di pulsanti radio.
Per implementare i pulsanti strumento su una barra strumenti:
Aggiungere un pulsante strumento
Assegnare le immagini ai pulsanti strumento
Impostare laspetto dei pulsanti strumento
Creare un gruppo di pulsanti strumento
Consentire la commutazione di pulsanti strumento
Aggiunta di un pulsante strumento
Per aggiungere un pulsante strumento a una barra strumenti, fare clic con il tasto
destro sulla barra strumenti e scegliere New Button.
La barra strumenti possiede il pulsante strumento, cos che, spostando o
nascondendo la barra strumenti, si sposta o si nasconde anche il pulsante. Inoltre,
tutti i pulsanti strumento sulla barra strumenti mantengono automaticamente
laltezza e la larghezza. Sulla barra strumenti possibile rilasciare altri controlli dalla
Component palette, e manterranno automaticamente unaltezza uniforme. I controlli,
inoltre, vanno automaticamente a capo e iniziano una nuova riga quando la
dimensione orizzontale della barra strumenti non sufficiente a contenerli.
8-50 G u i d a a l l a p r o g r a mma z i o n e
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
Assegnazione di immagini ai pulsanti strumento
Ogni pulsante strumento ha una propriet ImageIndex che determina quale immagine
appare su di esso in fase di esecuzione. Se al pulsante strumento viene fornita solo
unimmagine, il pulsante manipola quellimmagine per indicare che il pulsante
disattivato. Per assegnare le immagini ai pulsanti strumento in fase di progettazione:
1 Selezionare la barra strumenti sulla quale devono apparire i pulsanti.
2 NellObject Inspector, assegnare un oggetto TImageList alla propriet Images della
barra strumenti. Un elenco di immagini una raccolta di icone o bitmap con le
stesse dimensioni.
3 Selezionare un pulsante strumento.
4 NellObject Inspector, assegnare un intero alla propriet ImageIndex del pulsante
strumento che corrisponde allimmagine dellelenco da assegnare al pulsante.
possibile specificare anche immagini distinte che appaiono sui pulsanti strumento
quando vengono disattivati e quando sono sotto il puntatore del mouse. Per eseguire
questa operazione, assegnare immagini distinte alle propriet DisabledImages e
HotImages della barra strumenti.
Impostazione dellaspetto di un pulsante strumento e delle condizioni iniziali
La Tabella 8.7 elenca alcune azioni che possibile impostare per cambiare laspetto di
un pulsante strumento:
_
Luso della propriet Flat di TToolBar richiede la versione 4.70 o successive di
COMCTL32.DLL.
Per forzare una nuova riga di controlli dopo un determinato pulsante, strumento,
selezionare il pulsante strumento che deve apparire per ultimo nella riga e impostare
la sua propriet Wrap a true.
Per disattivare la caratteristica auto-wrap di una barra strumenti, impostare la
propriet Wrapable della barra strumenti a false.
Creazione di gruppi di pulsanti strumento
Per creare un gruppo di pulsanti strumento, selezionare i pulsanti da associare e
impostare la loro propriet Style a tbsCheck; quindi impostare la loro propriet
Grouped a true. La selezione di un pulsante strumento di gruppo obbliga gli altri
Tabella 8.7 Impostazione dellaspetto di pulsanti strumento
Per fare in modo che un pulsante
strumento: Nella barra strumenti, impostare
Appaia premuta (La propriet Style (su un pulsante strumento) a tbsChecke
e la propriet Down a true.
Appaia disattivato La propriet Enabled a false.
Abbia un margine sinistro La propriet Indent a una valore maggiore di 0.
Appaia con i bordi pop-up,
rendendo perci la barra strumenti
trasparente
La propriet Flat a true.
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-51
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
pulsanti del gruppo a pop up, che un utile modo di rappresentare un insieme di
scelte che si escludono a vicenda.
Una qualsiasi sequenza ininterrotta di pulsanti strumento adiacenti con Style
impostata a tbsCheck e Grouped impostata a true forma un singolo gruppo. Per
spezzare un gruppo di pulsanti strumento, separare i pulsanti con un qualsiasi:
Pulsante strumento la cui propriet Grouped false.
Pulsante strumento la cui propriet Style non impostata a tbsCheck. Per creare
spazi o divisioni sulla barra strumenti, aggiungere un pulsante strumento la cui
propriet Style tbsSeparator o tbsDivider.
Un altro controllo che non sia un pulsante strumento.
Come consentire pulsanti strumento commutati
Usare AllowAllUp per creare un pulsante strumento di gruppo che agisce come un
commutatore: facendo clic su esso una prima volta, rimane gi; facendo clic di
nuovo, ritorna su.Perch un pulsante strumento di gruppo diventi un commutatore,
impostare la sua propriet AllowAllUp a true.
Come i pulsanti di scelta rapida, impostando AllowAllUp a true per tutti i pulsanti
strumento di un gruppo, si imposta automaticamente lo stesso valore di propriet
per tutti i pulsanti del gruppo.
Aggiunta di un componente coolbar
_
Il componente TCoolBar richiede la versione 4.70 o successiva di COMCTL32.DLL e
non disponibile in CLX.
Il componente coolbar (TCoolBar) detto anche rebar visualizza controlli con
finestra su bande mobili e ridimensionabili in modo indipendente. Lutente pu
posizionare le bande trascinando i grip di ridimensionamento sul lato sinistro di
ciascuna banda.
Per aggiungere una coolbar a una scheda in unapplicazione Window:
1 Aggiungere alla scheda un componente coolbar (dalla pagina Win32 della
Component palette). La coolbar viene allineata automaticamente alla parte
superiore della scheda.
2 Aggiungere alla barra i controlli windowed dalla Component palette.
Solo i componenti della VCL che discendono da TWinControl sono controlli con
finestra. possibile aggiungere alla coolbar controlli grafici, come etichette o
pulsanti, ma non appariranno su bande distinte.
8-52 G u i d a a l l a p r o g r a mma z i o n e
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
Impostazione dellaspetto della coolbar
Il componente coolbar offre molte utili opzioni di configurazione. La Tabella 8.8
elenca alcune azioni che possibile impostare per cambiare laspetto di un pulsante
strumento:
Per assegnare immagini alle singole bande, selezionare la coolbar e fare doppio clic
sulla propriet Bands nellObject Inspector. Quindi selezionare una banda e assegnare
un valore alla sua propriet ImageIndex.
Risposta ai clic
Quando lutente fa clic su un controllo, come un pulsante su una barra strumenti,
lapplicazione genera un evento OnClick a cui possibile rispondere con un gestore
di evento. Poich OnClick levento predefinito dei pulsanti, possibile generare uno
scheletro di gestore di evento facendo doppio clic sul pulsante in fase di
progettazione.
Assegnazione di un menu a un pulsante strumento
Se viene usata una barra strumenti (TToolBar) con pulsanti strumento (TToolButton),
possibile associare un menu a uno specifico pulsante:
1 Selezionare il pulsante strumento.
2 NellObject Inspector, assegnare un menu a comparsa (TPopupMenu) alla propriet
DropDownMenu del pulsante strumento.
Tabella 8.8 Impostazione dellaspetto di un pulsante cool
Per fare in modo che la coolbar: Nella barra strumenti, impostare:
Venga ridimensionata automaticamente
per alloggiare le bande che contiene
La propriet AutoSize a true.
Mantenga le bande a unaltezza
uniforme
La propriet FixedSize a true.
Venga orientata verticalmente invece
che orizzontalmente
La propriet Vertical a true. Questa operazione cambia
leffetto della propriet FixedSize.
Impedisca alle propriet Text delle
bande la visualizzazione in fase di
esecuzione
La propriet ShowText a false. Ciascuna banda di una
coolbar ha una sua propriet Text.
Rimuova il bordo che la circonda La propriet BandBorderStyle a bsNone.
Impedisca agli utenti di cambiare
lordine delle bande in fase di
esecuzione. (Lutente pu sempre
spostare e ridimensionare le bande.)
FixedOrder a true.
Crei unimmagine per lo sfondo della
coolbar
La propriet Bitmap alloggetto TBitmap.
Scelga un elenco di immagini da
visualizzare a sinistra di qualsiasi banda
La propriet Images alloggetto TImageList.
S v i l u p p o d e l l i n t e r f a c c i a u t e n t e d e l l a p p l i c a z i o n e 8-53
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
Se la propriet AutoPopup del menu impostata a true, apparir automaticamente
quando il pulsante viene premuto.
Aggiunta di barre strumenti nascoste
Le barre strumenti non devono essere visibili tutte le volte. Infatti, spesso comodo
avere a disposizione un gran numero di barre strumenti, ma mostrarle solo quando
lutente desidera usarle. Altrettanto spesso, quindi, viene creata una scheda che ha
molte barre strumenti, ma tutte o in parte nascoste.
Per creare una barra strumenti nascosta:
1 Aggiungere alla scheda un componente barra strumenti, coolbar o pannello.
2 Impostare la propriet Visible del componente a false.
Anche se la barra strumenti rimane visibile in fase di progettazione in modo da
poterla modificare, rimane nascosta in fase di esecuzione finch lapplicazione non la
rende specificamente visibile.
Come nascondere e mostrare le barre strumenti
Spesso, opportuno che unapplicazione abbia barre strumenti multiple, ma non si
vuole ingombrare la scheda visualizzandole tutte insieme. Oppure, si pu lasciare
agli utenti la possibilit di decidere se visualizzare le barre strumenti. Come tutti i
componenti, le barre strumenti possono essere mostrate o nascoste, secondo le
necessit, in fase di esecuzione.
Per nascondere o mostrare una barra strumenti in fase di esecuzione, impostare la
sua propriet Visible, rispettivamente, a false o true. Normalmente, questa
operazione viene eseguita in risposta a particolari eventi dellutente o a modifiche nel
modo operativo dellapplicazione. Per eseguire questa operazione, normalmente c
un pulsante close su ciascuna barra strumenti. Quando lutente fa clic su quel
pulsante, lapplicazione nasconde la corrispondente barra strumenti.
anche possibile fornire strumenti per la commutazione della barra strumenti. nel
seguente esempio, una barra strumenti di penne viene commutata da un pulsante
sulla barra strumenti principale. Poich ciascun clic preme o rilascia il pulsante, un
gestore di evento OnClick pu mostrare o nascondere al barra strumenti Pen a
seconda che il pulsante sia su o gi.
veIi __?aatcaII ..cc.ccc .c.c
.ci>scc .c>.,
8-54 G u i d a a l l a p r o g r a mma z i o n e
P r o g e t t a z i o n e d i b a r r e s t r u m e n t i e d i c o o l b a r
T i p i d i c o n t r o l l i 9-1
C a p i t o l o
9
Capitolo9Tipi di controlli
I controlli sono componenti visuali che aiutano a progettare linterfaccia utente.
Questo capitolo descrive i vari controlli che possibile utilizzare, tra cui controlli di
testo, controlli di input, pulsanti, controlli elenco, controlli di raggruppamento,
controlli di visualizzazione, griglie, editor di valori di elenco e controlli grafici.
Per la creazione di un controllo grafico consultare il Capitolo 54, Creazione di un
controllo grafico. Per sapere come implementare tali controlli vedere il Capitolo 6,
Uso dei controlli.
Controlli di testo
Molte applicazioni utilizzano controlli di testo per mostrare il testo allutente.
possibile utilizzare:
Controlli di editing, che permettono allutente di aggiungere testo.
Utilizzare questo
componente: Per consentire allutente di:
TEdit Modificare una singola riga di testo.
TMemo Modificare pi righe di testo.
TMaskEdit Immettere un testo in modo conforme a un particolare formato, come un
codice postale oppure un numero di telefono.
TRichEdit Modificare pi righe di testo utilizzando il formato rich text (solo per la
VCL).
9-2 G u i d a a l l a p r o g r a mma z i o n e
C o n t r o l l i d i t e s t o
Controlli per la visualizzazione del testo ed etichette, che non consentono
allutente di aggiungere testo:
Controlli di editing
I controlli di editing mostrano del testo allutente e gli consentono di immettere del
testo. Il tipo di controllo utilizzato a questo scopo dipende dalle dimensioni e dal
formato delle informazioni.
TEdit e TMaskEdit sono semplici controlli di testo che includono una casella di
modifica per una singola linea di testo in cui possibile inserire informazioni.
Quando la casella di modifica riceve il fuoco, viene visualizzato un punto di
inserimento lampeggiante.
possibile includere del testo nella casella di modifica assegnando un valore di
stringa alla propriet Text. Laspetto del testo nella casella di modifica viene
controllato assegnando dei valori alla propriet Font. possibile specificare il tipo di
carattere, le dimensioni, il colore e gli attributi del carattere. Gli attributi influiscono
su tutto il testo nella casella di modifica e non possono essere applicati a singoli
caratteri.
Una casella di modifica pu essere progettata in modo che modifichi le proprie
dimensioni a seconda delle dimensioni del font utilizzato. Loperazione possibile
impostando la propriet AutoSize a true. possibile limitare il numero di caratteri
che una casella di modifica pu contenere assegnando un valore alla propriet
MaxLength.
TMaskEdit uno speciale controllo per lediting che convalida il testo immesso a
fronte di una maschera che codifica i possibili formati validi che un testo pu
assumere. La maschera pu anche formattare il testo che viene mostrato allutente.
TMemo e TRichEdit permettono allutente di aggiungere diverse righe di testo.
Utilizzare questo
componente: Per consentire allutente di:
TTextBrowser Visualizzare un file di testo o una semplice pagina HTML che gli utenti
possono scorrere.
TTextViewer Visualizzare un file di testo o una semplice pagina HTML. Gli utenti
possono far scorrere la pagina o fare clic sui collegamenti per visualiz-
zare altre pagine e immagini.
TLCDNumber Visualizzare informazioni numeriche con un formato digitale.
TLabel Visualizzare del testo in un controllo senza finestra.
TStaticText Visualizzare testo in un controllo con finestra.
T i p i d i c o n t r o l l i 9-3
C o n t r o l l i d i t e s t o
Propriet dei controlli di editing
Di seguito sono elencate alcune importanti propriet dei controlli testo:
Controlli memo e rich edit
Entrambi i controlli TMemo e TRichEdit gestiscono pi linee di testo.
iis>.c> .c>c.,
I? .c.c ...c
iis>.c>.c ,s..,
eIae I? .c.c is.c
iis>.c>.c ,sis,
eIae I? .c.c .c
iis>.c>.c ,s,
eIae I? .c.c is.c
iis>.c>.c ,sis,
eIae I? .c.c is.c
iis>.c>.c ,sis,
eIae I? .c.c ci.c
iis>.c>.c ,sci,
10-8 G u i d a a l l a p r o g r a mma z i o n e
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
Il gestore di evento visto in precedenza potebbe essere ulteriormente ridotto
ponendo le costanti relative allo stile della penna nelle propriet Tag dei pulsanti
relativi allo stile delle penne. In questo caso, il codice dellevento sarebbe simile al
seguente::
veIi __?aatcaII ..c.c.cccc .c.c
I? .c.c>Lcs. __cIaaaIi.,cc.
iis>.c>.c .c.c .,cc. .c.c>i,
iis>s> s>ic..,
I? .c.c ..s
iis>s>.c cs..,
eIae I? .c.c cis
iis>s>.c csci,
eIae I? .c.c -.is
iis>s>.c cs-.i,
eIae I? .c.c ccis
iis>s>.c cscci,
eIae I? .c.c iis
iis>s>.c csii,
eIae I? .c.c iis
iis>s>.c csii,
eIae I? .c.c sss
iis>s>.c csss,
eIae I? .c.c isss
iis>s>.c csiss,
I? .c.c>Lcs. __cIaaaIi.,cc.
iis>s>.c s.c .,cc. .c.c>i,
iis>.c,,
iis>cc., c-c,
iis>.c, c-c,
iis>cc., ,
Disegno di spezzate
Oltre alle singole linee, il canvas pu disegnare anche spezzate, cio gruppi di un
numero qualunque di segmenti consecutivi.
Per disegnare una spezzata su un canvas, si deve chiamare il metodo Polyline del
canvas.
Il parametro passato al metodo Polyline un array di punti.Si pu pensare ad una a
spezzata come allesecuzione di un MoveTo sul primo punto e di un LineTo su ciascun
punto successivo. Per disegnare pi linee, Polyline pi rapido delluso dei metodi
MoveTo e LineTo, in quanto viene eliminato loverhead derivante dalle successive
chiamate.
Il metodo seguente, per esempio, disegna un rombo in una scheda:
veIi __?aatcaII ...iccc .c.c
. cccs,,
cccs, ., ,
cccs, ., ,
cccs,. ., ,
cccs, .., ,
cccs,1 ., ,
iis>.ccccs, 1,
Si noti che lultimo parametro di Polyline lindice dellultimo punto, e non il numero
di punti.
Disegno di figure
I canvas hanno metodi per disegnare tipi differenti di figure. Il canvas disegna il
contorno di una figura con la sua penna, quindi ne riempie linterno con il suo
pennello. La linea che rappresenta il bordo della figura controllata dalloggetto Pen
attivo.
In questa sezione vengono trattati i seguenti argomenti:
10-12 G u i d a a l l a p r o g r a mma z i o n e
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
Disegno di rettangoli ed ellissi.
Disegno di rettangoli arrotondati.
Disegno di poligoni.
Disegno di rettangoli ed ellissi
Per disegnare un rettangolo o unellisse su un canvas, si deve chiamare il metodo
Rectangle o il metodo Ellipse del canvas, passando le coordinate di un rettangolo di
contorno.
Il metodo Rectangle disegna il rettangolo di contorno; Ellipse disegna unellisse che
tocca tutti i lati del rettangolo.
Il metodo seguente disegna un rettangolo riempiendo il quadrante superiore sinistro
di una scheda, quindi disegna unellisse nella stessa area:
veIi __?aatcaII ...iccc .c.c
Disegno di poligoni
Per disegnare un poligono con un numero qualsiasi di lati su un canvas, si deve
chiamare il suo metodo Polygon.
Polygon accetta come unico parametro un array di punti. Questi vengono collegati
con la penna, e lultimo punto viene collegato al primo per chiudere il poligono.
Dopo aver disegnato le linee, Polygon usa il pennello per riempire larea allinterno
del poligono.
Ad esempio, il codice seguente disegna un triangolo rettangolo nella met inferiore
sinistra di una scheda:
veIi __?aatcaII ...iccc .c.c
. cccs,,
O p e r a z i o n i c o n e l e me n t i g r a f i c i e mu l t i me d i a l i 10-13
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
cccs, ., ,
cccs, ., c-c,
cccs,. .c.,c-c,
iis>.cccs,.,
i. .c,
i. .ccic,
i. .,sc,
i. ..cc,
caae .c
iis>.cx, ,
iis>c., ,
bteak,
caae .ccic
iis>ccicx, , ., ,
bteak,
caae .,sc
iis>,scx, , ., ,
bteak,
caae ..cc
iis>ccicx, , ., , x ..,
.,
bteak,
i. ?aIae,
I? i.
caae .c
iis>.cx, ,
iis>c.c.x, .c.,
iis>.cx, ,
iis>c., ,
bteak,
caae .ccic
iis>ccicx, , .c.x, .c.,
iis>ccicx, , ., ,
bteak,
caae .,sc
iis>,scx, , .c.x, .c.,
iis>,scx, , ., ,
bteak,
caae ..cc
iis>ccicx, , .c.x, .c.,
x .c.x., .c..,
iis>ccicx, , ., ,
x .., .,
10-16 G u i d a a l l a p r o g r a mma z i o n e
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
bteak,
.c. .., ,
iis>.c>..c ,.,,
iis>.c>..c ~..c,
avItca i.
caae .c
iis>.c,c.x, ,c.,
iis>c.x, .,
bteak,
caae .ccic
iis>ccic,c.x, ,c., .x, .,
bteak,
caae .,sc
iis>,sc,c.x, ,c., .x, .,
bteak,
caae ..cc
iis>ccic,c.x, ,c., .x, .,
,c.x .x.,,c. ..,
bteak,
I? i.
Disegno su un grafico
Non sono necessari componenti per manipolare gli oggetti grafici dellapplicazione.
possibile costruire, prelevare, salvare e distruggere oggetti grafici senza dover
necessariamente disegnare qualcosa sullo schermo. Infatti, raramente le applicazioni
disegnano direttamente su una scheda. Pi spesso unapplicazione opera sui grafici e
poi utilizza un componente controllo immagine per visualizzare il grafico su una
scheda.
10-18 G u i d a a l l a p r o g r a mma z i o n e
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
Una volta spostato il disegno dellapplicazione nel grafico del controllo immagine,
facile aggiungere le funzioni di stampa, di clipboard, di caricamento e salvataggio
per tutti gli oggetti grafici. Gli oggetti grafici possono essere file bitmap, metafile,
icone o qualsiasi altra classe di grafici installati, come, ad esempio, i grafici jpeg.
_
Poich si disegna su unimmagine fuori schermo come un canvas TBitmap,
limmagine non viene visualizzata finch un controllo non copia da una bitmap sul
canvas del controllo.Cio, quando si disegnano bitmap e si assegnano ad un controllo
immagine, limmagine appare solo quando il controllo ha lopportunit per elaborare
il messaggio Paint. Se, invece, si disegna direttamente sulla propriet canvas di un
controllo, loggetto Picture viene visualizzato immediatamente.
Come far scorrere i grafici
Il grafico non deve avere le stesse dimensioni della scheda: pu essere pi piccolo o
pi grande. Aggiungendo alla scheda un controllo casella di scorrimento e
collocando limmagine grafica al suo interno, possibile visualizzare grafici che sono
pi grandi della scheda o addirittura pi grandi dello schermo. Per aggiungere un
grafico con scorrimento, occorre prima aggiungere un componente TScrollBox e
quindi aggiungere il controllo immagine.
Aggiunta di un controllo immagine
Un controllo immagine un componente contenitore che consente di visualizzare
oggetti Bitmap. Un controllo immagine serve per contenere una bitmap che non
necessariamente viene visualizzata sempre, o che unapplicazione ha bisogno di
usare per generare altre figure.
_
Il paragrafoAggiunta di grafici ai controlli a pagina 6-12 illustra come usare i
grafici nei controlli.
Collocazione del controllo
Un controllo immagine pu essere collocato in qualsiasi punto di una scheda. Se si
desidera sfruttare la capacit del controllo immagine di autodimensionarsi in
funzione della figura, occorre impostare solo langolo superiore sinistro. Se il
controllo immagine un contenitore non visibile per una bitmap, si pu collocarlo in
un punto qualsiasi, proprio come se fosse un componente non visuale.
Se si rilascia il controllo immagine su una casella di scorrimento gi allineata allarea
client della scheda, ci garantisce che la casella aggiunger tutte le barre di
scorrimento necessarie per accedere alle parti fuori schermo dellimmagine. Dopo di
che si deve impostare la propriet del controllo immagine.
Impostazione delle dimensioni iniziali della bitmap
Quando si colloca un controllo immagine, questo solo un contenitore. Tuttavia, in
fase di progettazione, possibile impostare la propriet Picture del controllo
immagine in modo da contenere un grafico statico. Il controllo pu caricare la sua
immagine da un file anche in fase di esecuzione, come descritto nel paragrafo
Caricamento e salvataggio dei file grafici a pagina 10-20.
O p e r a z i o n i c o n e l e me n t i g r a f i c i e mu l t i me d i a l i 10-19
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
Per creare una bitmap vuota quando viene avviata lapplicazione:
1 Collegare un gestore allevento OnCreate per la scheda che contiene limmagine.
2 Creare un oggetto Bitmap, e assegnarlo alla propriet Picture->Graphic del
controllo immagine.
In questo esempio limmagine si trova nella scheda principale dellapplicazione,
Form1, cosicch il codice collega un gestore allevento OnCreate di Form1:
veIi __?aatcaII ..cicccc .c.c
Nel caso di applicazioni multipiattaforma, modificare il codice specifico per
Windows e per la VCL in modo che lapplicazione possa esere eseguita in ambiente
Linux. Ad esempio, nei nomi dei percorsi in Linux si utilizza come delimitatore una
barra diritta. Per ulteriori informazioni sulle applicazioni CLX e multipiattaforma ,
vedere il Capitolo 14, Sviluppo di applicazioni multipiattaforma.
Caricamento e salvataggio dei file grafici
Le immagini grafiche che esistono solo per la durata dellesecuzione di
unapplicazione hanno un valore molto limitato. Spesso, si preferisce usare la stessa
figura ogni volta o salvare una figura creata per usarla successivamente. Il
componente image facilita il caricamento delle immagini da un file e il loro
salvataggio.
I componenti usati per caricare, salvare e sostituire immagini grafiche supportano
molti formati grafici, compresi i file bitmap, i metafiles, i glifi, e cos via. Essi
supportano anche le classi grafiche installabili.
Il modo di caricare e di salvare i file grafici simile a quello di qualsiasi altro file e
viene descritto nelle seguenti sezioni:
Caricamento di unimmagine da un file.
Salvataggio di unimmagine in un file.
Sostituzione dellimmagine.
Caricamento di unimmagine da un file
Lapplicazione deve fornire la possibilit di caricare unimmagine da un file se ha
bisogno di modificarla o se si desidera memorizzarla in un file esterno, in modo che
un utente o unaltra applicazione possa modificarla.
Per caricare un file grafico in un controllo immagine, si deve chiamare il metodo
LoadFromFile delloggetto Picture del controllo immagine.
Il codice seguente riceve un nome di file da una finestra di dialogo per lapertura dei
file, e quindi carica quel file in un controllo immagine di nome Image:
veIi __?aatcaII .,cc.ccc .c.c
I? ,c.cci>xccc
O p e r a z i o n i c o n e l e me n t i g r a f i c i e mu l t i me d i a l i 10-21
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
cc ,c.cci>c.i.c,
L.ic>.cc>i..ccc,
I? ccLs.,
L.ic>.cc>.icccc, sic . ici. i.c.
eIae .ic~sc..c.c, c.sc c i i.c
I? .ici>xccc c i .c i.c
Sostituzione dellimmagine
In qualsiasi momento possibile sostituire la e figura di un controllo immagine. Se si
assegna un nuovo grafico ad unimmagine che ne ha gi uno, il nuovo grafico
sostituisce quello esistente.
Per sostituire la figura di un controllo immagine, si deve assegnare un nuovo grafico
alloggetto Picture del controllo immagine.
Il processo adottato per la creazione del nuovo grafico identico a quello utilizzato
per creare il grafico iniziale (consultare Impostazione delle dimensioni iniziali della
bitmap a pagina 10-18), ma in questo caso si deve fornire anche un modo che
consenta alperch lutente di scegliere una dimensione diversa da quella standard
10-22 G u i d a a l l a p r o g r a mma z i o n e
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
usata per il grafico iniziale. Un semplice modo per fornire questa opzione consiste
nel presentare una finestra di dialogo, come quella della Figura 10.1.
Figura 10.1 Finestra di dialogo Bitmap Dimension dalla unit BMPDlg
Questa particolare finestra di dialogo viene creata nella unit BMPDlg che fa parte del
progetto GraphEx (nella directory EXAMPLES\DOC\GRAPHEX).
Avendo questa finestra di dialogo nel progetto, aggiungere unistruzione include
relativa a BMPDlg.hpp nel file .cpp della scheda principale. Quindi, si pu collegare
un gestore allevento onClick della voce di menu File|New. Ecco un esempio:
veIi __?aatcaII ..c.c.ccc .c.c
i,cs.i, .i,,
.i.c sc .cs s .. .c.
.c....>~cc .c....>..,
i.c cc ..css is .c.i
.c....>..>cx L.L.ic>.cc>i,c>.,
.c....>-c.>cx L.L.ic>.cc>i,c>-c,
I? .c....>....i L~. . sc .cs cicc .i
.i, aev i,cs.i,, ccic i c. c.i, ccc
sc s,cc.c. ..css
.i,>. .L.c....>..>cx,
.i,>-c .L.c....>-c.>cx,
L.ic>.cc>i,c .i,, c,icc i,c . c. c.i,
cc .,., .cic i.c. .c
ieIete .i,,
_
Lassegnazione di una nuova bitmap alla propriet Graphic delloggetto Picture
provoca la copia del nuovo grafico nelloggetto ma loggetto non ne prende possesso.
Loggetto Picture gestisce il proprio oggetto grafico interno. . A causa di ci, il codice
precedente libera loggetto bitmap dopo avere fatto lassegnazione.
Uso della clipboard con i grafici
possibile usare la clipboard di Windows per copiare e incollare grafici allinterno
delle applicazioni o per scambiare grafici con altre applicazioni. Loggetto Clipboard
della VCL semplifica la gestione di diversi tipi di informazione, compresi i grafici.
Prima di poter usare loggetto clipboard nellapplicazione, necessario aggiungere
ad ogni file .cpp che dovr accedere ai dati della clipboard unistruzione include per
il file Clipbrd.hpp.
WidthEdit
HeightEdit
O p e r a z i o n i c o n e l e me n t i g r a f i c i e mu l t i me d i a l i 10-23
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
Per le applicazioni multipiattaforma, i dati memorizzati nella clipboard utilizzando
la CLX vengono memorizzati come un tipo MIME a cui associato un oggetto
TStream. Nella CLX sono previste le seguenti costanti predefinite per i tipi MIME
seguenti.
Operazioni di copia di grafici nella clipboard
Nella clipboard possibile copiare qualsiasi immagine, compreso il contenuto dei
controlli image. Una volta nella clipboard, limmagine disponibile per tutte le
applicazioni.
Per copiare unimmagine nella clipboard, bisogna assegnarla alloggetto clipboard
usando il metodo Assign.
Questo codice mostra come copiare unimmagine da un controllo immagine di nome
Image nella clipboard in risposta ad un clic sulla voce di menu Edit|Copy:
veIi __?aatcaII .,c.ccc .c.c
,ci.>~ssL.ic>.cc,
cc ~cc,
,c..c.c, c, ,cc c,ci.
L.ic>iis>,..c c.ccss, c, cc is .c
~cc cc, , L.ic>., L.ic>-c, c ..css . .ic
L.ic>iis>,cc~cc, L.ic>iis, ~cc, c, c.i, c sc.
L.ic>iis>,..c c..c,, csc .c.i ..c
Questo codice mostra come incollare una figura dalla clipboard in un controllo
immagine in risposta ad un clic su una voce di menu Edit|Paste:
veIi __?aatcaII ..iscc.ccc .c.c
i,cs.i, .i,,
I? ,ci.>-is.i_L.~.
L.ic>.cc>.i,>~ss,ci.,
Lo stesso esempio in un programma CLX multipiattaforma sarebbe simile al
seguente:
veIi __?aatcaII ..iscc.ccc .c.c
_i,cs.i, .i,,
I? ,ci.>..cs.c,.i,
L.ic>.cc>.i,>~ss,ci.,
iis>cx., , '-cc', .c cx i .,
iis>.c., , sc ,c ,s
Ora la pressione del pulsante del mouse imposta la posizione della penna, definendo
il punto iniziale della linea. Per disegnare una linea fino al punto in cui lutente
rilascia il pulsante, si deve rispondere ad un evento mouse-up.
Risposta ad unazione mouse-up
Ogni volta che lutente rilascia un pulsante del mouse si verifica un evento
OnMouseUp. Solitamente levento va alloggetto sul quale si trova il cursore del
mouse quando lutente preme il pulsante, che non necessariamente lo stesso
oggetto sul quale si trova il cursore quando il pulsante viene rilasciato. Ci consente,
per esempio, di disegnare una linea come se si estendesse oltre il bordo della scheda.
Per rispondere alle azioni mouse-up, si deve definire un gestore per levento
OnMouseUp.
Il codice seguente un semplice gestore di evento OnMouseUp che disegna una linea
fino al punto di rilascio del pulsante del mouse:
veIi __?aatcaII ...sc,ccc .c.c, .sc ,
O p e r a z i o n i c o n e l e me n t i g r a f i c i e mu l t i me d i a l i 10-27
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
...ic .., Iat ., Iat
iis>c., , .i. c cc ,s
Con questo codice, lo spostamento del mouse sulla scheda fa s che il disegno segua il
mouse, anche prima che il pulsante del mouse venga premuto.
Gli eventi mouse-move si verificano quando non sono stati premuti i pulsanti del
mouse.
Se si vuole tenere traccia del fatto che sia stato premuto un pulsante del mouse,
occorre aggiungere un campo oggetto alloggetto scheda.
Aggiunta di un campo ad un oggetto scheda per tenere traccia delle azioni del
mouse
Per tenere traccia del fatto che sia stato premuto o meno un pulsante del mouse,
occorre aggiungere un campo oggetto alloggetto scheda. Quando ad una scheda
viene aggiunto un componente, C++Builder aggiunge alloggetto scheda un campo
che rappresenta quel componente, in modo che sia possibile fare riferimento al
componente tramite il nome del campo. Inoltre, si possono aggiungere alla scheda
campi propri modificando la dichiarazione di tipo nel file header della scheda.
Nellesempio seguente la scheda ha bisogno di registrare se lutente ha premuto un
pulsante del mouse. Per farlo, essa aggiunge un campo booleana e ne imposta il
valore quando lutente preme il pulsante del mouse.
Per aggiungere un campo ad un oggetto, si deve modificare la definizione di tipo
delloggetto, specificando lidentificatore di campo e il tipo dopo la direttiva public
in fondo alla dichiarazione.
10-28 G u i d a a l l a p r o g r a mma z i o n e
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
CC++Builder possiede qualsiasi dichiarazione prima della direttiva public: questo
il punto in cui vengono immessi i campi che rappresentano i controlli e i metodi che
rispondono agli eventi.
Il codice seguente d ad una scheda un campo di nome Drawing di tipo bool, nella
dichiarazione delloggetto scheda. Inoltre, aggiunge due campi per memorizzare i
punti Origin e MovePt di tipo TPoint.
cIaaa . pabIIc .
i. ttae, sc c i. .i
iis>.c., , sc ,c ,s
I? i.
iis>c., , .i. . .sc s ..
Questo codice genera un disegno solo tra gli eventi mouse-down e mouse-up, ma
genera anche una linea scarabocchiata che traccia gli spostamenti del mouse anzich
una linea retta.
Il problema che ogni volta che il mouse si sposta, il relativo gestore di evento
chiama LineTo, il quale sposta la posizione della penna, e nel momento in cui viene
O p e r a z i o n i c o n e l e me n t i g r a f i c i e mu l t i me d i a l i 10-29
P a n o r a m i c a s u l l a p r o g r a m m a z i o n e d e i g r a f i c i
rilasciato il pulsante, si perde lindicazione del punto dal quale doveva partire la
linea retta.
Affinamento del disegno delle linee
Con i campi collocati per tracciare i vari punti, possibile rifinire il disegno di una
linea dellapplicazione.
Memorizzazione del punto di origine
Quando si disegnano linee, per tener traccia del punto in cui inizia la linea si utilizza
il campo Origin.
Origin deve essere impostato al punto in cui si verifica levento mouse-down, in
modo che il gestore di evento mouse-up possa usare Origin per indicare linizio della
linea, come in questo codice:
veIi __?aatcaII ...sc.ccc .c.c, .sc ,
...ic .., Iat ., Iat
i. ttae, sc c i. .i
iis>.c., , sc ,c ,s
.., , cc. .cc c c sis
iis>.cx, , .c ,c si ,
iis>c., , .i. c .. .c.s .,
i. ?aIae, cci c i. .i
I? i.
iis>.cx, , .c ,c si ,
iis>c., ,
10-30 G u i d a a l l a p r o g r a mma z i o n e
U s o d i c o m p o n e n t i m u l t i m e d i a l i
Questo codice registra la posizione attuale del mouse, ma le linee intermedie non
scompaiono, cosicch risulta difficile vedere la linea finale. Lesempio ha bisogno di
eliminare ogni linea prima di disegnare quella successiva, tenendo traccia di dove si
trovava quella precedente. Il campo MovePt consente di realizzare ci.
MovePt deve essere impostato al punto finale di ciascuna linea intermedia, in modo
che si possa usare MovePt e Origin per eliminare quella linea la volta successiva in cui
viene disegnata una linea:
veIi __?aatcaII ...sc.ccc .c.c, .sc ,
...ic .., Iat ., Iat
i. ttae, sc c i. .i
iis>.c., , sc ,c ,s
.., , cc. .cc c c sis
.c. .., , cc. is c.,
I? i.
-c.c c>
-,i.i .s,
-c.c '.'
-,i.i ,ic.ics.i_
Occorre completare il codice per il costruttore e per il metodo Execute. Le fasi relative
a tale operazione vengono descritte nelle sezioni successive.
S c r i t t u r a d i a p p l i c a z i o n i mu l t i - t h r e a d 11-3
D e f i n i z i o n e d i o g g e t t i t h r e a d
Inizializzazione del thread
Utilizzare il costruttore per inizializzare una nuova classe thread. qui che si pu
assegnare una priorit predefinita per il thread e indicare se verr rilasciato
automaticamente al termine dellesecuzione.
Assegnazione di una priorit predefinita
La priorit indica il grado di attenzione che il thread riceve quando il sistema
operativo programma il tempo che la CPU deve dedicare ad ogni thread
dellapplicazione. Per gestire operazioni per le quali il tempo determinante, si deve
usare un thread ad alta priorit, mentre per tutte le altre operazioni si pu ricorrere
ad un thread a bassa priorit. Per indicare la priorit delloggetto thread, impostare la
propriet Priority.
Se si sta scrivendo unapplicazione Windows, i valori di Priority sono disposti su una
scala, come descritto nella Tabella 11.1:
_
Se si scrive unapplicazione multipiattaforma, necessario utilizzare codice
differente per lassegnazione delle priorit in Windows e Linux. In Linux, Priority
un valore numerico che dipende dalle politiche di threading che puossono essere
cambiate solo dallutente root. Per i dettagli, consultare la versione CLX di TThread e
Priority nella Guida in linea.
j
Laumento della priorit del thread di unoperazione che richiede un uso intensivo
della CPU pu lasciare a bocca asciutta gli altri thread dellapplicazione. Esso si
applica solo ai thread che trascorrono la maggior parte del tempo in attesa di eventi
esterni.
Il codice seguente mostra il costruttore di un thread a bassa priorit che esegue
operazioni secondarie che non interferiranno con le altre prestazioni
dellapplicazione:
. ,L.c,
>c.,
.c.cci..c..sc,
S c r i t t u r a d i a p p l i c a z i o n i mu l t i - t h r e a d 11-5
D e f i n i z i o n e d i o g g e t t i t h r e a d
Synchronize aspetta il thread principale per avviare il ciclo di messaggi, dopo di che
esegue il metodo passato.
_
Dal momento che Synchronize usa il ciclo di messaggi, non funziona nelle
applicazioni console. Per proteggere laccesso agli oggetti VCL e CLX nelle
applicazioni per console, si devono, pertanto, usare altri meccanismi, come le sezioni
critiche.
Non occorre usare sempre il thread principale. Alcuni oggetti sono associati ai
thread. Omettendo luso del metodo Synchronize quando si certi che i metodi di un
oggetto sono thread-safe si miglioreranno le prestazioni, poich non occorrer
aspettare che il thread VCL o CLX avvii il proprio ciclo di messaggi. Non necessario
usare il metodo Synchronize nelle seguenti situazioni:
I componenti per laccesso ai dati sono thread-safe a patto che, per i dataset che
utilizzano BDE, ciascun thread abbia il proprio componente session di database.
Lunica eccezione si presenta quando si utilizzano i driver di Access Microsoft, che
sono costruiti usando una libreria Microsoft, che non thread-safe. Per dbDirect,
finch la libreria client del produttore thread-safe, i componenti dbDirect
saranno thread-safe. I componenti ADO e InterbaseExpress sono thread-safe.
Quando si usano componenti di accesso ai dati, occorre sempre passare al metodo
Synchronize tutte le chiamate che interessano i controlli associati ai dati. Quindi,
per esempio, occorre sincronizzare le chiamate che collegano un controllo dati ad
un dataset impostando la propriet DataSet delloggetto data source, ma non
occorre alcuna sincronizzazione per accedere ai dati di un campo del dataset.
Per maggiori informazioni sullutilizzo delle sessioni database con i thread, in
applicazioni che utilizzano BDE, consultare Gestione di sessioni multiple a
pagina 24-29.
Gli oggetti DataCLX sono thread-safe mentre gli oggetti VisualCLX non lo sono.
Gli oggetti grafici sono thread-safe. Non occorre usare il thread VCL principale
per accedere a TFont, TPen, TBrush, TBitmap, TMetafile (solo VCL), TDrawing(solo
CLX), o TIcon. Gli oggetti canvas possono essere utilizzati allesterno del metodo
Synchronize bloccandoli (vedere Blocco di oggetti a pagina 11-8).
Bench gli oggetti list non siano thread-safe, si pu usare una versione thread-safe,
TThreadList, al posto di TList.
Chiamare periodicamente la routine CheckSynchronize dallinterno del thread
principale dellapplicazione in modo che i thread in background possano
sincronizzare la propria esecuzione con il thread principale. Il momento ideale per
chiamare CheckSynchronize quando lapplicazione inattiva (ad esempio, da un
gestore di evento OnIdle ). Ci garantisce che sicuro effettuare chiamate ai metodi
nel thread di background.
Uso di variabili locali al thread
Il metodo Execute e tutte le routine che chiama hanno proprie variabili locali,
esattamente come qualsiasi altra routine di C++. Queste routine possono accedere
anche a tutte le variabili globali. Infatti, queste variabili forniscono un potente
meccanismo per la comunicazione tra i thread.
11-6 G u i d a a l l a p r o g r a mma z i o n e
D e f i n i z i o n e d i o g g e t t i t h r e a d
Qualche volta, tuttavia, pu risultare preferibile usare variabili che sono globali per
tutte le routine che vengono eseguite nel thread, ma non sono condivise con altre
istanze della stessa classe thread. Per ottenere questo risultato, occorre dichiarare le
variabili locali al thread. Creare una variabile locale al thread aggiungendo alla
dichiarazione della variabile il modificatore __thread. Ad esempio:
Iat __tateai x,
dichiara una variabile di tipo integer che privata per ciascun thread
dellapplicazione, ma globale allinterno di ciascun thread.
Il modificatore __thread pu essere utilizzato solamente per variabili globali (il cui
campo dazione il file) e statiche. Pointer e Function non possono essere variabili
thread. Non funzionano come variabili neppure i tipi che usano la semantica a sola
scrittura, cos come pure le variabili di tipo AnsiStrings. Un elemento di programma
che richieda una inizializzazione o una finalizzazione al momento dellesecuzione
non pu essere dichiarato di tipo __thread.
Le seguenti dichiarazioni richiedono una inizializzazione al momento
dellesecuzione e pertanto non sono consentite.
Iat . ,
Iat __tateai x . , ci
La creazione di unistanza di una classe mediante un costruttore o un distruttore
definito dallutente richiede una inizializzazione al momento dellesecuzione e non ,
pertanto, consentita:
cIaaa .
. ,
-. ,
,
. __tateai .ciss, ci
Controllo del termine da parte di altri thread
Il thread inizia lesecuzione quando viene chiamato il metodo Execute (vedere
Esecuzione di oggetti thread a pagina 11-12) e continua finch Execute non finisce.
Ci riflette il modello che prevede che il thread esegua una specifica operazione e
quindi si fermi non appena ha terminato. Qualche volta, tuttavia, unapplicazione ha
bisogno di un thread da eseguire finch non viene soddisfatto un criterio esterno.
Controllando la propriet Terminated, si pu consentire ad altri thread di segnalare al
thread attivo che il momento di terminare lesecuzione. Quando un altro thread
tenta di interrompere il thread attivo, chiama il metodo Terminate. Terminate imposta
la propriet Terminated del thread attivo a true. Spetta al metodo Execute
implementare il metodo Terminate controllando e rispondendo alla propriet
Terminated. Il seguente esempio mostra un modo per eseguire questa operazione:
veIi __?aatcaII .ci.xccc
vaIIe c.ic.
.c....cis.,
S c r i t t u r a d i a p p l i c a z i o n i mu l t i - t h r e a d 11-7
C o o r d i n a m e n t o d e i t h r e a d
Gestione delle eccezioni nella funzione di thread
Il metodo Execute deve intercettare tutte le eccezioni che si verificano nel thread. Se
non si riesce a intercettare uneccezione nella funzione di thread, lapplicazione
potrebbe provocare violazioni di accesso. Ci potrebbe non essere evidente quando si
sta sviluppando lapplicazione, in quanto lIDE intercetta le eccezioni, ma quando si
eseguir lapplicazione esternamente al debugger, leccezione causer un errore di
esecuzione e lapplicazione si bloccher.
Per intercettare le eccezioni che si verificano allinterno della funzione di thread,
aggiungere un blocco try...catch allimplementazione del metodo Execute:
veIi __?aatcaII .ci.xccc
tt,
vaIIe c.ic.
.c....cis.,
catca
. s.c . cxcc,s
s.,
__?IaaII,
,c..>ccisc,
s ,s ci.s>c.s,
?et Iat , ,s>, --
.ccssLc.,s>Lc.s,,
ci.s>c.s,
Nellesempio precedente gli elementi della lista erano accessibili solo quando il
metodo WaitFor indicava che la lista era stato effettivamente riempita. Questo valore
restituito deve essere assegnato dal metodo Execute del thread che era atteso.
Tuttavia, poich i thread che chiamano WaitFor vogliono conoscere il risultato
dellesecuzione del thread e non il codice che chiama Execute, il metodo Execute non
restituisce alcun valore. Invece, il metodo Execute imposta la propriet ReturnValue.
ReturnValue viene quindi restituito dal metodo WaitForquando viene chiamato da
altri thread. I valori restituiti sono interi. Lapplicazione determina il loro significato.
Attesa che venga completata unoperazione
Qualche volta necessario aspettare che un thread finisca una certa operazione
piuttosto che attendere che uno specifico thread termini lesecuzione. Per ottenere
questo risultato, occorre usare un oggetto evento. Gli oggetti evento (TEvent) devono
essere creati con un campo dazione globale in modo che possano agire come segnali
visibili per tutti i thread.
Quando un thread completa unoperazione da cui dipendono altri thread, chiama
TEvent::SetEvent. SetEvent attiva il segnale, in modo che tutti gli altri thread che
S c r i t t u r a d i a p p l i c a z i o n i mu l t i - t h r e a d 11-11
C o o r d i n a m e n t o d e i t h r e a d
controllano sapranno che loperazione stata completata. Per disattivare il segnale,
usare il metodo ResetEvent.
Per esempio, si consideri una situazione in cui si deve aspettare che terminino
lesecuzione diversi thread anzich uno solo. Dal momento che non si sa quale thread
finir per ultimo, non basta usare il metodo WaitFor di uno dei thread. Occorre,
invece, che ogni thread incrementi un contatore quando ha finito, e che lultimo
thread segnali la fine dellintera operazione attivando un evento. Instead, you can
have each thread increment a counter when it is finished, and have the last thread
signal that they are all done by setting an event.
Il codice seguente mostra la fine del gestore di evento OnTerminate per tutti i thread
che devono completare lesecuzione. CounterGuard un oggetto sezione critica
globale, che impedisce che pi thread utilizzino il contatore contemporaneamente.
Counter una variabile globale che conta il numero di thread che sono stati
completati.
veIi __?aatcaII ii..cis.ci.c.icccc .c.c
ci.>~cc, c. c cc
I? c .ccc.c c ci cc
c>.cc, si . s s c is ci.
ci.>ccisc, ccisc c c. c cc
veIi .ci..c.i.c
-~.~._L. .,
...,c x,
.s..i.c '.ci..i.c',
...ci.L ,
...is ,
__tt,
iscxcc, x1, , s.c..s.c.,. ,
__except ..L._.L._.L.
_
Impostare .s..i.c al nome della classe thread.
Il debugger rileva leccezione e controlla il nome del thread nella struttura che gli
stata passata. Durante le operazioni di debug, il debugger mostra il nome del
thread nel campo Thread ID della finestra Thread Status.
2 Aggiungere allinizio del metodo Execute una chiamata al nuovo metodo SetName:
.c.i.c,
.icc cxs F.~.~ .c. c.c cc
.cc.ic.iic., scic,
catca Lccic ic
.c cc . ci i. . c cxcc,
tatev, c. c cxcc,
veIi ._c.ic
,.'xcc, ci',
ic,
.c ._c.ic is c c.i .c
sc_c.ic._c.ic,
i .cc.ic s ccics i cxcc, cccisc c sc ic s cic
i ccisc c ci s i cc., ._c.ic s cic.
.cc.ic, ,
Se una funzione specifica quali sono le eccezioni sollevate e solleva uneccezione non
specificata, viene chiamata una funzione unexpected. possibile specificare la
funzione unexpected con set_unexpected. Se non si specifica una funzione unexpected,
viene chiamata la funzione unexpected.
G e s t i o n e d e l l e e c c e z i o n i 12-7
E c c e z i o n i s t r u t t u r a t e i n a m b i e n t e W i n 3 2
Eccezioni strutturate in ambiente Win32
Win32 supporta la gestione delle eccezioni strutturate basate su C, che sono simili
alle eccezioni di C++. Esistono, comunque, alcune differenze fondamentali che
richiedono un utilizzo attento quando vengono mescolate con codice C++ per la
gestione delle eccezioni.
Quando si utilizza la gestione delle eccezioni strutturate nelle applicazioni
C++Builder, occorre tenere presente quanto segue:
Le eccezioni strutturate del C possono essere utilizzate in programmi C++.
Le eccezioni C++ non possono essere utilizzate in programmi C, in quanto
richiedono che il loro gestore sia specificato tramite la parola chiave catch, e catch
non consentita nei programmi C.
Uneccezione generata da una chiamata alla funzione RaiseException viene gestita
mediante il blocco try/__except (C++) o __try/__except (C). (Si possono anche
utilizzare i blocchi try/__finally oppure __try/__finally. Vedere Sintassi delle
eccezioni strutturate a pagina 12-7.) Tutti i gestori dei blocchi try/catch vengono
ignorati quando viene chiamata la funzione RaiseException.
Le eccezioni che non sono gestite dalle applicazioni non generano una chiamata a
terminate(), ma vengono passate invece al sistema operativo (in generale, il
risultato finale la fine del processo).
I gestori di eccezioni non ricevono una copia delloggetto eccezione, a meno che
non la richiedano.
Nei programmi C e C++ si possono utilizzare le seguenti funzioni di supporto delle
eccezioni C:
GetExceptionCode
GetExceptionInformation
SetUnhandledExceptionFilter
UnhandledExceptionFilter
C++Builder non limita lutilizzo della funzione UnhandledExceptionFilter al filtro di
eccezione dei blocchi __try/__except o try/__except. Comunque, il comportamento
del programma non definito quando questa funzione viene chiamata al di fuori del
blocco __try/__except o try/__except.
Le applicazioni CLX in esecuzione su Linux non supportano eccezioni strutturate C/
C++.
Sintassi delle eccezioni strutturate
In un programma C le parole chiave ANSI compatibili utilizzate per implementare le
eccezioni strutturate sono __except, __finally e __try.
_
La parola chiave __try pu apparire soltanto in programmi C. Se si vuole scrivere del
codice portabile, nei programmi C++ non si deve utilizzare la gestione delle eccezioni
strutturate.
12-8 G u i d a a l l a p r o g r a mma z i o n e
E c c e z i o n i s t r u t t u r a t e i n a m b i e n t e W i n 3 2
Sintassi per la gestione delle eccezioni try-except
La sintassi per la gestione delle eccezioni try-except la seguente:
ccc
s.c c.,si __tt, ..
s.c c.,si tt, .. i --
csc
__except cs,cssc s.c c.,si
Sintassi della terminazione try-finally
Nel caso della terminazione try-finally la sintassi ::
ccc
s.c c.,si __tt, ..
s.c c.,si tt, .. i --
c.i.c
__?IaaII, s.c c.,si
Gestione delle eccezioni strutturate
Le eccezioni strutturate possono essere gestite utilizzando unestensione della
gestione delle eccezioni di C++:
.,
__cxcc,__cx,__
i.c cc
__cx,__ unespressione che pu assumere uno dei tre valori seguenti:
Win32 fornisce due funzioni che possono essere utilizzate per ricercare informazioni
sulleccezione attiva: GetExceptionCode() e GetExceptionInformation(). Se si vuole
chiamare una funzione come parte dellespressione filtro sopra indicata, queste
funzioni devono essere chiamate direttamente dallinterno del contesto di __except():
-c.c ..s>
-c.c cxc,>
Valore Descrizione
EXCEPTION_CONTINUE_SEARCH (0) Il gestore delle eccezioni non stato indicato e il
sistema operativo continua a cercarlo.
EXCEPTION_CONTINUE_EXECUTION (-1) Continua lesecuzione nel punto delleccezione.
EXCEPTION_EXECUTE_HANDLER (1) Attiva il gestore delle eccezioni. Se il codice stato
compilato con il distruttore di cleanup abilitato (-
xd, opzione attiva per impostazione predefinita),
tutti i distruttori per gli oggetti locali creati tra il
punto di eccezione e il gestore di eccezioni vengono
chiamati quando viene scaricato lo stack. Lo scarico
dello stack viene completato prima dellattivazione
del gestore.
G e s t i o n e d e l l e e c c e z i o n i 12-9
E c c e z i o n i s t r u t t u r a t e i n a m b i e n t e W i n 3 2
.c_.c..L._.L.. ,
..L._.L.. x, ,
.,
__cxcc,.c_.cx, cxcc,L..i
Oppure, se si preferisce utilizzare loperatore virgola per assegnazioni annidate nelle
chiamate a funzioni, vedere lesempio seguente:
__cxcc,x, cxcc,L..i, .c_.cx,
Filtri delle eccezioni
Unespressione filtro pu richiamare una funzione filtro, ma la funzione filtro non
pu chiamare GetExceptionInformation. possibile passare alla funzione filtro il valore
restituito da GetExceptionInformation come parametro.
Per passare linformazione EXCEPTION_POINTERS ad un gestore di eccezioni,
lespressione o la funzione filtro devono copiare il puntatore o i dati da
GetExceptionInformation in una posizione a cui il gestore pu accedere
successivamente.
Nel caso di istruzioni try-except annidate, ogni espressione filtro dellistruzione
viene valutata finch non viene individuato EXCEPTION_EXECUTE_HANDLER o
EXCEPTION_CONTINUE_EXECUTION. Unespressione filtro pu richiamare
GetExceptionInformation per ottenere informazioni sulleccezione.
A patto che GetExceptionInformation o GetExceptionCode siano chiamate direttamente
nellespressione fornita a __except, si pu usare una funzione per determinare cosa
fare con uneccezione anzich tentare di creare unespressione C++ complessa. Quasi
tutte le informazioni necessarie per gestire uneccezione possono essere ricavate dal
risultato di GetExceptionInformation(). GetExceptionInformation() restituisce un
puntatore ad una struttura EXCEPTION_POINTERS:
sc ..L._.L..
..L._ xcc,cc.,
.. cx,
,
EXCEPTION_RECORD contiene la stato indipendente dalla macchina:
sc ..L._
xcc,.c,
xcc,is,
sc ..L._ xcc,cc.,
. xcc,~..css,
..cc.ii.ccs,
xcc,L..i,..L._.~.L.._.~~..,
,
12-10 G u i d a a l l a p r o g r a mma z i o n e
E c c e z i o n i s t r u t t u r a t e i n a m b i e n t e W i n 3 2
Generalmente, la funzione filtro analizza le informazioni contenute in
ExceptionRecord per decidere come rispondere. Talvolta si ha bisogno di
informazioni pi specifiche (specialmente se lazione da intrapendere
EXCEPTION_CONTINUE_EXECUTION: se non si fa nulla, il codice che ha causato
leccezione sar eseguito nuovamente). In questi casi, laltro campo della struttura
EXCEPTION_POINTERS fornisce lo stato del processore al momento delleccezione.
Se questa struttura viene modificata e il filtro restituisce
EXCEPTION_CONTINUE_EXCEPTION, tale valore viene usato per impostare lo
stato del thread prima di procedere con lesecuzione. Per esempio:
sic x.c..L._.L.. x,
c,
..L._ x x,>xcc,cc.,
.. xc x,>cx,
s.c x>xcc,.c
cisc ..L._~.L.
.,s, s.cc c. i c.cc..c. cci.,
s sc, c cc x
--xc>,,
c ..L._.L._.L.,
cci.,
cisc ..L._~.._L~L.
c ..L._._-~.,
cci.,
.c.i
c ,
c ..L._.L._.~-,
cci.,
,
c c,
..L._.L.. x,,
.c,
__cxcc,x.cx, cxcc,L..i
ic,
Abbinamento di eccezioni strutturate con C++
Bisogna essere consapevoli delle conseguenze derivanti dallutilizzo delle eccezioni
strutturate nei programmi C++. Innanzi tutto, anche se C++Builder implementa le
G e s t i o n e d e l l e e c c e z i o n i 12-11
E c c e z i o n i s t r u t t u r a t e i n a m b i e n t e W i n 3 2
eccezioni C++ con le eccezioni strutturate Win32, le eccezioni C++ sono trasparenti
ad un blocco __except.
Un blocco try pu essere seguito esattamente da un blocco except o da almeno un
blocco catch. Il tentativo di abbinarli genera un errore in fase di compilazione. Il
codice necessario per gestire entrambi i tipi di eccezione deve essere semplicemente
annidato allinterno di due blocchi try:
..L._.L.. x,,
.c,
__cxcc,x.cx, cxcc,L..i
cic
La specifica di una funzione throw() non incide sul comportamento di un programma
rispetto ad uneccezione Win32. Inoltre, uneccezione non gestita viene
eventualmente gestita dal sistema operativo (se un debugger non la gestisce prima), a
differenza di quanto fanno i programmi C++ che chiamano terminate().
Tutti i moduli compilati con lopzione -xd del compilatore (attiva per impostazione
predefinita) richiameranno i distruttori di tutti gli oggetti con memorizzazione di
tipo auto. Si ha lo scarico dello stack dal punto in cui si verificata leccezione fino al
punto in cui essa viene catturata.
Eccezioni basate su C in un programma di esempio C++
.i. css
~c cxcc,
i i cisc. cxcc,
i -- cxcc,,-i..ic c .c c
-- i.s __.i
-c.c s.>
-c.c s>
-c.c ...s>
ciss xcc,
,cc
xcc,ci s '..' .i s.,s,
xcc,cs xcc, c .i s.,c.i,
-xcc, .ccc, .i,
ci .s cs c .i,
,ic
ci .i,
,
12-12 G u i d a a l l a p r o g r a mma z i o n e
E c c e z i o n i s t r u t t u r a t e i n a m b i e n t e W i n 3 2
.i
.i c, ., ,
. ,
,
,s'~c cxcc,',
c . ,
__cxcc,..L._._-~.
,s'i i cisc. cxcc,',
.xcc,'-i..ic c .c c ',
ciccs xcc, c
,.'i -- xcc, `s ', c.s,
__.i
,s'-- i.s __.i ',
c c,
-c.c s.>
-c.c ...s>
.i
.i c, ., ,
. ,
,
,s'~ cxcc,',
c . ,
__cxcc,..L._._-~.
,s'i i cxcc,',
__.i
,s'c __.i s cxccc. ',
. ,
.,
,s'. cxcc,',
c . ,
__cxcc,..L._._-~.
,s'i i cxcc,',
__.i
,s'. cxcc, i,,cc., c __.i s cxcccs',
G e s t i o n e d e l l e e c c e z i o n i 12-15
G e s t i o n e d e l l e e c c e z i o n i V C L / C L X
c c,
ci , ,
, ,
,.' ci . i',
G e s t i o n e d e l l e e c c e z i o n i 12-17
G e s t i o n e d e l l e e c c e z i o n i V C L / C L X
Le classi utilizzate da C++Builder sono le stesse utilizzate da Delphi e sono
disponibili soltanto per le applicazioni VCL e CLX di C++Builder. Sono derivate da
TObject e richiedono di appoggiarsi alla VCL o alla CLX.
Di seguito sono riportate alcune caratteristiche della gestione delle eccezioni di
C++Builder:
Non si responsabili del rilascio delloggetto eccezione.
Le eccezioni del sistema operativo devono essere intercettate per riferimento.
Non si pu sollevare di nuovo uneccezione di sistema operativo una volta che si
usciti dal frame di intercettazione e loperazione di intercettazione stata
effettuata tramite i frame di intercettazione della VCL o della CLX.
Non si pu sollevare di nuovo uneccezione di sistema operativo una volta che si
usciti dal frame di intercettazione e loperazione di intercettazione stata
effettuata tramite i frame di intercettazione del sistema operativo.
Gli ultimi due punti possono essere sintetizzati in questo modo: una volta che
leccezione di sistema operativo stata intercettata come uneccezione C++, essa non
pu essere sollevata di nuovo come un+eccezione di sistema operativo o come
un+eccezione della VCL o della CLX, a meno che non ci si trovi nella struttura dello
stack di intercettazione.
Gestione delle eccezioni della VCL e della CLX
C++Builder amplia la semantica per la gestione delle eccezioni software sollevate
dalla VCL e dalla CLX o, analogamente, delle eccezioni sollevate da C++, in cui la
classe di eccezione da sollevare derivata da TObject. In questo caso, si applica una
coppia di regole derivanti dal fatto che le classi in stile VCL possono essere allocate
solo nello heap.
Le classi di eccezione in stile VCL possono essere intercettate solo per puntatore,
se si tratta di uneccezione software, o per riferimento (che la modalit preferita).
Uneccezione in stile VCL deve essere sollevata mediante la sintassi per valore.
Classi di eccezioni VCL e CLX
C++Builder include un vasto gruppo di classi di eccezione native per la gestione
automatica degli errori di divisione per zero, degli errori di I/O su file, degli errori di
conversione di tipo e di molte altre condizioni di eccezione. Tutte le classi di
eccezione VCL e CLX discendono da un oggetto radice di nome Exception. Exception
incapsula le propriet fondamentali e i metodi per tutte le eccezioni ti tipo VCL e
fornisce uninterfaccia compatibile in modo che le applicazioni gestiscano le
eccezioni.
Le eccezioni possono essere passate ad un blocco catch che accetta un parametro di
tipo Exception. Per intercettare le eccezioni VCL e CLX, utilizzare la seguente sintassi:
cic cxcc,_ciss cxcc,_iicc
12-18 G u i d a a l l a p r o g r a mma z i o n e
G e s t i o n e d e l l e e c c e z i o n i V C L / C L X
Si deve specificare la classe di eccezione che si vuole intercettare e fornire una
variabile tramite la quale fare riferimento alleccezione.
Lesempio seguente mostra come sollevare uneccezione VCL o CLX:
veIi __?aatcaII ..xcc,ccc .c.c
tt,
catcaceaat xcc,
...cssic~s.iss.i.c- .cssic,
pabIIc
vIttaaI veIi __aticaII .i-c.veIi ,
,
Di solito, quando si dichiara una classe interfaccia, il codice C++Builder dichiara
anche una classe DelphiInterface corrispondente che semplifica loperativit con
linterfaccia:
t,peie? .sc.c,Lc.icc L-c. > _._L-c.,
Per informazioni sulla classe DelphiInterface, vedere Interfacce Delphi a
pagina 13-21.
IUnknown e IInterface
Tutte le interfacce di Object Pascal discendono da un singolo antenato comune,
IInterface. Non necessario che le classi interfaccia di C++ utilizzino IInterface come
classe di base, nel senso che una classe in stile VCL pu utilizzarle come classi di base
aggiuntive, ma il codice VCL e CLX che opera con le interfacce presume che siano
presenti i metodi di IInterface.
Nella programmazione COM, tutte le interfacce discendono da IUnknown. Il
supporto COM nella VCL basato su una definizione di IUnknown che mappa
direttamente a IInterface. Ci significa che, in Object Pascal, IUnknown e IInterface sono
identici.
La definizione Object Pascal di IUnknown, tuttavia, non corrisponde alla definizione
di IUnknown utilizzata in C++Builder. Il file unknwn.h definisce IUnknown in modo
tale da includere i seguenti tre metodi:
vIttaaI -. .~ _cLc.icc ceaat L ., veIi ,, ,
vIttaaI . .~ ~..c. ,
vIttaaI . .~ ccisc ,
Ci corrisponde alla definizione di IUnknown che definito da Microsoft come parte
delle specifiche COM.
_
Per informazioni su IUnknown e sul suo utilizzo, vedere il Capitolo 38, Panoramica
sulle tecnologie COM oppure consultare la documentazione Microsoft.
A differenza di quanto accade in Object Pascal, la definizione di IInterface di
C++Builder non equivalente alla definizione di IUnknown. IInterface invece un
discendente di IUnknown che comprende un metodo aggiuntivo, Supports:
c.,ic ,ci.c >
-. __aticaII .,,sc,Lc.icc> s.iL.
tetata _cLc.icc__aaIie?,
13-4 G u i d a a l l a p r o g r a mma z i o n e
M o d e l l i d i o g g e t t i C + + e O b j e c t P a s c a l
teIatetptet_caat veIi>atatIc_caat >s.iL.,
tetata Lc.icc.ccc_~..c.,
tetata Lc.icc.ccc_ccisc,
I? _.c
tatev xcc,'_.c s .c',
ptIvate
Iat _.c,
,
Iat .iveIi
Questo esempio presenta uneccezione nel costruttore di Base. Poich Base viene
costruita prima di Derived, not_zero, non stata ancora inizializzata con il valore di 42
passato al costruttore. Si tenga presente che non possibile inizializzare i membri
dati della classe in stile VCL prima che vengano chiamati i costruttori della sua classe
base.
Distruzione di oggetti
Due meccanismi, riguardanti la distruzione degli oggetti, funzionano
differentemente in C++ e in Object Pascal. Questi sono:
distruttori chiamati a causa delle eccezioni presentate dai costruttori
i metodi virtuali chiamati dai distruttori
Le classi in stile VCL abbinano i metodi di questi due linguaggi. Gli aspetti vengono
discussi qui di seguito.
13-14 G u i d a a l l a p r o g r a mma z i o n e
M o d e l l i d i o g g e t t i C + + e O b j e c t P a s c a l
Eccezioni sollevate dai costruttori
Se si verifica uneccezione durante la costruzione delloggetto, i distruttori vengono
chiamati in modo differente in C++ e in Object Pascal. Si prenda come esempio una
classe C, derivata da una classe B, che derivata da una classe A:
cIaaa ~
c.
,
cIaaa pabIIc ~
c.
,
cIaaa pabIIc
c.
,
Supponendo che si sia verificata uneccezione nel costruttore della classe B durante la
costruzione di unistanza di C, questi sarebbero i risultati in C++, in Object Pascal e in
classi in stile VCL:
In C++ prima vengono chiamati i distruttori per tutti i membri dati delloggetto
completamente costruiti di B, quindi viene chiamato il distruttore di A, e
successivamente vengono chiamati i distruttori per tutti i membri dati delloggetto
completamente costruiti di A. Comunque, i distruttori per B e C non vengono
chiamati.
In Object Pascal solo il distruttore della classe istanziata viene chiamato
automaticamente. Questo il distruttore per C. Come avviene con i costruttori,
esclusivamente responsabilit del programmatore chiamare inherited nei
distruttori. In questo esempio, se si suppone che tutti i distruttori chiamano
inherited, allora i distruttori per C, B e A vengono chiamati in questo ordine.
Inoltre, indipendentemente dal fatto che inherited sia gi stata o meno chiamata
nel costruttore di B prima che si verificasse leccezione, il distruttore di A viene
chiamato perch inherited stato chiamato nel distruttore di B. La chiamata al
distruttore per A indipendente dal fatto che il suo costruttore sia stato
effettivamente chiamato. Inoltre, fattore pi importante, poich di solito i
costruttori chiamano immediatamente inherited, il distruttore per C viene
chiamato indipendentemente dal fatto che il corpo del suo costruttore sia stato o
no completamente eseguito.
Nelle classi in stile VCL le basi della VCL o della CLX (implementate in Object
Pascal) seguono il metodo Object Pascal di chiamata dei distruttori. Le classi
derivate (implementate in C++) non seguono esattamente nessuno dei metodi del
linguaggio. Succede invece che vengono chiamati tutti i distruttori; ma i corpi di
quelli che non saranno stati chiamati secondo le regole del linguaggio C++, non
vengono immessi.
Le classi implementate in Object Pascal, pertanto, forniscono unopportunit per
elaborare qualsiasi codice di cleanup scritto nel corpo del distruttore. Ci vero
anche per il codice che libera memoria per i sotto-oggetti (membri dati che sono
S u p p o r t o d e l l i n g u a g g i o C + + p e r l a V C L e l a C L X 13-15
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
oggetti) che vengono costruiti prima che si verifichi uneccezione del costruttore. Si
deve tenere presente che, per le classi in stile VCL, il codice di cleanup pu non
essere elaborato per la classe istanziata o per le sue basi implementate con C++,
anche se vengono chiamati i distruttori.
Per maggiori informazioni sulla gestione delle eccezioni in C++Builder, consultare
Gestione delle eccezioni VCL/CLX a pagina 12-15.
Metodi virtuali chiamati dai distruttori
Linvio dei metodi virtuali nei distruttori segue lo stesso modello definito per i
costruttori. Questo significa che per le classi in stile VCL, la classe derivata viene
distrutta per prima, ma il tipo runtime delloggetto rimane quello della classe
derivata in tutte le successive chiamate ai distruttori della classe base. Pertanto, se i
metodi virtuali vengono chiamati nei distruttori della classe base VCL o CLx, c il
rischio che linvio riguardi una classe che gi stata distrutta.
AfterConstruction e BeforeDestruction
TObject propone due metodi virtuali, BeforeDestruction e AfterConstruction, che
consentono ai programmatori di scrivere del codice che viene elaborato
rispettivamente prima e dopo la distruzione e la creazione degli oggetti.
AfterConstruction viene chiamato dopo la chiamata dellultimo costruttore.
BeforeDestruction viene chiamato prima che venga chiamato il primo distruttore.
Questi metodi sono pubblici e vengono chiamati automaticamente.
Funzioni virtuali di classe
Object Pascal ha il concetto di funzione virtuale di classe.Lanalogo C++ sarebbe una
funzione virtuale statica, se fosse possibile; ma C++ non ha alcun corrispondente di
questo tipo di funzione. Queste funzioni vengono chiamate con sicurezza allinterno
della VCL e della CLX. Tuttavia, in C++Builder non verr mai chiamata una funzione
di questo tipo. + possibile identificare queste funzioni nei file header in quanto sono
precedute dal seguente commento:
i ciss .c.
Supporto per i tipi di dati Object Pascal e per le strutture del
linguaggio
Per supportare la VCL e la CLX, C++Builder implementa, traduce o mette comunque
in relazione la maggior parte dei tipi di dati, dei costrutti e delle strutture del
linguaggio Object Pascal con quelli del linguaggio C++. Ci viene realizzato nei
seguenti modi:
Typedefs per i tipi C++ nativi
Classes, strutture e modelli di classe
Equivalenti del linguaggio C++
13-16 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
Macro
Parole chiave che sono estensioni del linguaggio ANSI standard
Non tutti gli aspetti del linguaggio Object Pascal coincidono perfettamente con quelli
del C++. A volte, luso di queste parti del linguaggio pu far s che lapplicazione
abbia dei comportamenti inattesi. Ad esempio:
Alcuni tipi esistono in Object Pascal e in C++, ma vengono definiti in modo
diverso. Essi possono richiedere una particolare attenzione quando il codice viene
condiviso dai due linguaggi.
Alcune estensioni sono state aggiunte a Object Pascal con lo scopo di supportare
C++Builder. Occasionalmente esse possono avere una notevole incidenza a livello
di interoperativit.
I tipi e i costrutti del linguaggio Object Pascal che hanno alcun corrispondente nel
linguaggio C++ saranno evitati in C++Builder quando il codice viene condiviso tra
questi linguaggi.
La sezione successiva presenta un riepilogo dei modi in cui C++Builder implementa
il linguaggio Object Pascal, e alcuni suggerimenti su quando occorre usare una certa
prudenza.
Typedef
La maggior parte dei tipi di dati intrinseci Object Pascal viene implementata in
C++Builder usando un typedef per un tipo C++ nativo. Questi si trovano in
sysmac.h. Ogni qual volta possibile, opportuno usare il tipo C++ nativo, anzich il
tipo Object Pascal.
Classi che supportano il linguaggio Object Pascal
Alcuni tipi di dati e costrutti del linguaggio Object Pascal che non hanno un
equivalente incorporato in C++ vengono implementati come classi o strutture. I
modelli di classe vengono usati anche per implementare i tipi di dati e i costrutti del
linguaggio Object Pascal, come set, da cui pu essere dichiarato uno specifico tipo. Le
relative dichiarazioni si trovano nei seguenti file header:
dstring.h
wstring.h
sysclass.h
syscomp.h
syscurr.h
sysdyn.h
sysopen.h
sysset.h
systdate.h
systobj.h
systvar.h
sysvari.h
S u p p o r t o d e l l i n g u a g g i o C + + p e r l a V C L e l a C L X 13-17
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
Le classi implementate in questi file header sono state create per supportare i tipi
nativi usati nelle routine Object Pascal. Esse sono destinate ad essere usate quando
queste routine vengono chiamate nel codice basato su VCL o CLX.
Equivalenti del linguaggio C++ presenti nel linguaggio Object Pascal
I parametri var e untyped di Object Pascal non sono nativi di C++. Entrambi hanno
degli equivalenti nel linguaggio C++ che vengono usati in C++Builder.
Parametri var
C++ e Object Pascal condividono la logica del passaggio per riferimento. Questi
sono argomenti modificabili. In Object Pascal vengono chiamati parametri var. La
sintassi per le funzioni che richiedono un parametro var
pteceiate .cvat x Lcc,
In C++ questi tipi di parametro devono essere passati per riferimento:
veIi .cIat x,
I riferimenti e i puntatori di C++ possono essere usati per modificare loggetto.
Tuttavia, un riferimento il corrispondente pi vicino ad un parametro var in
quanto, a differenza di un puntatore, un riferimento non pu essere rebound e un
parametro var non pu essere assegnato una seconda volta; anche se possibile
cambiare il valore di ci a cui fa riferimento.
Parametri senza tipo
Object Pascal consente luso di parametri di tipo non specificato. Questi parametri
vengono passati alle funzioni senza alcun tipo definito. La funzione ricevente deve
ricondurre il parametro ad un tipo noto prima di usarlo. C++Builder interpreta i
parametri di tipo non specificato come puntatori a vuoto (void *). La funzione
ricevente deve ricondurre il puntatore vuoto ad un puntatore del tipo desiderato.
Questo un esempio:
Iat ..cveIi ..i.c
Open array
Object Pascal ha un costrutto open array che permette di passare a una funzione un
array di dimensioni non specificate. Mentre in C++ non esiste alcun supporto diretto
per questo tipo, una funzione Object Pascal che ha un parametro array aperto pu
essere chiamata passando esplicitamente il puntatore al primo elemento di un array,
e il valore allultimo indice (il numero di elementi dellarray meno uno). Per esempio,
la funzione Mean in math.hpp ha questa dichiarazione in Object Pascal:
13-18 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
?aactIea .ciii atta, e? cc xc.c.,
La dichiarazione in C++
xc.c. __?aatcaII .ciceaat ieabIe ii, ceaat Iat ii_..c,
Il codice seguente illustra la chiamata della funzione Mean da C++:
ieabIe ., , 11, ,
cx,c s,cc. is .cx
Iea ieabIe x .ci., .,
ccc sc s.c. csc i c ccc ic s ,issc.
Iea ieabIe .ci., aIzee?. aIzee?., ,
sc .ic ss,c
Iea ieabIe . .ci., ~~.L.. ,
_
In casi simili allesempio sopra riportato, ma dove la funzione Object Pascal aspetta
un parametro var, i parametri di dichiarazione di funzione C++ non saranno const.
Calcolo del numero di elementi
Quando si usa sizeof(), la macro ARRAYSIZE o la macro EXISTINGARRAY per
calcolare il numero di elementi di un array, occorre prestare attenzione a non usare
invece un puntatore allarray. Passare invece il nome dello stesso array:
ieabIe ., , 11, ,
Iat ~~.L.., aIzee?.aIzee?., > .1 >
ieabIe ,. .,
Iat . ~~.L.,., aIzee?,.aIzee?,., > 1 > >
Prendere il sizeof di un array non equivale a prendere il sizeof di un puntatore.
Per esempio, data la seguente dichiarazione,
ieabIe .,,
ieabIe , .,
che assume le dimensioni dellarray come mostrato
aIzee?.aIzee? .,
non equivale a calcolare le dimensioni del puntatore:
aIzee?,aIzee?,,
Questo esempio e quelli seguenti usano la macro ARRAYSIZE anzich loperatore
sizeof(). Per maggiori informazioni sulla macro ARRAYSIZE, consultare la Guida in
linea.
Array temporanei
Object Pascal fornisce il supporto per il passaggio di array aperti temporanei senza
nome alle funzioni. In C++ non esiste alcuna sintassi che svolga questa operazione.
Tuttavia, poich le definizioni di variabili possono essere mischiate con altre
istruzioni, un modo per risolvere il problema quello di fornire semplicemente la
variabile con un nome.
Object Pascal:
S u p p o r t o d e l l i n g u a g g i o C + + p e r l a V C L e l a C L X 13-19
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
cs .ci,, 11, ,
C++, usando un array temporaneo con nome:
ieabIe ., , 11, ,
tetata .ci., ~~.L.. ,
Per restringere il campo dazione dellarray temporaneo con nome ed evitare
conflitti con altre variabili locali, consigliabile aprire un nuovo campo dazione:
Iea ieabIe x,
ieabIe ., 11, , ,
x .ci., ~~.L.. ,
Macro OPENARRAY
La macro OPENARRAY definita in sysopen.h pu essere usata come alternativa ad
una variabile con nome per passare un open array temporaneo ad una funzione che
acquisisce un open array per valore. Luso della macro assume questo formato
..~~, ic, ic., ic , ics
dove T il tipo open array da costruire e i parametri value sono utilizati per
compilare larray. Le parentesi per racchiudere gli argomenti dei valori sono
necessarie. Ad esempio:
veIi s._cIat c_c.c, ~s. ceaat c_.s
13-20 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
Con la macro OPENARRAY possono essere passati fino a 19 valori. Se fosse
necessario un array pi grande, occorrerebbe definire una variabile esplicita. Inoltre,
usando la questa macro, si paga un ulteriore piccolo costo in fase di esecuzione,
dovuto sia alla spazio richiesto per lallocazione dellarray sottostante sia alla
ulteriore copia di ciascun valore.
Macro EXISTINGARRAY
La macro EXISTINGARRAY definita in sysopen.h pu essere usata per passare un
array esistente al posto di un open array. Luso della macro assume questo formato
Iea ieabIe .ciceaat ieabIe ii, ceaat Iat ii_..c,
ieabIe ., , 1, .. ,
.ci.L.L.~~ .,
_
La sezione Calcolo del numero di elementi a pagina 13-18 vale anche per la macro
EXISTINGARRAY.
Funzioni C++ che accettano argomenti di tipo open array
Quando si scrive una funzione C++ a cui verr passato un array aperto da Object
Pascal, importante conservare esplicitamente la semantica del passaggio per
valore. In particolare, se la dichiarazione per la funzione corrisponde al passaggio
per valore, bisogna accertarsi di aver copiato esplicitamente tutti gli elementi prima
di modificarli. In Object Pascal un array aperto un tipo incorporato e pu essere
passato per valore. In C++ il tipo array aperto viene implementato usando un
puntatore, il quale modifica larray originale, a meno che non ne venga fatta una
copia locale.
Tipi definiti in altro modo
I tipi che in Object Pascal e C++ vengono definiti in modo diverso normalmente non
sono causa di preoccupazioni. I rari casi in cui sono problematici risultano
difficilmente individuabili. Per tale motivo, questi tipi vengono trattati in questa
sezione.
Tipi di dati booleani
In Object Pascal il valore True per i tipi di dati ByteBool, WordBool e LongBool viene
rappresentato con 1. False viene rappresentato con 0.
_
Il tipo di dati Boolean rimane costante (true = 1, false = 0)).
Mentre il tipo bool di C++ converte correttamente questi tipi di Object Pascal,
nascono problemi quando vengono condivise una funzione WinAPI o una qualsiasi
altra funzione che usa un tipo BOOL di Windows rappresentato con 1. Se viene
passato un valore ad un parametro di tipo BOOL, esso vale 1 in Object Pascal e 1 in
C++. Pertanto, se tra questi due linguaggi viene condiviso del codice, qualsiasi
confronto dei due identificatori pu risultare errato, a meno che non siano entrambi 0
(False, false). Per aggirare lostacolo, si pu usare il seguente metodo di confronto:
~ ,
S u p p o r t o d e l l i n g u a g g i o C + + p e r l a V C L e l a C L X 13-21
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
La Tabella 13.2 mostra i risultati delluso di questo metodo di confronto
delluguaglianza:
Con questo metodo di confronto qualunque serie di valori sar calcolata
correttamente.
Tipi di dati char
Il tipo char in C++ con segno, mentre in Object Pascal senza segno. + molto raro
che si verifichi una situazione in cui questa differenza potrebbe diventare un
problema quando viene condiviso del codice.
Interfacce Delphi
l compilatore Object Pascal gestisce automaticamente molti dettagli durante le
attivit con le interfacce. Incrementa automaticamente il contatore dei riferimenti di
uninterfaccia quando il codice dellapplicazione acquisisce un puntatore
allinterfaccia e decrementa tale contatore quando linterfaccia esce dal campo di
validit.
In C++Builder, la classe modello DelphiInterface fornisce alle classi interfaccia di C++
solo una parte di tali automatismi. Per le propriet e i metodi nella VCL e nella CLX
che utilizzano i tipi interfaccia in Object Pascal, i wrapper di C++ utilizzano una
DelphiInterface che costruita utilizzando la classe interfaccia sottostante.
Il costruttore DelphiInterface, il costruttore copia, loperatore di assegnazione e il
distruttore incrementano o decrementano alloccorrenza il contatore dei riferimenti.
Tuttavia, DelphiInterface non cos conveniente quanto il supporto offerto dal
compilatore per le interfacce in Object Pascal. Altri operatori che forniscono laccesso
al puntatore allinterfaccia sottostante non gestiscono il conteggio dei riferimenti
perch la classe non pu sempre dire quando opportuno farlo. Potrebbe essere
necessario chiamare esplicitamente AddRef o Release per essere certi che il conteggio
dei riferimenti sia corretto.
Stringhe di risorse
Se nel codice presente una unit Pascal che usa stringhe di risorse, il compilatore
Pascal (DCC32) genera una variabile globale e una corrispondente macro del
preprocessore per ciascuna stringa di risorse quando genera il file header. Le macro
vengono usate per caricare automaticamente le stringhe di risorse, e sono destinate
Tabella 13.2 Confronto delluguaglianza !A == !B di variabili BOOL
Object Pascal C++ !A == !B
0 (False) 0 (false) !0 == !0 (TRUE)
0 (False) 1 (true) !0 == !1 (FALSE)
1 (True) 0 (false) !1 == !0 (FALSE)
1 (True) 1 (true) !1 == !1 (TRUE)
13-22 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
ad essere usate nel codice C++ dovunque si fa riferimento alla stringa di risorse. Per
esempio, la sezione resourcestring nel codice Object Pascal pu contenere
aaIt c.c.,
Iatet?ace
teaeatceattIa
i c cic. .c icccss s csccs,
IepIeeeatatIea
beIa
eai.
Il codice corrispondente generato dal compilatore Pascal per C++Builder sar
exteta .~~ .sc.cscc cscc. _i,
-ie?Iae .c._i .sc.i.cscc..c._i
Questo consente di usare le stringhe di risorse Object Pascal esportate senza dover
chiamare in modo esplicito LoadResourceString.
Parametri predefiniti
La versione pi recente del compilatore Pascal accetta parametri predefiniti per i
costruttori per compatibilit con C++. A differenza di C++, i costruttori Object Pascal
possono per avere stesso numero e gli stessi tipi di parametri, poich ad essi viene
attribuito un nome univoco. In tali casi nei costruttori Object Pascal vengono usati
parametri fittizi per distinguerli quando vengono generati i file header di C++. Per
esempio, per una classe chiamata TInCompatible, i costruttori Object Pascal
potrebbero essere
ceaattactet cic~.c .,c,
ceaattactet cic.c.~.c .,c,
che porterebbero, senza parametri predefiniti, al seguente codice ambiguo in C++ per
entrambi i costruttori:
__?aatcaII L.,iccisscs.,c .c, -- cs . c .isci cic
csc
__?aatcaII L.,iccisscs.,c .c, -- cs . c .isci cic.c.
csc
Tuttavia, usando parametri predefiniti, per una classe chiamata TCompatible, i
costruttori Object Pascal sono
ceaattactet cic~.c .,c,
ceaattactet cic.c.~.c .,c, .. Lcc ,
Essi portano al seguente codice non ambiguo in C++Builder:
__?aatcaII .,iccisscs.,c .c, -- cs . c .isci cic
csc
__?aatcaII .,iccisscs.,c .c, .., -- cs . c .isci
cic.c. csc
_
Il problema principale con i parametri predefiniti che DCC32 rimuove il valore
predefinito del parametro predefinito. Un errore in tale operazione pu generare
S u p p o r t o d e l l i n g u a g g i o C + + p e r l a V C L e l a C L X 13-23
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
ambiguit qualora non ci siano parametri predefiniti. Bisogna tenerne conto quando
si usano classi VCL o CLX oppure componenti di produttori terzi.
Informazioni di tipo runtime
Object Pascal ha costrutti di linguaggio che hanno a che fare con RTTI. Alcuni hanno
equivalenti in C++. Essi vengono elencati nella Tabella 13.3:
Nella Tabella 13.3, ClassName un metodo TObject che restituisce una stringa
contenente il nome del tipo attuale delloggetto, indipendentemente dal tipo di
variabile dichiarata. Gli altri metodi RTTI introdotti in TObject non hanno equivalenti
in C++. Essi sono tutti pubblici e sono elencati qui di seguito:
ClassInfo restituisce un puntatore alla tabella contenente le informazioni di tipo
runtime (RTTI) del tipo di oggetto.
ClassNameIs determina se un oggetto di uno specifico tipo.
ClassParent restituisce il tipo dellantenato diretto della classe. Nel caso di TObject
ClassParent restituisce nil perch TObject non non ha alcun parente. Viene usato
dagli operatori is e as, e dal metodo InheritsFrom.
ClassType determina dinamicamente il tipo attuale di un oggetto. Viene usato
internamente dagli operatori is e as di Object Pascal.
FieldAddress usa RTTI per ottenere lindirizzo di un campo pubblicato. Viene usato
internamente dal sistema steaming.
InheritsFrom determina la relazione tra due oggetti. Viene usato internamente
dagli operatori is e as di Object Pascal.
MethodAddress usa RTTI per trovare lindirizzo di un metodo. Viene usato
internamente dal sistema steaming.
Alcuni di questi metodi di TObject sono destinati principalmente alluso interno da
parte del compilatore o del sistema streaming. Per maggiori informazioni, consultare
la Guida in linea.
Tabella 13.3 Esempi di correlazioni RTTI da Object Pascal a C++
RTTI Object Pascal RTTI C++
if Sender is TButton... if (dynamic_cast <TButton*> (Sender)
// dynamic_cast restituisce NULL in caso di errore.
b := Sender as TButton;
(* genera uneccezione in caso di
errore *)
TButton& ref_b = dynamic_cast <TButton&> (*Sender)
// genera uneccezione in caso di errore.
ShowMessage(Sender.ClassName); ShowMessage(typeid(*Sender).name());
13-24 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
Tipi non mappati
Tipi real a 6 byte
Il vecchio formato a virgola mobile a 6 byte di Object Pascal ora viene chiamato
Real48. Il vecchio tipo Real ora un double. C++ non ha un equivalente per il tipo
Real48. Conseguentemente, non si deve usare del codice Object Pascal che includa
questo tipo con il codice C++. Altrimenti, il generatore del file header generer un
messaggio.
Arrays come tipi restituiti da funzioni
In Object Pascal una funzione pu richiedere come argomento, o restituire come tipo,
un array. Per esempio, la sintassi per una funzione GetLine che restituisce un array di
80 caratteri
t,pe
c_ii atta,, e? caat,
?aactIea cc c_ii,
C++ non ha un equivalente di questa funzione. In C++ gli array non sono consentiti
come tipi restituiti da funzioni. E tantomeno C++ accetta array come tipo di
argomento di una funzione.
bene tenere presente che, sebbene la VCL e la CLX non abbiano alcuna propriet
che sia un array, il linguaggio Object Pascal lo consente. Dal momento che le
propriet possono usare i metodi di lettura e di scrittura Get e Set, che richiedono e
restituiscono valori del tipo della propriet, in C++Builder non possibile avere una
propriet di tipo array.
_
Le propriet array, che sono valide anche in Object Pascal, non sono un problema in
C++ perch il metodo Get prende un valore di indice come parametro, mentre il
metodo Set restituisce un oggetto del tipo contenuto dallarray. Per maggiori
informazioni sulle propriet array, consultare Creazione di propriet array a
pagina 47-8.
Estensioni di parole chiave
Questa sezione descrive le estensioni di parole chiave conformi con lo standard
ANSI, implementate in C++Builder per supportare la VCL e la CLX. Per un elenco
completo delle parole chiave e delle relative estensioni in C++Builder, consultare la
Guida in linea.
__classid
Loperatore __classid viene usato dal compilatore per generare un puntatore a vtable
per il classname specificato. Questo operatore viene usato per ottenere la classe meta
da una classe.
Sintassi __cIaaaIicissi.c
Per esempio, __classid viene usato per la registrazione di editor di propriet, di
componenti e di classi, e con il metodo InheritsFrom di TObject. Il codice seguente
S u p p o r t o d e l l i n g u a g g i o C + + p e r l a V C L e l a C L X 13-25
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
illustra luso di __classid per la creazione di un nuovo componente derivato da
TWinControl:
aaeeapace ..c
__closure
La parola chiave __closure serve per dichiarare uno speciale tipo di puntatore ad una
funzione membro. Nel linguaggio C++ standard, il solo modo per ottenere un
puntatore a una funzione membro consiste nellutilizzare il nome del membro per
esteso, come mostrato nellesempio seguente:
cIaaa cisc
pabIIc
veIi .cIat x ,
,
t,peie? veIi cisc ,isc.c.ccIat,
Iat .iIat ic, caat i,
cisc ciscccc,
,isc.c.cc . cisc.c, c ,c .c.cc .c
i .c c ,c .c.cc
ciscccc.,
tetata ,
pabIIc
veIi c._.cIat ,
,
Iat .iIat ic, caat i,
.cc. .cc.ccc,
,isc.c.cc . .cc.c._.c, L~
tetata ,
13-26 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
Lestensione della parola chiave __closure permette di aggirare questa limitazione e
di fare qualcosa in pi. Utilizzando un closure possibile ottenere un puntatore a
funzione membro di un oggetto (cio una particolare istanza di una classe). Loggetto
pu essere qualsiasi oggetto, indipendentemente dalla sua gerarchia di eredit. Il
puntatore this delloggetto viene utilizzato automaticamente quando si chiama la
funzione membro mediante il closure. Lesempio seguente mostra come dichiarare e
utilizzare un closure. Si presume che le classi base e derivate fornite in precedenza
siano state definite.
Iat .iIat ic, caat i,
.cc. .cc.ccc,
veIi __cIeaate .cc.sc,
.cc.sc .cc.cccc._.c, c i ,c c c._.c .c.cc
.c c csc s isscic. . c
,ici ccc, .cc.ccc
.cc.sc, i c._.c c csc
tetata ,
~ csc i. i i.c i. c .
veIi __cIeaate .sc Iat,
Li.c c csc
.sc ,c>.c,
sc c csc ci c .c.cc .c
.sc,
tetata,
.cc. .cc.ccc,
veIi __cIeaate .cc.scIat,
.cc.sc .cc.cccc._.c, .i.c is cc.c
.cc.sc,
c ci sc ,cs i.c i csc,
c ci is c i ,c c .c .c.cc .c
c cisc ciss
.c.cc.ccc,
tetata ,
Notare che si sta passando un puntatore a unistanza della classe derivata e lo si sta
utilizzando per ottenere un puntatore a una funzione membro nella classe base una
cosa che il linguaggio C++ standard non consente di fare.
S u p p o r t o d e l l i n g u a g g i o C + + p e r l a V C L e l a C L X 13-27
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
I closure sono una parte fondamentale dellambiente RAD di C++ Builder. Essi
danno la capacit di assegnare un gestore di evento nellObject Inspector. Ad
esempio, un oggetto TButton ha un evento di nome OnClick. Nella classe TButton,
levento OnClick una propriet che utilizza nella sua dichiarazione lestensione
della parola chiave __closure. La parola chiave __closure permette di assegnare alla
propriet una funzione membro di unaltra classe (di solito una funzione membro in
un oggetto TForm). Quando si colloca un oggetto TButton su una scheda e quindi si
crea un gestore per levento OnClick del pulsante, C++Builder crea una funzione
membro nel TForm genitore del pulsante e assegna quella funzione membro
allevento OnClick di TButton. In questo modo, il gestore di evento viene associato a
quella particolare istanza di TButton e a nessun altro.
Per ulteriori informazioni su eventi e closure, vedere il Chapter 48, Creazione di
eventi.
__property
La parola chiave __property dichiara un attributo di una classe. Le propriet
appaiono al programmatore esattamente come qualsiasi altro attributo (campo) di
una classe. Tuttavia, come la sua controparte Object Pascal, la parola chiave
__property di C++Builder aggiunge molte altre funzionalit altre alla semplice
capacit di esaminare e modificare il valore dellattributo. Poich gli attributi della
propriet controllano completamente laccesso alla propriet, non esistono
limitazionni sul modo in cui si implementa la propriet allinterno della stessa classe.
Sintassi __ptepett, type propertyName,index1Type index1,indexNType indexN attributes ,
in cui
type un tipo di dati intrinseco o dichiarato in precedenza.
propertyName un qualsiasi identificativo valido.
indexNType un tipo di dati intrinseco o dichiarato in precedenza.
indexN il nome di un parametro indice che sar passato alle funzioni read e write
della propriet.
attributes una sequenza separata da virgole di read, write, stored, default (o
nodefault), o index.
I parametri indexN fra parentesi quadre sono facoltativi. Se presenti, dichiarano una
propriet array. I parametri index vengono passati ai metodi read e write della
propriet array.
Lesempio seguente mostra alcune dichiarazioni di propriet semplici:
cIaaa .,cxi.,c
ptIvate
Iat x,,
?Ieat ccs,,,
ptetectei
Iat ci.. tetatax,
veIi .c.Iat c.x x c.x,
ieabIe c.,c.
s.c c.,i i. c i .i , ic
13-28 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o p e r i t i p i d i d a t i O b j e c t P a s c a l e p e r l e s t r u t t u r e d e l l i n g u a g g i o
tetata,
I?ci.csis,
,--,
,--,
I?ci.csis,
, ..cxci,,
eIae
,--,
-,i.i .cssic cc
-,i.i .cssic cc .
-,i.i .cssic cc
-.c.c cx i cs s
-,i.i .cssic cx
- c,
cs ci cicc.cc '...ici.cics',
. c,ccx-_._., cicc.cc, , _~_~.., c
_...
. sccicc.c
c.cicxc, c.i.c, , _.., cs cicc.c, 1,
csccc,
ii.cc>ii.c .>icc,
_
Per ulteriori informazioni sugli stati del dataset, consultare Determinazione degli
stati del dataset a pagina 22-3.
Modifica e aggiornamento dei dati
Tutti i controlli dati, tranne il navigatore, visualizzano i dati di un campo database.
Inoltre, possono essere utilizzati per modificare e aggiornare i dati finch il dataset
sottostante lo permette.
_
I dataset unidirezionali non consentono mai allutente di modificare e aggiornare i
dati.
Abilitazione dellediting nei controlli allatto dellimmissione dati
Un dataset deve essere in stato dsEdit perch sia possibile modificarne i dati. Se la
propriet AutoEdit del datasource true (impostazione predefinita), il controllo dati
gestisce lattivit di porre il dataset in modalit dsEdit non appena lutente prova a
modificarne i dati.
Se AutoEdit false, necessario fornire un meccanismo alternativo per porre il
dataset in modalit editing. Un possibile meccanismo consiste nellutilizzare un
controllo TDBNavigator con un pulsante Edit che consenta esplicitamente allutente di
porre il dataset in modalit editing. Per ulteriori informazioni su TDBNavigator,
vedere Spostamento e gestione dei record a pagina 19-31. In alternativa, possibile
scrivere del codice che chiami il metodo Edit del dataset quando si desidera porre il
dataset in modalit editing.
Modifica dei dati in un controllol
Un controllo dati pu registrare le modifiche apportate al dataset associato solo se la
propriet CanModify del dataset true. CanModify sempre false per i dataset
unidirezionali. Alcuni dataset hanno una propriet ReadOnly che consente di
specificare se CanModify true.
_
Il fatto che un dataset client possa aggiornare i dati dipende dal fatto che la tabella
del database sottostante consenta o meno gli aggiornamenti.
19-6 G u i d a a l l a p r o g r a mma z i o n e
U s o d e l l e f u n z i o n i c o m u n i a i c o n t r o l l i d a t i
Anche se la propriet CanModify del dataset impostata a true, affinch il controllo
possa registrare gli aggiornamenti nella tabella di database, necessario impostare a
true anche la propriet Enabled del datasource che connette il dataset al controllo. La
propriet Enabled del datasource determina se il controllo pu visualizzare i valori
dei campi del dataset e, di conseguenza, se un utente pu modificare i valori e
registrare le modifiche. Se Enabled true (impostazione predefinita), i controlli
possono visualizzare i valori dei campi.
Infine, possibile controllare anche se lutente pu apportare modifiche ai dati
visualizzati nel controllo. La propriet ReadOnly del controllo dati determina se un
utente pu modificare i dati visualizzati dal controllo. Se false (impostazione
predefinita), gli utenti possono modificare i dati. Ovviamente, sar bene assicurarsi
che la propriet ReadOnly del controllo sia true quando la propriet CanModify del
dataset false. In caso contrario, si dar falsamente allutente limpressione che possa
influire sui dati nella tabella del database sottostante.
In tutti i controlli dati, ad eccezione di TDBGrid, le modifiche apportate a un campo
vengono copiate nel componente field sottostante in un dataset quando viene
premuto il tasto Tab dal controllo. Se in un campo si preme Esc prima di Tab, il
controllo dati abbandona le modifiche e ripristina il valore del campo antecedente
alle modifiche.
In TDBGrid, le modifiche vengono confermate solo quando si passa a un altro record;
per annullare tutte le modifiche apportate a un qualsiasi record di un campo,
possibile premere Esc prima di passare a un altro record.
Quando un record viene registrato, C++Builder controlla tutti i componenti data-
aware associati al dataset, per verificare se il loro stato cambiato. Se sorge un
problema di aggiornamento di un campo contenente dati modificati, C++Builder
solleva uneccezione e il record non viene modificato.
_
Se lapplicazione memorizza gli aggiornamenti nella cache (ad esempio, utilizzando
un dataset client), tutte le modifiche vengono inviate a una cache interna. Queste
modifiche non vengono applicate alla tabella di database sottostante finch non si
chiama il metodo ApplyUpdates del dataset.
Disabilitazione e abilitazione della visualizzazione dei dati
Quando lapplicazione elabora in sequenza un dataset o esegue una ricerca,
opportuno impedire temporaneamente laggiornamento dei valori visualizzati nei
controlli associati ai dati a ogni variazione del record attivo. Impedendo
laggiornamento dei valori, loperazione sequenziale o la ricerca risultano pi veloci e
si evita il fastidioso sfarfallio dello schermo.
DisableControls un metodo dei dataset che disabilita la visualizzazione di tutti i
controlli associati ai dati legati a un dataset. Non appena sono terminate
lelaborazione sequenziale o la ricerca, lapplicazione deve chiamare
immediatamente il metodo EnableControls del dataset per abilitare nuovamente la
visualizzazione nei controlli.
Di solito, i controlli vengono disabilitati prima di iniziare un processo iterativo.
Questultimo deve aver luogo allinterno di unistruzione try...finally, in modo che
U s o d e i c o n t r o l l i d a t i 19-7
U s o d e l l e f u n z i o n i c o m u n i a i c o n t r o l l i d a t i
sia possibile riabilitare i controlli anche se si verifica uneccezione durante
lelaborazione. La clausola finally chiamer EnableControls. Il codice seguente illustra
come utilizzare DisableControls e EnableControls in questo modo:
sicc>siccs,
tt,
__?IaaII,
sicc>iccs,
.ii~>ii.cc s.c.,i>ii.cc,
.ii~>sccs .c cs c. c.cx cis,
eIae
.ii~>ii.cc .c..>ii.cc,
.ii~>sccs .c cLsc cccc c.
c.s cicc cc.cs,
19-34 G u i d a a l l a p r o g r a mma z i o n e
S p o s t a m e n t o e g e s t i o n e d e i r e c o r d
Visualizzazione del fumetto guida
Per visualizzare in esecuzione il fumetto guida per ciascun pulsante del navigatore,
impostare la propriet ShowHint del navigatore a true. Quando ShowHint true, il
navigatore visualizza una miniguida di suggerimento ogni volta che si passa il
cursore del mouse sui pulsanti del navigatore. Per impostazione predefinita
ShowHint false.
La propriet Hints controlla il testo del fumetto guida per ciascun pulsante. Per
impostazione predefinita, Hints una lista di stringhe vuota. Quando Hints vuota,
ogni pulsante del navigatore visualizza il testo guida predefinito. Per fornire un
fumetto guida personalizzato per i pulsanti del navigatore, usare lo String editor per
registrare nella propriet Hints una riga separata di testo per il suggerimento
associato a ciascun pulsante. Se presenti, le stringhe create sovrascrivono i
suggerimenti predefiniti forniti dal controllo navigatore.
Uso di un singolo navigatore per pi dataset
Come avviene per gli altri controlli data-aware, la propriet DataSource di un
navigatore specifica il datasource che collega il controllo a un dataset. Modificando
la propriet DataSource di un navigatore in esecuzione, un singolo navigatore pu
consentire lo spostamento tra i record e la gestione di pi dataset.
Si supponga che una scheda contenga due controlli di modifica collegati
rispettivamente ai dataset CustomersTable e OrdersTable tramite le sorgenti dati
CustomersSource e OrdersSource. Quando un utente seleziona il controllo di modifica
connesso a CustomersSource, anche il navigatore dovrebbe usare CustomersSource e
quando lutente seleziona il controllo di modifica connesso a OrdersSource, anche il
navigatore dovrebbe passare a OrdersSource. possibile programmare il gestore di
evento OnEnter di uno dei controlli di modifica e quindi condividere quellevento
con laltro controllo di modifica. Per esempio:
veIi __?aatcaII .s.c.,icccc .c.c
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-1
C a p i t o l o
20
Capitolo20Uso dei componenti di supporto
decisionale
I componenti di supporto decisionale aiutano a creare tabelle incrociate - dette anche
crosstab - e grafici. possibile quindi usare queste tabelle e grafici per vedere e
riassumere i dati da prospettive diverse. Per maggiori informazioni sui dati
incrociati, consultare I crosstab a pagina 20-2.
Panoramica
I componenti di supporto decisionale appaiono sulla pagina Decision Cube della
tavolozza Component:
Il cubo decisionale, TDecisionCube, un magazzino dati multidimensionale.
La sorgente decisionale, TDecisionSource, definisce lo stato del pivot attivo di una
griglia o di un grafico decisionale.
La query decisionale, TDecisionQuery, una forma specializzata di TQuery usata
per definire i dati in un cubo decisionale.
Il pivot decisionale, TDecisionPivot, consente di ingrandire o di rimpicciolire le
dimensioni del cubo decisionale o i campi con la semplice pressione di pulsanti.
La griglia decisionale, TDecisionGrid, mostra dati mono e multidimensionali in
forma tabellare.
Il grafico decisionale, TDecisionGraph, mostra i campi di una griglia decisionale
come un grafico dinamico che cambia al variare delle dimensioni dei dati.
La Figura 20.1 mostra tutti i componenti di supporto decisionale collocati su una
scheda in fase di progettazione.
20-2 G u i d a a l l a p r o g r a mma z i o n e
I c r o s s t a b
Figura 20.1 Componenti di supporto decisionale in progettazione
I crosstab
Le tabelle incrociate, o crosstab, sono un modo di presentare sottoinsiemi di dati per
rendere pi evidenti relazioni e andamenti. I campi della tabella diventano le
dimensioni del crosstab mentre i valori dei campi definiscono le categorie e i
riepiloghi allinterno di una dimensione.
possibile usare i componenti di supporto decisionale per disporre sulle schede i
crosstab. TDecisionGrid mostra i dati in una tabella, mentre TDecisionGraph la traccia
graficamente. TDecisionPivot dispone di pulsanti che semplificano la visualizzazione
o loccultamento delle dimensioni e il loro spostamento tra le colonne e le righe.
I crosstab possono essere monodimensionali o multidimensionali.
Query decisionale
Cubo decisionale
Griglia decisionale
Pivot decisionale
Grafico decisionale
Sorgente decisionale
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-3
R e g o l e g e n e r a l i p e r l u s o d e i c o m p o n e n t i d i s u p p o r t o d e c i s i o n a l e
Crosstab monodimensionali
I crosstab monodimensionali mostrano una riga (o una colonna) di riepilogo per le
categorie di una singola dimensione. Ad esempio, se la dimensione della colonna
scelta Payment e la categoria di riepilogo Amount Paid, il crosstab in Figura 20.2
mostra limporto pagato con ciascuno dei metodi.
Figura 20.2 Un crosstab mono-dimensionale
Crosstab multidimensionali
I crosstab multidimensionali usano dimensioni supplementari per le righe e/o per le
colonne. Per esempio, un crosstab bidimensionale pu mostrare gli importi pagati in
base al metodo di pagamento per ciascun paese.
Un crosstab tridimensionale pu mostrare gli importi pagati in base al metodo e alle
condizioni di pagamento paese per paese, come mostrato nella Figura 20.3.
Figura 20.3 Crosstab tridimensionale
Regole generali per luso dei componenti di supporto decisionale
I componenti di supporto decisionale, elencati a pagina 20-1,possono essere usati
contemporaneamente per presentare dati multidimensionali sotto forma di tabelle e
di grafici. Ad ogni dataset possono essere collegati pi tabelle o grafici. In esecuzione,
possibile usare pi istanze di TDecisionPivot per visualizzare dati di prospettive
differenti.
Per creare una scheda con tabelle e grafici di dati multidimensionali, procedere nel
modo seguente:
1 Creare una scheda.
20-4 G u i d a a l l a p r o g r a mma z i o n e
R e g o l e g e n e r a l i p e r l u s o d e i c o m p o n e n t i d i s u p p o r t o d e c i s i o n a l e
2 Aggiungere questi componenti alla scheda (usando poi lObject Inspector per
collegarli come indicato di seguito):
Un dataset, di solito TDecisionQuery (per maggiori informazioni, consultare
Creazione di dataset decisionali con leditor Decision Query a pagina 20-6) o
TQuery
Un cubo decisionale, TDecisionCube, collegato al dataset impostando la
propriet DataSet al nome del dataset
Una sorgente decisionale, TDecisionSource, collegato al cubo decisionale
impostando la propriet di DecisionCube al nome del cubo decisionale
3 Aggiungere un pivot decisionale, TDecisionPivot, e collegarlo alla sorgente
decisionale con lObject Inspector impostando la propriet DecisionSource al nome
della sorgente decisionale appropriata. Il pivot decisionale facoltativo ma utile;
permette allo sviluppatore e agli utenti finali della scheda di modificare le
dimensioni visualizzate in griglie o in grafici decisionali con la semplice pressione
di pulsanti.
Nel loro orientamento predefinito, quello orizzontale, i pulsanti sul lato sinistro
del pivot decisionale agiscono sui campi posti sul lato sinistro della griglia
decisionale (le righe); i pulsanti sul lato destro agiscono sui campi della parte
superiore della griglia decisionale (le colonne).
possibile determinare dove fare apparire i pulsanti del pivot decisionale
impostando la propriet GroupLayout a xtVertical, xtLeftTop o xtHorizontal
(impostazione predefinita). Per maggiori informazioni sulle propriet del pivot
decisionale, consultare Uso dei pivot decisionali a pagina 20-10.
4 Aggiungere una o pi griglie e grafici decisionali, collegandoli alla sorgente
decisionale. Per maggiori informazioni, consultare Creazione e uso delle griglie
decisionali a pagina 20-11 e Creazione e uso dei grafici decisionali a
pagina 20-13.
5 Usare leditor della query decisionale o la propriet SQL di TDecisionQuery (o di
TQuery) per specificare le tabelle, i campi e i riepiloghi da visualizzare nella
griglia o nel grafico. Lultimo campo dellistruzione SQL SELECT deve essere il
campo di riepilogo. Gli altri campi nellistruzione SELECT devono essere i campi
di GROUP BY. Per istruzioni, consultare Creazione di dataset decisionali con
leditor Decision Query a pagina 20-6.
6 Impostare la propriet Active della query decisionale (o del componente dataset
alternativo) a true.
7 Usare la griglia e il grafico decisionali per mostrare e tracciare sotto forma di
grafico dimensioni dati differenti. Per istruzioni e suggerimenti, consultare Uso
delle griglie decisionali a pagina 20-11 e Uso dei grafici decisionali a
pagina 20-14.
Per vedere unillustrazione che riporti in una scheda tutti i componenti di supporto
decisionale, consultare Figura 20.1 a pagina 20-2.
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-5
U s o d e i d a t a s e t c o n i c o m p o n e n t i d i s u p p o r t o d e c i s i o n a l e
Uso dei dataset con i componenti di supporto decisionale
Lunico componente di supporto decisionale collegato direttamente a un dataset il
cubo decisionale, TDecisionCube. TDecisionCube si aspetta ricevere i dati tramite i
gruppi e i riepiloghi definiti da unistruzione SQL di un formato accettabile. La frase
GROUP BY deve contenere gli stessi campi non riepilogati (e nello stesso ordine)
contenuti nella frase SELECT, e i campi di riepilogo devono essere identificati.
Il componente query decisionale, TDecisionQuery, una versione specializzata di
TQuery. possibile usare TDecisionQuery per definire pi semplicemente la
configurazione delle dimensioni (righe e colonne) e i valori di riepilogo usati per
fornire i dati ai cubi decisionali, TDecisionCube. Come dataset per TDecisionCube un
possibile anche usare un comune TQuery o altri dataset abilitati a BDE, ma la corretta
configurazione del dataset e di TDecisionCube sono di competenza del progettista.
Per operare correttamente col cubo decisionale, tutti i campi progettati nel dataset
devono essere dimensioni o riepiloghi. I riepiloghi devono essere valori aggiuntivi
(come somma o conteggio) e devono rappresentare i totali per ciascuna
combinazione dei valori di dimensione. Per semplificare al massimo la
configurazione, nel dataset le somme devono essere chiamate Sum... mentre i
conteggi dovrebbero essere chiamati Count....
Decision Cube pu calcolare correttamente pivot, totali parziali e in dettaglio solo per
i riepiloghi le cui celle sono di tipo additivo. (SUM e COUNT sono celle additive,
AVERAGE, MAX e MIN no). La crosstab di costruzione del pivot visualizza solo le
griglie che contengono totali additivi. Se si usano totali non additivi, ricorrere ad una
griglia decisionale statica che non sia pivot, dettaglio o totale parziale.
Poich le medie possono essere calcolate usando SUM diviso per COUNT, viene
aggiunta automaticamente una media pivot quando le dimensioni SUM e COUNT
per un campo vengono incluse nel dataset. Questo tipo di media deve essere
utilizzato preferibilmente per una media calcolata usando unistruzione AVERAGE.
Le medie possono essere calcolate anche usando COUNT(*). A questo scopo,
includere un selettore COUNT(*) COUNTALL nella query. Se per calcolare le
medie si usa COUNT(*), il singolo aggregatore pu essere usato per tutti i campi.
COUNT(*) deve essere utilizzato solo nei casi in cui nessuno dei campi che deve
essere riepilogato include valori vuoti, o in cui non disponibile un totale COUNT
per ogni campo.
Creazione di dataset decisionali con TQuery o TTable
Se si usa come dataset decisionale un comune componente TQuery, si deve preparare
manualmente listruzione SQL, facendo attenzione a fornire una frase GROUP BY
che contenga gli stessi campi (e nello stesso ordine) della frase SELECT.
Listruzione SQL pu essere simile a questa:
. .'c.s', .'.,L~',
.'.i.c.c.', .. .'~..i.'
. '.' .
. .'c.s', .'.,L~', .'.i.c.c.'
20-6 G u i d a a l l a p r o g r a mma z i o n e
U s o d e i d a t a s e t c o n i c o m p o n e n t i d i s u p p o r t o d e c i s i o n a l e
Lordinamento dei campi SELECT deve coincidere con quello di GROUP BY.
Con TTable occorre dire al cubo decisionale quali sono i campi della query da
considerare campi di raggruppamento e quali quelli da considerare campi di
riepilogo. Per eseguire questa operazione, compilare Dimension Type per ciascun
campo in DimensionMap della pagina Decision Cube. Occorre indicare se ciascun
campo una dimensione o un riepilogo, e se un riepilogo, si deve fornirne il tipo.
Poich le medie pivot dipendono dai calcoli SUM/COUNT, occorre fornire anche il
nome base del campo per consentire al cubo decisionale di confrontare le coppie di
aggregatori SUM e COUNT.
Creazione di dataset decisionali con leditor Decision Query
Tutti i dati usati dai componenti di supporto decisionale passano attraverso il cubo
decisionale che accetta un dataset formattato in modo particolare, prodotto molto
facilmente da una query SQL. Per maggiori informazioni, consultare Uso dei dataset
con i componenti di supporto decisionale a pagina 20-5.
Anche se possibile usare TTable e TQuery come dataset decisionali, risulta pi
semplice ricorrere a TDecisionQuery, leditor della query decisionale fornito insieme
al prodotto. Pu essere usato per specificare tabelle, campi e riepiloghi che devono
apparire nel cubo decisionale contribuendo a configurare correttamente le porzioni
SELECT e GROUP BY della query SQL.
Per usare leditor Decision Query:
1 Selezionare il componente della query decisionale sulla scheda, poi fare clic col
tasto destro e scegliere Decision Query editor. Apparir la finestra di dialogo
Decision Query editor.
2 Selezionare il database da utilizzare.
3 Per query su una singola tabella, fare clic sul pulsante Select Table.
Per query pi complesse, che coinvolgono join su pi tabelle, fare clic sul pulsante
Query Builder per visualizzare SQL Builder oppure, nella pagina SQL, scrivere
listruzione SQL utilizzando la casella di testo apposita.
4 Ritornare alla finestra di dialogo Decision Query editor.
5 Nella finestra di dialogo Decision Query editor selezionare i campi nellelenco
Available Fields e assegnarli a Dimensions o a Summaries facendo clic sul
pulsante freccia a destra opportuno. Mano mano che si aggiungono i campi
allelenco Summaries, selezionare dal menu visualizzato il tipo di riepilogo da
utilizzare: somma, conteggio o media.
6 Per impostazione predefinita, tutti i campi e i riepiloghi definiti nella propriet
SQL della query decisionale appaiono nelle caselle di riepilogo Active Dimensions
e Active Summaries. Per eliminare una dimensione o riepilogo, selezionarlo
nellelenco e fare clic sulla freccia sinistra accanto allelenco, o fare doppio clic
sullelemento da eliminare. Per aggiungerlo allelenco originale, selezionarlo nella
casella di riepilogo Available Fields e fare clic sulla freccia destra opportuna.
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-7
U s o d e i c u b i d e c i s i o n a l i
Una volta definiti i contenuti del cubo decisionale, possibile modificare
ulteriormente le dimensioni di visualizzazione agendo sulla propriet DimensionMap
e sui pulsanti di TDecisionPivot. Per maggiori informazioni, consultare le sezioni
successive Uso dei cubi decisionali, Uso delle sorgenti decisionali a pagina 20-9,
e Uso dei pivot decisionali a pagina 20-10.
_
Quando si usa leditor Decision Query, la query inizialmente viene gestita nella
sintassi SQL ANSI-92, quindi tradotta (se necessario) nel dialetto usato dal server.
Leditor Decision Query legge e visualizza solo il formato SQL ANSI standard. La
traduzione del dialetto viene assegnata automaticamente alla propriet SQL di
TDecisionQuery. Per modificare una query, effettuare lediting della versione ANSI-92
in Decision Query anzich nella propriet SQL.
Uso dei cubi decisionali
Il componente cubo decisionale, TDecisionCube, unarea di memorizzazione dati
multidimensionale che recupera i dati da un dataset (di solito usando unistruzione
SQL, strutturata in modo particolare, immessa con TDecisionQuery o TQuery). I dati
sono memorizzati in un formato che ne semplifica lutilizzo come pivot (ovvero,
modifica il modo in cui i dati vengono organizzati e riepilogati) senza dover eseguire
la query una seconda volta.
Propriet del cubo decisionale e eventi
Le propriet DimensionMap di TDecisionCube non solo controllano quali dimensioni e
riepiloghi far apparire, ma consentono anche di impostare gli intervalli di dati e di
specificare il numero massimo di dimensioni che il cubo decisionale pu supportare.
Si pu anche indicare se visualizzare o meno i dati in fase di progetto. possibile
visualizzare nomi (le categorie), valori, totali parziali o dati. La visualizzazione dei
dati in fase di progetto pu essere dispendiosa in termini di tempo, a seconda della
sorgente dati utilizzata.
Facendo clic sul pulsante con le ellissi accanto a DimensionMap nellObject Inspector,
appare la finestra di dialogo Decision Cube editor. possibile usarne le pagine e i
controlli per impostare le propriet di DimensionMap.
Levento OnRefresh viene attivato ogni qualvolta si rigenera la cache del cubo
decisionale. Gli sviluppatori possono accedere alla nuova mappa della dimensione e
modificarla per liberare memoria, modificare il valore massimo dei riepiloghi o delle
dimensioni, e cos via. OnRefresh anche utile se gli utenti accedono alleditor del
cubo decisionale; in questa fase il codice dellapplicazione pu rispondere alle
modifiche apportate dallutente.
Uso di Decision Cube editor
possibile usare leditor del cubo decisionale per impostare le propriet di
DimensionMap dei cubi decisionali. Leditor del cubo decisionale pu essere
visualizzato tramite lObject Inspector, come descritto nella sezione precedente, o
20-8 G u i d a a l l a p r o g r a mma z i o n e
U s o d e i c u b i d e c i s i o n a l i
facendo clic, in fase di progetto, con il tasto destro su un cubo decisionale in una
scheda e selezionando Decision Cube editor.
La finestra di dialogo Decision Cube Editor ha due separatori:
Dimension Settings, usato per attivare o disattivare le dimensioni disponibili,
cambiare il nome e riformattare le dimensioni, mettere le dimensioni in un stato
permanentemente espanso e impostare gli intervalli dati da visualizzare.
Memory Control, usato per impostare il massimo numero di dimensioni e
riepiloghi che possono essere contemporaneamente attivi, per visualizzare
informazioni sulluso della memoria, e per determinare i nomi e i dati che
appaiono in fase di progetto.
Visualizzazione e modifica delle impostazioni delle dimensioni
Per vedere le impostazioni delle dimensioni, visualizzare leditor Decision Cube e
fare clic sul separatore Dimension Settings. Quindi, selezionare una dimensione o un
riepilogo nellelenco Available Fields. Le informazioni appaiono nelle caselle sul lato
destro delleditor:
Per modificare la dimensione o il nome del riepilogo che appaiono nel pivot, nella
griglia o nel grafico decisionali, immettere un nuovo nome nella casella di testo
Display Name.
Per determinare se il campo selezionato una dimensione o un riepilogo, leggere
il testo nella casella di testo Type.Se il dataset un componente TTable, possibile
usare Type per specificare se il campo selezionato una dimensione o un
riepilogo.
Per disattivare o attivare la dimensione o il riepilogo selezionati, modificare
limpostazione nella casella di riepilogo a discesa Active Type: Active, As Needed
o Inactive. La disattivazione di una dimensione o luso dellimpostazione As
Needed fanno risparmiare memoria.
Per modificare il formato di quella dimensione o quel riepilogo, immettere una
stringa di formato nella casella di testo Format.
Per visualizzare quella dimensione o quel riepilogo per Anno, Trimestre o Mese
(Year, Quarter, o Month), modificare limpostazione nella casella di riepilogo a
discesa Binning. Per mettere la dimensione o il riepilogo selezionati in uno stato
permanentemente compresso, si pu scegliere lopzione Set nella casella di
riepilogo Binning. Ci pu essere utile per risparmiare memoria quando una
dimensione ha molti valori. Per maggiori informazioni, consultaree Componenti
di supporto decisionale e controllo della memoria a pagina 20-20.
Per determinare i valori iniziali degli intervalli, o il valore drill-down per una
dimensione Set, scegliere innanzi tutto lappropriato valore Grouping
nellelenco a discesa Grouping, quindi immettere il valore iniziale dellintervallo o
il valore drill-down permanente nellelenco a discesa Initial Value.
Impostazione del numero massimo di dimensioni e di riepiloghi disponibili
Per determinare il numero massimo di dimensioni e di riepiloghi disponibili per i
pivot, le griglie e i grafici decisionali associati al cubo decisionale selezionato,
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-9
U s o d e l l e s o r g e n t i d e c i s i o n a l i
visualizzare leditor Decision Cube e fare clic sul separatore Memory Control. Usare i
controlli di modifica per regolare, se necessario, le impostazioni attive. Queste
aiutano a controllare la quantit di memoria necessaria per il cubo decisionale. Per
maggiori informazioni, consultare Componenti di supporto decisionale e controllo
della memoria a pagina 20-20.
Visualizzazione e modifica delle opzioni di progetto
Per determinare quante informazioni appaiono in fase di progetto, visualizzare il
Decision Cube editor e fare clic sul separatore Memory Control. Quindi, controllare
limpostazione che indica quali nomi e dati visualizzare. La visualizzazione dei dati o
dei nomi di campo in fase di progetto pu causare a volte un degrado delle
prestazioni dovuto al tempo necessario per recuperare i dati.
Uso delle sorgenti decisionali
Il componente sorgente decisionale, TDecisionSource, definisce lo stato attuale del
pivot di griglie o di grafici decisionali. Qualunque coppia di oggetti che usa la stessa
sorgente decisionale condivide anche gli stati del pivot.
Propriet ed eventi
Di seguito sono elencate alcune propriet ed eventi particolari che controllano
laspetto e il comportamento delle sorgenti decisionali:
La propriet ControlType di TDecisionSource indica se i pulsanti del pivot
decisionale devono agire come caselle di controllo (selezioni multiple) o come
pulsanti di opzione (selezioni mutuamente esclusive).
Le propriet SparseCols e SparseRows di TDecisionSource indicano se visualizzare o
meno le colonne o le righe senza valori; se true, vengono visualizzate le colonne o
le righe rade.
TDecisionSource ha i seguenti eventi:
OnLayoutChange si verifica quando lutente esegue rotazioni o compressioni che
riorganizzano i dati.
OnNewDimensions si verifica quando i dati vengono completamente modificati,
come, ad esempio, quando vengono alterati i campi di riepilogo o delle
dimensioni.
OnSummaryChange si verifica quando viene modificato il riepilogo attuale.
OnStateChange si verifica quando si attiva o si disattiva Decision Cube.
OnBeforePivot si verifica quando le modifiche sono gi state confermate ma
linterfaccia utente non stata ancora aggiornata. Gli sviluppatori hanno
lopportunit di apportare modifiche, per esempio, alla capacit o allo stato di
pivot, prima che gli utenti dellapplicazione vedano il risultato delle azioni
precedenti.
20-10 G u i d a a l l a p r o g r a mma z i o n e
U s o d e i p i v o t d e c i s i o n a l i
OnAfterPivot si attiva dopo una modifica nello stato di pivot. In quel preciso
momento, gli sviluppatori possono intercettare informazioni.
Uso dei pivot decisionali
Il componente pivot decisionale, TDecisionPivot, consente di aprire o di chiudere le
dimensioni del cubo decisionale o i campi premendo dei pulsanti. Quando si apre
una riga o una colonna premendo uno dei pulsanti di TDecisionPivot, la dimensione
corrispondente appare sul componente TDecisionGrid o TDecisionGraph. Quando si
chiude una dimensione, i dati particolareggiati non appaiono; la vista viene ridotta
mostrando solo i totali delle altre dimensioni. Una dimensione pu essere anche in
uno stato compresso, in cui appaiono solamente i riepiloghi per un determinato
valore del campo dimensione.
inoltre possibile usare il pivot decisionale per riorganizzare le dimensioni
visualizzate nella griglia decisionale e nel grafico decisionale. sufficiente trascinare
un pulsante sullarea della riga o della colonna o riordinare i pulsanti allinterno della
stessa area.
Per le illustrazioni dei pivot decisionali in progettazione consultare le Figure 20.1,
20.2, e 20.3.
Propriet dei pivot decisionali
Di seguito sono elencate alcune propriet speciali che controllano laspetto e il
comportamento dei pivot decisionali:
Le prime propriet elencate per TDecisionPivot ne definiscono il comportamento
complessivo e laspetto. possibile impostare ButtonAutoSize a false per fare in
modo che TDecisionPivot impedisca lespansione e la contrazione dei pulsanti
mentre si sta modificando la dimensione del componente.
La propriet Groups di TDecisionPivot definisce quali pulsanti di dimensione
dovranno apparire. possibile visualizzare la riga, la colonna e i gruppi di
pulsanti di selezione di riepilogo in qualsiasi combinazione. Si deve tenere
presente che se si vuole maggior flessibilit sul posizionamento di questi gruppi,
possibile collocare in una posizione della scheda un componente TDecisionPivot
che contiene solamente righe, e, in unaltra posizione, un secondo componente che
contiene solamente colonne.
Solitamente, TDecisionPivo viene aggiunto sopra a TDecisionGrid. In base
allorientamento predefinito, quello orizzontale, i pulsanti sul lato sinistro di
TDecisionPivot agiscono sui campi posti sul lato sinistro di TDecisionGrid (le righe);
i pulsanti sul lato destro agiscono sui campi posti nella parte superiore di
TDecisionGrid (le colonne).
possibile determinare il punto in cui appaiono i pulsanti di TDecisionPivot
impostandone la propriet GroupLayout a xtVertical, xtLeftTop, o xtHorizontal (che
il valore predefinito ed descritto nel paragrafo precedente).
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-11
C r e a z i o n e e u s o d e l l e g r i g l i e d e c i s i o n a l i
Creazione e uso delle griglie decisionali
I componenti della griglia decisionale, TDecisionGrid, presentano i dati incrociati
sotto forma di tabella. Queste tabelle, descritte a pagina 20-2, vengono anche
chiamate crosstab. La Figura 20.1 a pagina 20-2 mostra una griglia decisionale su una
scheda in progettazione.
Creazione di griglie decisionali
Per creare una scheda con uno o pi tabelle di dati incrociati:
1 Seguire le istruzioni da 1 a 3 elencate nella sezione Regole generali per luso dei
componenti di supporto decisionale a pagina 20-3.
2 Aggiungere uno o pi componenti TDecisionGrid (griglia decisionale) e collegarli
alla sorgente decisionale, TDecisionSource, con lObject Inspector impostando la
propriet DecisionSource al componente sorgente decisionale opportuno.
3 Procedere con le istruzioni da 5 a 7 elencate nella sezione Regole generali per
luso dei componenti di supporto decisionale.
Per una descrizione di ci che appare nella griglia decisionale e sul modo di
utilizzarla, consultare la sezione Uso delle griglie decisionali a pagina 20-11.
Per aggiungere un grafico alla scheda, seguire le istruzioni riportate nella sezione
Creazione di grafici decisionali a pagina 20-14.
Uso delle griglie decisionali
Il componente griglia decisionale, TDecisionGrid, visualizza i dati provenienti dai
cubi decisionali (TDecisionCube) collegati a sorgenti decisionali (TDecisionSource).
Per impostazione predefinita, la griglia appare con i campi dimensione disposti sul
lato sinistro e/o superiore, a seconda delle istruzioni di raggruppamento definite nel
dataset. Le categorie, una per ciascun valore dei dati, appaiono sotto ciascun campo.
possibile
Aprire e chiudere le dimensioni
Riorganizzare o ruotare righe e colonne
Espandere una riga per avere altri dettagli
Limitare la selezione della dimensione a una singola dimensione per ciascun asse
Per maggiori informazioni sulle propriet speciali e sugli eventi della griglia
decisionale, consultare la sezione Propriet della griglia decisionale a pagina 20-12.
Apertura e chiusura dei campi della griglia decisionale
Se in una dimensione o in un campo di riepilogo appare il segno pi (+), significa che
uno o pi campi alla sua destra sono chiusi (nascosti). possibile aprire campi e
categorie supplementari facendo clic sul segno. Il segno meno () indica un campo
20-12 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e u s o d e l l e g r i g l i e d e c i s i o n a l i
completamente aperto (espanso). Quando si fa clic sul segno, il campo si chiude.
Questa opzione pu essere disattivata; per maggiori informazioni, consultare il
paragrafo Propriet della griglia decisionale a pagina 20-12.
Riorganizzazione di righe e colonne in griglie decisionali
possibile trascinare le intestazioni di riga e di colonna in nuove posizioni allinterno
dello stesso asse o su un altro asse. In questo modo possibile riorganizzare la griglia
e vedere i dati da nuove prospettive man mano che cambia la modalit di
raggruppamento. Questa opzione pu essere disattivata; per maggiori informazioni,
consultare il paragrafo Propriet della griglia decisionale a pagina 20-12.
Se si include un pivot decisionale, possibile premere e trascinare i pulsanti per
riorganizzare la visualizzazione. Per istruzioni, consultare Uso dei pivot
decisionali a pagina 20-10.
Espansione dei dettagli nelle griglie decisionali
possibile espandere una dimensione per vedere pi dettagli.
Ad esempio, se si fa clic col tasto destro su unetichetta di categoria (intestazione di
riga) per una dimensione mentre ce ne sono altre sotto di essa in forma contratta,
possibile decidere se espandere e consultare solamente i dati di quella categoria. Se
una dimensione espansa, sulla griglia non appaiono le etichette di categoria della
dimensione, dato che vengono visualizzati solamente i record per un singolo valore
della categoria. Se sulla scheda c un pivot decisionale, questo visualizza i valori di
categoria e, volendo, consente di passare ad altri valori.
Per espandere una dimensione:
Fare clic col tasto destro su unetichetta di categoria e selezionare Drill In To This
Value, oppure
Fare clic col tasto destro su un pulsante pivot e scegliere Drilled In.
Per riattivare di nuovo la dimensione completa:
Fare clic col tasto destro sul pulsante pivot corrispondente, oppure fare clic col
tasto destro nellangolo superiore-sinistro della griglia decisionale e selezionare la
dimensione.
Limitazione della selezione delle dimensioni in griglie decisionali
Modificando la propriet ControlType della sorgente decisionale si determina se
possibile selezionare pi dimensioni per ciascun asse della griglia. Per maggiori
informazioni, consultare Uso delle sorgenti decisionali a pagina 20-9.
Propriet della griglia decisionale
Il componente griglia decisionale, TDecisionGrid, visualizza i dati provenienti dal
componente TDecisionCube collegato a TDecisionSource. Per impostazione predefinita,
i dati appaiono in una griglia con i campi di categoria disposti sul lato sinistro e nella
parte superiore della griglia.
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-13
C r e a z i o n e e u s o d e i g r a f i c i d e c i s i o n a l i
Di seguito sono elencate alcune propriet speciali che controllano laspetto e il
comportamento delle griglie decisionali:
TDecisionGrid ha propriet uniche per ciascuna dimensione.Per impostarle,
scegliere Dimensions nellObject Inspector, e selezionare poi una dimensione. A
questo punto, le propriet di quella dimensione appaiono nellObject Inspector:
Alignment definisce lallineamento delle etichette di categoria per quella
dimensione, Caption pu essere usata per sostituire il nome predefinito della
dimensione, Color definisce il colore delle etichette di categoria, FieldName
visualizza il nome della dimensione attiva, Format pu memorizzare qualsiasi
formato standard per quel tipo di dati e Subtotals indica se visualizzare o meno i
totali parziali per quella dimensione. Con i campi di riepilogo queste stesse
propriet vengono usate per modificare laspetto dei dati che appaiono nellarea di
riepilogo della griglia. Una volta completata limpostazione delle propriet della
dimensione, fare clic su un componente nella scheda o scegliere un componente
nella casella di riepilogo a discesa nella parte superiore dellObject Inspector.
La propriet Options di TDecisionGrid consente di controllare la visualizzazione
delle linee della griglia (cgGridLines = true), permettendo lattivazione delle
opzioni secondarie (contrazione ed espansione delle dimensioni con indicatori + e
- ; cgOutliner = true), e lattivazione della rotazione tramite drag and drop
(cgPivotable = true)).
Levento OnDecisionDrawCell di TDecisionGrid consente di modificare laspetto di
ciascuna cella mentre viene disegnata. Levento passa String, Font e Color della
cella attiva come parametri di riferimento. possibile modificare questi parametri
per realizzare effetti come, ad esempio, colori speciali per indicare valori negativi.
Oltre a DrawState, che passato da TCustomGrid, levento passa
TDecisionDrawState, che pu essere usato per determinare quale tipo di cella viene
disegnando. possibile ottenere ulteriori informazioni sulla cella utilizzando le
funzioni Cells, CellValueArray, o CellDrawState.
Levento OnDecisionExamineCell di TDecisionGrid consente di agganciare levento
clic destro sulle celle dei dati, ed stato creato per permettere al programma di
visualizzare informazioni (come ad esempio i record di dettaglio) su quella
determinata cella di dati. Quando lutente fa clic col tasto destro su una cella di
dati, allevento vengono fornite tutte le informazioni usate per comporre i valori
dei dati, compresi il valore di riepilogo attualmente attivo e un ValueArray di tutti i
valori della dimensione usati per creare il valore di riepilogo.
Creazione e uso dei grafici decisionali
I componenti grafico decisionale, TDecisionGraph, presentano dati incrociati in
formato grafico. Ciascun grafico decisionale mostra il valore di un singolo riepilogo,
come Sum, Count, o Avg, tracciato per una o pi dimensioni. Per maggiori
informazioni sui crosstab, consultare la pagina 20-3. Per illustrazioni di grafici
decisionali in fase di progetto, vedere la Figura 20.1 a pagina 20-2 e la Figura 20.4 a
pagina 20-15.
20-14 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e u s o d e i g r a f i c i d e c i s i o n a l i
Creazione di grafici decisionali
Per creare una scheda con uno o pi grafici decisionali:
1 Seguire le istruzioni da 1 a 3 elencate nella sezione Regole generali per luso dei
componenti di supporto decisionale a pagina 20-3.
2 Aggiungere uno o pi componenti grafici decisionali (TDecisionGraph) e collegarli
con lObject Inspector alla sorgente decisionale, TDecisionSource, impostandone la
propriet DecisionSource al componente della sorgente decisionale opportuno.
3 Procedere con le istruzioni da 5 a 7 elencate nella sezione Regole generali per
luso dei componenti di supporto decisionale.
4 Per finire, fare clic col tasto destro sul grafico e selezionare Edit Chart per
modificare laspetto della serie del grafico. Per ciascuna dimensione del grafico
possibile impostare delle propriet campione, e impostare poi singolarmente una
serie di propriet per sostituire quelle predefinite. Per maggiori informazioni,
consultare la sezione Personalizzazione dei grafici decisionali a pagina 20-16.
Per una descrizione di ci che appare nel grafico decisionale e del modo in cui usarlo,
consultare la prossima sezione Uso dei grafici decisionali.
Per aggiungere una griglia decisionale o una tabella crosstab alla scheda, seguire le
istruzioni della sezione Creazione e uso delle griglie decisionali a pagina 20-11.
Uso dei grafici decisionali
Il componente grafico decisionale, TDecisionGraph, visualizza i campi provenienti
dalla sorgente decisionale (TDecisionSource) come un grafico dinamico che si
modifica quando le dimensioni dei dati vengono aperte, chiuse, spostate con drag-
and-drop o riordinate con il pivot decisionale (TDecisionPivot).
I dati trasformati in grafico provengono da un dataset specificamente formattato
come TDecisionQuery. Per una panoramica su come i componenti di supporto
decisionale gestiscono e ordinano questi dati, consultare la pagina 20-1.
Per impostazione predefinita, la prima dimensione della riga appare come lasse
delle x e la prima dimensione della colonna appare come lasse delle y.
possibile usare i grafici decisionali in alternativa o in aggiunta alle griglie
decisionali, che presentano dati incrociati in forma tabellare. Le griglie decisionali e i
grafici decisionali che sono collegati alla stessa sorgente decisionale presentano le
stesse dimensioni di dati. Per mostrare i diversi dati di riepilogo per le stesse
dimensioni, possibile collegare pi di un grafico decisionale alla stessa sorgente
decisionale. Per mostrare dimensioni diverse, collegare i grafici decisionali a sorgenti
decisionali diverse.
Nella Figura 20.4, ad esempio, il primo pivot decisionale e il primo grafico sono
collegati alla prima sorgente decisionale, mentre il secondo pivot decisionale e il
secondo grafico sono collegati alla seconda. In questo modo, ciascun grafico mostra
dimensioni diverse.
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-15
C r e a z i o n e e u s o d e i g r a f i c i d e c i s i o n a l i
Figura 20.4 Grafici decisionali collegati a sorgenti decisionali diverse
Per maggiori informazioni su ci che appare in un grafico decisionale, consultare la
prossima sezione Visualizzazione del grafico decisionale.
Per creare un grafico decisionale, consultare la sezione precedente Creazione di
grafici decisionali.
Per una trattazione delle propriet del grafico decisionale e delle modalit per
modificare laspetto e il comportamento dei grafici decisionali, consultare
Personalizzazione dei grafici decisionali a pagina 20-16.
Visualizzazione del grafico decisionale
Per impostazione predefinita, il grafico decisionale traccia i valori di riepilogo delle
categorie nel primo campo attivo della riga (lungo lasse delle y) rispetto ai valori nel
primo campo attivo della colonna (lungo lasse delle x). Ogni categorie riportata nel
grafico appare come una serie separata.
Se viene selezionata una sola dimensionead esempio, facendo clic solamente su un
pulsante di TDecisionPivotviene riportata in grafico una sola serie.
Se si utilizzato un pivot decisionale, possibile premerne i pulsanti per determinare
quali campi del cubo decisionale (dimensioni) devono essere riportati in grafico. Per
scambiare gli assi del grafico, trascinare i pulsanti di dimensione del pivot
decisionale da un lato allaltro dello spazio separatore. Se si ha un grafico mono-
dimensionale con tutti i pulsanti disposti su un solo lato dello spazio separatore,
possibile usare licona Row o licona Column per aggiungere pulsanti sullaltro lato
del separatore e trasformare il grafico in multidimensionale.
20-16 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e u s o d e i g r a f i c i d e c i s i o n a l i
Per attivare una sola riga e una sola colonna alla volta, possibile impostare la
propriet ControlType di TDecisionSource a xtRadio. A quel punto, ci pu essere un
solo campo attivo alla volta per ciascun asse del cubo decisionale, mentre la
funzionalit del pivot decisionale corrisponder al comportamento del grafico.
xtRadioEx funziona in modo analogo a xtRadio, ma non prevede la condizione in cui
tutte le dimensioni della riga o della colonna siano chiuse.
Quando la griglia e il grafico decisionali sono connessi allo stessa TDecisionSource,
sar probabilmente opportuno reimpostare ControlType a xtCheck in modo che
corrisponda al comportamento pi flessibile di TDecisionGrid.
Personalizzazione dei grafici decisionali
Il componente grafico decisionale, TDecisionGraph, visualizza i campi provenienti
dalla sorgente decisionale (TDecisionSource) come un grafico dinamico che si
modifica quando le dimensioni dei dati vengono aperte, chiuse, spostate con drag-
and-drop, o quando vengono riordinate usando il pivot decisionale (TDecisionPivot).
possibile modificare tipo, colori, tipi di contrassegni per le linee del grafico e molte
altre propriet dei grafici decisionali.
Per personalizzare un grafico:
1 Fare clic col tasto destro sul grafico e scegliere Edit Chart. Apparir la finestra di
dialogo Chart Editing.
2 Usare la pagina Chart della finestra di dialogo Chart Editing per visualizzare un
elenco di serie visibili, selezionare la definizione della serie da usare quando, per
una stessa serie, ve ne sono due o pi disponibili, modificare i tipi di grafico per
un modello o per una serie, e impostare le propriet complessive del grafico.
Lelenco Series sulla pagina Chart mostra tutte le dimensioni del cubo decisionale
(precedute da Template:) e le categorie attualmente visibili. Ciascuna categoria o
serie un oggetto separato. possibile:
Aggiungere o cancellare serie derivare da serie esistenti del grafico decisionale.
Le serie derivate sono in grado di fornire annotazioni su serie esistenti o
rappresentare valori calcolati da altre serie.
Modificare il tipo di grafico predefinito e il titolo dei modelli e delle serie.
Per una descrizione degli altri separatori della pagina Chart cercare largomento
Chart page (Chart Editing dialog box) nella Guida in linea.
3 Usare la pagina Series per impostare i modelli delle dimensioni, e personalizzare
poi le propriet per ogni singola serie del grafico.
Per impostazione predefinita, tutte le serie vengono tracciate come grafici a barre a
cui vengono assegnati fino a 16 colori. possibile modificare il tipo di modello e le
propriet per creare una nuova impostazione predefinita. Poi, mentre si agisce sulla
sorgente decisionale facendola passare a stati differenti, il modello viene usato per
creare dinamicamente le serie per ciascun nuovo stato. Per maggiori dettagli sui
modelli, consultare Impostazioni predefinite dei modelli di grafico decisionale a
pagina 20-17.
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-17
C r e a z i o n e e u s o d e i g r a f i c i d e c i s i o n a l i
Per personalizzare le singole serie, seguire le istruzioni in Personalizzazione delle
serie del grafico decisionale a pagina 20-18.
Per una descrizione dei separatori della pagina Series, cercare largomento Series
page (Chart Editing dialog box) nella Guida in linea.
Impostazioni predefinite dei modelli di grafico decisionale
I grafici decisionali visualizzano i valori provenienti da due dimensioni del cubo
decisionale: una dimensione visualizzata come un asse del grafico, laltra usata
per creare un insieme di serie. Il modello di quella dimensione fornisce le propriet
predefinite per quelle serie (per esempio, se le serie sono barre, linee, aree e cos via).
Via via che gli utenti passano da uno stato allaltro, tutte le serie richieste per la
dimensione vengono create utilizzando il tipo di serie e le altre impostazioni
predefinite specificate nel modello.
Per i casi in cui gli utenti passano ad uno stato con una sola dimensione attiva, viene
fornito un modello separato. Un stato monodimensionale viene spesso rappresentato
con un grafico a torta, e quindi, per questo caso, viene fornito un modello a parte.
possibile
Modificare il tipo di grafico predefinito.
Modificare altre propriet del modello grafico.
Visualizzare e impostare le propriet complessive del grafico.
Modifica del tipo di grafico decisionale predefinito
Per modificare il tipo di grafico predefinito:
1 Selezionare un modello nellelenco Series della pagina Chart della finestra di
dialogo Chart Editing.
2 Fare clic sul pulsante Change.
3 Selezionare un nuovo tipo e chiudere la finestra di dialogo Gallery.
Modifica di altre propriet del modello di grafico decisionale
Per modificare il colore o le altre propriet di un modello:
1 Selezionare la pagina Series nella parte superiore della finestra di dialogo Chart
Editing.
2 Scegliere un modello nellelenco a discesa nella parte superiore della pagina.
3 Scegliere lopportuno separatore propriet e selezionare le impostazioni.
Visualizzazione delle propriet complessive del grafico decisionale
Per vedere e impostare propriet del grafico decisionale diverse dal tipo e dalle serie:
1 Selezionare la pagina Chart nella parte superiore della finestra di dialogo Chart
Editing.
2 Scegliere lopportuno separatore propriet e selezionare le impostazioni.
20-18 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e u s o d e i g r a f i c i d e c i s i o n a l i
Personalizzazione delle serie del grafico decisionale
I modelli forniscono molte impostazioni predefinite per ciascuna dimensione del
cubo decisionale, quali, ad esempio, i tipi di grafico e il modo in cui le serie vengono
visualizzate. Le altre impostazioni predefinite, quale, ad esempio, il colore della serie,
sono definite da TDecisionGraph. Volendo, possibile sostituire le impostazioni
predefinite di ciascuna serie.
I modelli sono stati ideati per i casi in cui il programma debba creare serie per le
categorie, man mano che queste si rendono necessarie, ed eliminarle quando non lo
sono pi. Volendo, possibile impostare serie personalizzate per determinati valori
della categoria. Per fare ci occorre agire sul grafico in modo che la vista attuale
presenti una serie per la categoria che si vuole personalizzare. Quando la serie
visualizzata sul grafico, si pu usare il Chart editor per:
Modificare il tipo di grafico.
Modificare le altre propriet della serie.
Salvare le serie del grafico che sono state personalizzate.
Per definire i modelli della serie e impostare le impostazioni predefinite complessive
del grafico, consultare la sezione Impostazioni predefinite dei modelli di grafico
decisionale a pagina 20-17.
Modifica del tipo di grafico delle serie
Per impostazione predefinita, ciascuna serie ha lo stesso tipo di grafico, definito dal
modello per la sua dimensione. Per modificare tutte le serie e fare in modo che
abbiano tutte lo stesso tipo di grafico, possibile modificare il tipo di modello. Per
istruzioni consultare il paragrafo Modifica del tipo di grafico decisionale
predefinito a pagina 20-17.
Per modificare il tipo di grafico per una singola serie:
1 Selezionare una serie nellelenco Series della pagina Chart di Chart editor.
2 Fare clic sul pulsante Change.
3 Selezionare un nuovo tipo e chiudere la finestra di dialogo Gallery.
4 Spuntare la casella di controllo Save Series.
Modifica di altre propriet delle serie del grafico decisionale
Per modificare il colore o le altre propriet di una serie di un grafico decisionale:
1 Selezionare la pagina Series nella parte superiore della finestra di dialogo Chart
Editing.
2 Scegliere una serie nellelenco a discesa nella parte superiore della pagina.
3 Scegliere lopportuno separatore propriet e selezionare le impostazioni.
4 Spuntare la casella di controllo Save Series.
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-19
C o m p o n e n t i d i s u p p o r t o d e c i s i o n a l e i n e s e c u z i o n e
Salvataggio delle impostazioni delle serie del grafico decisionale
Per impostazione predefinita, solamente le impostazioni dei modelli vengono salvate
in fase di progetto. Le modifiche apportate a una determinata serie vengono salvate
solo se la casella Save attiva per quella serie nella finestra di dialogo Chart Editing.
Il salvataggio delle serie pu essere dispendioso in termini di memoria, quindi, se
non occorre salvarle si pu disattivare la casella Save.
Componenti di supporto decisionale in esecuzione
Durante lesecuzione, gli utenti possono compiere molte operazioni facendo clic col
tasto sinistro, destro e trascinando i componenti di supporto decisionale visibili.
Queste operazioni, descritte nelle sezioni precedenti di questo capitolo, sono
riassunte di seguito.
Pivot decisionali in esecuzione
Gli utenti possono:
Fare clic con il tasto sinistro sul pulsante di riepilogo allestremit sinistra del pivot
decisionale per visualizzare lelenco di riepiloghi disponibili. Possono usare
questo elenco per modificare i dati di riepilogo visualizzati in griglie e grafici
decisionali.
Fare clic col tasto destro su un pulsante di dimensione e scegliere di:
Spostarlo dallarea della riga allarea della colonna o viceversa.
Selezionare Drill In per visualizzare i dati nel dettaglio.
Fare clic con il tasto sinistro su uno dei pulsanti di dimensione dopo il comando
Drill In e scegliere:
Open Dimension per ritornare al livello superiore di quella dimensione.
All Values per passare dalla visualizzazione dei soli riepiloghi alla
visualizzazione dei riepiloghi e di tutti gli altri valori nelle griglie decisionali.
Da un elenco di categorie disponibili per quella dimensione, selezionare una
categoria da sondare per avere i valori nel dettaglio.
Fare clic con il tasto sinistro su un pulsante di dimensione per aprire o chiudere
quella dimensione.
Trascinare e rilasciare i pulsanti di dimensione dallarea della riga allarea della
colonna e viceversa; possono essere rilasciati accanto ai pulsanti esistenti in
quellarea o sullicona della riga o della colonna.
Griglie decisionali in esecuzione
Gli utenti possono:
20-20 G u i d a a l l a p r o g r a mma z i o n e
C o m p o n e n t i d i s u p p o r t o d e c i s i o n a l e e c o n t r o l l o d e l l a m e m o r i a
Fare clic col tasto destro allinterno della griglia decisionale e scegliere di:
Attivare o disattivare i totali parziali per singoli gruppi di dati, per tutti i valori
di una dimensione o per la griglia intera.
Visualizzare il Decision Cube editor, descritto a pagina 20-7.
Aprire e chiudere le dimensioni e i riepiloghi.
Fare click su + e su - allinterno delle intestazioni di riga e di colonna per aprire e
chiudere le dimensioni.
Trascinare e rilasciare le dimensioni dalle righe alle colonne e viceversa.
Grafici decisionali in esecuzione
Gli utenti possono trascinare le dimensioni da lato allaltro o in su e in gi nellarea
della griglia del grafico per fare scorrere sullo schermo categorie e valori.
Componenti di supporto decisionale e controllo della memoria
Il caricamento di una dimensione o di un riepilogo nel cubo decisionale richiede
parecchia memoria. Laggiunta di un nuovo riepilogo incrementa il consumo di
memoria in modo lineare: ovvero, un cubo decisionale che dispone di due riepiloghi
utilizza il doppio della memoria che lo stesso userebbe con un riepilogo solo; un cubo
decisionale con tre riepiloghi usa il triplo della memoria che lo stesso userebbe con
un solo riepilogo e cos via. Laumento del consumo della memoria per le dimensioni
ancora pi rapido. Laggiunta di una dimensione con 10 valori aumenta il consumo
di memoria di dieci volte. Laggiunta di una dimensione con 100 valori aumenta il
consumo di memoria di 100 volte. Quindi, laggiunta di dimensioni a un cubo
decisionale pu avere un effetto drammatico sulluso della memoria, e pu causare
rapidamente problemi di prestazioni. Questo effetto particolarmente evidente
quando si aggiungono dimensioni che hanno molti valori.
I componenti di supporto decisionale dispongono di un certo numero di
impostazioni che aiutano lutente a controllare come e quando la memoria viene
usata. Per maggiori informazioni sulle propriet e sulle tecniche descritte in questa
sezione, consultare TDecisionCube nella Guida in linea.
Impostazione dei valori massimi per dimensioni, riepiloghi e celle
Le propriet MaxDimensions e MaxSummaries del cubo decisionale possono essere
usate con la propriet CubeDim->ActiveFlag per controllare il numero di dimensioni e
di riepiloghi che possibile caricare in una sola volta. possibile impostare i valori
massimi sulla pagina Cube Capacity del Decision Cube editor per introdurre un
controllo complessivo sul numero di dimensioni o di riepiloghi da portare
contemporaneamente in memoria.
Limitando il numero delle dimensioni o dei riepiloghi, si ottiene un calcolo
approssimativo della quantit di memoria usata dal cubo decisionale. Comunque,
U s o d e i c o mp o n e n t i d i s u p p o r t o d e c i s i o n a l e 20-21
C o m p o n e n t i d i s u p p o r t o d e c i s i o n a l e e c o n t r o l l o d e l l a m e m o r i a
non possibile distinguere tra dimensioni con molti valori e dimensioni con pochi
valori. Per avere un controllo pi preciso dello spazio assoluto di memoria richiesto
dal cubo decisionale, possibile limitare anche il numero delle celle nel cubo.
Impostare il numero massimo di celle sulla pagina Cube Capacity del Decision Cube
editor.
Impostazione dello stato della dimensione
La propriet ActiveFlag controlla quali dimensioni vengono caricate. possibile
impostare questa propriet sul separatore Dimension Settings del DecisionCube
editor utilizzando il controllo Activity Type. Quando questo controllo impostato ad
Active, non ci sono limiti nel caricamento della dimensione che quindi occuper
sempre pi spazio. Si noti che il numero di dimensioni in questa condizione deve
sempre essere inferiore a quello di MaxDimensions, e il numero dei riepiloghi
impostati ad Active deve essere inferiore a quello di MaxSummaries. Si dovrebbe
impostare una dimensione o un riepilogo ad Active solo se indispensabile che siano
sempre disponibili. Unimpostazione Active diminuisce la capacit del cubo di gestire
la memoria disponibile.
Quando ActiveFlag impostato a AsNeeded, una dimensione o un riepilogo vengono
caricati solamente se possibile farlo senza superare i limiti di MaxDimensions,
MaxSummaries o di MaxCells. Il cubo decisionale gestir le dimensioni e i riepiloghi
contrassegnati da AsNeeded eseguendo swap di memoria per caricarli e scaricarli, in
modo da rimanere nei limiti imposti da MaxCells, MaxDimensions e MaxSummaries. In
questo modo, una dimensione o un riepilogo non possono essere caricati in memoria
se in quel momento non sono utilizzati. Limpostazione delle dimensioni che non
vengono usate di frequente, come AsNeeded, comporta un miglioramento delle
prestazioni in fase di caricamento e di gestione, anche se laccesso alle dimensioni
non caricate risulter leggermente pi lento.
Utilizzo delle dimensioni paginate
Quando Binning impostato a Set nella pagina Dimension Settings del Decision
Cube editor e Start Value non NULL, la dimensione si dice essere paginata o
permanentemente espansa. possibile accedere ai dati solo per un singolo valore
alla volta di quella dimensione, sebbene da programma sia possibile accedere a una
serie di valori in modo sequenziale. Tale dimensione non pu essere usata come
pivot o aperta.
estremamente dispendioso, dal punto di vista della memoria, includere dati
dimensionali per le dimensioni che hanno un numero elevato di valori. Paginando
tali dimensioni, possibile visualizzare informazioni di riepilogo per un valore alla
volta. Solitamente, quando vengono visualizzate in questo modo, le informazioni
sono pi facili da leggere e il consumo di memoria molto pi semplice da gestire.
20-22 G u i d a a l l a p r o g r a mma z i o n e
C o m p o n e n t i d i s u p p o r t o d e c i s i o n a l e e c o n t r o l l o d e l l a m e m o r i a
C o n n e s s i o n e a i d a t a b a s e 21-1
C a p i t o l o
21
Capitolo21Connessione ai database
La maggior parte dei componenti dataset pu collegarsi direttamente a un server di
database. Appena connesso, il dataset comunica con il server automaticamente.
Quando si apre il dataset, esso si popola con i dati dal server e quando si registrano i
record, essi vengono restituiti al server e applicati. Un singolo componente
connection SQL pu essere condiviso da pi dataset oppure ciascun dataset pu
utilizzare la propria connessione.
Ogni tipo del dataset si collega al server di database utilizzando il proprio tipo di
componente connection, progettato per funzionare con un singolo meccanismo di
accesso ai dati. La seguente tabella elenca questi meccanismi di accesso ai dati e i
componenti connection associati:
_
Per una trattazione dei pro e contro di ciascuno di questi meccanismi consultare Uso
dei databases a pagina 18-1.
Il componente connection fornisce tutte le informazioni necessarie per stabilire una
connessione al database. Queste informazioni sono diverse per ogni tipo di
componente connection:
Per informazioni sulla descrizione di una connessione basata su BDE, vedere
Identificazione del database a pagina 24-14.
Per informazioni sulla descrizione di una connessione basata su ADO, vedere
Connessione a un datastore mediante TADOConnection a pagina 25-3.
Tabella 21.1 Componenti di connessione del database
Meccanismo di accesso ai dati Componente connection
Borland Database Engine (BDE) TDatabase
ActiveX Data Objects (ADO) TADOConnection
dbExpress TSQLConnection
InterBase Express TIBDatabase
21-2 G u i d a a l l a p r o g r a mma z i o n e
U s o d i c o n n e s s i o n i i m p l i c i t e
Per informazioni sulla descrizione di una connessione dbExpress, vedere
Impostazione di TSQLConnection a pagina 26-3.
Per informazioni sulla descrizione di una connessione InterBase Express, vedere la
Guida in linea per TIBDatabase.
Bench ogni tipo di dataset utilizzi un componente connection diverso, tali
componenti discendono tutti da TCustomConnection. Tutti quanti assolvono
moltissimi compiti identici e rendono disponibili molte propriet, metodi ed eventi
identici. Il presente capitolo tratta la maggior parte di queste attivit comuni.
Uso di connessioni implicite
Indipendentemente dal meccanismo di accesso ai dati utilizzato, sempre possibile
creare il componente connection in modo esplicito e utilizzarlo per gestire la
connessione a un server di database e la comunicazione con esso. Per dataset BDE e
basati su ADO, c la possibilit di descrivere la connessione al database tramite
propriet del dataset e di permettere al dataset di generare una connessione
implicita. Per i dataset BDE, si specifica una connessione implicita utilizzando la
propriet DatabaseName. Per i dataset basati su ADO, si utilizza la propriet
ConnectionString.
Quando si utilizza una connessione implicita, non necessario creare esplicitamente
un componente connection. Ci pu semplificare lo sviluppo dellapplicazione e la
connessione predefinita che si specifica pu coprire unampia gamma di situazioni.
Per applicazioni client/server complesse e cruciali, con molti utenti e diversi requisiti
per connessioni al database, comunque, si consiglia di creare i propri componenti
connection in modo da adattare ciascuna connessione di database alle necessit
dellapplicazione. I componenti connection espliciti offrono un maggiore controllo.
Ad esempio, necessario accedere al componente connection per eseguire le seguenti
operazioni:
Personalizzare il supporto per il login al server di database. (le connessioni
implicite visualizzano una finestra di dialogo di login predefinita per richiedere
allutente un nome utente e una password.)
Controllare le transazioni e specificarne i livelli di isolamento delle transazioni.
Eseguire comandi SQL sul server senza utilizzare un dataset.
Compiere operazioni su tutti i dataset aperti che sono connessi allo stesso
database.
Inoltre, se si hanno pi dataset che utilizzano tutti lo stesso server, potrebbe essere
pi semplice utilizzare un componente connection, in modo che si debba specificare
una sola volta il server da utilizzare. In questo modo, se in un secondo momento si
modificher il server, non sar necessario aggiornare tutti i componenti dataset ma
solo il componente connection.
C o n n e s s i o n e a i d a t a b a s e 21-3
C o n t r o l l o d e l l e c o n n e s s i o n i
Controllo delle connessioni
Prima di potere stabilire una connessione a un server di database, lapplicazione deve
fornire determinate informazioni chiave che descrivono il server desiderato. Ogni
tipo di componente connection rende disponibile un diverso set di propriet per
permettere lidentificazione del server. Di solito, comunque, offrono tutti un modo
per assegnare il nome del server desiderato e per fornire un set di parametri di
connessione che controllano il modo in cui viene stabilita la connessione. I parametri
di connessione variano da server a server. Possono includere informazioni come
nome utente e password, dimensione massima dei campi BLOB, ruoli SQL, e cos via.
Una volta identificati il server richiesto e tutti i parametri di connessione, possibile
utilizzare il componente connection per aprire o chiudere esplicitamente una
connessione. Allapertura e alla chiusura di una connessione, il componente
connection genera eventi che possibile utilizzare per personalizzare la risposta
dellapplicazione alle modifiche nella connessione al database.
Connessione a un server di database
Esistono due modi per connettersi a un server database usando un componente
connection:
Chiamando il metodo Open.
Impostando la propriet Connected a true.
La chiamata del metodo Open imposta Connected a true.
_
Quando un componente connection non connesso a un server e unapplicazione
tenta di aprire i dataset a lui associati, il dataset chiama automaticamente il metodo
Open del componente connection.
Quando si imposta Connected a true, il componente connection genera per prima cosa
un evento BeforeConnect, in cui possibile eseguire qualsiasi inizializzazione. Ad
esempio, possibile utilizzare questo evento per modificare i prametri di
connessione.
Dopo levento BeforeConnect, il componente connection pu visualizzare una finestra
di dialogo predefinita per il login, a seconda di come si sceglie di controllare il login
al server. Quindi passa al driver il nome utente e la password, aprendo una
connessione.
Una volta aperta la connessione, il componente connection genera un evento
AfterConnect in cui possibile eseguire qualsiasi operazione che richieda una
connessione aperta.
_
Alcuni componenti connection generano anche altri eventi nel momento in cui
stabiliscono una connessione.
Una volta che la connessione stata stabilita, tale connessione viene mantenuta attiva
finch c almeno un dataset attivo che la utilizza. Quando non ci sono pi dataset
attivi, il componente connection rilascia la connessione. Alcuni componenti
connection rendono disponibile una propriet KeepConnection che permette alla
21-4 G u i d a a l l a p r o g r a mma z i o n e
C o n t r o l l o d e l l o g i n a l s e r v e r
connessione di rimanere aperta anche se tutti i dataset che la utilizzano sono chiusi.
Se KeepConnection impostato a true, la connessione viene mantenuta aperta. Per
connessioni a server di database remoti o per applicazioni che aprono e chiudono
dataset con una certa frequenza, limpostazione di KeepConnection a true riduce il
traffico di rete e velocizza lapplicazione. Se KeepConnection impostato a false, la
connessione viene interrotta appena non vi sono pi dataset attivi che utilizzano il
database. Se un dataset che utilizza il database viene aperto in un secondo momento,
la connessione deve essere ristabilita e inizializzata.
Disconnessione da un server di database
Esistono due modi per sconnettersi da un server usando un componente connection:
Impostando la propriet Connected a false.
Chiamata al metodo Close.
La chiamata a Close imposta Connected a false.
Quando la propriet Connected impostata a false, il componente connection genera
un evento BeforeDisconnect in cui possibile eseguire qualsiasi operazione di pulizia
prima che la connessione venga chiusa. Ad esempio, possibile utilizzare questo
evento per memorizzare nella cache le informazioni su tutti i dataset aperti prima che
essi vengano chiusi.
Dopo levento BeforeConnect, il componente connection chiude tutti i dataset aperti e
si scollega dal server.
Infine, il componente connection genera un evento AfterDisconnect in cui possibile
rispondere alla modifica nello stato della connessione, come ad esempio lattivazione
di un pulsante Connect dellinterfaccia utente.
_
La chiamata al metodo Close o limpostazione della propriet Connected a false causa
lo scollegamento da un server di database anche se la propriet KeepConnection del
componente connection impostata a true.
Controllo del login al server
La maggior parte dei server database remoti includono funzioni di sicurezza per
proibire laccesso non autorizzato. Generalmente, il server richiede un nome utente e
una password di login prima di consentire laccesso al database.
In fase di progettazione, se un server richiede un login, C++Builder visualizza una
finestra di dialogo Login standard che, quando si tenta di connettersi al database per
la prima volta, richiede il nome dellutente e la password.
In fase di esecuzione, ci sono tre modi con cui gestire la richiesta di login del server:
Consentire la gestione del login alla finestra di dialogo di login e di elaborazione.
Questo il metodo predefinito. Impostare la propriet LoginPrompt del
componente connection a true (impostazione predefinita) e aggiungere
DBLogDlg.hpp alla clausola che dichiara il componente connection.
C o n n e s s i o n e a i d a t a b a s e 21-5
C o n t r o l l o d e l l o g i n a l s e r v e r
Lapplicazione visualizzer la finestra di dialogo di login standard appena il
server richiede un nome utente e una password.
Fornire le informazioni di login prima del tentativo di login. Ogni tipo di
componente connection utilizza un meccanismo diverso per la specifica del nome
utente e della password:
Per i dataset BDE, dbExpress e InterBaseExpress, si pu accedere ai parametri di
connessione nome utente e password tramite la propriet Params. (Per i dataset
BDE, i valori dei parametri possono essere associati anche a un alias BDE,
mentre per i dataset dbExpress possono essere associati anche a un nome di
connessione).
Per i dataset ADO, il nome utente e la password possono essere inclusi nella
propriet ConnectionString (o forniti come parametri al metodo Open).
Se si specificano nome utente e password prima che il server li richieda, accertarsi
di impostare il LoginPrompt a false, in modo che non venga visualizzata la finestra
di dialogo login predefinita. Ad esempio, il codice seguente imposta il nome e la
password dellutente per un componente SQl connection nel gestore di evento
BeforeConnect, decifrando una password crittografata memorizzata associata al
nome di connessione corrente:
veIi __?aatcaII .._ccc.cccccc .c.c
I? ._cc>.., .isc
._cc>.ii.s>ics,'sc_.i.c' '..~',
._cc>.ii.s>ics,'.iss..'
cc,._cc>.ii.s>ics,'.iss..',
Come gi visto con gli altri metodi utilizzati per fornire i parametri di login,
quando si scrive un gestore di evento OnLogin o OnWillConnect bene evitare di
scrivere esplicitamente la password nel codice dellapplicazione. La password
dovrebbe apparire solo come valore crittografato, come un elemento in un
database sicuro utilizzato dallapplicazione per cercare il valore, oppure dovrebbe
essere ottenuta dinamicamente dallutente.
Gestione delle transazioni
Una transazione un gruppo di azioni che devono essere tutte portate a termine con
successo su una o pi tabelle di un database prima che siano compiute (rese
permanenti). Se una delle azioni nel gruppo non riesce, allora tutte le azioni vengono
fatte scorrere a ritroso (annullate). Utilizzando le transazioni, nel caso si verifichi un
problema durante il compimento di una delle azione che compongono la
transazione, ci si assicura che il database non venga lasciato in uno stato
incongruente.
Ad esempio, in unapplicazione bancaria, il trasferimento di fondi da un conto
allaltro unoperazione che sarebbe bene proteggere con una transazione. Se, dopo
aver decrementato il saldo di un conto, si verifica un errore incrementando il saldo
dellaltro, sar possibile annullare la transazione in modo che il database rifletta
ancora il saldo totale corretto.
sempre possibile gestire le transazioni inviando comandi SQL direttamente al
database. Quasi tutti i database sono dotati di un proprio modello per la gestione
delle transazioni, bench alcuni non forniscano alcun supporto per le transazione.
Per i server che le supportano, potrebbe essere necessario scrivere in prima persona il
codice per la gestione delle transazioni, sfruttando le capacit di gestione di
transazioni avanzate esistenti su un particolare server di database, come la cache di
schema.
Se non necessario utilizzare queste capacit evolute di gestione delle transazioni, i
componenti connection mettono a disposizione un insieme di metodi e propriet che
possibile utilizzare per gestire le transazioni senza inviare esplicitamente alcun
comando SQL. Lutilizzo di queste propriet e di questi metodi offre il vantaggio che
non necessario personalizzare lapplicazione per ogni tipo di server di database
C o n n e s s i o n e a i d a t a b a s e 21-7
G e s t i o n e d e l l e t r a n s a z i o n i
utilizzato, sempre che il server supporti le transazioni. (Anche BDE fornisce un
supporto limitato per le transazione con tabelle locali che non dispongono di
supporto per transazioni del server). (Se non si utilizza BDE il tentativo di avviare le
transazioni su un database che non le supporta provoca il sollevamento di
uneccezione da parte dei componenti connection.)
j
Quando un componente dataset provider applica gli aggiornamenti, genera
implicitamente transazioni per qualsiasi aggiornamento. bene prestare attenzione
al fatto che qualsiasi transazione iniziata esplicitamente non vada in conflitto con
quelle generati dal provider.
Avvio di una transazione
Quando si avvia una transazione, tutte le successive istruzioni di lettura o di scrittura
nel database si verificano nel contesto di quella transazione, finch la transazione non
viene terminata esplicitamente o, nel caso di transazioni sovrapposte, finch non
viene avviata unaltra transazione. Ogni istruzione considerata parte di un gruppo.
Tutte le modifiche dovranno essere registrate con successo nel database, altrimenti
sar necessario annullare ogni modifica fatta nel gruppo.
Mentre la transazione in corso, la vista dei dati nelle tabelle di database
determinata dal livello di isolamento della transazione. Per ulteriori informazioni sui
livelli di isolamento delle transazioni, consultare Specifica del livello di isolamento
delle transazioni a pagina 21-10.
Per TADOConnection avviare una transazione chiamando il metodo BeginTrans:
cc ~cc>cis,
BeginTrans restituisce il livello di annidamento della transazione appena iniziata.
Una transazione annidata una transazione inclusa allinterno di unaltra
transazione genitore. Dopo che il server ha avviato la transazione, la connessione
ADO riceve un evento OnBeginTransComplete.
Per TDatabase, utilizzare il metodo StartTransactionmethod invece.TDataBase non
supporta transazioni annidate o sovrapposte: Se si chiama il metodo StartTransaction
di un componente TDatabase mentre in corso unaltra transazione, il componente
solleva uneccezione. Per evitare di chiamare StartTransaction, possibile controllare
la propriet InTransaction property:
I? iicisc>Lisic
iicisc>.iisic,
Anche TSQLConnection utilizza il metodo StartTransaction ma la versione utilizza
offre un controllo maggiore. Nello specifico, StartTransaction accetta un descrittore di
transazione che permette di gestire pi transazioni simultanee e di specificare il
livello di isolamento delle transazioni, transazione per transazione. (Per ulteriori
informazioni sui livelli delle transazioni, vedere Specifica del livello di isolamento
delle transazioni a pagina 21-10.) Per gestire pi transazioni simultanee, impostare
il campo TransactionID del descrittore di transazione a un valore univoco.
TransactionID pu essere un qualsiasi valore scelto dallutente, a patto che sia
univoco (non sia cio in conflitto con una qualsiasi altra transazione attualmente in
21-8 G u i d a a l l a p r o g r a mma z i o n e
G e s t i o n e d e l l e t r a n s a z i o n i
esecuzione). A seconda del server, le transazioni avviate da TSQLConnection possono
essere annidate (come quando si utilizza ADO) o sovrapposte.
isiccsc ,
isicL ,
Lsicc x~..L,
._cc>.iisic,
Per impostazione predefinita, nel caso di transazioni sovrapposte, la prima
transazione diventa inattiva non appena parte la seconda transazione, bench sia
possibile rimandare la conferma o lannullamento della prima transazione ad una
fase successiva. Se si utilizza TSQLConnection con un database InterBase, possibile
identificare ogni dataset nellapplicazione con una particolare transazione attiva,
impostandone la propriet TransactionLevel. Ci significa che, dopo avere avviato una
seconda transazione, possibile continuare a gestire contemporaneamente entrambe
le transazioni, semplicemente associando un dataset alla transazione che si desidera.
_
A differenza di TADOConnection, TSQLConnection e TDatabase non ricevono alcun
evento quando parte la transazione.
InterBase Express offre un controllo ancora maggiore rispetto a quello di
TSQLConnection perch utilizza un componente di transazione separato invece di un
singolo componente connection che avvia anche le transazioni. possibile utilizzare,
tuttavia, TIBDatabase per avviare una transazione predefinita:
I? Liicisc>c.iisic>Lisic
Liicisc>c.iisic>.iisic,
possibile ottenere transazioni sovrapposte utilizzando due componenti di
transazione separati. Ogni componente di transazione ha un set di parametri che
permettono di configurare la transazione. Questi parametri permettono di specificare
il livello di isolamento della transazione, oltre ad altre propriet.
Chiusura di una transazione
Idealmente, una transazione dovrebbe durare solo il tempo necessario. Pi a lungo
una transazione attiva, maggiore il numero di utenti che accedono
simultaneamente al database, e pi grande il numero di transazioni simultanee che
vengono avviate e terminano durante lesistenza della transazione, maggiore la
probabilit che la transazione sia in conflitto con unaltra quando si tenter di
confermare una qualsiasi modifica.
Chiusura di una transazione andata a buon fine
Non appena tutte le azioni che compongono la transazione sono andate a buon fine,
possibile rendere permanenti le modifiche al database confermando la transazione.
Per TDatabase, si convalida una transazione utilizzando il metodo Commit:
.icccc>..,
Anche per TSQLConnection si utilizza il metodo Commit ma necessario specificare
quale transazione si sta convalidando fornendo lo stesso descrittore della transazione
passato al metodo StartTransaction:
C o n n e s s i o n e a i d a t a b a s e 21-9
G e s t i o n e d e l l e t r a n s a z i o n i
.icccc>..,
Per TIBDatabase, si convalida un oggetto transazione utilizzando il metodo Commit:
Liicisc>c.iisic>..,
Per TADOConnection, si convalida una transazione utilizzando il metodo
CommitTrans:
~cc>..is,
_
possibile convalidare una transazione annidata, solo affinch sia possibile
annullare le le modifiche in un secono momento nel caso venga annullata la
transazione genitore.
Dopo che la transazione stata convalidata con successo, un componente connection
ADO riceve un evento OnCommitTransComplete. Altri componenti connection non
ricevono un tale evento.
Una chiamata per convalidare la transazione corrente di solito viene tentata in un
blocco di istruzioni try...catch. In questo modo, se la transazione non viene inoltrata
con esito positivo, possibile utilizzare il blocco catch per gestire lerrore e ritentare
loperazione oppure per eseguire il roll-back della transazione.
Chiusura di una transazione non andata a buon fine
Nel caso si verifichi un errore durante lesecuzione delle modifiche che fanno parte
della transazione o durante la conferma della transazione, si render necessario
eliminare tutte le modifiche apportate dalla transazione. Labbandono delle
modifiche detto annullamento, o roll-back, della transazione.
Per TDatabase, si annulla una transazione chiamando il metodo Rollback:
.icccc>cic.,
Per TSQLConnection, possibile usaare anche il metodo Rollback, ma necessario
specificare quale transazione si sta annullando fornendo il descrittore della transazione
passato al metodo StartTransaction:
.icccc>cic.,
Per TIBDatabase, possibile annullare un oggetto transaction chiamandone il metodo
Rollback:
Liicisc>c.iisic>cic.,
Per TADOConnection, si annulla una transazione chiamando il metodo RollbackTrans:
~cc>cic.is,
Dopo che la transazione stata annullata con successo, un componente ADO
connection riceve un evento OnRollbackTransComplete. Altri componenti connection
non ricevono un tale evento.
Una chiamata per annullare la transazione corrente di solito si verifica
Nella porzione di codice che gestisce leccezione, nel caso sia impossibile
ripristinare un errore di database.
21-10 G u i d a a l l a p r o g r a mma z i o n e
G e s t i o n e d e l l e t r a n s a z i o n i
Nel codice dellevento di un pulsante o di un menu, ad esempio quando lutente fa
clic su un pulsante Cancel.
Specifica del livello di isolamento delle transazioni
Il livello di isolamento della transazione determina come una transazione interagisce
con altre transazioni simultanee quando operano con le stesse tabelle. In particolare,
influenza quanto una transazione vede delle altre modifiche apportate dalle
transazioni a una tabella.
Ogni tipo di server supporta un diverso set di possibili livelli di isolamento della
transazione. Esistono tre possibili livelli di isolamento di una transazione:
DirtyRead: Quando il livello di isolamento DirtyRead, la transazione vede tutte le
modifiche fatte da altre transazioni, anche se tali modifiche non sono stati
confermate. Le modifiche non confermate non sono permanenti e potrebbero
essere annullate in qualsiasi momento. Questo valore fornisce il livello di
isolamento minimo e non disponibile per molti server di database (come Oracle,
Sybase, MS-SQL e InterBase).
ReadCommitted: Quando il livello di isolamento ReadCommitted, risultano visibili
solo le modifiche confermate fatte da altre transazioni. Bench questa
impostazione impedisca alla transazione di vedere le modifiche non confermate e
che potrebbero essere annullate, nel caso unaltra transazione venga confermata
durante la fase di lettura della transazione in corso, tuttavia possibile che si abbia
una vista incongruente dello stato del database. Questo livello disponibile per
tutte le transazioni tranne che per le transazioni locali gestite da BDE.
RepeatableRead: Quando il livello di isolamento RepeatableRead, alla transazione
viene garantita la visione di uno stato congruente dei dati del database. La
transazione vede una singola istantanea dei dati. Non in grado di vedere
nessuna successiva modifica ai dati da parte di altre transazioni simultanee, anche
nel caso in cui le mdifiche vengano confermate. Questo livello di isolamento
garantisce che una volta che la transazione ha letto un record, la vista di quel
record non cambier. A questo livello la transazione risulta veramente isolata dalle
modifiche fatte da altre transazioni. Questo livello non disponibile su alcuni
server, come Sybase e MS-SQL e non disponibile per transazioni locali gestite da
BDE.
Inoltre, TSQLConnection permette di specificare livelli di isolamento custom, specifici
per un certo database. I livelli di isolamento custom sono definiti dal driver
dbExpress. Consultare la documentazione del driver per i dettagli.
_
Per una descrizione dettagliata dellimplementazione di ogni livello di isolamento,
consultare la documentazione del server.
TDatabase e TADOConnection permettono di specificare il livello di isolamento della
transazione impostando la propriet TransIsolation. Quando si imposta TransIsolation
a un valore che non supportato dal server di database, si ottiene il successivo livello
di isolamento pi elevato (se disponibile). Se non c alcun livello pi elevato
disponibile, appena si prova ad avviare una transazione il componente connection
solleva uneccezione.
C o n n e s s i o n e a i d a t a b a s e 21-11
I n v i o d i c o m a n d i a l s e r v e r
Utilizzando TSQLConnection, il livello di isolamento della transazione controllato
dal campo IsolationLevel del descrittore della transazione.
Utilizzando InterBase Express, il livello di isolamento della ttransazione controllato
da un parametro della transazione.
Invio di comandi al server
Tutti i componenti database connection, tranne TIBDatabase,permettono di eseguire
istruzioni SQL sul server associato chiamando il metodo Execute. Bench Execute
possa restituire un cursor nel caso listruzione sia unistruzione SELECT, questo
utilizzo non consigliato. Il metodo preferenziale per lesecuzione di istruzioni che
restituiscono dati quello di utilizzare un dataset.
Il metodo Execute molto comodo per lesecuzione di semplici istruzioni SQL che
non restituiscono record. Tali istruzioni includono istruzioni Data Definition
Language (DDL), che operano sui metadati di un database o li creano, come CREATE
INDEX, ALTER TABLE e DROP DOMAIN. Anche alcune istruzioni DML (Data
Manipulation Language) di SQL non restituiscono un set risultato. Le istruzioni DML
che compiono unazione sui dati ma non restituiscono un set risultato sono: INSERT,
DELETE e UPDATE.
La sintassi del metodo Execute varia in funzione del tipo di connessione:
Per TDatabase, Execute accetta quattro parametri: una stringa Ansi che specifica la
singola istruzione SQL che si desidera eseguire, un oggetto TParams che fornisce
tutti i valori dei parametri per quellistruzione, un valore boolean che indica se
listruzione deve essere messa in cache o meno perch la si vorr eseguire di
nuovo, e un puntatore a un cursor BDE che pu essere restituito. (Si consiglia di
passare il valore NULL).
Per TADOConnection, esistono due versioni di Execute. La prima versione richiede
una WideString che specifica listruzione SQL e un secondo parametro che
specifica un set di opzioni che controllano se listruzione viene eseguita in modo
asincrono o se restituisce dei record. Questa prima sintassi restituisce
uninterfaccia per i record restituiti. La seconda sintassi richiede una WideString
che specifica listruzione SQL, un secondo parametro che restituisce il numero di
record interessati dallesecuzione dellistruzione, e un terzo parametro che
specifica varie opzioni, come, ad esempio, se listruzione viene eseguita in modo
asincrono. Notare che nessuna delle due sintassi consente il passaggio di
parametri.
Per TSQLConnection, Execute accetta tre parametri, una stringa ANSI che specifica
la singola istruzione SQL che si desidera eseguire, un oggetto TParams che fornisce
tutti i valori dei parametri per quellistruzione e un puntatore che pu ricevere un
oggetto TCustomSQLDataSet creato per restituire ai record il valore NULL.
_
Execute pu solo eseguire unistruzione SQL alla volta. Non possibile per eseguire
pi istruzioni SQL con una singola chiamata a Execute, come di solito si fa con i
programmi di utilit di scrittura di codice SQL. Per eseguire pi di unistruzione,
chiamare Execute pi volte.
21-12 G u i d a a l l a p r o g r a mma z i o n e
I n v i o d i c o m a n d i a l s e r v e r
relativamente facile eseguire unistruzione che non include nessun parametro. Ad
esempio, il seguente codice esegue unistruzione CREATE TABLE (DDL) senza alcun
parametro su un componente TSQLConnection:
veIi __?aatcaII ii.ciciccc.ccc .c.c
._cc>ccc. ttae,
~s. ._s. '~ ~ .c.ss ' -
' ' -
' s. L., ' -
' .,i -~1, ' -
' .ic -~., ' -
' .L.~ s. ' -
'',
._cc>xccc._s., ., .,
Per utilizzare parametri, necessario creare un oggetto TParams. Per ogni valore di
parametro utilizzare il metodo TParams, per aggiungere un oggetto TParam utilizzare
il metodo CreateParam. Quindi utilizzare le propriet di TParam per descrivere il
parametro e impostarne il valore.
Questo procedimento illustrato nellesempio seguente che utilizza TDatabase per
eseguire unistruzione INSERT. Listruzione INSERT ha un singolo parametro con
nome :StateParam. Viene creato un oggetto TParams (di nome stmtParams) per fornire
il valore CA a quel parametro.
veIi __?aatcaII .L.._.ii.sc.ccc .c.c
~s. ._s.,
.ii.s s..ii.s aev .ii.s,
tt,
iicisc>ccc. ttae,
s..ii.s>cic.ii..., '.ic.ii.', ,L,,
s..ii.s>.ii..i.c'.ic.ii.'>~s. '~',
._s. 'L.. L. s..c ',
._s. - 's., .,i, .ic ',
._s. - '~. , c ici. s, .ic.ii.',
iicisc>xccc._s., s..ii.s, ?aIae, .,
__?IaaII,
ieIete s..ii.s,
_
Quando si desidera modificare determinate propriet, ad esempio TableName di un
componente TTable, pu essere necessario chiudere il dataset. Quando si riapre il
dataset, i nuovi valori delle propriet diventano effettivi.
Spostamenti nei dataset
Ogni dataset attivo ha un cursore, o puntatore, che indica la riga corrente del dataset.
La riga corrente di un dataset quella i cui valori di campo appaiono nei controlli
associati ai dati e riferiti a un singolo campo di una scheda, quali TDBEdit, TDBLabel e
TDBMemo. Se il dataset supporta lediting, il record corrente contiene valori che
possono essere trattati dai metodi per lediting, linserimento e la cancellazione.
La riga corrente pu essere cambiata spostando il cursore in modo tale che punti a
unaltra riga. La seguente tabella elenca i metodi utilizzabili nel codice di
unapplicazione per passare ad altri record:
Il componente visuale associato ai dati TDBNavigator incapsula questi metodi come
pulsanti selezionabili dagli utenti per spostarsi tra i record in fase di esecuzione. Per
ulteriori informazioni sul componente Navigator, vedere Spostamento e gestione
dei record a pagina 19-31.
Ogni volta che si modifica il record corrente utilizzando uno di questi metodi (o da
altri metodi di navigazione che agiscono in base a un criterio di ricerca), il dataset
Tabella 22.2 Metodi di navigazione dei dataset
Metodo Sposta il cursore a
First La prima riga in un dataset.
Last Lultima riga in un dataset. (Non disponibile per dataset unidirezionali)
Next La riga successiva in un dataset.
Prior La riga precedente in un dataset. (Non disponibile per dataset unidirezionali)
MoveBy Un numero di righe specificate in avanti o a ritroso in un dataset.
22-6 G u i d a a l l a p r o g r a mma z i o n e
S p o s t a m e n t i n e i d a t a s e t
riceve due eventi: BeforeScroll (prima di lasciare il record corrente) e AfterScroll (dopo
essere arrivato sul nuovo record). possibile utilizzare questi eventi per aggiornare
linterfaccia utente (ad esempio, per aggiornare una barra di stato riporta
informazioni sul record corrente).
TDataSet definisce due propriet booleane che forniscono informazioni utili sulla
posizione del cursore tra i record di un dataset.
Utilizzo dei metodi First e Last
Il metodo First sposta il cursore alla prima riga di un dataset e imposta la propriet
Bof a true. Se il cursore gi alla prima riga del dataset, First non esegue alcuna
operazione.
Ad esempio, il seguente codice determina lo spostamento del cursore al primo record
di CustTable:
sicc>s,
Il metodo Last sposta il cursore allultima riga di un dataset e imposta la propriet Eof
a true. Se il cursore gi allultima riga del dataset, Last non esegue alcuna
operazione.
Il seguente codice determina lo spostamento del cursore allultimo record di
CustTable:
sicc>is,
_
Il metodo Last solleva uneccezione con i dataset unidirezionali.
_
Anche se possono esservi motivi pratici di programmazione per spostare il cursore
alla prima o allultima riga di un dataset senza lintervento dellutente, lo
sviluppatore pu anche permettere agli utenti di spostarsi tra i record, avvalendosi
del componente TDBNavigator. Il componente Navigator contiene una serie di
pulsanti che, quando sono attivi e visibili, consentono allutente di posizionarsi alla
prima o allultima riga di un dataset attivo. Gli eventi OnClick per questi pulsanti
chiamano i metodi First e Last del dataset. Per ulteriori informazioni sullutilizzo
efficace del componente Navigator, vedere Spostamento e gestione dei record a
pagina 19-31.
Tabella 22.3 Propriet di navigazione dei dataset
Propriet Descrizione
Bof (Beginning-of-file) true: il cursore si trova in corrispondenza della prima riga del dataset.
false: il cursore non stato trovato in corrispondenza della prima riga
del dataset
Eof (End-of-file) true: il cursore si trova in corrispondenza dellultima riga del dataset.
false: il cursore non stato trovato in corrispondenza della prima riga
del dataset
I d a t a s e t 22-7
S p o s t a m e n t i n e i d a t a s e t
Utilizzo dei metodi Next e Prior
Il metodo Next sposta il cursore alla riga successiva nel dataset e imposta la propriet
Bof a false se il dataset non vuoto. Se il cursore si trova gi allultima riga del
dataset quando si chiama Next, non accade nulla.
Ad esempio, il seguente codice sposta il cursore al record successivo in CustTable:
sicc>.cx,
Il metodo Prior fa arretrare il cursore alla riga precedente nel dataset e imposta Eof a
false se il dataset non vuoto. Se il cursore si trova gi alla prima riga del dataset
quando si chiama Prior, non accade nulla.
Ad esempio, il seguente codice sposta il cursore al record precedente in CustTable:
sicc>.,
_
Il metodo Prior solleva uneccezione con i dataset unidirezionali.
Utilizzo del metodo MoveBy
MoveBy consente di specificare quante righe avanti o indietro il cursore deve essere
spostato in un dataset. Lo spostamento relativo al record corrente al momento della
chiamata di MoveBy. MoveBy imposta inoltre in modo appropriato le propriet Bof e
Eof per il dataset.
Questa funzione legge un parametro rappresentato da un numero intero che indica il
numero di record dello spostamento. I numeri interi positivi designano uno
spostamento in avanti, mentre i numeri interi negativi designano uno spostamento
allindietro.
_
MoveBy solleva uneccezione con i dataset unidirezionali se si utilizza un argomento
con segno negativo.
MoveBy restituisce il numero di righe dello spostamento. Se si cerca di oltrepassare
linizio o la fine del dataset, il numero di righe restituito da MoveBy differisce dal
numero di righe richieste per lo spostamento. Questo perch MoveBy si ferma
quando raggiunge il primo o lultimo record del dataset.
Il seguente codice determina lo spostamento a ritroso di due righe in CustTable:
sicc>.c.,
_
Se lapplicazione usa MoveBy in un ambiente database multiutente, occorre tenere
presente che i dataset sono dinamici. Se pi utenti possono accedere
simultaneamente al database e modificarne i dati, un record che un attimo prima era
in posizione arretrata di cinque record, nellarco di pochi istanti, potrebbe essere
arretrato di quattro o sei o addirittura di un numero indeterminato di record.
22-8 G u i d a a l l a p r o g r a mma z i o n e
S p o s t a m e n t i n e i d a t a s e t
Utilizzo delle propriet Eof e Bof
Due propriet a sola lettura utilizzabili in fase di esecuzione, Eof (End-of-file) e Bof
(Beginning-of-file), risultano utili quando si desidera elaborare in modo iterativo tutti
i record di un dataset.
Eof
Quando Eof true, indica che il cursore inequivocabilmente posizionato sullultima
riga di un dataset. Eof impostato a true quando unapplicazione
Apre un dataset vuoto.
Chiama il metodo Last di un dataset.
Chiama il metodo Next di un dataset e il metodo non riesce a compiere alcuna
operazione (perch il cursore si trova allultima riga del dataset).
Chiama SetRange su un intervallo o dataset vuoto.
In tutti gli altri casi, Eof false; si deve presupporre che Eof sia false, a meno che si
verifichi una delle suddette condizioni e la propriet stata verificata direttamente.
Eof viene comunemente verificata in una condizione di ciclo, per controllare
lelaborazione in sequenza di tutti i record di un dataset. Se viene aperto un dataset
contenente record (o se viene chiamato First) Eof false. Per elaborare tutti record nel
dataset uno per volta, creare un ciclo che si sposti di record in record chiamando il
metodo Next e che termini quando Eof impostato a true. Eof rimarr false fino al
momento in cui Next verr chiamato quando il cursore gi sullultimo record.
Il seguente codice illustra un modo per impostare un ciclo di elaborazione dei record
per un dataset denominato CustTable:
sicc>siccs,
tt,
__?IaaII,
sicc>iccs,
_
Questo esempio dimostra anche come disabilitare e abilitare i controlli visuali
associati ai dati correlati a un dataset. Disabilitando i controlli visuali durante
literazione, lelaborazione risulta pi rapida, in quanto lapplicazione non ha
bisogno di aggiornare il contenuto dei controlli quando il record corrente cambia. Al
completamento delliterazione, opportuno abilitare nuovamente i controlli per
aggiornarli con i valori della nuova riga corrente. Si tenga presente che lattivazione
dei controlli visuali avviene nella clausola __finally di unistruzione try...__finally.
I d a t a s e t 22-9
S p o s t a m e n t i n e i d a t a s e t
Questo assicura che, anche se uneccezione pone fine prematuramente
allelaborazione del ciclo, i controlli non rimangano disabilitati.
Bof
Quando Bof true, indica che il cursore posizionato inequivocabilmente sulla prima
riga di un dataset. Bof true quando unapplicazione
Apre un dataset.
Chiama il metodo First di un dataset.
Chiama il metodo Prior di un dataset e il metodo non riesce a compiere alcuna
operazione (perch il cursore si trova alla prima riga del dataset).
Chiama SetRange su un intervallo o dataset vuoto.
Bof false in tutti gli altri casi; si deve presupporre che Bof sia false, a meno che si
verifichi una delle suddette condizioni e la propriet stata verificata direttamente.
Come Eof, Bof pu essere inserita in una condizione di ciclo per controllare
lelaborazione in sequenza dei record di un dataset. Il seguente codice illustra un
modo per impostare un ciclo di elaborazione dei record per un dataset denominato
CustTable:
sicc>siccs, .,cc. , ,ccss, ,cc sccc .c.c
tt,
vaIIe sicc>. // cc . s c
sicc>.,
. .isc scccss, . c .c . .is .s cc.
__?IaaII,
sicc>iccs,
,ccss cc
I d a t a s e t 22-11
R i c e r c h e n e i d a t a s e t
__?IaaII,
c>..i...i.,
c>iccs, .s,i . cc.s .ii cs
c>cc..i...i., cicic .c. . c c..i.
.,csscc.c,
I? Ls.
,c.ics>~..,
eIae
,c.ics>~..,
Come Locate, Lookup adotta il metodo pi veloce possibile per trovare i record
corrispondenti. Se le colonne in cui effettuare la ricerca sono indicizzate, Lookup
utilizza lindice.
Visualizzazione e modifica di un sottoinsieme di dati usando i filtri
Spesso unapplicazione interessata solo a un sottoinsieme di record di un dataset.
Per esempio, pu essere necessario reperire o visualizzare solo i record relativi alle
aziende con sede in un determinato Paese nel database dei clienti, oppure pu servire
solo un record contenente un insieme specifico di valori di campi. In ciascun caso,
possibile usare filtri per restringere laccesso di unapplicazione a un sottoinsieme di
tutti i record del dataset.
Con i dataset unidirezionali, possibile ridurre i record nel dataset solo se si specifica
una query che limita il numero di record nel dataset. Con altri discendenti di
TDataSet, tuttavia, possibile definire un sottoinsieme dei dati che sono gi stati
prelevati. Per limitare laccesso di unapplicazione a un sottoinsieme di tutti i record
nel dataset, possibile utilizzare filtri.
Un filtro specifica le condizioni che un record deve soddisfare per essere
visualizzato. Le condizioni del filtro possono essere stipulate nella propriet Filter di
un dataset o possono essere codificate nel suo gestore di evento OnFilterRecord. Le
condizioni del filtro sono basate sui valori di un qualunque numero di campi di un
dataset, siano essi indicizzati o meno. Ad esempio, per visualizzare solamente i
record relativi alle aziende con sede in California, un semplice filtro richiederebbe
che i record contengano il valore CA nel campo State.
_
I filtri valgono per ogni record reperito in un dataset. Quando devono essere filtrati
volumi ingenti di dati, invece di utilizzare i filtri pu essere pi efficace ricorrere a
una query per limitare il reperimento dei record, oppure impostare un intervallo in
una tabella indicizzata.
Attivazione e disattivazione dei filtri
Lattivazione dei filtri su un dataset un processo in tre fasi:
22-14 G u i d a a l l a p r o g r a mma z i o n e
V i s u a l i z z a z i o n e e m o d i f i c a d i u n s o t t o i n s i e m e d i d a t i u s a n d o i f i l t r i
1 Creazione di un filtro.
2 Impostazione, se occorre, delle opzioni per i filtri basati su stringhe.
3 Impostazione della propriet Filtered a true.
Quando il filtro attivo, solamente i record che ne soddisfano i criteri sono
disponibili a unapplicazione. Il filtro sempre una condizione provvisoria. Il filtro
pu essere disattivato impostando la propriet Filtered a false.
Creazione di filtri
Ci sono due modi per creare un filtro per un dataset:
Specificare semplici condizioni di filtro nella propriet Filter. Filter
particolarmente utile per creare e applicare filtri in fase di esecuzione.
Scrivere un gestore di evento OnFilterRecord per condizioni del filtro semplici o
complesse. Con OnFilterRecord, si specificano in fase di progetto le condizioni di
filtro. A differenza della propriet Filter, che limitata a una singola stringa che
contiene la logica del filtro, un evento OnFilterRecord pu sfruttare salti
condizionali e cicli per creare complesse condizioni di filtro multi-livello.
Il vantaggio principale di creare filtri usando la propriet Filter che unapplicazione
pu creare, modificare e applicare dinamicamente filtri, (per esempio, in risposta a
un input dellutente). Lo svantaggio principale consiste nel fatto che le condizioni del
filtro devono essere esprimibili in una singola stringa di testo, non si pu far uso di
costrutti di diramazione condizionale o ciclici, e non possibile verificare o
confrontare valori con valori che non siano gi presenti nel dataset.
I vantaggi dellevento OnFilterRecord sono che un filtro pu essere complesso e
variabile, pu essere basato su molte righe di codice che usano strutture condizionali
e cicliche, e pu confrontare valori del dataset con valori esterni al dataset, come ad
esempio il testo in una casella di testo. Il principale punto debole di OnFilterRecord
che si imposta il filtro in fase di progetto e quindi non pu essere cambiato in risposta
a un input dellutente. ( comunque possibile creare molti gestori di filtro e passare
dalluno allaltro in risposta alle condizioni generali di unapplicazione).
Le sezioni che seguono descrivono come creare filtri usando la propriet Filter e il
gestore di evento OnFilterRecord.
Impostazione della propriet Filter
Per creare un filtro usando la propriet Filter, impostare il valore della propriet a
una stringa che contiene le condizioni del filtro. Listruzione che segue, ad esempio,
crea un filtro che verifica se il campo State di un dataset contiene un valore per lo
stato della California:
iisc>c .ic ~,
anche possibile fornire un valore a Filter in base al testo immesso in un controllo.
Listruzione che segue, ad esempio, assegna a Filter il testo di una casella di testo:
iisc>c .>cx,
I d a t a s e t 22-15
V i s u a l i z z a z i o n e e m o d i f i c a d i u n s o t t o i n s i e m e d i d a t i u s a n d o i f i l t r i
Ovviamente, possibile creare una stringa basata su un testo inserito a livello di
codice e sui dati immessi dallutente:
iisc>c ~s..ic - .>cx - ,
I valori dei campi vuoti non vengono visualizzati a meno che non siano inclusi
esplicitamente nel filtro:
iisc>c .ic > ~ .ic ~.,
_
Dopo aver specificato un valore di Filter, si imposti a true la propriet Filtered per
applicare il filtro al dataset.
I filtri possono confrontare i valori dei campi con letterali e costanti usando i seguenti
operatori logici e di confronto:
Usando combinazioni di questi operatori, possibile creare filtri abbastanza
sofisticati. Listruzione che segue, ad esempio, si assicura che le due condizioni di
verifica siano soddisfatte prima di accettare un record da visualizzare:
s > 1 ~. s ,
_
Quando il filtro attivato, le modifiche apportate da un utente a un record possono
determinare che questultimo non corrisponda pi alle condizioni verificate dal filtro.
Al successivo reperimento del record nel dataset, il record pu dunque scomparire.
In questo caso, il record successivo che passa la condizione di filtro diventa il record
corrente.
Tabella 22.4 Operatori logici e di confronto che possono apparire in un filtro
Operatore Significato
< Minore di
> Maggiore di
>= Maggiore o uguale a
<= Minore o uguale a
= Uguale a
<> Non uguale a
AND Verifica che due istruzioni siano entrambe true
NOT Verifica che listruzione seguente non sia true
OR Verifica che almeno uno delle due istruzioni sia true
+ Aggiunge numeri, concatena stringhe, aggiunge numeri a valori data/ora
(disponibile solo per alcuni driver)
- Sottrae numeri, sottrae date o sottrae un numero da una data (disponibile solo per
alcuni driver)
* Moltiplica due numeri (disponibile solo per alcuni driver)
/ Divide due numeri (disponibile solo per alcuni driver)
* carattere jolly per confronti parziali (FilterOptions deve includere
foPartialCompare)
22-16 G u i d a a l l a p r o g r a mma z i o n e
V i s u a l i z z a z i o n e e m o d i f i c a d i u n s o t t o i n s i e m e d i d a t i u s a n d o i f i l t r i
Scrittura di un gestore di eventi OnFilterRecord
Per indicare se un record soddisfa la condizione di filtro, il gestore di evento
OnFilterRecord imposta il parametro Accept a true per includere un record o a false
per escluderlo. Per esempio, il seguente filtro visualizza solo i record con il campo
State impostato su CA.
veIi __?aatcaII .iccccc.ii.c ii.c, beeI ~ccc,
~ccc, ii.c>c..i.c,.ic>~s. ~,
Quando il filtro attivo, per ciascun record reperito viene generato un evento
OnFilterRecord. Il gestore di evento verifica ciascun record e visualizza solamente
quelli che soddisfano le condizioni del filtro. Poich levento OnFilterRecord viene
generato per ogni record di un dataset, il codice del gestore di evento dovrebbe
essere il pi breve possibile per evitare che influenzi negativamente le prestazioni
dellapplicazione.
Commutazione dei gestori evento di filtro in esecuzione
possibile programmare un numero qualsiasi di gestori evento OnFilterRecord e
passare dalluno allaltro in fase di esecuzione. Le istruzioni che seguono, ad
esempio, passano a un gestore di evento OnFilterRecord, chiamato NewYorkFilter:
ii.c>ccc. .c..c,
c.cs,
Impostazione delle opzioni del filtro
La propriet FilterOptions consente di specificare se un filtro che confronta campi
basati su stringhe accetta i record in base a un confronto parziale e se il confronto
delle stringhe deve tener conto delle maiuscole/minuscole. FilterOptions una
propriet set che pu essere un set vuoto (impostazione predefinita), o che pu
contenere luno o laltro o entrambi i seguenti valori:
Le istruzioni che seguono, ad esempio, prepararono un filtro che, durante il
confronto dei valori nel campo State, non tiene conto delle maiuscole/minuscole:
c,s c,s,
c,s>ci,
c,s .iscLscsc,
icc>c,s c,s,
icc>c .ic ~,
Tabella 22.5 Valori di FilterOptions
Valore Significato
foCaseInsensitive Ignora maiuscolo/minuscolo durante il confronto delle stringhe.
foNoPartialCompare Disattiva la corrispondenza parziale di stringa; vale a dire che le stringhe
che terminano con un asterisco (*) non vengono confrontate.
I d a t a s e t 22-17
M o d i f i c a d e i d a t i
Spostamento tra i record in un dataset filtrato
Esistono quattro metodi del dataset che consentono di spostarsi tra i record di un
dataset filtrato. La tabella che segue elenca questi metodi e descrive ci che fanno:
Listruzione che segue, ad esempio, trova il primo record filtrato di un dataset:
ii.c>.s,
Purch si imposti la propriet Filter o si crei un gestore di evento OnFilterRecord per
unapplicazione, questi metodi posizionano il cursore sul record specificato
indipendentemente dal fatto che il filtraggio si attivo o meno. Se si chiamano questi
metodi quando il filtro non attivo
Attivano temporaneamente il filtro.
Posizionano il cursore su un record corrispondente, se ne viene trovato uno.
Disattivano il filtro.
_
Se il filtro disattivato e non si imposta la propriet Filter o si crea un gestore di
evento OnFilterRecord, questi metodi non fanno alcunch di diverso da First(), Last(),
Next() e Prior().
Tutti i metodi filtro di spostamento posizionano il cursore su un record
corrispondente, se ne stato trovato uno, rendendolo il record attivo, e restituiscono
true. Se non si trova un record corrispondente, la posizione del cursore rimane
immutata e questi metodi restituiscono false. possibile controllare lo stato della
propriet Found per inglobare queste chiamate, ed eseguire unazione solo quando
Found true. Se, ad esempio, il cursore gi sullultimo record corrispondente del
dataset e si chiama FindNext, il metodo restituisce false e il record corrente non
cambia.
Modifica dei dati
possibile utilizzare i metodi del dataset sotto elencati per inserire, aggiornare e
cancellare dati se la propriet a sola lettura CanModify true. CanModify true a
meno che il dataset non sia unidirezionale, che il database sottostante al dataset non
consenta i diritti di lettura e di scrittura o non intervengano altri fattori. (Questi
Tabella 22.6 Metodi di navigazione nei dataset filtrati
Metodo Scopo
FindFirst Si sposta al primo record che corrisponde al criterio di filtro corrente. La ricerca
del primo record corrispondente comincia sempre dal primo record del dataset
non filtrato.
FindLast Si muove allultimo record che corrisponde al criterio di filtro corrente.
FindNext Si sposta dal record attuale del dataset filtrato al successivo.
FindPrior Si sposta dal record corrente del dataset filtrato a quello precedente.
22-18 G u i d a a l l a p r o g r a mma z i o n e
M o d i f i c a d e i d a t i
fattori includono la propriet ReadOnly di alcuni dataset o la propriet RequestLive dei
componenti TQuery).
Modifica dei record
Un dataset deve essere in modalit dsEdit perch unapplicazione possa modificare i
record. Nel codice, il metodo Edit pu essere utilizzato per impostare un dataset in
modalit dsEdit se la propriet a sola lettura CanModify del dataset true.
Quando un dataset passa in modalit dsEdit, riceve dapprima un evento BeforeEdit.
Dopo il passaggio alla modalit editing, il dataset riceve un evento AfterEdit. Di
solito, questi eventi sono utilizzati per laggiornamento dellinterfaccia utente per
indicare lo stato corrente del dataset. Se il dataset non pu essere posto in modalit
editing per un qualche motivo, si verifica un evento OnEditError, in cui possibile
informare lutente del problema o provare a correggere la situazione che ha impedito
al dataset di passare in modalit editing.
Nelle schede dellapplicazione, alcuni controlli associati ai dati possono portare
automaticamente un dataset allo stato dsEdit se
La propriet ReadOnly del controllo false (impostazione predefinita),
La propriet AutoEdit del datasource true e
CanModify true per il dataset.
_
Anche se un dataset nello stato dsEdit, la modifica dei record pu non riuscire per i
database basati su SQL se lutente dellapplicazione non possiede i privilegi di
accesso SQL appropriati.
Quando un dataset in modalit dsEdit, un utente pu modificare i valori dei campi
del record corrente che appaiono nei controlli associati ai dati di una scheda. I
controlli associati ai dati per i quali la modifica consentita chiamano
automaticamente Post quando un utente esegue unoperazione che cambia il record
corrente (per esempio lo spostamento a un altro record in una griglia).
Se nelle schede previsto un componente Navigator, gli utenti possono annullare le
modifiche facendo clic sul pulsante Cancel del Navigator. Annullando le modifiche,
viene ripristinato lo stato dsBrowse del dataset.
Tabella 22.7 Metodi dei dataset per inserire, aggiornare e cancellare dati
Metodo Descrizione
Edit Imposta il dataset in modalit dsEdit, se gi non nello stato dsEdit o dsInsert.
Append Invia i dati in attesa, sposta il record attivo alla fine del dataset e pone il dataset in
modalit dsInsert.
Insert Invia i dati in attesa e pone il dataset in modalit dsInsert.
Post Cerca di registrare nel database il record nuovo o modificato. Se loperazione riesce,
il dataset torna allo stato dsBrowse; se non riesce, il dataset rimane nello stato
corrente.
Cancel Annulla loperazione corrente e pone il dataset in modalit dsBrowse.
Delete Cancella il record corrente e pone il dataset in modalit dsBrowse.
I d a t a s e t 22-19
M o d i f i c a d e i d a t i
Nel codice, necessario scrivere o annullare le modifiche chiamando i metodi
appropriati. Le modifiche vengono scritte chiamando Post. Possono essere annullate
chiamando Cancel. Nel codice, Edit e Post sono sovente utilizzati insieme. Per
esempio,
icc>.,
icc>c.ics,s. .1,
icc>.s,
Nellesempio precedente, la prima riga di codice imposta la modalit dsEdit per il
dataset. La successiva riga di codice assegna la stringa 1234 al campo CustNo del
record corrente. Infine, lultima riga scrive, ovvero registra, il record modificato nel
database. Se non si utilizzano gli aggiornamenti in cache, la registrazione scrive le
modifiche nel database di origine. Se si utilizzano gli aggiornamenti in cache, la
modifica vengono scritte in un buffer temporaneo, in cui restano finch non viene
chiamato il metodo ApplyUpdates del dataset.
Aggiunta di nuovi record
Un dataset deve essere in modalit dsInsert perch unapplicazione possa
aggiungervi nuovi record. Nel codice, possibile utilizzare i metodi Insert o Append
per portare un dataset in modalit dsInsert, a patto che la propriet a sola lettura
CanModify del dataset sia true.
Quando un dataset passa in modalit dsInsert, riceve dapprima un evento
BeforeInsert. Dopo che il completamento con successo del passaggio alla modalit
inserimento, il dataset riceve prima un evento OnNewRecord e quindi un evento
AfterInsert. possibile usare questi eventi, ad esempio, per fornire dei valori iniziali
per i record appena inseriti:
veIi __?aatcaII ..csicc.c.cc.ii.c ii.c
ii.c>c..i.c'.cic'>~sic.c ic,
icc>.,
icc>.cc.s~~... ., . ., . .,
11, 1,
icc>.s,
Questo codice assegna i valori ai campi Area e Population e quindi li registra nel
database. I tre puntatori NULL si comportano come segnaposto per le prime tre
colonne, in modo da preservarne il contenuto attuale.
j
Quando si usano puntatori NULL con SetFields per lasciare inalterati alcuni valori di
campo, bisogna accertarsi di effettuare la conversione da NULL a puntatore void *.
Se si usa NULL come parametro senza effettuare la conversione di tipo, il campo
verr impostato ad un valore vuoto.
22-24 G u i d a a l l a p r o g r a mma z i o n e
C a l c o l o d e i c a m p i
Calcolo dei campi
Utilizzando Fields editor, possibile definire dei campi calcolati per i dataset.
Quando un dataset contiene campi calcolati, si deve preparare del codice per
calcolare quei valori di campo in un gestore di evento OnCalcFields. Per ulteriori
informazioni sulla definizione dei campi calcolati con leditor Fields, consultare
Definizione di un campo calcolato a pagina 23-7.
La propriet AutoCalcFields determina quando OnCalcFields viene chiamato. Se
AutoCalcFields true, OnCalcFields viene chiamato quando
Un dataset viene aperto.
Il dataset passa in modalit editing.
Un record viene reperito nel database.
Il fuoco si sposta da un componente visivo a un altro o da una colonna a unaltra
in un controllo di griglia associata ai dati e il record attivo stato modificato.
Se AutoCalcFields false, OnCalcFields non viene chiamato quando si modificano
singoli campi allinterno di un record (la quarta condizione vista in precedenza).
j
OnCalcFields viene chiamato frequentemente, quindi il codice scritto per esso deve
essere breve. Inoltre, se AutoCalcFields true, OnCalcFields non deve svolgere
operazioni che modificano il dataset (o un dataset collegato nel caso appartienga a
una relazione master/detail), in quanto ci questo pu dar luogo a ricorsivit. Per
esempio, se OnCalcFields esegue unoperazione Post e AutoCalcFields true,
OnCalcFields viene chiamato nuovamente, dando origine a unaltra operazione Post, e
cos via.
Quando viene eseguito OnCalcFields, il dataset passa in modalit dsCalcFields. Questo
stato impedisce modifiche o aggiunte ai record di un dataset, ad eccezione dei campi
calcolati che il gestore previsto possa modificare. Il motivo per prevenire altre
modifiche dovuto al fatto che OnCalcFields utilizza i valori contenuti in altri campi
per derivare i valori dei campi calcolati. Eventuali modifiche a questi altri campi,
potrebbero invalidare i valori assegnati ai campi calcolati. Dopo il completamento di
OnCalcFields, il dataset torna allo stato dsBrowse.
Tipi di dataset
Utilizzo dei discendenti di TDataSet a pagina 22-2 classifica i discendenti di
TDataSet in base al metodo che essi utilizzano per accedere ai propri dati. Un altro
metodo utile per classificare i discendenti di TDataSet quello di considerare il tipo
di server dati che essi rappresentano. In base a questottica, ci sono tre classi di base
di dataset:
Datasets di tipo tabella: I dataset di tipo tabella rappresentano una singola tabella
di un server di database, comprese tutte le sue righe e colonne. $$$$I dataset di
tipo tabella includono TTable, TADOTable, TSQLTable e TIBTable.
I d a t a s e t 22-25
T i p i d i d a t a s e t
I dataset di tipo tabella permettono di sfruttare indici definiti sul server. Poich c
una corrispondenza biunivoca tra tabella di database e dataset, possibile
utilizzare gli indici server definiti per la tabella di database. Gli indici permettono
allapplicazione di ordinare i record nella tabella, di velocizzare ricerche e
consultazioni e possono costituire la base di una relazione master/detail. Inoltre,
alcuni dataset di tipo tabella sfruttano il vantaggio della relazione uno-a-uno
esistente tra il dataset e la tabella di database per permettere di eseguire
operazioni a livello di tabella, come la creazione e la cancellazione di tabelle di
database.
Dataset di tipo query : I dataset di tipo query rappresentano un singolo comando
SQL o una query. Le query possono rappresentare il set risultato derivante
dallesecuzione di un comando (di solito unistruzione SELECT) o possono
eseguire un comando che non restituisce alcun record (ad esempio, unistruzione
UPDATE). I dataset di tipo query includono TQuery, TADOQuery, TSQLQuery e
TIBQuery.
Per utilizzare un dataset di tipo query, necessario avere familiarit con SQL e con
limplementazione SQL del server, compresi eventuali limiti ed estensioni
ampliamenti allo standard SQL-92. Se non si ha padronanza di SQL, potrebbe
valer la pena acquistare un manuale tecnico che tratti SQL in dettaglio. Uno dei
migliori Understanding the New SQL: A Complete Guide, di Jim Melton e Alan R.
Simpson, edito da Morgan Kaufmann.
Dataset di tipo procedura registrata: I dataset di tipo procedura registrata
rappresentano una procedura registrata sul server di database. I dataset di tipo
procedura registrata includono TStoredProc, TADOStoredProc, TSQLStoredProc e
TIBStoredProc.
Una procedura registrata un programma indipendente scritto nella linguaggio di
procedure e trigger specifici del sistema di database utilizzato. Di solito
gestiscono operazioni relative al database ripetute di frequente, e risultano
particolarmente utili per operazioni che agiscono su grandi quantit di record o
che utilizzano funzioni di aggregazione o matematiche. Di solito lutilizzo di
procedure registrate migliora le prestazioni di unapplicazione database:
Sfruttando lenorme potenza e velocit di elaborazione tipiche dei server.
Riducendo il traffico di rete perch tutte le elaborazioni vengono spostate sul
server.
Le procedure registrate possono restituire o meno dei dati. Quelle che
restituiscono dati possono restituirli come un cursor (in modo analogo al risultato
di una query SELECT), come pi cursor (restituendo in effetti pi dataset) o
restituire dati nei parametri di output. Queste differenze dipendono in parte dal
server: alcuni server non permettono alle procedure registrate di restituire dati o
permettono solo parametri di output. Altri server invece non supportano affatto le
procedure registrate. Per determinare cosa possibile fare, consultare la
documentazione del server.
_
Solitamente possibile utilizzare un dataset di tipo query per eseguire procedure
registrate poich la maggior parte dei server dispone di estensioni a SQL per operare
con le procedure registrate. Ogni server, tuttavia, utilizza a questo scopo la propria
22-26 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t a s e t d i t i p o t a b e l l a
sintassi. Se si sceglie di utilizzare un dataset di tipo query invece di un dataset di tipo
procedura registrata, consultare la documentazione del server per la sintassi
necessaria.
Oltre ai dataset che rientrano chiaramente in queste tre categorie, TDataSet ha alcuni
discendenti che possono essere considerati appartententi a pi di una categoria:
TADODataSet e TSQLDataSet hanno una propriet CommandType che permette di
specificare se rappresentano una tabella, una query o una procedura registrata. I
nomi delle propriet e dei metodo sono molto simili a quelli dei dataset di tipo
query, bench TADODataSet permetta di specificare un indice come un dataset di
tipo tabella.
TClientDataSet rappresenta i dati da un altro dataset. Come tale, pu rappresentare
una tabella, una query o una procedura registrata. TClientDataSet si comporta in
modo molto simile a un dataset di tipo tabella, a causa del suo supporto per gli
indici. Tuttavia, anche ha alcune delle funzioni dei dataset di tipo query e
procedura registrata: la gestione dei parametri e la capacit di essere eseguito
senza acquisire un set risultato.
Alcuni altri dataset client (TBDEClientDataSet e TSQLClientDataSet) hanno una
propriet CommandType che permette di specificare se essi rappresentano una
tabella, una query o una procedura registrata. I nomi delle propriet e dei metodi
sono come quelli di TClientDataSet, e gli somiglia anche per il supporto dei
parametri e degli indici e la capacit la capacit di essere eseguito senza acquisire
un set risultato.
TIBDataSet pu rappresentare sia le query che le procedure registrate. Infatti, pu
rappresentare pi query e procedure registrate contemporaneamente, con
propriet separate per ognuno.
Utilizzo dei dataset di tipo tabella
Per utilizzare un dataset di tipo tabella,
1 Collocare il componente dataset appropriato in un modulo dati o su una scheda e
impostarne la propriet Name a un valore univoco, consono allapplicazione.
2 Identificare il server di database che contiene la tabella che si vuole usare. Ogni
dataset di tipo tabella lo compie in modo diverso, ma di solito si specifica un
componente database connection:
Per TTable, specificare un componente TDatabase o un alias BDE utilizzando la
propriet DatabaseName.
Per TADOTable, specificare un componente TADOConnection utilizzando la
propriet Connection.
Per TSQLTable, specificare un componente TSQLConnection utilizzando la
propriet SQLConnection.
Per TIBTable, specificare un componente TIBConnection utilizzando la propriet
Database.
I d a t a s e t 22-27
U t i l i z z o d e i d a t a s e t d i t i p o t a b e l l a
Per informazioni sullutilizzo di componenti database connection, vedere il
Capitolo 21 Capitolo 21, Connessione ai database.
3 Impostare la propriet al nome della tabella nel database. possibile selezionare le
tabelle da una lista a discesa se si gi identificato un componente database
connection.
4 Mettere un componente datasource nel modulo dati o sulla scheda e impostarne la
propriet DataSet al nome del dataset. Il componente datasource viene usato per
passare un set risultato dal dataset ai componenti data-aware affinch siano
visualizzati.
Vantaggi dellutilizzo dei dataset di tipo tabella
Il vantaggio principale dellutilizzo di dataset di tipo tabella la disponibilit di
indici. Gli indici consentono allapplicazione di
Ordinare i record nel dataset.
Individuare rapidamente i records.
Limitare i record visibili.
Stabilire relazioni master/detail.
Inoltre, la relazione uno-a-uno tra dataset di tipo tabella e tabelle di database
permette di utilizzare molti di loro per i seguenti scopi
Controllo dellaccesso alle tabelle in lettura/scrittura
Creazione e cancellazione di tabelle
Svuotamento di tabelle
Sincronizzazione di tabelle
Ordinamento dei record con indici
Un indice determina lordine di visualizzazione dei record in una tabella. Di solito, i
record vengono visualizzati in ordine ascendente in base a un indice primario o
predefinito. Questo comportamento predefinito non richiede intervento da parte
dellapplicazione. Se si desidera una sequenza di ordinamento diversa, tuttavia,
necessario specificare
Un indice alternativo, oppure.
Una lista di colonne su cui ordinare (non disponibile su server che non sono basati
su SQL).
Gli indici permettono di presentare i dati da una tabella secondo diversi ordinamenti.
Su tabelle basate su SQL, questa sequenza di ordinamento implementata
utilizzando lindice per generare una clausola ORDER BY in una query che preleva i
record della tabella. Su altre tabelle (come tabelle Paradox e dBASE), lindice
utilizzato dal meccanismo di accesso di dati per presentare i record nellordine
richiesto.
22-28 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t a s e t d i t i p o t a b e l l a
Ottenimento di informazioni sugli indici
Lapplicazione pu ottenere informazioni su indici definiti dal server da tutti i
dataset di tipo tabella. Per ottenere una lista degli indici disponibili per il dataset,
chiamare il metodo GetIndexName. GetIndexNames riempie una lista di stringhe con i
nomi degli indici validi. Ad esempio, il seguente codice riempie una casella di
riepilogo con i nomi di tutti gli indici definiti per il dataset CustomersTable:
s.csicc>cL.cx.i.cssx>Lc.s,
_
Nel caso di tabelle Paradox, lindice principale senza nome e non viene quindi
restituito da GetIndexNames. Con una tabella Paradox, comunque, sempre possibile
reimpostare lindice in uso allindice principale, dopo avere utilizzato un indice
alternativo, impostando la propriet IndexName a una stringa vuota.
Per ottenere informazioni sui campi dellindice corrente, utilizzare
La propriet IndexFieldCount, per determinare il numero di colonne nellindice.
La propriet IndexFields, per esaminare una lista dei componenti campo per le
colonne che comprendono lindice.
Il codice seguente mostra come si protrebbero utilizzare IndexFieldCount e IndexFields
per passare in sequenza una lista di nomi di colonna in unapplicazione:
~s. s.L.cxc.s,.,
?et Iat , s.csicc>L.cxc., --
s.L.cxc.s, s.csicc>L.cxc.s,>c..i.c,
_
IndexFieldCount non valido per una tabella dBASE aperta in base a un indice di
espressione.
Specifica di un indice con IndexName
Per fare in modo che un indice diventi attivo, utilizzare la propriet IndexName. Una
volta attivo, un indice determina lordine dei record nel dataset. (Pu essere
utilizzato anche come base per un collegamento master-detail, per una ricerca basata
su indice o per un filtraggio basato su indice).
Per attivare un indice, impostare la propriet IndexName al nome di un indice. In
alcuni sistemi di database, gli indici principali non hanno nomi. Per attivare uno di
questi indici, impostare IndexName a una stringa vuota.
In progettazione, possibile selezionare un indice da una lista di indici disponibili
facendo clic nellObject Inspector sul pulsante ellissi della propriet. In fase di
esecuzione, impostare IndexName utilizzando una costante o una variabile AnsiString.
possibie ottenere una lista degli indici disponibili chiamando il metodo
GetIndexName.
Il seguente codice imposta lindice per CustomersTable a CustDescending:
s.csicc>L.cx.i.c scscc.,
Creazione di un indice con IndexFieldNames
Se non c alcun indice definito che implementa la sequenza di ordinamento
desiderata, possibile creare uno pseudo-indice utilizzando la propriet
IndexFieldNames.
I d a t a s e t 22-29
U t i l i z z o d e i d a t a s e t d i t i p o t a b e l l a
_
IndexName and IndexFieldNames sono reciprocamente esclusivi. Limpostazione della
propriet di uno cancella i valori impostati per laltro.
Il valore di IndexFieldNames una stringa ansi. Per specificare una sequenza di
ordinamento, elencare ogni nome di colonna da utilizzare nellordine che dovrebbe
essere utilizzato e delimitare i nomi con punti e virgola. Lordinamento solo
ascendente. La dipendenza dellordinamento dalle maiuscole legata alle capacit
del server. Per ulteriori informazioni, vedere la documentazione del server.
Il seguente codice imposta la sequenza di ordinamento per PhoneTable in base a
LastName, quindi a FirstName:
.cicc>L.cxc..i.cs 'is.i.c,s.i.c',
_
Se si utilizza IndexFieldNames su tabelle Paradox e dBASE, il dataset tenta di trovare
un indice che utilizza le colonne specificate. Se non in grado di trovare un tale
indice, solleva uneccezione.
Utilizzo di indici per la ricerca di record
Si pu effettuare una ricerca in un qualsiasi dataset usando i metodi Locate e Lookup
di TDataSet. Comunque, se si utilizzano esplicitamente gli indici, alcuni dataset di
tipo tabella possono migliorare di molto le prestazioni di una ricerca fornite dai
metodi Locate e Lookup.
I dataset ADO supportano tutti il metodo Seek, che sposta a un record in base a un
insieme di valori di campo per i campi nellindice corrente. Seek permette di
specificare dove spostare il cursore rispetto al primo o allultimo record
corrispondente.
TTable e tutti i tipi di dataset client supportano ricerche simili basate su indici, ma
utilizzano una combinazione di metodi collegati. La seguente tabella riassume i sei
metodi collegati forniti da TTable e dai dataset client per supportare le ricerche basate
su indice:
Tabella 22.9 Metodi di ricerca basati sugli indici
Metodo Scopo
EditKey Preserva il contenuto corrente del buffer della chiave di ricerca e pone il dataset
nello stato dsSetKey in modo che lapplicazione possa modificare i criteri di
ricerca esistenti prima dellesecuzione di una ricerca.
FindKey Combina in un singolo metodo i metodi SetKey e GotoKey.
FindNearest Combina in un singolo metodo i metodi SetKey e GotoNearest.
GotoKey Ricerca il primo record in un dataset che corrisponde esattamente ai criteri di
ricerca e, nel caso lo trovi, sposta il cursore su quel record.
GotoNearest Ricerca, in base a un valore di chiave parziale, nei campi basati su stringhe la
corrispondenza pi simile a un record e sposta il cursore a quel record.
SetKey Cancella il buffer della chiave di ricerca e pone la tabella nello stato dsSetKey in
modo che lapplicazione possa specificare nuovi criteri di ricerca prima di
eseguire una ricerca.
22-30 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t a s e t d i t i p o t a b e l l a
GotoKey e FindKey sono funzioni boolean che, se vanno a buon fine, spostano il
cursore a un record corrispondente e restituiscono true. Se la ricerca non va a buon
fine, il cursore non viene spostato e queste funzioni restituiscono false.
GotoNearest e FindNearest ricollocano sempre il cursore o sulla prima corrispondenza
esatta trovata o, nel caso non venga trovata alcuna corrispondenza, sul primo record
che maggiore dei criteri di ricerca specificati.
Esecuzione di una ricerca con metodi Goto
Per eseguire una ricerca utilizzando i metodi Goto, seguire questi passi generali:
1 Specificare lindice da utilizzare per la ricerca. Questo lo stesso indice che ordina
i record nel dataset (vedere Ordinamento dei record con indici a pagina 22-27).
Per specificare lindice, utilizzare la propriet IndexName o IndexFieldNames.
2 Aprire il dataset.
3 Porre il dataset nello stato dsSetKey chiamando SetKey.
4 Specificare il valore o i valori da ricercare nella propriet Fields. Fields un oggetto
TFields, che gestisce una lista indicizzata di componenti campo, a cui possibile
accedere specificando il numero ordinale che corrisponde alla colonna. Il primo
numero di colonna in un dataset 0.
5 Cercare e spostarsi al primo record corrispondente trovato con GotoKey o con
GotoNearest.
Ad esempio, il codice seguente, collegato allevento OnClick di un pulsante, utilizza il
metodo GotoKey per spostarsi al primo record in cui il primo campo nellindice ha un
valore che corrisponde esattamente al testo immesso in una casella di testo:
veIi __?aatcaII .cicc..cicxicc.ccc .c.c
cii.c>.cc,
cii.c>c.s>c.s,>~s. .>cx,
I? cii.c>c
...cssiccc. ..,
.icc>iccic,
s.c_c>cci ttae,
s.c_c>.c,ic. ttae,
s.c_c>,c, cs i cs sc . i c.i cs
22-52 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i d a t a s e t d i t i p o p r o c e d u r a r e g i s t r a t a
_
Non confondere la propriet UniDirectional con un dataset unidirezionale. I dataset
unidirezionali (TSQLDataSet, TSQLTable, TSQLQuery e TSQLStoredProc) utilizzano
dbExpress, che restituisce solo cursor unidirezionali. Oltre a limitare la capacit di
spostamento a ritroso, i dataset unidirezionali non bufferizzano i record e pertanto
hanno limitazioni aggiuntive (come lincapacit di utilizzare i filtri).
Utilizzo di dataset di tipo procedura registrata
Il modo in cui lapplicazione utilizza una procedura registrata dipende da come
stata codificata la procedura registrata, dal fatto che restituisca o meno dati e in che
modo, dallo specifico server di database utilizzato, o da una combinazione di tutti
questi fattori.
In generale, per accedere a una procedura registrata su un server, unapplicazione
deve:
1 Collocare il componente dataset appropriato in un modulo dati o su una scheda e
impostarne la propriet Name a un valore univoco, consono allapplicazione.
2 Identificare il server di database che definisce la procedura registrata. Ogni dataset
di tipo procedura registrata lo fa in modo diverso, ma di solito si specifica un
componente database connection:
Per TStoredProc, specificare un componente TDatabase o un alias BDE
utilizzando la propriet DatabaseName.
Per TADOStoredProc, specificare un componente TADOConnection utilizzando
la propriet Connection.
Per TSQLStoredProc, specificare un componente TSQLConnection utilizzando la
propriet SQLConnection.
Per TIBStoredProc, specificare un componente TIBConnection utilizzando la
propriet Database.
Per informazioni sullutilizzo di componenti database connection, vedere Capitolo
21, Connessione ai database.
3 Specificare la procedura registrata da eseguire. Per la maggior parte dei dataset di
tipo procedura registrata, lo si fa impostando la propriet StoredProcName.
Uneccezione TADOStoredProc, che ha invece una propriet ProcedureName.
4 Se la procedura registrata restituisce un cursor da usare con controlli dati visuali,
aggiungere al modulo dati un componente datasource e impostarne la propriet
DataSet al dataset di tipo procedura registrata. Connettere i componenti data-
aware al datasource utilizzando le loro propriet DataSource e DataField.
5 Fornire, se necessario, i valori dei parametri di input per la procedura registrata.
Se il server non fornisce informazioni su tutti i parametri della procedura
registrata, potrebbe essere necessario specificare ulteriori informazioni per i
parametri di input, come i nomi dei parametri e i tipi di dati. Per i dettagli sui
parametri delle procedure registrate, consultare Operazioni con i parametri delle
procedure registrate a pagina 22-53.
I d a t a s e t 22-53
U t i l i z z o d i d a t a s e t d i t i p o p r o c e d u r a r e g i s t r a t a
6 Eseguire la procedura registrata. Per procedure registrate che restituiscono un
cursor, utilizzare la propriet Active o il metodo Open. Per eseguire procedure
registrate che non restituisce alcun risultato o che restituiscono solo parametri di
output, utilizzare il metodo ExecProc in fase di esecuzione. Se si prevede di
eseguire la procedura registrata pi di una volta, potrebbe essere oportuno
chiamare Prepare per inizializzare lo strato di accesso ai dati e inglobare i valori dei
parametri nella procedura registrata. Per informazioni sulla preparazione di una
query, vedere Esecuzione di procedure registrate che non restituiscono un set
risultato a pagina 22-56.
7 Elaborare gli eventuali risultati. Questi risultati possono essere restituiti come
parametri risultato e parametri di output, oppure possono essere restituiti come
set risultato che riempie il dataset di tipo procedura registrata. Alcune procedure
registrate restituiscono pi cursor. Per dettagli su come accedere ai cursor
aggiuntivi, vedere Prelievo di pi set risultato a pagina 22-57.
Operazioni con i parametri delle procedure registrate
Esistono quattro tipi di parametri che possibile associare a procedure registrate:
Parametri di input, utilizzati per passare valori a una procedura registrata per
lelaborazione.
Parametri di output, utilizzati da una procedura registrata per passare a
unapplicazione i valori restituiti.
Parametri di input/output, utilizzati per passare valori a una procedura registrata
per lelaborazione e utilizzati dalla procedura registrata per passare
allapplicazione i valori restituiti.
Un parametro risultato, utilizzato da alcune procedure registrate per restituire a
unapplicazione un valore di errore o di stato. Una procedura registrata pu
restituire un solo parametro risultato.
Il fatto che una procedura registrata utilizzi un particolare tipo di parametro dipende
sia dallimplementazione generale del linguaggio delle procedure registrate sul
server di database sia dalla specifica istanza della procedura registrata. Per tutti i
server, le singole procedure registrate possono utilizzare o meno parametri di input.
Daltra parte, alcuni utilizzi dei parametri sono tipici del server. Ad esempio, su MS-
SQL Server e Sybase, le procedure registrate restituiscono sempre un parametro
risultato, mentre limplementazione InterBase di una procedura registrata non
restituisce mai un parametro risultato.
Laccesso ai parametri di una procedura registrata garantito dalla propriet Params
(in TStoredProc, TSQLStoredProc, TIBStoredProc) o dalla propriet Parameters (in
TADOStoredProc). Quando si assegna un valore alla propriet StoredProcName (o
ProcedureName), il dataset genera automaticamente oggetti per ogni parametro della
procedura registrata. Per alcuni dataset, se il nome della procedura registrata non
vinespecificato fino al mometo dellesecuzione, gli oggetti per ogni parametro
devono essere creati da programma in quel preciso momento. La mancata specifica
della procedura registrata e la creazione manualmente gli oggetti TParam o
22-54 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i d a t a s e t d i t i p o p r o c e d u r a r e g i s t r a t a
TParameter permette di utilizzare un singolo dataset con tutte le procedure registrate
disponibili.
_
Oltre ai parametri di output e risultato, alcune procedure registrate restituiscono un
dataset. Le applicazioni possono visualizzare i record del dataset in controlli data-
aware, ma devono elaborare separatamente i parametri di output e risultato.
Impostazione dei parametri in progettazione
possibile specificare in fase progettazione i valori dei parametri della procedura
registrata utilizzando il Parameter collection editor. Per visualizzare il Parameter
collection editor, fare clic nellObject Inspector sul pulsante ellissi della propriet
Params o Parameters.
j
possibile assegnare valori ai parametri di input selezionandoli nel Parameter
collection editor e utilizzando lObject Inspector per impostarne la propriet Value.
Tuttavia, non si devono modificare i nomi o i tipi di dati dei parametri di input
segnalati dal server. In caso contrario, quando si eseguir la procedura registrata
verr sollevata uneccezione.
Alcuni server non riportano i nomi dei parametri o i tipi di dati. In questi casi,
necessario configurare i parametri utilizzando manualmente leditor Parameter
collection. Per aggiungere parametri, fare clic destro e scegliere il comando Add. Per
ogni parametro aggiunto, necessario farne una descrizione completa. Anche se non
necessario aggiungere alcun parametro, si dovrebbero controllare le propriet dei
singoli oggetti parametro per assicurasi che siano corretti.
Se il dataset ha una propriet Params (oggetti TParam), necessario specificare
correttamente le seguenti propriet:
La propriet Name indica il nome del parametro cos come definito dalla
procedura registrata.
La propriet DataType riporta il tipo di dati per il valore del parametro. Quando si
utilizza TSQLStoredProc, alcuni tipi di dati richiedono ulteriori informazioni:
La propriet NumericScale indica il numero di cifre decimali per i parametri
numerici.
La propriet Precision indica il numero totale di cifre per i parametri numerici.
La propriet Size indica il numero di caratteri nei parametri stringa.
La propriet ParamType riporta il tipo del parametro selezionato. Pu essere
ptInput (per parametri di input), ptOutput (per parametri di output), ptInputOutput
(per parametri di input/output) o ptResult (per parametri risultato).
La propriet Value specifica un valore per il parametro selezionato. Non mai
possibile impostare i valori per i parametri di output e risultato. Questi tipi di
parametri hanno valori che vengono impostati dallesecuzione della procedura
registrata. Nel caso dei parametri di input/output, se lapplicazione fornisce i
valori dei parametri in esecuzione, possibile non compilare Value.
Se il dataset utilizza una propriet Parameters (oggetti TParameter), necessario
specificare correttamente le seguenti propriet:
I d a t a s e t 22-55
U t i l i z z o d i d a t a s e t d i t i p o p r o c e d u r a r e g i s t r a t a
La propriet Name indica il nome del parametro cos come definito dalla
procedura registrata.
La propriet DataType riporta il tipo di dati per il valore del parametro. Per alcuni
tipi di dati, necessario fornire ulteriori informazioni:
La propriet NumericScale indica il numero di cifre decimali per i parametri
numerici.
La propriet Precision indica il numero totale di cifre per i parametri numerici.
La propriet Size il numero di caratteri nei parametri stringa.
La propriet Direction riporta il tipo del parametro selezionato. Pu essere pdInput
(per parametri di input), pdOutput (per parametri di output), pdInputOutput (per
parametri di input/output) o pdReturnValue (per parametri risultato).
La propriet Attributes controlla il tipo dei valori accettati dal parametro. Attributes
pu essere impostato a una combinazione di psSigned, psNullable e psLong.
La propriet Value specifica un valore per il parametro selezionato. Non impostare
i valori per i parametri di output e risultato. Nel caso dei parametri di input/
output, se lapplicazione fornisce i valori dei parametri in esecuzione, possibile
non compilare Value.
Utilizzo di parametri in esecuzione
Con alcuni dataset, se il nome della procedura registrata non viene specificato fino al
momento dellesecuzione, per i parametri non verr creato automaticamente alcun
oggetto TParam ed dovranno essere creati da programma. possibile fare ci
istanziando un nuovo oggetto TParam oppure il metodo TParams::AddParam:
.ii. ., ..,
.c..c>.c..c.i.c '_.._.',
.c..c>.ii.s>ci,
. aev .ii..c..c>.ii.s, ,L,,
.. aev .ii..c..c>.ii.s, ,,,
tt,
.c..c>.ii.s>Lc.s,>.i.c '.._.',
.c..c>.ii.s>Lc.s,>.i.c '._L',
.c..c>.ii..i.c'.._.'>~s..iL .,
.c..c>xcc.c,
.>cx .c..c>.ii..i.c'._L'>~s.,
__?IaaII,
ieIete .,
ieIete ..,
.>cx s.cs.,i>ic,
.ic
.,
Utilizzo di componenti campo persistenti
Il modo pi semplice per accedere a valori di un campo ADT consiste nellutilizzare
componenti campo persistenti. Per la struttura ADT vista in precedenza, possibile
aggiungere alla tabella Customer i seguenti campi persistenti utilizzando il Fields
editor:
s.c~..css ~c.,
s.c~...cc .c.,
s.c~.. .c.,
s.c~...ic .c.,
s.c~..., .c.,
Dati questi campi persistenti, possibile accedere semplicemente ai campi figlio di
un campo ADT mediante il nome:
.>cx s.c~..>~s.,
Bench i campi persistenti siano il modo pi semplice per accedere a campi figlio di
ADT, non possibile utilizzarli se, in fase di progettazione, non si conosce la struttura
23-26 G u i d a a l l a p r o g r a mma z i o n e
U s o d e i c a m p i o g g e t t o
del dataset. Quando si accede ai campi figli di ADT senza utilizzare campi
persistenti, necessario impostare a True la propriet ObjectView del dataset.
Utilizzo del metodo FieldByName del dataset
possibile accedere ai figli di un campo ADT utilizzando il metodo FieldByName del
dataset, qualificando il nome del campo figlio con il nome del campo ADT:
.>cx s.c>c..i.c~..css>~s.,
Utilizzo della propriet FieldValues del dataset
possibile utilizzare nomi di campo qualificati anche con la propriet FieldValues di
un dataset:
.>cx s.c>c.ics,'~..css',
_
A differenza di altri metodi di esecuzione per accedere ai valori dei campo figlio di
ADT, la propriet FieldValues funziona anche se la propriet ObjectView del dataset
impostata a false.
Utilizzo della propriet FieldValues del campo ADT
Tramite la propriet FieldValues di TADTField possibile accedere al valore di un
campo figlio. FieldValues accetta e restituisce un Variant, cosicch pu gestire e
convertire campi di qualunque tipo. Il parametro dellindice un valore integer che
specifica lo scostamento del campo.
.>cx ~c.s.c>c..i.c'~..css'>c.ics,,
Utilizzo della propriet Fields del campo ADT
Ogni campo ADT ha una propriet Fields analoga alla propriet Fields di un dataset.
Come la propriet Fields di un dataset, possibile utilizzarla per accedere a campi
figlio in base alla loro posizione:
.>cx ~c.s.c>c..i.c'~..css'>c.s>
c.s,>~s.,
oppure in base al nome:
.>cx ~c.s.c>c..i.c'~..css'>
c.s>c..i.c''>~s.,
Uso dei campi array
I campi array sono costituiti da un gruppo di campi dello stesso tipo. Il tipo di campo
pu essere scalare (per esempio, float o string), o non scalare (un ADT), ma non pu
essere un campo array di array. La propriet SparseArrays di TDataSet determina se
per ciascun elemento del campo array viene creato un oggetto TField univoco.
Esistono diversi modi per accedere ai dati nei tipi di campo array. Se non si utilizzano
campi persistenti, prima di potere accedere agli elementi di un campo array
necessario impostare a True la propriet ObjectView del dataset.
O p e r a z i o n i c o n i c o mp o n e n t i c a mp o 23-27
U s o d e i c a m p i o g g e t t o
Utilizzo di campi persistenti
possibile mappare i campi persistenti su singoli elementi dellarray di un campo
array. Ad esempio, si prenda in esame un campo array TelNos_Array, che un array di
stringhe con sei elementi. I campi persistenti seguenti, creati per il componente
tabella Customer, rappresentano il campo TelNos_Array e i suoi sei elementi:
s.c.._~~ ~ic.,
s.c.._~~ .c.,
s.c.._~~ .c.,
s.c.._~~. .c.,
s.c.._~~ .c.,
s.c.._~~1 .c.,
s.c.._~~ .c.,
Dati questi campi persistenti, il seguente codice utilizza un campo persistente per
assegnare il valore di un elemento dellarray a una casella di testo di nome TelEdit.
c.>cx s.c.._~~>~s.,
Uso della propriet FieldValues del campo array
Tramite la propriet FieldValues del campo array possibile accedere al valore di un
campo figlio. FieldValues accetta e restituisce un Variant, pertanto pu gestire e
convertire campi di qualunque tipo. Ad esempio:
c.>cx ~ic.s.c>c..i.c'c.s_~i'>c.ics,,
Uso della propriet Fields del campo array
TArrayField ha una propriet Fields che possibile utilizzare per accedere ai singoli
sottocampi. Il procedimento illustrato nel codice seguente, in cui un campo array
(OrderDates) viene utilizzato per riempire una casella di riepilogo con elementi di
array non nulli:
?et Iat , .cics>..c, --
. .cics>c.s>c.s,>Ls.
.cicsx>Lc.s>~...cics>c.s>c.s,>~s.,
Uso dei campi dataset
I campi dataset forniscono laccesso ai dati memorizzati in un dataset annidato. La
propriet NestedDataSet referenzia il dataset annidato. Ai dati del dataset annidato si
pu poi accedere tramite gli oggetti campo del dataset stesso.
Visualizzazione dei campi dataset
I controlli TDBGrid consentono la visualizzazione dei dati memorizzati nei campi del
dataset. In un controllo TDBGrid, un campo del dataset viene indicato in ciascuna
cella di una colonna del dataset mediante la stringa (DataSet) e, in fase di
esecuzione, alla destra del campo appare anche un pulsante ellissi. Facendo clic sul
pulsante si richiama una nuova scheda con una griglia che visualizza il dataset
associato al campo dataset del record attivo. Questa scheda pu anche essere
richiamata da programma con il metodo ShowPopupEditor della griglia DB. Per
23-28 G u i d a a l l a p r o g r a mma z i o n e
U s o d e i c a m p i o g g e t t o
esempio, se la settima colonna della griglia rappresenta un campo dataset, il codice
seguente visualizzer il dataset associato a quel campo per il record attivo.
.>...,,..>.s>Lc.s,, , ,
Accesso ai dati in un dataset annidato
Di solito un campo di un dataset non collegato direttamente a un controllo associato
ai dati. Piuttosto, poich un dataset annidato non altro che un dataset, il mezzo per
accedere ai dati in esso contenuti tramite un discendente di TDataSet. Il tipo di
dataset che si utilizza determinato dal dataset genitore (quello con il campo
dataset). Ad esempio, un dataset BDE utilizza TNestedTable per rappresentare i dati
nei campi del proprio dataset, mentre i dataset client utilizzano altri dataset client.
Per accedere ai dati in un campo dataset:
1 Creare un oggetto persistente TDataSetField richiamando il Fields editor per il
dataset genitore.
2 Creare un dataset per rappresentare i valori in quel campo dataset. Deve essere di
un tipo compatibile con il dataset genitore.
3 Impostare la propriet DataSetField del dataset creato al punto 2 al campo dataset
persistente creato al punto 1.
Se il campo dataset annidato del record corrente ha un valore, il componente dataset
di dettaglio conterr record con dati annidati; in caso contrario, il dataset di dettaglio
sar vuoto.
Before inserting records into a nested dataset, you should be sure to post the
corresponding record in the master table, if it has just been inserted. If the inserted
record is not posted, it will be automatically posted before the nested dataset.
Uso dei campi riferimento
I campi riferimento memorizzano un puntatore o un riferimento a un altro oggetto
ADT. Questo oggetto ADT un singolo record di unaltra tabella oggetto. I campi
riferimento si riferiscono sempre a un unico record di un dataset (tabella oggetto). I
dati delloggetto referenziato vengono di fatto restituiti in un dataset annidato, ma
possibile accedervi tramite la propriet Fields in TReferenceField.
Visualizzazione dei campi riferimento
In un controllo TDBGrid, un campo riferimento viene rappresentato, in ciascuna cella
della colonna del dataset, con la scritta (Reference) e, in fase di esecuzione, tramite un
pulsante con puntini di sospensione a destra. In fase di esecuzione, facendo clic sul
pulsante si richiama una nuova scheda con una griglia che visualizza loggetto
associato al campo riferimento del record attivo.
Questa scheda pu anche essere richiamata da programma con il metodo
ShowPopupEditor della griglia DB. Per esempio, se la settima colonna della griglia
rappresenta un campo riferimento, il codice seguente visualizzer loggetto associato
a quel campo per il record attivo.
O p e r a z i o n i c o n i c o mp o n e n t i c a mp o 23-29
U s o d e i c a m p i o g g e t t o
.>...,,..>.s>Lc.s,, , ,
Accesso ai dati di un campo riferimento
possibile accedere ai dati in un campo riferimento in modo analogo a quello
utilizzato per accedere a un dataset annidato:
1 Creare un oggetto persistente TDataSetField richiamando il Fields editor per il
dataset genitore.
2 Creare un dataset per rappresentare il valore di quel campo di dataset.
3 Impostare la propriet DataSetField del dataset creato al punto 2 al campo dataset
persistente creato al punto 1.
Se il riferimento assegnato, il dataset conterr un unico record con i dati
referenziati. Se nullo, il dataset di riferimento sar vuoto.
possibile anche utilizzare la propriet Fields del campo riferimento per accedere ai
dati in un campo riferimento. Lesempio seguente assegna i dati del campo
riferimento CustomerRefCity a una casella di modifica di nome CityEdit:
.>cx s.c~.._>.csc.ii.c>c.s>c.s,>~s.,
Quando si modificano i dati in un campo riferimento, di fatto vengono modificati i
dati referenziati.
Per assegnare un campo riferimento, bisogna prima usare unistruzione SELECT per
selezionare il riferimento dalla tabella. Ad esempio:
~..css_c>._>cx '. ~ . ~..cssicc ~ - ~ .i
icsc',
~..css_c>,c,
s.c~..cssc.>~ss~..css_c>c.s>c.s,,
23-30 G u i d a a l l a p r o g r a mma z i o n e
U s o d e i c a m p i o g g e t t o
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-1
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
C a p i t o l o
24
Capitolo24Uso di Borland Database Engine
Borland Database Engine (BDE) un meccanismo di accesso ai dati condivisibile da
pi applicazioni. Definisce una potente libreria di chiamate API che servono a creare,
a ristrutturare, a prelevare dati da server di database locali e remoti, ad aggiornarli o
comunque a manipolarli. BDE offre uninterfaccia uniforme per laccesso a unampia
variet di server di database, utilizzando dei driver per collegarsi a vari database. A
seconda della versione di C++Builder disponibile, si utilizzeranno i driver per
database locali (Paradox, dBASE, FoxPro e Access), i driver SQL Links per server di
database remoti come InterBase, Oracle, Sybase, Informix, server Microsoft SQL e
DB2, pi un adattatore ODBC che consente di fornire driver ODBC realizzati in
proprio.
Per la distribuzione di applicazioni BDE, necessario distribuire BDE con
lapplicazione. La dimensione e la complessit dellapplicazione aumentano, ma
sono possibili sia luso condiviso con altre applicazioni BDE sia unampia gamma di
funzioni ausiliarie per la manipolazione dei database. Bench sia possibile utilizzare
lAPI di BDE direttamente nelle applicazioni, i componenti alla pagina BDE della
Component palette si incaricano di svolgere la maggior parte di queste funzionalit .
_
Per informazioni sullAPI BDE, consultare il file di guida in linea, BDE32.hlp, che si
trova nella directory dove stato installato Borland Database Engine.
Larchitettura BDE
Le applicazioni che utilizzano BDE sfruttano una variante dellarchitettura generale
di database descritta in Architettura di un database a pagina 18-6. Oltre agli
elementi dellinterfaccia utente, al datasource e ai dataset comuni a tutte le
applicazioni database C++Builder , le applicazioni BDE possono comprendere
Uno o pi componenti database per il controllo delle transazioni e la gestione delle
connessioni con il database.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-2 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
Uno o pi componenti session per isolare le operazioni di accesso ai dati come le
connessioni con il database e la gestione di gruppi di database.
Le relazioni tra i componenti di unapplicazione BDE sono illustrate in Figura 24.1:
Figura 24.1 Componenti in unapplicazione BDE
Impiego di dataset per BDE
I dataset utilizzano Borland Database Engine (BDE) per accedere ai dati. Essi
ereditano le funzionalit dei dataset comuni descritte in Capitolo 22, I dataset,
mentre sfruttano BDE per limplementazione. Inoltre, tutti i dataset per BDE
aggiungono propriet , eventi e metodi per le seguenti funzioni:
Associazione di un dataset a connessioni di database e di sessione.
Cache dei BLOB.
Ottenimento degli handle BDE.
Ci sono tre dataset per BDE:
TTable, un dataset di tipo tabella che rappresenta tutte le righe e le colonne di una
singola tabella di database. Per la descrizione delle funzioni comuni ai dataset
tabellari fare riferimento a Utilizzo dei dataset di tipo tabella a pagina 22-26. Per
la descrizione delle funzioni univoche a TTable, fare riferimento a Utilizzo di
TTable a pagina 24-5.
TQuery, un dataset di tipo query che incorpora unistruzione SQL e permette alle
applicazioni di accedere ai record risultanti, se esistono. Consultare Utilizzo di
dataset di tipo query a pagina 22-43 per la descrizione delle funzioni comuni ai
dataset di tipo query. Consultare Utilizzo di TQuery a pagina 24-9 per la
descrizione delle funzioni speciali di TQuery.
TStoredProc, un dataset di tipo procedura registrata che esegue una procedura
registrata definita su un server di database. Consultare Utilizzo di dataset di tipo
procedura registrata a pagina 22-52 per una descrizione delle funzioni comuni ai
dataset di tipo procedura registrata. Per la descrizione delle funzioni uniche di
TStoredProc consultare Utilizzo di TStoredProc a pagina 24-12.
_
Oltre ai tre tipi di dataset per BDE, esiste un dataset client basato su BDE
(TBDEClientDataSet) utilizzabile per la gestione degli aggiornamenti in cache. Per le
user
interface
elements
data source
Borland
Database
Engine
Session
database
dataset
dataset data source
Data Module Form
database
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-3
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
informazioni relative, consultare Utilizzo di un dataset client per registrare in cache
gli aggiornamenti a pagina 27-17.
Associazione di un dataset a connessioni di database e di sessione
Per prelevare i dati da un server di database, i dataset BDE utilizzano sia un database
che una sessione.
I database rappresentano connessioni a specifici server di database. Il database
identifica un certo driver BDE, un particolare server di database che lo utilizza, e
un set di parametri per la connessione al server di database. Ogni database
rappresentato da un componente TDatabase. Si possono associare i dataset a un
componente TDatabase che viene aggiunto a una scheda o a un modulo dati,
oppure semplicemente, si identifica il server di database tramite il nome e si lascia
che sia C++Builder a generare un componente database implicito. Limpiego di
componenti TDatabase creati esplicitamente raccomandato nella maggior parte
delle applicazioni, perch essi consentono di controllare meglio le modalit di
connessione, compreso il processo di login, e permettono al programmatore di
creare e di utilizzare le transazioni.
Per associare un dataset per BDE a un database, si ricorre alla propriet
DatabaseName. DatabaseName una stringa contenente informazioni diverse, a
seconda che si utilizzi un componente database esplicito, oppure, in caso
contrario, il tipo di database che si utilizza:
Se si utilizza un componente esplicito TDatabase, DatabaseName il valore della
sua propriet DatabaseName.
Se si vuole usare un componente database implicito, e il database ha un alias
BDE, si pu specificare, lalias BDE come valore di DatabaseName,. Un alias BDE
rappresenta un database, pi informazioni relative alla sua configurazione. Le
informazioni di configurazione associate a un alias sono diverse a seconda del
tipo di database (Oracle, Sybase, InterBase, Paradox, dBASE e cos via). Per
creare e gestire gli alias BDE si ricorre allo strumento BDE Administration o a
SQL Explorer.
Volendo utilizzare un componente database implicito con un database Paradox
o dBASE, possibile anche ricorrere a DatabaseName e specificare
semplicemente la directory dove sono situate le tabelle di database.
In unapplicazione, una sessione fornisce la gestione globale di un gruppo di
connessioni di database. Quando allapplicazione si aggiungono dei dataset BDE,
questa conterr automaticamente un componente session, chiamato Session. Il
database e i componenti dataset aggiunti allapplicazione sono associati
automaticamente a questa sessione predefinita. Viene anche controllato laccesso
ai file Paradox protetti da password e vengono specificate le directory per la
condivisione di file Paradox in rete. Le connessioni al database e laccesso ai file
Paradox si controllano utilizzando le propriet , gli eventi e i metodi della
sessione.
Si pu utilizzare la sessione predefinita per controllare tutte le connessioni al
database nellapplicazione. In alternativa, si aggiungono ulteriori componenti in
progettazione o si creano dinamicamente in esecuzione per controllare un
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-4 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
sottoinsieme di connessioni al database. Per associare il dataset a un componente
session esplicitamente creato, si ricorre alla propriet SessionName. Se
nellapplicazione non si utilizzano componenti session espliciti, non necessario
fornire il valore di questa propriet . Se si utilizza la sessione predefinita, o si
specifica esplicitamente una sessione mediante la propriet SessionName,
possibile accedere alla sessione associata a un dataset leggendo la propriet
DBSession.
_
Se si utilizza un componente session, la propriet SessionName di un dataset deve
corrispondere alla propriet SessionName del componente database a cui il dataset
associato.
Per ulteriori informazioni su TDatabase e su TSession, consultare Collegamento ai
database tramite TDatabase a pagina 24-13 e Gestione delle sessioni di database a
pagina 24-17.
Cache dei BLOB
I dataset BDE hanno tutti una propriet CacheBlobs che controlla se BDE registra a
livello locale i campi, quando unapplicazione legge i record BLOB. Per impostazione
predefinita, CacheBlobs true, il che significa che BDE memorizza nella cache una
copia locale dei campi BLOB. La registrazione nella cache dei campi BLOB migliora
le prestazioni dellapplicazione in quanto BDE memorizza localmente le copie dei
BLOB, invece di prelevarli ripetutamente dal server di database mano a mano che
lutente fa scorrere i record.
Nelle applicazioni e negli ambienti dove i BLOB si aggiornano o si sostituiscono
spesso e dove una vista fresca dei dati BLOB pi importante delle prestazioni,
possibile impostare CacheBlobs a false per assicurarsi che venga sempre vista la
versione pi recente di un campo BLOB.
Ottenimento degli handle BDE
possibile utilizzare dei dataset per BDE senza fare chiamate dirette alla API di
Borland Database Engine. I dataset per BDE, combinati con componenti database e di
sessione, incorporano molte funzionalit BDE. Tuttavia, se necessario fare chiamate
dirette alla API di BDE, per le risorse gestite da BDE servono gli handle BDE. Molte
API BDE richiedono questi handle come parametri.
Tutti i dataset per BDE includono tre propriet a sola lettura per laccesso in fase di
esecuzione agli handle BDE:
Handle un handle al cursor BDE che accede ai record nel dataset.
DBHandle un handle al database che contiene le tabelle o la procedura registrata
relative.
DBLocale un handle al driver BDE del linguaggio del dataset e controlla la
sequenza di ordinamento e il set di caratteri utilizzati per i dati di stringa.
Queste propriet sono assegnate automaticamente a un dataset quando questo si
collega a un server di database tramite BDE. Per ulteriori informazioni sulla API di
BDE, consultare il file della guida in linea, BDE32.HLP.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-5
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
Utilizzo di TTable
TTable incapsula la struttura completa e i dati in una tabella di database e
implementa tutte le funzionalit di base introdotte da TDataSet, come pure tutte le
funzioni speciali tipiche dei dataset di tipo tabella. Prima di analizzare le funzionalit
esclusive di TTable, conviene familiarizzare con le funzionalit comuni dei database
descritte in I dataset, compresa la sezione sui dataset tabellari che inizia a
pagina 22-26.
TTable un dataset per BDE, e quindi deve essere associato a un database e a una
sessione. Il paragrafo Associazione di un dataset a connessioni di database e di
sessione a pagina 24-3 spiega come si formano queste associazioni. Una volta che il
dataset associato a un database e a una sessione, possibile legarlo a una
particolare tabella di database impostando la propriet TableName e, se si utilizza una
tabella di testo ASCII Paradox, dBASE, FoxPro o comma-delimited, alla propriet
TableType.
_
La tabella deve essere chiusa quando si modifica la sua associazione a un database, a
una sessione o a una tabella di database, o quando si imposta la propriet TableType.
Tuttavia, prima di chiudere la tabella per modificare queste propriet , bisogna
registrare o annullare le modifiche in attesa. Se sono abilitati gli aggiornamenti in
cache, bisogna chiamare il metodo ApplyUpdates per scrivere nel database le
modifiche richieste.
I componenti TTable offrono un supporto ineguagliabile per la gestione delle tabelle
di database locali (Paradox, dBASE, FoxPro e tabelle di testo ASCII comma-
delimited). Qui di seguito sono riportati le propriet e i metodi speciali che
implementano questo supporto.
Inoltre, i componenti TTable possono sfruttare il supporto BDE per le operazioni in
batch (operazioni a livello di tabella per aggiungere, aggiornare, cancellare o copiare
interi gruppi di record). Largomento trattato in Importazione di dati da altre
tabelle a pagina 24-8.
Specifica del tipo di tabella per tabelle locali
Se unapplicazione accede a tabelle Paradox, dBASE, FoxPro o di testo ASCII comma-
delimited, allora BDE utilizza la propriet TableType per determinare il tipo di tabella
(la sua struttura prevista). TableType non viene usato quando TTable rappresenta una
tabella a base SQL su un server di database.
Per impostazione predefinita, TableType impostato a ttDefault. In questo caso, BDE
determina il tipo di tabella dalla sua estensione. La Tabella 24.1 riporta le estensioni
riconosciute da BDE, e le ipotesi che fa sul tipo della tabella:
Tabella 24.1 Tipi di tabella riconosciuti da BDE in base allestensione del file
Estensione Tipo di tabella
No file extension Paradox
.DB Paradox
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-6 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
Se le tabelle di testo Paradox, dBASE e ASCII locali utilizzano le estensioni file come
descritto in Tabella 24.1, possibile lasciare TableType impostato su ttDefault.
Altrimenti, lapplicazione deve impostare TableType in modo da indicare il tipo di
tabella corretto. In Tabella 24.2 sono indicati i valori che possibile assegnare a
TableType:
Controllo dellaccesso a tabelle locali in lettura/scrittura
Come qualsiasi dataset di tipo tabella, TTable permette di controllare laccesso in
lettura e in scrittura da parte dellapplicazione tramite la propriet ReadOnly.
Inoltre, nel caso di tabelle Paradox, dBASE e FoxPro, TTable consente di controllare
laccesso in lettura e in scrittura alle tabelle da parte di altre applicazioni. La
propriet Exclusive determina se lapplicazione ottiene laccesso esclusivo in lettura/
scrittura a una tabella Paradox, dBASE o FoxPro. Allo scopo, si imposta a true la
propriet Exclusive del componente tabella prima di aprire la tabella. Se si riesce ad
aprire una tabella per accesso esclusivo, le altre applicazioni non possono n leggere
n scrivere dati nella tabella. La richiesta di accesso esclusivo non viene concessa
quando la tabella gi in uso.
Le seguenti istruzioni aprono una tabella per accesso esclusivo:
s.csicc>xcsc ttae, .c ccs . cxcsc c.
s.csicc>~cc ttae, .. ,c c icc
_
possibile tentare di impostare la propriet Exclusive su tabelle SQL, ma alcuni
server non supportano il blocco esclusivo a livello di tabella. Altri server concedono il
blocco esclusivo, ma consentono ad altre applicazioni di leggere i dati dalla tabella.
Per ulteriori informazioni sul blocco esclusivo di tabelle di database su un server,
consultare la documentazione del server.
Specifica di file indice dBASE
Nella maggior parte dei server, per specificare un indice si utilizzano i metodi
comuni a tutti i dataset tabellari, descritti in Ordinamento dei record con indici a
pagina 22-27.
.DBF dBASE
.TXT ASCII text
Tabella 24.2 Valori di TableType
Valore Tipo di tabella
ttDefault Tipo di tabella determinato automaticamente da BDE
ttParadox Paradox
ttDBase dBASE
ttFoxPro FoxPro
ttASCII Testo ASCII Comma-delimited
Tabella 24.1 Tipi di tabella riconosciuti da BDE in base allestensione del file (continua)
Estensione Tipo di tabella
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-7
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
Tuttavia, per le tabelle dBASE che utilizzano file indice aggiunti, oppure indici tipo
dBASE III PLUS (*.NDX), necessario invece utilizzare le propriet IndexFiles e
IndexName. Alla propriet IndexFiles si assegna il nome del file indice aggiunto, o si
elencano i file.NDX. Poi si specifica un indice nella propriet IndexName per fare in
modo che ordini attivamente il dataset.
In fase di progetto, si fa clic sul pulsante ellissi (...)nel valore della propriet IndexFiles
di Object Inspector per richiamare lIndex Files editor. Per aggiungere un file indice
aggiunto o un file .NDX si fa clic sul pulsante Add nella finestra di dialogo Index
Files e si seleziona il file nella finestra di dialogo Open. La procedura va ripetuta per
ogni file indice non di produzione o .NDX. Dopo avere aggiunto tutti gli indici
desiderati si fa clic sul pulsante OK della finestra di dialogo Index Files.
La stessa operazione pu essere eseguita da programma in fase di esecuzione. Allo
scopo, si accede alla propriet IndexFiles utilizzando le propriet e i metodi delle liste
di stringhe. Quando si aggiunge un nuovo gruppo di indici, prima si chiama il
metodo Clear della propriet IndexFiles della tabella per rimuovere eventuali voci
inserite. Si chiama il metodo Add per aggiungere ogni file indice non di produzione o
file .NDX:
icc.>L.cxcs>ci,
icc.>L.cxcs>~..'sic.x',
icc.>L.cxcs>~..'.,.x',
icc.>L.cxcs>~..'i.c.x',
icc.>L.cxcs>~..'._i.c.x',
Dopo avere aggiunto gli eventuali file indice non di produzione o .NDX, diventano
disponibili i nomi dei singoli indici nel file indice ed possibile assegnarli alla
propriet IndexName. I tag indice vengono elencati anche quando si utilizza il metodo
GetIndexNames ed quando si esaminano le definizioni di indice attraverso gli oggetti
TIndexDef nella propriet IndexDefs. I file .NDX elencati correttamente vengono
aggiornati automaticamente mano a mano che i dati vengono aggiunti, modificati o
cancellati nella tabella (indipendentemente dal fatto che la propriet IndexName
utilizzi o meno un certo indice).
Nellesempio qui riportato, il componente IndexFiles del componente tabella
AnimalsTable impostato al file indice non di produzione ANIMALS.MDX e quindi
la sua propriet IndexName impostata al tag indice chiamato NAME:
~.isicc>L.cxcs>~..~.L.~...,
~.isicc>L.cx.i.c '.~.',
Una volta che si specificato il file indice, lutilizzo di indici non di produzione o
.NDX non differisce da quello di qualsiasi altro indice. Specificando un nome indice
si ordinano i dati nella tabella rendendoli disponibili per ricerche indicizzate, per
intervalli e (nel caso di indici non di produzione) per collegamenti master-detail. Per
i dettagli su questo modo di usare gli indici, consultare Utilizzo dei dataset di tipo
tabella a pagina 22-26.
Quando si utilizzano indici .NDX, in stile dBASE III, con componenti TTable vanno
tenute presenti due considerazioni particolari. La prima che i file .NDX non si
possono usare come base per collegamenti master-detail. La seconda che quando si
attiva un indice .NDX con la propriet IndexName, necessario includere lestensione
.NDX nel valore della propriet come parte del nome dellindice:
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-8 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
icc>L.cx.i.c '.ic..',
icc '.',
icc>.c, ,
Come rinominare tabelle locali
Per rinominare in fase di progettazione le tabelle Paradox o dBASE, si fa clic con il
pulsante destro sul componente tabella e si seleziona Rename Table nel menu di
scelta rapida.
Per rinominare in fase di esecuzione le tabelle Paradox o dBASE, si chiama il metodo
RenameTable della tabella. Ad esempio, con la seguente istruzione si rinomina la
tabella Customer in CustInfo:
s.c>ci.ciccsL.,
Importazione di dati da altre tabelle
Per importare dati da unaltra tabella si utilizza il metodo BatchMove di un
componente tabella. BatchMove pu
Copiare nella tabella attiva dei record da unaltra tabella.
Aggiornare nella tabella attiva dei record che si trovano in unaltra tabella.
Aggiungere alla fine della tabella attiva dei record di unaltra tabella.
Cancellare nella tabella attiva dei record che si trovano in unaltra tabella.
BatchMove accetta due parametri: il nome della tabella da cui importare i dati e una
specifica di modo che determina quale operazione di importazione eseguire. La
Tabella 24.3 mostra le possibili impostazioni della specifica di modo:
Ad esempio, con questo codice si aggiornano tutti i record della tabella attiva con
record della tabella Customer che hanno gli stessi valori per i campi dellindice attivo:
icc>ic.c.., ci,.ic,
BatchMove restituisce il numero di record importati con successo.
j
Importando record con il modo batCopy si sovrascrivono i record esistenti. Per
conservarli si ricorre invece a batAppend.
Tabella 24.3 Modalit di importazione di BatchMove
Valore Significato
batAppend Aggiunge tutti i record dalla tabella sorgente alla fine della tabella attiva.
batAppendUpdate Aggiunge tutti i record dalla tabella sorgente alla fine della tabella attiva e
aggiorna nella tabella attiva i record esistenti con record corrispondenti
della tabella sorgente.
batCopy Copia nella tabella attiva tutti i record della tabella sorgente.
batDelete Cancella tutti i record della tabella attiva presenti anche nella tabella
sorgente.
batUpdate Aggiorna i record esistenti nella tabella attiva con record corrispondenti
della tabella sorgente.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-9
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
BatchMove esegue solo alcune delle operazioni batch supportate da BDE. Il
componente TBatchMove dispone di ulteriori funzioni. Se necessario spostare una
grande quantit di dati tra tabelle, preferibile utilizzare TBatchMove invece di
chiamare un metodo BatchMove. Per informazioni sullutilizzo di TBatchMove,
consultare Utilizzo di TBatchMove a pagina 24-50.
Utilizzo di TQuery
TQuery rappresenta una singola istruzione Data Definition Language (DDL) o Data
Manipulation Language (DML) (ad esempio, un comando SELECT, INSERT,
DELETE, UPDATE, CREATE INDEX o ALTER TABLE). Il linguaggio nei comandi
dipende dal server, ma di solito conforme allo standard SQL-92 del linguaggio
SQL. TQuery implementa tutte le funzionalit di base introdotte da TDataSet, come
pure tutte le funzionalit speciali tipiche dei dataset di tipo query. Prima di
analizzare le funzionalit esclusive di cui TQuery dispone, bene prendere
familiarit con le funzioni database fondamentali descritte in I dataset, tra cui la
sezione sui dataset di tipo query che inizia a pagina 22-43.
Siccome TQuery un dataset per BDE, si deve di solito associarlo a un database e a
una sessione. (Lunica eccezione quando si utilizza TQuery per una query
eterogenea). Il paragrafo Associazione di un dataset a connessioni di database e di
sessione a pagina 24-3 descrive come si formano queste associazioni. Si specifica
listruzione SQL della query impostando la propriet SQL.
Un componente TQuery pu accedere a dati in:
Tabelle Paradox o dBASE, utilizzando Local SQL, che fa parte di BDE. Local SQL
un sottoinsieme delle specifiche SQL-92. Supporta la maggior parte del DML e una
porzione di DDL sufficiente a funzionare con questi tipi di tabelle. Per i dettagli
sulla sintassi SQL supportata, consultare la guida SQL locale, LOCALSQL.HLP..
Database locali InterBase Server, utilizzando il motore InterBase. Per informazioni
sul supporto della sintassi SQL standard e della sintassi estesa SQL-92 di
InterBase, consultare Language Reference di InterBase.
Database su server di database remoti come Oracle, Sybase, MS-SQL Server,
Informix, DB2 e InterBase. Per accedere a un server remoto necessario installare
il driver SQL Link e appropriato e il software client (fornito dal produttore)
specifico per il server di database. Viene accettata qualsiasi sintassi standard SQL
supportata da questi server. Per informazioni sulla sintassi SQL, sulle sue
limitazioni ed estensioni, fare riferimento alla documentazione del server in
questione.
Creazione di query eterogenee
TQuery supporta query eterogenee verso pi server o pi tipi di tabella (ad esempio,
dati da una tabella Oracle e da una tabella Paradox). Quando si esegue una query
eterogenea, BDE analizza ed elabora la query utilizzando Local SQL e per questa
ragione non supportata la sintassi SQL specifica del server.
Per eseguire una query eterogenea, seguire questi passi:
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-10 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
1 Definire alias BDE distinti per ogni database cui si deve accedere nella query
utilizzando lo strumento BDE BDE Administration o SQL Explorer.
2 Lasciare in bianco la propriet DatabaseName di TQuery; i nomi dei database
utilizzati saranno specificati nellistruzione SQL.
3 Nella propriet SQL, specificare listruzione SQL da eseguire. Far precedere ogni
nome di tabella nellistruzione con lalias BDE del database della tabella, racchiuso
tra segni di due punti. Lintero riferimento viene poi racchiuso tra virgolette.
4 Impostare i parametri della query nella propriet Params.
5 Chiamare Prepare per preparare la query all esecuzione prima di eseguirla per la
prima volta.
6 Chiamare Open o ExecSQL, a seconda del tipo di query che si esegue.
Ad esempio, si supponga di definire un alias chiamato Oracle1 per un database
Oracle che ha una tabella CUSTOMER e Sybase1 per un database Sybase che ha una
tabella ORDERS. Una semplice query verso queste due tabelle sarebbe:
. s.cs., .cs.c.
. icc..
L. .cisc.
. s.cs. .css.
- s.cs.
Come alternativa allutilizzo di un alias BDE per specificare il database in una query
eterogenea, si pu utilizzare un componente TDatabase. Configurare il TDatabase
come normale per puntare al database, impostare il TDatabase.DatabaseName a un
valore arbitrario ma univoco, quindi utilizzarlo nellistruzione SQL al posto del nome
dellalias BDE.
Ottenimento di un set risultato modificabile
Per richiedere un set risultato che gli utenti possono editare in controlli data-aware,
impostare a true la propriet RequestLive di un componente query. Limpostazione di
RequestLive a true non garantisce un set risultato live ma BDE fa il possibile per
rispettare la richiesta. Le richieste di set risultato live sono soggette ad alcune
limitazioni, a seconda che la query utilizzi il parser locale SQL, o un parser SQL del
server.
Le query in cui i nomi di tabella sono preceduti da un alias di database BDE (come
nelle query eterogenee) e le query eseguite verso Paradox o dBASE, sono
analizzate da BDE utilizzando Local SQL. Quando le query utilizzano il parser di
Local SQL, BDE offre un supporto esteso per set risultato aggiornabili e live sia
nelle tabelle singole che nelle query multitabella. Quando si utilizza Local SQL,
una query su una singola tabella o vista restituisce un set risultato live se non
contiene:
DISTINCT nella clausola SELECT
Join (interno, esterno, o UNION)
Funzioni di aggregazione con o senza clausole GROUP BY o HAVING
Tabelle o viste base non aggiornabili
Sottoquery
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-11
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
Clausole ORDER BY non basate su un indice
Le query verso un server di database remoto vengono analizzate dal server. Se la
propriet RequestLive impostata a true, listruzione SQL deve attenersi agli
standard Local SQL, oltre a rispettare tutte le limitazioni imposte dal server,
perch BDE deve utilizzarla per convogliare alla tabella i dati modificati. Una
query su una singola tabella o vista restituisce un set risultato live se la query
non contiene:
Una clausola DISTINCT nellistruzione SELECT
Funzioni aggregate, con o senza clausole GROUP BY o HAVING
Riferimenti a pi tabelle base o viste aggiornabili (concatenamenti)
Subquery che fanno riferimento alla tabella nella clausola FROM o altre tabelle
Se unapplicazione richiede e riceve un set risultato live, la propriet CanModify del
componente query impostata a true. La query, anche se restituisce un set risultato
live, potrebbe non essere in grado di aggiornare direttamente il set risultato nel
caso contenesse campi collegati o se si commutassero gli indici prima di tentare
laggiornamento. In presenza di queste condizioni, il set risultato andrebbe trattato
come se fosse a sola lettura e andrebbe aggiornato di conseguenza.
Se unapplicazione richiede un set risultato live, ma la sintassi dellistruzione
SELECT non lo consente, BDE restituisce
Un set risultato a sola lettura nel caso di query rivolte a Paradox o a dBASE.
Un codice di errore nel caso di query SQL rivolte a un server remoto.
Aggiornamento di set risultato a sola lettura
Le applicazioni possono aggiornare dati restituiti in un set risultato a sola lettura se
utilizzano gli aggiornamenti in cache.
Se per gli aggiornamenti in cache si utilizza un dataset client, questo, o il provider
associato pu generare automaticamente lo SQL per effettuare gli aggiornamenti, a
meno che la query non rappresenti pi tabelle. In questo caso, necessario indicare
come applicare gli aggiornamenti:
Se tutti gli aggiornamenti sono applicati a una sola tabella di database, possibile
indicare alla tabella in questione laggiornamento tramite un gestore di evento
OnGetTableName.
Se gli aggiornamenti vanno tenuti sotto stretto controllo, si pu associare la query
a un oggetto update (TUpdateSQL). Un provider utilizza automaticamente questo
oggetto update per applicare gli aggiornamenti:
1 Associare loggetto update alla query, applicando la propriet UpdateObject
della query alloggetto TUpdateSQL che si utilizza.
2 Impostare le propriet ModifySQL, InsertSQL e DeleteSQL delloggetto update a
istruzioni SQL che eseguono gli opportuni aggiornamenti dei dati della query.
Se si utilizza BDE per gli aggiornamenti in cache, necessario utilizzare un oggetto
update.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-12 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
_
Per ulteriori informazioni sullutilizzo di oggetti update, consultare Aggiornamento
di dataset mediante oggetti update a pagina 24-41.
Utilizzo di TStoredProc
TStoredProc rappresenta una procedura registrata e implementa tutte le funzionalit
di base introdotte da TDataSet, in aggiunta alla maggior parte delle funzioni speciali
tipiche dei dataset di tipo procedura registrata. Prima di studiare le funzioni
esclusive introdotte da TStoredProc, bene impadronirsi delle funzionalit database
comuni descritte in I dataset,, compresa la sezione sui dataset di tipo procedura
registrata che inizia a pagina pagina 22-52.
TStoredProc un dataset per BDE, per cui va associato a un database e a una sessione.
Il paragrafo Associazione di un dataset a connessioni di database e di sessione a
pagina 24-3 spiega come formare queste associazioni. Una volta associato il dataset
a un database e a una sessione, possibile collegarlo a una particolare procedura
registrata impostando la propriet StoredProcName.
TStoredProc differisce dagli altri dataset di tipo procedura registrata per queste
ragioni:
Consente di controllare meglio la connessione dei parametri.
Supporta le procedure registrate ridefinite Oracle.
Inglobamento dei parametri
Quando una procedura registrata viene preparata ed eseguita, i relativi parametri di
input sono collegati automaticamente a parametri sul server.
TStoredProc consente di usare la propriet ParamBindMode per specificare in che
modo collegare i parametri ai parametri sul server. Per impostazione predefinita
ParamBindMode impostato a pbByName, cio i parametri provenienti dal
componente procedura registrata corrispondono per nome a del server. Questo il
metodo pi facile di collegare i parametri.
Determinati server supportano anche i parametri di connessione secondo il valore
ordinale, cio secondo lordine in cui i parametri vengono visualizzati nella
procedura registrata. In questo caso, significativo lordine in cui si specificano i
parametri nelleditor di raccolta dei parametri. Il primo parametro specificato
corrisponde al primo parametro di input sul server, il secondo parametro al secondo
parametro di input sul server, e cos via. Se il server supporta la connessione di
parametri secondo il valore ordinale, si pu impostare ParamBindMode a
pbByNumber.
_
Se si desidera impostare ParamBindMode a pbByNumber, necessario specificare i tipi
di parametro corretti nellordine corretto. Nello SQL Explorer si pu visualizzare il
codice sorgente di una procedura registrata di un server per determinare lordine
corretto e il tipo di parametri da specificare.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-13
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
Operazioni con procedure registrate ridefinite di Oracle
I server Oracle consentono la ridefinizionedelle procedure registrate; le procedure
ridefinite sono procedure diverse che hanno lo stesso nome. La propriet Overload del
componente procedura registrata permette a unapplicazione di specificare quale
procedura eseguire.
Se Overload zero (limpostazione predefinita), si presume che non vi sia nessuna
ridefinizione. Se Overload uno (1), il componente procedura registrata esegue la
prima procedura registrata che trova sul server Oracle contenente il nome ridefinito;
se due (2), esegue la seconda, e cos via.
_
Le procedure registrate ridefinite accettano parametri di input e di output diversi.
Per ulteriori informazioni, fare riferimento alla documentazione del server Oracle.
Collegamento ai database tramite TDatabase
Quando unapplicazione C++Builder utilizza Borland Database Engine (BDE) per
collegarsi a un database, la connessione incorporata in un componente TDatabase.
Un componente database rappresenta la connessione a un singolo database, nel
contesto di una sessione BDE.
TDatabase esegue molte delle attivit di altri componenti di connessione ai database
con i quali ha in comune molte propriet , metodi ed eventi. Propriet , metodi ed
eventi comuni sono spiegati nel Capitolo 21, Connessione ai database..
In aggiunta a questo, TDatabase introduce molte funzioni specifiche di BDE, che
vengono descritte qui di seguito.
Associazione di un componente database a una sessione
Tutti i componenti database devono essere associati a una sessione BDE. Per stabilire
lassociazione si ricorre a SessionName. Quando si crea un componente database in
fase di progetto, SessionName impostato a Default, il che significa che associato
al componente session predefinito che referenziato dalla variabile globale Session.
Le applicazioni multithread o reentrant BDE possono richiedere pi di una sessione.
Se necessario utilizzare sessioni multiple, bisogna aggiungere componenti TSession
per ciascuna sessione. Poi si associata il dataset a un componente session impostando
la propriet SessionName alla propriet SessionName di un componente session.
In esecuzione, si accede al componente session cui il database associato leggendo la
propriet Session. Se SessionName vuoto o ha il valore Default, allora la propriet
Session fa riferimento alla stessa istanza TSession referenziata dalla variabile globale
Session. Session consente alle applicazioni di accedere alle propriet , ai metodi e agli
eventi del componente session superiore di un componente database senza conoscere
il nome effettivo della sessione.
Per ulteriori informazioni sulle sessioni BDE, vedere Gestione delle sessioni di
database a pagina 24-17.
Se si utilizza un componente database implicito, la sessione relativa per quel
componente database quella specificata dalla propriet SessionName del dataset.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-14 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
Interazioni tra il componente Session e i database
Di solito, le propriet del componente session determinano i comportamenti globali e
predefiniti applicati a tutti i componenti database impliciti creati in fase di
esecuzione. Ad esempio, la propriet KeepConnections della sessione controllante
determina se la connessione con un database rimane attiva anche quando sono chiusi
i dataset associati (impostazione predefinita), o se i collegamenti vengono interrotti
quando tutti i suoi dataset sono chiusi. Similmente, levento predefinito OnPassword
di una sessione garantisce che quando unapplicazione tenta di collegarsi a un
database su un server che richiede una password, appare una finestra di dialogo
standard con la richiesta di indicare la password.
Lapplicazione dei metodi della sessione piuttosto diversa. I metodi di TSession
influiscono su tutti i componenti database, sia che vengano creati esplicitamente
oppure istanziati implicitamente da un dataset. Ad esempio, il metodo di sessione
DropConnections chiude tutti i dataset che appartengono ai componenti database di
una sessione, poi interrompe tutti i collegamenti con il database, anche se la propriet
KeepConnection per singoli componenti database true.
I metodi dei componenti database si applicano solo ai dataset associati a un
determinato componente database. Ad esempio, si supponga che il componente
database Database1 sia associato alla sessione predefinita. Database1->CloseDataSets()
chiude solo i dataset associati a Database1. I dataset aperti appartenenti ad altri
componenti database allinterno della sessione predefinita rimarranno aperti.
Identificazione del database
AliasName e DriverName sono propriet reciprocamente esclusive che identificano il
server di database cui si collega il componente TDatabase.
AliasName specifica il nome di un alias BDE esistente da usare con il componente
database. Lalias appare in liste a discesa successive dei componenti dataset
consentendo la connessione al componente database desiderato. Se si specifica
AliasName di un componente database, leventuale valore assegnato a DriverName
viene cancellato perch il nome del driver fa sempre parte di un alias BDE.
Gli alias BDE si creano e si modificano con Database Explorer o con il programma
di utilit BDE Administration. Per ulteriori informazioni sulla creazione e la
manutenzione degli alias BDE, consultare la relativa documentazione in linea.
DriverName il nome di un driver BDE. Un nome di driver un parametro in un
alias BDE , ma si pu specificare il nome del driver invece dellalias quando si crea
lalias locale BDE di un componente database utilizzando la propriet
DatabaseName. Specificando DriverName, leventuale valore precedentemente
assegnato ad AliasName viene cancellato per evitare potenziali conflitti tra il nome
del driver che si specifica e quello che fa parte dellalias BDE identificato in
AliasName.
DatabaseName consente di fornire il nome di una connessione a un database. Il nome
fornito si aggiunge ad AliasName o a DriverName ed locale allapplicazione.
DatabaseName pu essere un alias BDE, o, nel caso di file Paradox e dBASE, il nome
completo del percorso. Come AliasName, DatabaseName viene visualizzato in liste a
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-15
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
discesa di componenti dataset in modo da consentire la connessione ai componenti
database.
In progettazione, per specificare un alias BDE, si assegna un driver BDE o si crea un
alias locale BDE, facendo doppio clic su un componente database e richiamando cos
Database Properties editor.
possibile immettere un DatabaseName nella casella di modifica Name nelleditor
delle propriet . Si pu immettere un nome di alias BDE esistente nella casella
combinata nome Alias della propriet Alias oppure selezionare tra gli alias esistenti
nella lista a discesa. La casella combinata Driver name permette di immettere il nome
di un driver BDE esistente per la propriet DriverName, o altrimenti di scegliere tra i
nomi dei driver esistenti nella lista a discesa.
_
Leditor Database Properties permette anche di visualizzare e di impostare i
parametri di connessione BDE e di impostare gli stati delle propriet LoginPrompt e
KeepConnection. Per informazioni sui parametri di connessione, consultare
Impostazione dei parametri degli alias BDE qui di seguito. Per informazioni su
LoginPrompt, consultare Controllo del login al server a pagina 21-4. Per
informazioni su KeepConnection consultare Apertura di una connessione utilizzando
TDatabase a pagina 24-16.
Impostazione dei parametri degli alias BDE
In progettazione possibile creare o modificare i parametri di connessione in tre
modi:
Utilizzare il programma di utilit Database Explorer o BDE Administration per
creare o modificare alias BDE, tra cui i parametri. Per ulteriori informazioni su
questi programmi di utilit , consultare i relativi file della Guida in linea.
Richiamare leditor String List facendo doppio clic sulla propriet Params
nellObject Inspector.
Richiamare leditor Database Properties facendo doppio clic su un componente
database in un modulo dati o in una scheda.
Con tutti questi metodi si pu modificare la propriet Params del componente
database. Params una lista di stringhe che contiene i parametri di connessione al
database relativi allalias BDE associato a un componente database. Alcuni parametri
di connessione tipici comprendono percorso, nome server, dimensione della cache di
schema, driver di linguaggio e modalit della query SQL.
Quando si richiama il Database Properties editor, i parametri dellalias BDE non sono
visibili. Per vedere le impostazioni attive, fare clic su Defaults. I parametri attivi
vengono visualizzati nel riquadro di nota Parameter overrides. possibile
modificare le voci esistenti o aggiungerne di nuove. Per cancellare i parametri
esistenti, fare clic su Clear. Le modifiche apportate agiscono quando si fa clic su OK.
In fase di esecuzione, unapplicazione pu impostare i parametri alias solo
modificando direttamente la propriet Params. Per ulteriori informazioni su
parametri specifici per limpiego dei di driver SQL Links con BDE, consultare il file
della guida in linea SQL Links.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-16 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
Apertura di una connessione utilizzando TDatabase
Come avviene per tutti i componenti di connessione ai database, per collegarsi a un
database mediante TDatabase si imposta la propriet Connected a true o si chiama il
metodo Open. La procedura descritta in Connessione a un server di database a
pagina 21-3. Una connessione, una volta che stabilita, rimane attiva fino a quando
almeno un dataset attivo. Quando non ci sono pi dataset attivi, la connessione
viene interrotta, a meno che non sia true la propriet KeepConnection del componente
database.
Quando da unapplicazione ci si collega a un server di database remoto,
lapplicazione stabilisce la connessione tramite BDE e il driver Borland SQL Links.
(BDE pu anche comunicare con un driver ODBC che bisogna fornire). Prima di
stabilire la connessione bisogna configurare il driver SQL Links o ODBC
dellapplicazione. I parametri SQL Links e ODBC sono memorizzati nella propriet
Params del componente database. Per informazioni su parametri SQL Links,
consultare SQL Links Users Guide. Per modificare la propriet Params, consultare
Impostazione dei parametri degli alias BDE a pagina 24-15.
Operazioni con i protocolli di rete
Per configurare il driver SQL Links o ODBC appropriato, pu essere necessario
specificare il protocollo di rete utilizzato dal server, come SPX/IPX o TCP/IP, a
seconda delle opzioni di configurazione del driver. Nella maggior parte dei casi, la
configurazione del protocollo di rete si gestisce tramite il software di installazione
client del server. Nel caso di ODBC potrebbe anche essere necessario controllare
linstallazione del driver tramite il driver manager di ODBC.
Stabilire il collegamento tra client e server a volte problematico. La seguente lista
delle anomalie di funzionamento si rivela utile se si incontrano difficolt :
La connessione dal lato client del server configurata correttamente?
I DLL dei driver di connessione e di database si trovano nel percorso di ricerca?
Se si utilizza TCP/IP:
Il software di comunicazione TCP/IP stato installato? stato installato il
WINSOCK.DLL corretto?
Lindirizzo IP del server registrato nel file HOSTS del client?
Il Domain Name Services (DNS) configurato correttamente?
possibile eseguire il ping sul server?
Per maggiori informazioni sulla ricerca delle anomalie, consultare SQL Links Users
Guide e la documentazione del server.
Uso di ODBC
Unapplicazione pu utilizzare delle sorgenti dati ODBC (ad esempio, Btrieve). Una
connessione tramite un driver ODBC richiede
Un driver ODBC acquistabile separatamente.
Il Microsoft ODBC Driver Manager.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-17
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
Il programma di utilit BDE Administration.
Per configurare un alias BDE di una connessione driver ODBC, si utilizza il
programma di utilit BDE Administration. Per ulteriori informazioni, consultare la
guida in linea del programma di utilit BDE Administration.
Impiego di componenti database nei moduli dati
I componenti database si inseriscono in tutta sicurezza nei moduli dati. Tuttavia, se si
mette nellObject Repository un modulo dati contenente un componente database e si
desidera che altri utenti siano in grado di ereditare da esso, necessario impostare a
true la propriet HandleShared del componente database per evitare conflitti di spazio
di nome globali.
Gestione delle sessioni di database
Le connessioni di database di unapplicazione BDE, i driver, i cursori, le query, e cos
via sono gestite allinterno del contesto di una o pi sessioni BDE. Le sessioni isolano
un gruppo di operazioni di accesso al database, come i collegamenti, senza la
necessit di avviare unaltra istanza dellapplicazione.
Tutte le applicazioni database BDE includono automaticamente un componente
session predefinito, chiamato Session, che comprende la sessione BDE predefinita. I
componenti database aggiunti allapplicazione vengono associati automaticamente
alla sessione predefinita (osservare che il suo SessionName Default). La sessione
predefinita fornisce il controllo totale di tutti i componenti database non associati a
unaltra sessione, sia che siano impliciti (creati dalla sessione in esecuzione
allapertura di un dataset non associato a un componente database creato) o stabili
(creati esplicitamente dallapplicazione). In fase di progetto, la sessione predefinita
non visibile nel modulo dati o nella scheda, ma in fase di esecuzione possibile
accedere alle sue propriet e ai suoi metodi nel codice.
Per utilizzare la sessione predefinita, non si deve scrivere alcun codice, a meno che
lapplicazione non debba
Attivare esplicitamente o disattivare una sessione, attivando o disattivando la
capacit di aprirsi dei database della sessione.
Modificare le propriet della sessione, come la specifica delle propriet predefinite
dei componenti database generati implicitamente.
Eseguire i metodi di una sessione, come la gestione dei collegamenti al database
(ad esempio aprendo e chiudendo la connessione in risposta ad azioni dellutente).
Rispondere a eventi di sessione, come avviene quando lapplicazione tenta di
accedere a una tabella Paradox o dBASE protetta da password.
Indicare la directory secondo le specifiche Paradox, come la propriet NetFileDir
per accedere a tabelle Paradox in rete e la propriet PrivateDir sullo hard disk
locale per per migliorare le prestazioni.
Gestire gli alias BDE che descrivono possibili configurazioni di connessione al
database, relativamente a database e a dataset che utilizzano la sessione.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-18 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
Sia che si aggiungano componenti database a unapplicazione in fase di
progettazione, sia che si creino dinamicamente in fase di esecuzione, essi vengono
associati automaticamente alla sessione predefinita, a meno che non li si assegni
specificatamente a una sessione diversa. Se si apre un dataset non associato a un
componente database, Delphi automaticamente
Crea per esso un componente database in fase di esecuzione.
Associa il componente database alla sessione predefinita.
Inizializza alcune propriet chiave del componente database in base alle propriet
della sessione predefinita. Una delle pi importanti KeepConnections, che
determina quando unapplicazione deve mantenere attivo o chiudere i
collegamenti.
La sessione predefinita fornisce un insieme ampiamente applicabile di impostazioni
predefinite utilizzabili cos come sono nella maggior parte delle applicazioni.
necessario solo associare un componente database a una sessione esplicitamente
chiamata, se il componente esegue una query simultanea verso un database gi
aperto dalla sessione predefinita. In questo caso, ogni query simultanea va eseguita
in una propria sessione. Anche le applicazioni database multithread richiedono
sessioni multiple, in cui ogni thread ha la propria sessione.
Le applicazioni possono creare ulteriori componenti session in base alle necessit . Le
applicazioni database BDE includono automaticamente un componente session list,
chiamato Sessions, utilizzabile per gestire tutti i componenti session. Per ulteriori
informazioni sulla gestione di sessioni multiple, consultare Gestione di sessioni
multiple a pagina 24-29.
I componenti session si possono mettere senza problemi anche nei moduli dati. Se si
mette un modulo dati che contiene uno o pi componenti session nellObject
Repository, tuttavia, bisogna assicurarsi che la propriet AutoSessionName sia true
per evitare conflitti di nome quando gli utenti ereditano da esso.
Attivazione di una sessione
Active una propriet Boolean che determina se il database e i componenti dataset
associati a una sessione sono aperti. La propriet pu servire per leggere lo stato
corrente delle connessioni del database e del dataset di una sessione o per
modificarlo. Se Active false (limpostazione predefinita), tutti i database e tutti i
dataset associati alla sessione sono chiusi. Se true, database e dataset sono aperti.
Una sessione viene attivata quando la si crea e, successivamente, ogni volta che la sua
propriet Active viene modificata a true da false (ad esempio, quando un database o
un dataset associato con una sessione aperta e non ci sono altri database o dataset
aperti). Impostando Active a true si innesca levento OnStartup della sessione, si
registrano le posizioni di directory Paradox con BDE e si registra la propriet
ConfigMode, che determina quali alias BDE sono disponibili allinterno della sessione.
possibile scrivere un gestore di evento OnStartup per inizializzare le propriet
NetFileDir, PrivateDir e ConfigMode prima che esse siano registrate con BDE, o per
eseguire altre specifiche attivit di avvio. Per informazioni sulle propriet NetFileDir
e PrivateDir, consultare Specifica delle ubicazioni delle directory di Paradox a
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-19
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
pagina 24-25. Per informazioni su ConfigMode, consultare Operazioni con gli alias
BDE a pagina 24-25.
Una volta attivata la sessione, possibile aprire le sue connessioni con il database
chiamando il metodo OpenDatabase.
Nel caso di componenti session inseriti in un modulo dati o in una scheda,
impostando Active a false si chiudono i database o i dataset aperti. In fase di
esecuzione, la chiusura dei database e dei dataset attiva gli eventi associati.
_
In fase di progettazione, non consentito impostare Active a false per la sessione
predefinita. Sebbene sia possibile chiudere la sessione predefinita in fase di
esecuzione, sconsigliabile farlo.
In fase di esecuzione, si possono anche utilizzare i metodi Open e Close di una
sessione per attivare o disattivare sessioni diverse dalla sessione predefinita. Ad
esempio, con questunica riga di codice si chiudono tutti i database e i dataset aperti
di una sessione:
.css>sc,
Questo codice imposta la propriet Active di Session1 a false. Quando la propriet
Active di una sessione false, un ulteriore tentativo dellapplicazione di aprire un
database o un dataset reimposta Active a true e chiama il gestore di evento OnStartup
della sessione, se esiste. possibile anche codificare esplicitamente la riattivazione
della in fase di esecuzione. Il seguente codice riattiva Session1:
.css>,c,
_
Quando una sessione attiva si possono aprire e chiudere i singoli collegamenti al
database. Per ulteriori informazioni, consultare Chiusura delle connessioni con il
database a pagina 24-20.
Specifica del comportamento predefinito della connessione al database
KeepConnections fornisce il valore predefinito della propriet KeepConnection dei
componenti database impliciti creati in fase di esecuzione. KeepConnection specifica
che cosa accade a una connessione di database stabilita per un componente database
quando tutti i suoi dataset sono chiusi. Se true (limpostazione predefinita), si
stabilisce una connessione costante o stabile anche se non ci sono dataset attivi.
Quando false, la connessione viene interrotta non appena tutti i suoi dataset sono
chiusi.
_
La persistenza della connessione di un componente database inserito esplicitamente
in un modulo dati o in una scheda controllata dalla sua propriet KeepConnection. Se
impostata diversamente, KeepConnection del componente database prevale sempre
sulla propriet KeepConnections della sessione. Per ulteriori informazioni sul controllo
delle singole connessioni database allinterno di una sessione, consultare Gestione
delle connessioni con il database a pagina 24-20.
KeepConnections dovrebbe essere impostato a true nelle applicazioni che aprono e
chiudono frequentemente tutti i dataset associati a un database situato su un server
remoto. Questa impostazione riduce il traffico di rete e velocizza laccesso ai dati, in
quanto significa che nel corso della sessione la connessione viene aperta e chiusa solo
una volta. Altrimenti, lapplicazione ogni volta che chiude o ristabilisce la
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-20 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
connessione, deve affrontare lincombenza aggiuntiva della connessione o dello
scollegamento con il database.
_
Anche quando in una sessione KeepConnections true, chiamando il metodo
DropConnections possibile chiudere e liberare i collegamenti database non attivi
relativamente a tutti i componenti database impliciti. Per ulteriori informazioni su
DropConnections, consultare Rilascio delle connessioni database non attive a
pagina 24-21.
Gestione delle connessioni con il database
possibile utilizzare un componente session per gestire i collegamenti con un
database. Il componente session contiene le propriet e i metodi che utilizzabili per
Aprire i collegamenti con il database.
Chiudere i collegamenti con il database.
Chiudere e disimpegnare tutti i collegamenti con il database non attivi.
Individuare collegamenti specifici con il database.
Iterare attraverso tutte le connessioni con il database aperte.
Apertura delle connessioni con il database
Per aprire una connessione database allinterno di una sessione, si chiama il metodo
OpenDatabase. OpenDatabase accetta un parametro, il nome del database da aprire. Il
nome un alias BDE, oppure il nome di un componente database. Nel caso di
Paradox o di dBASE, il nome pu anche essere il nome del percorso per esteso. Ad
esempio, la seguente istruzione utilizza la sessione predefinita e tenta di stabilire la
connessione con il database puntato dallalias BCDEMOS:
iicisc c.siicisc .css>,ciicisc'..',
OpenDatabase attiva la sessione se questa non gi attiva e poi verifica se il nome del
database specificato corrisponde alla propriet DatabaseName di qualsiasi
componente database della sessione. Se il nome non corrisponde a un componente
database esistente, OpenDatabase ne crea uno temporaneo utilizzando il nome
specificato. Infine, OpenDatabase chiama il metodo Open del componente database
per la connessione al server. Ogni chiamata a OpenDatabase fa aumentare di ununit
il numero di riferimento del database. Il database rimane aperto fino a quando il
numero di riferimento maggiore di 0.
Chiusura delle connessioni con il database
Per chiudere una singolo collegamento con un database, si chiama il metodo
CloseDatabase. Quando si chiama CloseDatabase, il numero di riferimento del database,
che viene incrementato ogni volta che si chiama OpenDatabase, diminuisce di
ununit . Quando il numero di riferimento 0, il database viene chiuso.
CloseDatabase accetta un parametro, il database da chiudere. Se il database stato
aperto utilizzando il metodo OpenDatabase, questo parametro pu essere impostato al
valore restituito da OpenDatabase.
.css>sciiciscc.siicisc,
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-21
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
Se il nome del database specificato associato a un componente database
temporaneo (implicito) e la propriet KeepConnections della sessione false, il
componente database viene liberato, e la connessione viene effettivamente chiusa.
_
Se KeepConnections false i componenti database temporanei vengono chiusi e
liberati automaticamente quando si chiude lultimo dataset associato al componente
database. Unapplicazione pu sempre chiamare CloseDatabase in anticipo per forzare
la chiusura. Per liberare dei componenti database temporanei quando
KeepConnections true, si chiamano il metodo Close del componente database, e poi il
metodo DropConnections della sessione.
_
La chiamata di CloseDatabase per un componente database costante in realt non
chiude la connessione. Allo scopo, bisogna chiamare direttamente il metodo Close del
componente database.
Ci sono due modi per chiudere tutte le connessioni database allinterno della
sessione:
Impostare la propriet Active della sessione a false.
Chiamare il metodo Close della sessione.
Quando Active ha il valore false, C++Builder chiama automaticamente il metodo
Close. Close si scollega da tutti i database attivi, liberando i componenti database
temporanei e chiamando ogni metodo Close del componente database stabile. Infine,
Close assegna il valore NULL al gestore BDE della sessione.
Rilascio delle connessioni database non attive
Se la propriet KeepConnections di una sessione true (limpostazione predefinita),
allora le connessioni database dei componenti database temporanei rimangono attive
anche se sono chiusi tutti i dataset utilizzati dal componente. possibile eliminare i
collegamenti in questione e liberare tutti i componenti database temporanei non
attivi di una sessione chiamando il metodo DropConnections. Ad esempio, il seguente
codice libera tutti i componenti database non attivi e temporanei della sessione
predefinita:
.css>,ccs,
I componenti database temporanei che hanno uno o pi dataset attivi non vengono
rilasciati o liberato da questa chiamata. Per liberare questi componenti, chiamare
Close.
Ricerca di una connessione con un database
Per determinare se un componente database specificato gi associato a una sessione
si utilizza il il metodo FindDatabase. FindDatabase accetta un parametro, il nome del
database da cercare, che pu essere lalias BDE o il nome del componente database.
Per Paradox o per dBASE, pu anche essere il nome del percorso per esteso.
FindDatabase restituisce il componente database se trova una corrispondenza.
Altrimenti restituisce NULL.
Il seguente codice cerca nella sessione predefinita un componente database
utilizzando lalias BCDEMOS e, se non lo trova, ne crea uno e lo apre:
iicisc .css>.iicisc'..',
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-22 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
I? iicisc .cs cxs . scss s
.css>,ciicisc'..', ccic i. ,c
I? >ceaaectei)
I? >Lisic
>.iisic,
icc>,c,
catca
...cssic. ,c icc,
~,,ci>c.ic,
_
Lutilizzo della funzione InputBox, sopra, ha solo scopi dimostrativi. Nelle
applicazioni reali, si ricorre alle funzionalit di immissione della password che
nascondono i singoli caratteri durante limmissione, come la funzione PasswordDialog
o una scheda custom.
Il pulsante Add della finestra di dialogo di PasswordDialog agisce proprio come il
metodo AddPassword.
I? .iss...css
icc>,c,
eIae
...cssic. ,iss.. c, c. ,c icc,
Utilizzo dei metodi RemovePassword e RemoveAllPasswords
RemovePassword cancella dalla memoria una password precedentemente inserita.
RemovePassword accetta un parametro contenente la password da cancellare.
.css>c.c.iss..'sccc',
RemoveAllPasswords cancella dalla memoria tutte le password precedentemente
aggiunte.
.css>c.c~.iss..s,
Utilizzo del metodo GetPassword e dellevento OnPassword
Levento OnPassword permette di controllare in che modo lapplicazione fornisce le
password quando vengono richieste quelle relative alle tabelle Paradox e dBASE. Se
si desidera ridefinire il comportamento di gestione della password predefinita
bisogna fornire il gestore dellevento OnPassword. Quando non si fornisce il gestore,
C++Builder presenta una finestra di dialogo predefinita per limmissione di una
password ma non previsto nessun comportamento particolare-o il tentativo di
aprire la tabella riesce, oppure viene sollevata uneccezione.
Se si fornisce il gestore dellevento OnPassword, questo deve fare due cose: chiamare
il metodo AddPassword e impostare il parametro Continue del gestore di evento a true.
Il metodo AddPassword passa alla sessione una stringa da utilizzare come password
della tabella. Il parametro Continue indica a C++Builder che non sono necessarie
ulteriori richieste di password per questo tentativo di aprire la tabella. Il valore
predefinito di Continue false per cui bisogna dargli esplicitamente il valore true. Se
Continue false, terminata lesecuzione del gestore di evento, riparte un evento
OnPassword -anche se mediante AddPassword stata passata la password valida. Se
Continue true, dopo lesecuzione del gestore di evento e se la stringa passata con
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-24 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
AddPassword non la password valida, il tentativo di aprire la tabella non riesce e
viene sollevata uneccezione.
OnPassword pu essere innescato da due circostanze. Il primo il tentativo di aprire
una tabella protetta da password (dBASE o Paradox) quando alla sessione non stata
gi fornita la password valida. (in caso contrario, levento OnPassword non si
verifica).
Laltra circostanza una chiamata al metodo GetPassword. GetPassword genera un
evento OnPassword oppure, se la sessione non ha un gestore di evento OnPassword,
visualizza una finestra di dialogo Default password. Restituisce true se il gestore di
evento OnPassword o la finestra di dialogo predefinita hanno aggiunto una password
alla sessione, e false se non stata indicata nessuna stringa.
Nel seguente esempio, il metodo Password indicato come gestore di evento
OnPassword della sessione predefinita, assegnandolo alla propriet OnPassword
delloggetto globale Session.
veIi __?aatcaII ..cicccc .c.c
.css>.iss.. .iss..,
tt,
s c cs c .iss.. cc
icc>,c,
cxcc, . ci ,c icc
catca
...cssic'. ,c icc',
~,,ci>c.ic,
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-25
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
Specifica delle ubicazioni delle directory di Paradox
Due propriet del componente sessione, NetFileDir e PrivateDir, riguardano
specificamente le applicazioni che lavorano con tabelle Paradox.
NetFileDir specifica la directory che contiene PDOXUSRS.NET, il file di controllo di
rete di Paradox. Questo file governa la condivisione delle tabelle Paradox sulle unit
di rete. Tutte le applicazioni che devono condividere delle tabelle Paradox devono
specificare la stessa directory del file di controllo di rete (di solito una directory su un
file server di rete). Per un certo alias di database, C++Builder deriva il valore per
NetFileDir dal file di configurazione di Borland Database Engine (BDE). Se si imposta
personalmente NetFileDir, il valore fornito prevale sullimpostazione di
configurazione di BDE, per cui bisogna assicurarsi di convalidare il nuovo valore.
In fase di progetto, si pu indicare il valore di NetFileDir tramite lObject Inspector. Si
pu anche impostare o modificare NetFileDir nel codice, in fase di esecuzione. Il
seguente codice impostare NetFileDir per la sessione predefinita allubicazione della
directory da dove lapplicazione viene eseguita:
.css>.cc xicc.i.ii..,
_
NetFileDir pu essere modificato solo quando in unapplicazione non ci sono file
Paradox aperti. Se si modifica NetFileDir in esecuzione, bisogna verificare che esso
punti una directory di rete valida che sia condivisa dagli utenti di rete.
PrivateDir specifica la directory dove vengono registrati i i file temporanei di
elaborazione delle tabelle, come quelli che BDE genera per gestire le istruzioni SQL
locali. Se non viene specificato il valore della propriet PrivateDir, BDE nel momento
in cui viene inizializzato utilizza automaticamente la directory corrente. Se
lapplicazione viene eseguita direttamente da un file server di rete, possibile
migliorare in esecuzione la performance dellapplicazione impostando PrivateDir su
un disco rigido locale di un utente prima di aprire il database.
_
Non impostare PrivateDir in fase di progettazione per poi aprire la sessione nellIDE.
Cos facendo, viene generato lerrore Directory is busy quando lapplicazione viene
eseguita a partire dallIDE.
Il seguente codice modifica limpostazione della propriet PrivateDir della sessione
predefinita sulla directory C: \TEMP di un utente:
.css>.ic '..',
_
Non impostare PrivateDir sulla directory principale di un drive. Bisogna sempre
specificare una subdirectory.
Operazioni con gli alias BDE
Ogni componente database associato a una sessione ha un alias BDE (bench il nome
del percorso per esteso possa facoltativamente essere sostituito da un alias quando si
accede a tabelle Paradox e dBASE). Una sessione quando attiva pu creare,
modificare e cancellare gli alias.
Il metodo AddAlias crea un nuovo alias BDE per un server di database SQL. AddAlias
prende tre parametri: una stringa che contiene un nome per lalias, una stringa che
specifica il driver SQL Links da utilizzare e una stringa lista popolata di parametri
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-26 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
per lalias. Ad esempio, le seguenti istruzioni utilizzano AddAlias per aggiungere un
nuovo alias per laccesso a un server InterBase alla sessione predefinita:
.s ~is.ii.s aev .s,
tt,
~is.ii.s>~..'.. .~',
~is.ii.s>~..'. .~.....~',
~is.ii.s>~..'. .~.~.L.~.~..L',
.css>~..~is'~.', 'L.~.', ~is.ii.s,
catca
ieIete ~is.ii.s,
.,
ieIete ~is.ii.s,
AddStandardAlias crea un nuovo alias BDE per le tabelle Paradox, dBASE o ASCII.
AddStandardAlias accetta tre parametri di stringa: il nome dellalias, il percorso
completo della tabella Paradox o dBASE cui si vuole accedere e il nome del driver
predefinito driver da usare quando si cerca di aprire una tabella priva di estensione.
Ad esempio, la seguente istruzione utilizza AddStandardAlias per creare un nuovo
alias per accedere a una tabella Paradox:
.css>~...i.i.~is'...', '.L...', '.ii.x',
Quando si aggiunge un alias a una sessione, BDE registra una copia dellalias in
memoria, dove disponibile per la sessione in corso e per le altre sessioni che
includano il valore cfmPersistent nella propriet ConfigMode. ConfigMode un set che
descrive quali tipi di alias possono essere utilizzati dai database della sessione.
Limpostazione predefinita cmAll, che equivale al set [ cfmVirtual, cfmPersistent,
cfmSession ]. Se ConfigMode cmAll, la sessione vede tutti gli alias creati al suo interno
(cfmSession), tutti gli alias nel file di configurazione BDE sul sistema dellutente
(cfmPersistent) e tutti gli alias che BDE conserva in memoria (cfmVirtual). possibile
modificare ConfigMode per limitare quali alias BDE i database in una sessione
possono utilizzare. Ad esempio, limpostazione di ConfigMode a cfmSession fa vedere
alla sessione solo gli alias creati allinterno della sessione. Tutti gli altri alias presenti
nel file di configurazione BDE e in memoria non sono disponibili.
Per mettere un alias appena creato a disposizione di tutte le sessioni e di altre
applicazioni, si ricorre al metodo SaveConfigFile della sessione. SaveConfigFile scrive
alias in memoria sul file di configurazione BDE, dove altre applicazioni BDE capaci
di funzionare con BDE possono leggerli e utilizzarli.
Dopo avere creato un alias, per modificarne i parametri si ricorre a ModifyAlias.
ModifyAlias accetta due parametri: il nome dellalias da modificare e una lista di
stringhe contenente i parametri da cambiare e i rispettivi valori. Ad esempio, con le
seguenti istruzioni ModifyAlias cambia in READ/WRITE il parametro OPEN MODE
dellalias CATS facendolo diventare nella sessione predefinita:
.s s aev .s,
s>ci,
s>~..'.. .~L',
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-27
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
.css>...~is'~.', s,
ieIete s,
Per cancellare un alias precedentemente creato nel corso di una sessione, si ricorre al
metodo DeleteAlias. DeleteAlias accetta un parametro, il nome dellalias da cancellare
e rende inaccessibile lalias alla sessione.
_
DeleteAlias non rimuove un alias dal file di configurazione BDE se lalias stato
scritto sul file da una chiamata precedente a SaveConfigFile. Per togliere lalias dal file
di configurazione dopo avere chiamato DeleteAlias, bisogna chiamare nuovamente
SaveConfigFile.
I componenti session forniscono cinque metodi per recuperare le informazioni
relative a un alias BDE, comprese le informazioni sul parametro e quelle sul driver.
Essi sono:
GetAliasNames, per elencare gli alias ai quali una sessione ha accesso.
GetAliasParams, per elencare i parametri di un alias specificato.
GetAliasDriverName, per restituire il nome del driver BDE utilizzato dallalias.
GetDriverNames, per restituire una lista di tutti i driver BDE disponibili per la
sessione.
GetDriverParams, per restituire parametri di driver relativi a un driver specificato.
Per ulteriori informazioni sullutilizzo dei metodi per recuperare le informazioni di
una sessione, consultare Reperimento di informazioni su una sessione qui di
seguito. Per ulteriori informazioni sugli alias BDE e sui driver SQL Links con cui essi
funzionano, consultare la Guida BDE in linea, BDE32.HLP.
Reperimento di informazioni su una sessione
Per recuperare le informazioni su una sessione e sui suoi componenti database si
utilizzano i metodi informativi di una sessione. Ad esempio, un metodo recupera i
nomi di tutti gli alias conosciuti dalla sessione, e un altro recupera i nomi delle tabelle
associate a uno specifico componente database utilizzato dalla sessione. La Tabella
24.4 riassume i metodi informativi di un componente session:
Tabella 24.4 Metodi informativi correlati al database dei componenti session
Metodo Scopo
GetAliasDriverName Recupera il driver BDE dellalias specificato di un database.
GetAliasNames Recupera la lista degli alias BDE di un database.
GetAliasParams Recupera la lista di parametri dellalias BDE specificato di un database.
GetConfigParams Recupera informazioni di configurazione dal file di configurazione
BDE.
GetDatabaseNames Recupera la lista degli alias BDE e i nomi di tutti i componenti TDatabase
attualmente in uso.
GetDriverNames Recupera i nomi di tutti i driver BDE installati.
GetDriverParams Recupera la lista di parametri di un driver BDE specificato.
GetStoredProcNames Recupera i nomi di tutte le procedure registrate relative a un database
specificato.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-28 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
Salvo GetAliasDriverName, questi metodi restituiscono un set di valori in una lista di
stringhe dichiarata e gestita dallapplicazione. (GetAliasDriverName restituisce una
sola stringa, il nome del driver BDE attivo di un particolare componente database
utilizzato dalla sessione).
Ad esempio, il seguente codice ricerca i nomi di tutti i componenti database e gli alias
conosciuti alla sessione predefinita:
.s s aev .s,
tt,
.css>ciicisc.i.css,
catca
ieIete s,
tatev,
ieIete s,
Creazione di sessioni supplementari
possibile creare sessioni per integrare la sessione predefinita. In fase di
progettazione, si possono situare le sessioni supplementari su un modulo dati (o su
una scheda), impostarne le propriet nellObject Inspector, scrivere per loro dei
gestori di evento, oltre a scrivere il codice per chiamare i loro metodi. Anche in fase
di esecuzione si possono creare sessioni, impostarne le propriet e chiamarne i
metodi.
_
Creare sessioni supplementari facoltativo, salvo il caso in cui lapplicazione esegua
query simultanee in un database, oppure lapplicazione sia di tipo multithread.
In fase di esecuzione per attivare la creazione dinamica di un componente session,
seguire questi passi:
1 Dichiarare una variabile TSession.
2 Istanziare una nuova sessione usando loperatore new.Questo operatore chiama il
costruttore di TSession per creare e inizializzare una nuova sessione. Il costruttore
assegna alla sessione una lista vuota di componenti database, imposta a true la
propriet KeepConnections, e inserisce la sessione nella lista gestita dal componente
session list dellapplicazione.
3 Assegnare un nome univoco alla propriet SessionName della nuova sessione a.
Questa propriet serve per per associare componenti database alla sessione. Per
GetTableNames Recupera i nomi di tutte le tabelle di un database specificato
corrispondenti a una struttura specificata.
GetFieldNames Recupera i nomi di tutti i campi di una tabella specificata in un database
specificato.
Tabella 24.4 Metodi informativi correlati al database dei componenti session (continua)
Metodo Scopo
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-29
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
L a r c h i t e t t u r a B D E
ulteriori informazioni sulla propriet SessionName, consultare Attribuzione del
nome a una sessione a pagina 24-29.
4 Attivare la sessione e facoltativamente modificarne le propriet .
possibile anche creare e aprire sessioni tramite il metodo OpenSession di
TSessionList. Usare OpenSession pi sicuro che utilizzare loperatore new, perch
OpenSession crea una sessione solo se questa non esiste gi . Per informazioni su
OpenSession, consultare Gestione di sessioni multiple a pagina 24-29.
Il seguente codice crea un nuovo componente session, gli assegna un nome e apre la
sessione per svolgere delle operazioni su un database (qui non riportate). Dopo
lutilizzo, il componente viene distrutto mediante una chiamata al metodo Free.
_
Non cancellare mai la sessione predefinita.
.css .cc..css aev .css.,
tt,
.cc..css>.css.i.c '.cc..css',
.cc..css>cc,ccs ?aIae,
.cc..css>,c,
__?IaaII,
ieIete .cc..css,
),
Attribuzione del nome a una sessione
La propriet SessionName di una sessione serve per dare il nome alla sessione, in
modo che sia possibile associarle i database e i dataset. Nel caso della sessione
predefinita, SessionName vale Default, For ogni componente session aggiuntivo che
si crea, necessario dare un valore univoco alla sua propriet SessionName.
I componenti database e dataset hanno propriet SessionName che corrispondono alla
propriet SessionName di un componente session. Se si lascia vuota la propriet
SessionName di un componente database o dataset questa viene associata
automaticamente alla sessione predefinita. possibile anche assegnare a SessionName
di un componente database o dataset un nome corrispondente al SessionName di un
componente session che si crea.
Il seguente codice utilizza il metodo OpenSession del componente predefinito
TSessionList, Sessions, per aprire un nuovo componente session, assegnare al suo
SessionName il nome InterBaseSession, attivare la sessione e associare alla sessione
Database1, un componente database esistente:
.css L.css .csss>,c.css'Lcisc.css',
iicisc>.css.i.c 'Lcisc.css',
Gestione di sessioni multiple
Se si crea una singola applicazione che utilizza pi thread per svolgere operazioni sul
database, necessario creare una sessione supplementare per ogni thread. La pagina
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-30 G u i d a a l l a p r o g r a mma z i o n e
L a r c h i t e t t u r a B D E
BDE sulla Component palette contiene un componente session che in fase di
progettazione si pu mettere in un modulo dati o su una scheda.
_
Quando si colloca un componente session, necessario anche dare alla sua propriet
SessionName un valore univoco, per evitare conflitti con la propriet SessionName
della sessione predefinita.
Il fatto di inserire in fase di progetto un componente session presuppone che il
numero di thread (e quindi di sessioni) richiesti dallapplicazione durante
lesecuzione sia stabile. Tuttavia, pi probabile che unapplicazione debba creare
sessioni dinamicamente. Per creare delle sessioni in modo dinamico, bisogna
chiamare in fase di esecuzione il metodo OpenSession delloggetto globale Sessions.
OpenSession richiede un singolo parametro, un nome di sessione univoco rispetto a
tutti i nomi di sessione dellapplicazione. Con questo codice si crea dinamicamente e
si attiva una nuova sessione con un nome generato univocamente:
.csss>,c.css'.c.css' - L..csss> - ,
Questa istruzione genera un nome univoco di una nuova sessione recuperando il
numero di sessioni corrente e aggiungendo uno al valore trovato. Notare che se si
creano e distruggono dinamicamente delle sessioni in fase di esecuzione, lesempio
qui riportato non si comporta come previsto. Tuttavia, lesempio mostra come
utilizzare le propriet e i metodi di Sessions per gestire sessioni multiple.
Sessions una variabile di tipo TSessionList che viene automaticamente istanziata nel
caso di applicazioni database BDE. Le propriet e i metodi di Sessions si utilizzano
per tenere il conto di sessioni multiple nelle applicazioni database multithread. La
Tabella 24.5 riassume le propriet e i metodi del componente TSessionList:
Come esempio delluso delle propriet e dei metodi Sessions in unapplicazione
multithread, si consideri che cosa accade quando si intende aprire una connessione
con un database. Per stabilire se la connessione gi in corso, si ricorre alla propriet
Sessions per far passare ciascuna sessione presente nella lista sessioni a partire dalla
Tabella 24.5 Propriet e metodi di TSessionList
Propriet o metodo Scopo
Count Restituisce il numero di sessioni, sia attive che non attive, presenti nella
lista di sessioni.
FindSession Cerca la sessione con il nome specificato e restituisce un puntatore ad essa,
oppure restituisce NULL se la con il nome specificato non esiste. Se viene
passato un nome di sessione vuoto, FindSession restituisce un puntatore
alla sessione predefinita, Session.
GetSessionNames Mette in una lista di stringhe i nomi di tutti i componenti session correnti.
La procedura aggiunge sempre almeno una stringa, Default, per la
sessione predefinita.
List Restituisce il componente session di un nome di sessione specificato. Se
non c alcuna sessione con il nome specificato, viene sollevata
uneccezione.
OpenSession Crea e attiva una nuova sessione oppure riattiva una sessione esistente
relativamente a un nome di sessione specificato.
Sessions Accede alla lista di sessioni in base al valore ordinale.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-31
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
U t i l i z z o d e l l e t r a n s a z i o n i c o n B D E
sessione predefinita. Per ciascun componente session, si esamina la propriet
Databases per vedere se il database in questione aperto. Se si scopre che un altro
thread sta gi usando il database richiesto, si esamina la sessione successiva nella
lista.
Se un thread esistente non utilizza il database, allora si pu stabilire la connessione
allinterno di quella sessione.
Se, daltra parte, tutti i thread esistenti utilizzano il database, necessario aprire una
nuova sessione in cui aprire unaltro collegamento con il database.
Se in unapplicazione multithread si replica un modulo dati contenente una sessione,
e ogni thread contiene una propria copia del modulo dati, con la propriet
AutoSessionName ci si pu accertare che tutti i dataset del modulo dati utilizzino la
sessione corretta. Limpostazione di AutoSessionName a true fa in modo che la
sessione quando viene creata in fase di esecuzione generi dinamicamente il proprio
nome univoco. Il nome poi viene assegnato a ciascun dataset del modulo dati,
ridefinendo qualunque nome di sessione esplicitamente impostato. In questo modo si
ha la certezza che ciascun thread abbia la propria sessione e che ciascun dataset
utilizzi la sessione nel proprio modulo dati.
Utilizzo delle transazioni con BDE
Per impostazione predefinita, BDE fornisce un controllo di transazione implicito alle
applicazioni. Quando unapplicazione soggetta a controllo di transazione implicito,
per ciascun record di un dataset che viene scritto nel database sottostante si ricorre a
una transazione separata. Le transazioni implicite garantiscono il minimo di conflitti
di aggiornamento di record sia una vista coerente del database. Daltra parte, siccome
per ogni riga di dati scritti in un database si ricorre a una transazionedistinta, il
controllo di transazione implicito pu portare a un eccessivo traffico di rete e a un
rallentamento delle prestazioni. Inoltre Il controllo di transazione implicito non
protegge le operazioni logiche che impegnano pi di un record.
Se si controllano esplicitamente le transazioni, si pu scegliere il momento migliore
per per farle partire, impegnarle e per fare il rollback. Nello sviluppo di applicazioni
in ambiente multiutente, in particolare quando le applicazioni vengono eseguite su
un server SQL remoto, si dovrebbero controllare le transazioni esplicitamente.
Nelle applicazioni database basate su BDE ci sono due modi che si escludono
reciprocamente per il controllo esplicito delle transazioni
Il controllo viene fatto mediante il componente database. Il vantaggio principale
dellimpiego dei metodi e delle propriet di un componente database quello di
fornire unapplicazione pulita e portabile, indiprendente dal database o dal server.
Questo tipo di controllo di transazione supportato da tutti i componenti di
connessione al database ed descritto in Gestione delle transazioni a
pagina 21-6.
Utilizzare una passthrough SQL in un componente query per passare istruzioni
SQL direttamente a un server SQL oppure ODBC remoto. Il vantaggio principale
del passthrough SQL sta nella possibilit di sfruttare le funzionalit avanzate di
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-32 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e l l e t r a n s a z i o n i c o n B D E
gestione di transazioni di un particolare server di database, come per esempio la
cache di schema. Per capire i vantaggi del modello di gestione delle transazioni del
server di cui si dispone, consultare la documentazione relativa. Per ulteriori
informazioni sullutilizzo di passthrough SQL, consultare Utilizzo di
passthrough SQL qui di seguito.
Quando si lavora su database locali, il componente database serve solo per creare
transazioni esplicite (i database locali non supportano passthrough SQL). Tuttavia,
limpiego di transazioni locali soggetto a certe limitazioni. Per ulteriori
informazioni sullutilizzo di transazioni locali, consultare Utilizzo delle transazioni
locali a pagina 24-33.
_
possibile rendere minimo il numero di transazioni necessarie registrando gli
aggiornamenti nella cache. Per ulteriori informazioni sugli aggiornamenti registrati
nella cache, consultare Utilizzo di un dataset client per registrare in cache gli
aggiornamenti a pagina 27-17 e Utilizzo di BDE per gli aggiornamenti in cache a
pagina 24-33.
Utilizzo di passthrough SQL
Con passthrough SQL, si utilizza un componente TQuery, TStoredProc o TUpdateSQL per
inviare direttamente a un server di database remoto unistruzione di controllo di
transazione SQL. BDE non elabora listruzione SQL. Usando passthrough SQL si
possono sfruttare direttamente i controlli di transazione offerti dal server, specialmente
quando sono di tipo non-standard.
Per per controllare una transazione mediante passthrough SQL, necessario
Installare i driver SQL Links corretti. Se installando C++Builder si era scelta
lopzione Typical, tutti i driver SQL Links risultano gi installati correttamente.
Configurare il protocollo di rete. Consultare lamministratore di rete per ulteriori
informazioni.
Avere accesso a un database situato su un server remoto.
Mediante SQL Explorer impostare SQLPASSTHRU MODE a NOT SHARED.
SQLPASSTHRU MODE specifica se le istruzioni BDE e passthrough SQL possono
condividere gli stessi collegamenti al database. Nella maggior parte dei casi,
limpostazione di SQLPASSTHRU MODE SHARED AUTOCOMMIT. Tuttavia,
impossibile luso condiviso di connessioni con il database quando si utilizzano
istruzioni di controllo di transazione. Per ulteriori informazioni su modi
SQLPASSTHRU, consultare il file di guida del programma di utilit BDE
Administration.
_
Quando SQLPASSTHRU MODE NOT SHARED, necessario utilizzare dei
componenti database distinti per i dataset che passano istruzioni di transazione SQL
al server e per quelli che non lo fanno.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-33
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
Utilizzo delle transazioni locali
BDE supporta transazioni locali con tabelle Paradox, dBASE, Access e FoxPro. Dal
punto di vista di chi programma, non c differenza fra una transazione locale e una
transazione con un server di database remoto.
_
Quando si utilizzano transazioni con tabelle locali Paradox, dBASE, Access e FoxPro,
impostare TransIsolation a tiDirtyRead invece di utilizzare il valore predefinito di
tiReadCommitted. Se nel caso di tabelle locali limpostazione di TransIsolation
comunque diversa da tiDirtyRead viene restituito un errore BDE.
Quando si inizia una transazione con una tabella locale, gli aggiornamenti eseguiti
vengono registrati. Ogni record registrato contiene il buffer di un record. Quando
una transazione attiva, i record da aggiornare sono bloccati fino a quando la
transazione non conclusa o annullata. In caso di rollback, i vecchi buffer dei record
vengono applicati ai record aggiornati in modo da riportarli allo stato precedente.
Le transazioni locali sono pi limitate delle transazioni con i server SQL o i driver
ODBC. In particolare, per le transazioni locali valgono le seguenti limitazioni:
Non fornito il crash recovery automatico.
Non sono supportate le istruzioni di definizione dati.
Non si possono effettuare transazioni con tabelle temporanee.
Il livello di TransIsolation pu essere solo tiDirtyRead.
Per Paradox, le transazioni locali possono essere eseguite solo su tabelle che
abbiano indici validi. Non possibile il rollback dei dati con tabelle Paradox prive
di indici.
Si pu bloccare e modificare solo un numero limitato di record. Con tabelle
Paradox, il limite 255 record. Con tabelle dBASE il limite 100.
Le non si possono eseguire transazioni con il driver ASCII BDE.
Se si chiude un cursore su una tabella durante una transazione se ne determina il
rollback a meno che:
Non ci siano pi tabelle aperte.
Il cursore venga chiuso su una tabella che non ha subito modifiche.
Utilizzo di BDE per gli aggiornamenti in cache
Lapproccio consigliato per utilizzare gli aggiornamenti in cache consiste nellusare
un dataset client (TBDEClientDataSet) o nel collegare il dataset BDE a un dataset
client utilizzando un provider di dataset. I vantaggi dellutilizzo di un dataset client
sono discussi in Utilizzo di un dataset client per registrare in cache gli
aggiornamenti a pagina 27-17.
Nei casi semplici, tuttavia, si pu invece decidere di registrare gli aggiornamenti in
cache ricorrendo a BDE. I dataset per BDE e i componenti TDatabase dispongono di
propriet , di metodi e di eventi per gestire gli aggiornamenti in cache. Nella maggior
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-34 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
parte dei casi, questi corrispondono direttamente alle propriet , ai metodi e agli
eventi che si usano con i dataset client e con i dataset provider quando si ricorre a un
dataset client per la gestione degli aggiornamenti in cache. La seguente tabella elenca
queste propriet , questi eventi e questi metodi accanto alle propriet , i metodi e gli
eventi corrispondenti di TBDEClientDataSet:
Per una panoramica dei processi di aggiornamento mediante la cache, consultare
Panoramica sullutilizzo degli aggiornamenti in cache a pagina 27-18.
_
Anche se si utilizza un dataset client per la gestione degli aggiornamenti in cache,
utile leggere la sezione sugli oggetti update a pagina 24-41. Si possono utilizzare gli
oggetti update nel gestore di evento BeforeUpdateRecord di TBDEClientDataSet o di
Tabella 24.6 Propriet , metodi ed eventi degli aggiornamenti in cache
Su dataset BDE
(o TDatabase) Su TBDEClientDataSet Scopo
CachedUpdates Non necessario per i
dataset client, che usano
sempre gli aggiornamenti
in cache.
Determina se gli aggiornamenti in cache
sono attivi per il dataset.
UpdateObject Usare un gestore di
evento
BeforeUpdateRecord, o, se si
utilizza TClientDataSet,
usare la propriet
UpdateObject del dataset
sorgente per BDE.
Specifica loggetto update per
laggiornamento di dataset di sola
lettura.
UpdatesPending ChangeCount Indica se la cache locale contiene record
aggiornati che devono essere applicati al
database.
UpdateRecordTypes StatusFilter Indica il genere di record aggiornati da
rendere visibili quando si applicano gli
aggiornamenti messi nella cache.
UpdateStatus UpdateStatus Indica se un record invariato,
modificato, inserito o cancellato.
OnUpdateError OnReconcileError Evento per la gestione record per record
degli errori di aggiornamento -
OnUpdateRecord BeforeUpdateRecord Evento per lelaborazione record per
record degli aggiornamenti.
ApplyUpdates
ApplyUpdates (database)
ApplyUpdates Applica al database i record presenti
nella cache locale.
CancelUpdates CancelUpdates Elimina dalla cache locale tutti gli
aggiornamenti senza applicarli.
CommitUpdates Reconcile Svuota la cache di aggiornamento dopo
la conclusione favorevole degli
aggiornamenti.
FetchAll GetNextPacket
(e PacketRecords)
Copia i record nella cache locale per
modificarli e aggiornarli.
RevertRecord RevertRecord Annulla gli aggiornamenti del record
attivo se non sono stati ancora applicati.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-35
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
TDataSetProvider per applicare aggiornamenti provenienti da procedure registrate o
da query su pi tabelle.
Attivazione degli aggiornamenti in cache con BDE
Per utilizzare BDE per gli aggiornamenti in cache, il dataset per BDE deve indicare
lintenzione di mettere gli aggiornamenti nella cache. Lo si specifica impostando la
propriet CachedUpdates a true. Quando laggiornamento dei dati memorizzati nella
cache attivo, nella memoria locale viene posta una copia di tutti i record. Gli utenti
visualizzano e modificano la copia locale dei dati. Nella cache vengono registrate
anche le modifiche, gli inserimenti e le cancellazioni che si accumulano in memoria
fino a quando lapplicazione non li applica al server di database. Se le modifiche
vanno a buon fine, nella cache i record modificati vengono scaricati dalla memoria.
Il dataset mette nella cache tutti gli aggiornamenti, fino a quando non si imposta
CachedUpdates a false. Lapplicazione delle modifiche presenti nella cache non
disabilita gli ulteriori aggiornamenti memorizzati, ma trascrive solo nel database
linsieme di modifiche corrente e le scarica dalla memoria. Se si annullano gli
aggiornamenti chiamando CancelUpdates, tutte le modifiche presenti nella cache
vengono annullate, senza per impedire al dataset di mettere nella cache le
modifiche successive.
_
Se si disattiva laggiornamento in cache impostando CachedUpdates a false, le
eventuali modifiche non ancora applicate vengono eliminate senza notifica. Per
evitare la perdita di modifiche, testare la propriet UpdatesPending prima di
disattivare laggiornamento in cache.
Applicazione degli aggiornamenti in cache basati su BDE
Lapplicazione degli aggiornamenti un processo in due fasi che dovrebbe verificarsi
nel contesto della transazione di un componente database, in modo che
lapplicazione possa ristabilirsi convenientemente da errori. Per informazioni sulla
gestione delle transazioni nel caso dei componenti database, consultare Gestione
delle transazioni a pagina 21-6.
Applicando gli aggiornamenti sotto il controllo delle transazioni si verifica quanto
segue:
1 Viene attivata una transazione con il database.
2 Gli aggiornamenti nella cache vengono trascritti nel database (fase 1). Se si fornisce
un evento OnUpdateRecord, questo viene attivato una volta ogni volta che nel
database viene trascritto un record. Se la trascrizione produce un errore, viene
attivato levento OnUpdateError, se previsto.
3 La transazione viene confermata se la trascrizione va a buon fine, o annullata in
caso contrario:
Se la trascrizione va a buon fine:
Le modifiche apportate al database vengono confermate e la transazione si
conclude.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-36 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
Gli aggiornamenti nella cache vengono confermati e il buffer interno della cache
viene scaricato (fase 2).
Se la trascrizione non va a buon fine:
Le modifiche al database vengono annullate e la transazione si conclude.
Gli aggiornamenti presenti nella cache non vengono confermati e rimangono
nella cache interna.
Per informazioni sulla creazione e sullimpiego dei gestori di evento OnUpdateRecord,
consultare Creazione di un gestore di evento OnUpdateRecord a pagina 24-38. Per
informazioni sulla gestione degli errori di aggiornamento che si verificano quando si
applicano gli aggiornamenti in cache, consultare Gestione degli errori di
aggiornamento a pagina 24-39.
_
Lapplicazione degli aggiornamenti in cache unoperazione particolarmente
delicata quando si ha a che fare con pi dataset collegati secondo una relazione
master/detail perch significativo lordine di applicazione degli aggiornamenti a
ciascun dataset. Di solito, necessario aggiornare le tabelle master prima di quelle di
dettaglio, salvo quando si ha a che fare con record cancellati, perch allora lordine va
invertito. A causa di questa difficolt , si raccomanda vivamente limpiego di dataset
client quando si mettono in cache gli aggiornamenti di una scheda master/detail. I
dataset client gestiscono automaticamente tutte le questioni di ordinamento nelle
relazioni master/detail.
Ci sono due modi per applicare gli aggiornamenti basati su BDE:
Un modo quello di applicare gli aggiornamenti utilizzando un componente
database e chiamando il suo metodo ApplyUpdates. Questo lapproccio pi
semplice, perch il database gestisce tutti i dettagli del processo di transazione e
scarica la cache ad aggiornamento concluso.
possibile aggiornare un singolo dataset chiamando i suoi metodi ApplyUpdates e
CommitUpdates. In questo caso, necessario codificare esplicitamente la
transazione che interessa il processo di aggiornamento, come pure chiamare
esplicitamente CommitUpdates per confermare gli aggiornamenti provenienti dalla
cache.
_
Per applicare gli aggiornamenti da una procedura registrata o da una query SQL che
non restituisce un set risultato live, necessario utilizzare TUpdateSQL per
specificare come eseguire gli aggiornamenti. Per aggiornamenti a concatenamenti
(query implicanti due o pi tabelle), necessario fornire un oggetto TUpdateSQL per
ogni tabella coinvolta, e utilizzare il gestore di evento OnUpdateRecord per richiamare
questi oggetti in modo da eseguire gli aggiornamenti. Consultare Aggiornamento di
dataset mediante oggetti update a pagina 24-41 per i dettagli.
Applicazione degli aggiornamenti nella cache mediante un database
Per applicare nel contesto di una connessione con un database gli aggiornamenti
presenti nella cache a uno o pi dataset, si usa il metodo ApplyUpdates del
componente database. Il seguente codice applica degli aggiornamenti al dataset
CustomersQuery in risposta allevento clic di un pulsante:
veIi __?aatcaII .~,,c.ccc .c.c
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-37
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
Con le righe precedenti si trascrivono nel database gli aggiornamenti presenti nella
cache nel contesto di una transazione generata automaticamente. Se loperazione ha
successo, la transazione viene confermata e poi vengono confermati gli
aggiornamenti nella cache. In caso contrario, si ha lannullamento della transazione e
la cache rimane invariata. In questo secondo caso, gli errori dovuti agli
aggiornamenti in cache andrebbero gestiti mediante levento OnUpdateError del
dataset. Per ulteriori informazioni sulla gestione degli errori di aggiornamento,
consultare Gestione degli errori di aggiornamento a pagina 24-39.
Il vantaggio principale della chiamata del metodo ApplyUpdates di un componente
database la possibilit di aggiornamento di qualsiasi numero di componenti dataset
associati al database. I due argomenti per il metodo ApplyUpdates di un database
sono un array di TDBDataSet, e lindice dellultimo dataset nellarray. Per applicare
gli aggiornamenti per pi di un dataset, creare un array locale di puntatori ai dataset.
Ad esempio, il seguente codice applica gli aggiornamenti di due query:
ii.c .s, s.c_c, .cs_c,
I? iicisc>Ls._isc. iicisc>isLsi ci.
iicisc>isLsi ci.,
iicisc>~,,,.ics.s,,
Applicazione degli aggiornamenti in cache con i metodi dei componenti
dataset
possibile aggiornare singoli dataset per BDE tramite i metodi ApplyUpdates e
CommitUpdates del dataset. Ognuno di questi metodi racchiude una fase del processo
di aggiornamento:
1 ApplyUpdates trascrive in un database le modifiche presenti nella cache (fase 1).
2 CommitUpdates scarica (cancella) la cache interna quando la trascrizione va a buon
fine (fase 2).
Il seguente codice illustra come si applicano gli aggiornamenti allinterno di una
transazione riguardante il dataset CustomerQuery:
veIi __?aatcaII .~,,c.ccc .c.c
iicisc>.iisic,
tt,
catca
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-38 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
.c.. ,.ics cc
I? ,.ic. .Lsc
icc ics,.,
?et Iat , ., --
ics, ii.c>c.s>c.s,>.c.ic,
,.icicc>~,,c.cc.ics, ,
eIae
cic,s ,
ci,
I? ,.icicc>cic'cc.', ii.c>c.s>c.s,>.ic,
avItca ,.ic.
caae ....
,.icicc>.,
,.icicc>c.s>c.s,>ic ii.c>c.s>c.s,>ic,
,.icicc>.s,
bteak,
caae .ccc
,.icicc>ccc,
bteak,
Gestione degli errori di aggiornamento
Borland Database Engine (BDE) controlla specificatamente i conflitti di
aggiornamento e altre condizioni quando tenta di applicare gli aggiornamenti e
riporta gli errori. Levento OnUpdateError del componente dataset consente di
rilevare e di rispondere agli errori. Se si utilizzano gli aggiornamenti in cache si
dovrebbe creare un gestore di questo evento. In caso contrario, quando si verifica un
errore, lintera operazione di aggiornamento non va a buon fine.
Ecco lo schema di codice di un gestore di evento OnUpdateError:
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-40 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
veIi __?aatcaII .ii.c,.icii.c ii.c,
iicisc , ,.ic. ,.ic., ,.ic~c ,.ic~c
cs,. cs cc
c , c ,
I? ,>s,,> >.c L_L
,.ic~c i..,, c i, s s., s cc.
_
Se durante lapplicazione degli aggiornamenti in cache si verifica un errore, viene
sollevata uneccezione e appare un messaggio di errore. Salvo il caso in cui
ApplyUpdates viene chiamato dallinterno di un ciclo try...catch, il messaggio di errore
visualizzato allutente da dentro il gestore di evento OnUpdateError pu apparire
ancora una volta. Per evitare la ripetizione bisogna dare a UpdateAction il valore
uaAbort e disattivare la comparsa del messaggio di errore di sistema.
Aggiornamento di dataset mediante oggetti update
Quando il dataset per BDE rappresenta una procedura registrata o una query che
non restituisce risultati live, non si possono effettuare aggiornamenti direttamente
dal dataset. Infatti si potrebbero verificare problemi quando si utilizza un dataset
client per mettere in cache gli aggiornamenti. In ambedue i casi, si evita il problema
utilizzando un oggetto update:
1 Se si utilizza un dataset client, ricorrere a un componente provider esterno con
TClientDataSet, piuttosto che a TBDEClientDataSet. Questo per consentire di
impostare la propriet UpdateObject del dataset sorgente per BDE (punto 3).
2 Aggiungere un componente TUpdateSQL al modulo dati del dataset per BDE.
3 Impostare la propriet UpdateObject del componente dataset per BDE al
componente TUpdateSQL nel modulo dati.
4 Specificare le istruzioni SQL necessarie per eseguire gli aggiornamenti tramite le
propriet ModifySQL, InsertSQL e DeleteSQL delloggetto update. Leditor Update
SQL aiuta a scrivere queste istruzioni.
5 Chiudere il dataset.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-42 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
6 Assegnare il valore true alla propriet CachedUpdates del componente dataset o
collegare il dataset con il dataset client utilizzando un provider di dataset.
7 Riaprire il dataset.
_
Talvolta, necessario utilizzare pi oggetti update. Ad esempio, quando si aggiorna
una join su pi tabelle o una procedura registrata che rappresenta dati provenienti da
pi dataset, bisogna fornire un oggetto TUpdateSQL a ogni tabella da aggiornare.
Quando si utilizzano pi oggetti update, non si pu semplicemente associare
loggetto update al dataset tramite la propriet UpdateObject. Invece, si deve chiamare
manualmente loggetto update da un gestore di evento OnUpdateRecord (se si utilizza
BDE per memorizzare gli aggiornamenti nella cache) o da un gestore di evento
BeforeUpdateRecord (se si utilizza un dataset client).
Loggetto update in effetti incorpora tre componenti TQuery, ognuno dei quali
esegue una sola operazione di aggiornamento. Uno fornisce unistruzione SQL
UPDATE per la modifica di record esistenti; un secondo fornisce unistruzione
INSERT per aggiungere nuovi record a una tabella; e un terzo fornisce unistruzione
DELETE per eliminare i record da una tabella.
Quando si mette un componente update in un modulo dati, i componenti query che
esso racchiude non si vedono. Essi vengono creati in fase di esecuzione dal
componente update in base a tre propriet di aggiornamento per le quali vanno
fornite le istruzioni SQL:
ModifySQL specifica listruzione UPDATE.
InsertSQL specifica listruzione INSERT.
DeleteSQL specifica listruzione DELETE.
In fase di esecuzione, quando il componente update viene usato per trascrivere gli
aggiornamenti:
1 Seleziona unistruzione SQL da eseguire a seconda che il record attivo venga
modificato, inserito o cancellato.
2 Fornisce valori del parametro allistruzione SQL.
3 Prepara ed esegue listruzione SQL in modo da farle portare a termine
laggiornamento specificato.
Creazione di istruzioni SQL per componenti update
Per aggiornare un record di un dataset associato, un oggetto update utilizza una di
tre istruzioni SQL. Ogni oggetto update pu aggiornare solo una singola tabella,
cosicch ciascuna istruzione di aggiornamento delloggetto deve fare riferimento alla
stessa tabella base.
Le tre istruzioni SQL rispettivamente cancellano, inseriscono e modificano i record
nella cache. Le istruzioni vanno fornite sotto forma di propriet DeleteSQL, InsertSQL
e ModifySQL. I valori possono essere forniti in fase di progetto o di esecuzione. Ad
esempio, il seguente codice specifica in fase di esecuzione il valore della propriet
DeleteSQL:
,.ic._>ccc._>ci,
,.ic._>ccc._>~.. . Lc L,
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-43
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
,.ic._>ccc._>~..- LLc.. _Lc..,
In fase di progettazione, leditor Update SQL aiuta a scrivere le istruzioni SQL con
cui si applicano gli aggiornamenti.
Gli oggetti update forniscono una connessione di parametro automatica nel caso dei
parametri che referenziano i valori di campo originali e aggiornati del dataset. Di
solito, quindi, quando si scrivono le istruzioni SQL si inseriscono parametri con nomi
che hanno un formato speciale. Per informazioni sulluso di questi parametri,
consultare Sostituzione dei parametri nelle istruzioni di aggiornamento SQL a
pagina 24-44.
Utilizzo di Update SQL editor
Per scrivere le istruzioni SQL di un componente update,
1 Mediante lObject Inspector, selezionare il nome delloggetto update nella lista a
discesa della propriet UpdateObject del dataset. In questo modo, lUpdate SQL
editor che verr richiamato nel passo successivo in grado di determinare i valori
predefiniti da utilizzare con le opzioni di generazione SQL.
2 Fare clic con il pulsante destro sulloggetto update e selezionare lUpdateSQL
Editor nel menu di scelta rapida. Appare leditor Update SQL, con cui si creano le
istruzioni SQL delle propriet ModifySQL, InsertSQL e DeleteSQL delloggetto
update in base al dataset inerente e ai valori che gli vengono forniti.
Leditor Update SQL ha due pagine. La pagina Options appare quando leditor viene
richiamato. Per selezionare la tabella da aggiornare utilizzare la casella combinata
Table Name. Quando si indica il nome della tabella, nelle caselle di riepilogo Key
Fields e Update Fields appaiono tutte le colonne disponibili.
La casella di riepilogo Update Fields indica quali colonne aggiornare. Quando si
specifica la tabella, appaiono selezionate tutte le colonne della casella di riepilogo
Update Fields. Si possono selezionare pi campi in base alle esigenze.
La casella di riepilogo Key Fields serve per specificare le colonne da usare come
chiave nellaggiornamento. Nel caso di tabelle Paradox, dBASE e FoxPro, le colonne
specificate devono corrispondere a un indice esistente, cosa non obbligatoria nel caso
di database SQL remoti. Invece di impostare Key Fields, facendo clic sul pulsante
Primary Keys si scelgono i campi chiave di aggiornamento in base allindice
principale della tabella. Facendo clic su Dataset Defaults si riportano le liste di
selezione allo stato originario: tutti i campi sono selezionati come chiavi e tutti i
campi sono selezionati per laggiornamento.
Spuntare la casella di controllo Quote Field Names se il server vuole che i nomi di
campo siano messi tra virgolette.
Una volta specificata la tabella si selezionano le colonne chiave e le colonne da
aggiornare, poi facendo clic su Generate SQL si generano le istruzioni preliminari
SQL da associare alle propriet ModifySQL, InsertSQL e DeleteSQL del componente
update. Nella maggior parte dei casi, preferibile o necessario mettere a punto le
istruzioni SQL generate automaticamente.
Per visualizzare e modificare le istruzioni SQL generate, selezionare la pagina SQL.
Se sono state generate delle istruzioni SQL, quando la pagina viene selezionata,
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-44 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
listruzione relativa alla propriet ModifySQL gi visibile nel riquadro SQL Text.
Tale istruzione pu essere modificata in base alle prorie esigenze.
j
Ricordare che le istruzioni SQL generate sono punti di partenza di creare le istruzioni
di aggiornamento. In certi casi, bisogna modificarle per farle eseguire correttamente.
Ad esempio, quando si gestiscono dati contenenti valori NULL, necessario
modificare la clausola WHERE in modo che sia
- .c. L. .
invece di usare la variabile di campo generata. Ognuna delle istruzioni va testata
personalmente prima di essere accettata.
Per commutare tra le istruzioni SQL generate e modificarle in base alle esigenze,
utilizzare i pulsanti di scelta Statement Type.
Per accettare le istruzioni e associarle alle propriet SQL del componente update, fare
clic su OK.
Sostituzione dei parametri nelle istruzioni di aggiornamento SQL
Le istruzioni di aggiornamento SQL ricorrono a una forma particolare di sostituzione
di parametro che permette di sostituire vecchi o nuovi valori di campo negli
aggiornamenti dei record. Leditor Update SQL quando genera le sue istruzioni,
determina quali valori di campo utilizzare. Quando si scrive laggiornamento SQL, si
specificano i valori del campo da utilizzare.
Quando il nome del parametro corrisponde a un nome di colonna nella tabella, viene
automaticamente utilizzato come valore del parametro il nuovo valore del campo
nellaggiornamento presente nella cache del record. Quando il nome del parametro
corrisponde a quello di una colonna ed preceduto dalla stringa OLD_, viene
usato il vecchio valore del campo. Ad esempio, nellistruzione di aggiornamento SQL
qui di seguito, il parametro :LastName viene riempito automaticamente con il nuovo
valore del campo presente nellaggiornamento in cache per il record inserito.
L.. L. .i.cs
is.i.c, s.i.c, ~..css, , .ic, .,
~. is.i.c, s.i.c, ~..css, , .ic, .,
Nuovi valori di campo vengono solitamente usati nelle istruzioni InsertSQL e
ModifySQL. Nellaggiornamento di un record modificato, il nuovo valore di campo
preso dalla cache viene utilizzato dallistruzione UPDATE per sostituire il vecchio
valore di campo nella tabella base aggiornata.
Nel caso di record cancellati, non c nessun nuovo valore, cosicch la propriet
DeleteSQL utilizza la sintassi :OLD_FieldName. I vecchi valori del campo vengono
normalmente usati anche nella clausola WHERE dellistruzione SQL per gli
aggiornamenti di modifica o di cancellazione, in modo da stabilire quali record
aggiornare o cancellare.
Nella clausola WHERE di unistruzione UPDATE o DELETE bisogna fornire almeno
il numero minimo di parametri per identificare univocamente il record nella tabella
base da aggiornare con i dati della cache. Per esempio, in una lista di clienti, il solo
cognome di un cliente potrebbe non essere sufficiente a identificare univocamente
nella tabella base il record corretto; potrebbero esserci molti record che hanno
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-45
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
Smith come cognome. Invece, i parametri del cognome, del nome e del numero di
telefono potrebbero rappresentare una combinazione univoca. Meglio ancora
sarebbe un valore univoco del campo come lidentificativo cliente.
_
Se si creano istruzioni SQL contenenti parametri che non rimandano i valori del
campo modificati oppure originali, loggetto update non sa come collegare i loro
valori. Tuttavia, lo si pu fare manualmente, mediante la propriet Query
delloggetto update. Per i dettagli fare riferimento a Utilizzo della propriet Query
di un componente update a pagina 24-49.
Stesura di istruzioni SQL di aggiornamento
In fase di progettazione, leditor Update SQL pu servire a scrivere le istruzioni SQL
per le propriet DeleteSQL, InsertSQL e ModifySQL. Se non lo si usa o se si desidera
modificare le istruzioni generate, bene aver presenti questi criteri quando si
scrivono le istruzioni per cancellare, inserire e modificare i record nella tabella base.
La propriet DeleteSQL deve contenere solo unistruzione SQL con il comando
DELETE. La tabella base da aggiornare deve essere indicata nella clausola FROM. Per
fare in modo che listruzione SQL cancelli nella tabella di base solo il record che
corrisponde al record cancellato nella cache di aggiornamento, si utilizza una
clausola WHERE. Nella clausola WHERE, si usa un parametro relativo a uno o pi
campi che consenta di identificare univocamente nella tabella di base il record
corrispondente al record da aggiornare nella cache. Se i parametri hanno lo stesso
nome del campo e sono preceduti da OLD_, assumono automaticamente i valori
dal campo corrispondente del record da aggiornare memorizzato nella cache. Se i
parametri hanno un qualsiasi altro nome, necessario fornirne i valori.
. Lc L
- LLc.. _Lc..
Alcuni tipi di tabella potrebbero non essere in grado di trovare il record nella tabella
base, quando i campi utilizzati per identificare il record contengono valori NULL. In
questi casi, laggiornamento per cancellazione non va a buon fine. Per ovviare a
questa situazione, bisogna aggiungere una condizione ai campi che potrebbero
contenere valori NULL utilizzando il predicato IS NULL (oltre a una condizione per i
valori non-NULL). Ad esempio, quando un campo FirstName pu contenere un
valore NULL:
. .i.cs
- is.i.c _is.i.c ~.
s.i.c _s.i.c s.i.c L. .
Listruzione InsertSQL deve contenere solo unistruzione SQL con il comando
INSERT. La tabella base da aggiornare deve essere indicata nella clausola INTO.
Nella clausola VALUES, va fornita una lista di parametri separati da virgole. Se i
parametri hanno lo stesso nome del campo, ricevono automaticamente il valore del
record di aggiornamento memorizzato nella cache. Se i nomi sono diversi, bisogna
fornire i valori del parametro. La lista di parametri fornisce i valori dei campi del
record appena inserito. Il numero di parametri deve essere uguale a quello dei campi
elencati nellistruzione.
L.. L. Lc
Lc.., ~.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-46 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
~. Lc..,
Nellistruzione ModifySQL ci deve essere solo unistruzione SQL con il comando
UPDATE. La tabella base da aggiornare va chiamata nella clausola FROM. Nella
clausola SET si includono una o pi assegnazioni di valore. Se i valori presenti nella
clausola SET sono parametri il cui nome uguale a quello dei campi, i parametri
ricevono automaticamente i valori dei campi con lo stesso nome presenti nel record
aggiornato nella cache. Si possono assegnare ulteriori valori di campo mediante altri
parametri, purch i nomi siano diversi e i valori siano indicati manualmente. Come
con listruzione DeleteSQL, va fornita una clausola WHERE per verificare
univocamente il record da aggiornare utilizzando parametri con lo stesso nome dei
campi ma preceduti da OLD_. Nellistruzione di aggiornamento qui di seguito, il
parametro :ItemNo riceve automaticamente un valore mentre :Price non lo riceve.
.~ Lc L
. LLc.. Lc.., ~. .cc
- LLc.. _Lc..
Considerando laggiornamento SQL precedente, ecco un esempio dove lutente
modifica un record esistente. Il valore originale del campo ItemNo 999. In una
griglia connessa al dataset memorizzato nella cache, lutente fa diventare 123 il valore
del campo ItemNo 123 mentre Amount diventa 20. Quando si richiama il metodo
ApplyUpdates, questa istruzione SQL agisce su tutti i record della tabella base in cui
il campo ItemNo 999, utilizzando il vecchio valore del campo nel parametro
:OLD_itemno. Nei record interessati, cambia il valore del campo ItemNo in 123
(utilizzando il parametro :ItemNo, il valore preso dalla griglia) mentre Amount
diventa 20.
Utilizzo di pi oggetti update
Quando si devono aggiornare pi tabelle base referenziate nel dataset, bisogna usare
pi oggetti update: uno per ciascuna tabella base aggiornata. Poich UpdateObject del
componente dataset consente di associare al dataset un solo oggetto update,
necessario associare a ciascun oggetto un dataset, assegnando alla sua propriet
DataSet il nome del dataset.
_
Quando si utilizzano pi oggetti update, possibile usare TBDEClientDataSet invece
di TClientDataSet con un provider esterno. Questo perch non si deve impostare la
propriet UpdateObject del dataset sorgente.
In fase di progetto, nellObject Inspector non disponibile la propriet DataSet degli
oggetti update. La si pu impostare solo in fase di esecuzione.
,.ic._>ii.c _c,
Loggetto update utilizza questo dataset per ottenere i valori di campi originali e
aggiornati per la sostituzione di parametro e, se si tratta di un dataset per BDE, per
verificare la sessione e il database da usare quando si trascrivono gli aggiornamenti.
Per far funzionare correttamente la sostituzione di parametro, la propriet DataSet
delloggetto update deve essere il dataset contenente i valori di campo aggiornati. Se
si usa un dataset per BDE per gli aggiornamenti in cache, questo lo stesso dataset
per BDE. Se si usa un dataset client, questo un dataset client fornito come
parametro al gestore di evento BeforeUpdateRecord.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-47
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
Quando loggetto update non stato assegnato alla propriet UpdateObject del
dataset, le sue istruzioni SQL non vengono eseguite automaticamente nel momento
in cui si richiama ApplyUpdates. Per aggiornare i record, bisogna chiamare
manualmente loggetto update da un gestore di evento OnUpdateRecord (se BDE che
memorizza gli aggiornamenti nella cache) o da un gestore di evento
BeforeUpdateRecord (se si usa un dataset client). Nel gestore di evento, le azioni
minime da eseguire sono
Se si utilizza un dataset client per memorizzare nella cache gli aggiornamenti,
bisogna accertarsi che le propriet DatabaseName e SessionName delloggetto da
aggiornare siano impostate sui valori delle propriet DatabaseName e SessionName
del dataset sorgente.
Il gestore di evento deve chiamare il metodo ExecSQL o Apply delloggetto update.
In questo modo, si richiama loggetto update per ciascun record da aggiornare. Per
ulteriori informazioni sullesecuzione di istruzioni di aggiornamento, consultare
Esecuzione delle istruzioni SQL qui di seguito.
Impostare il parametro UpdateAction del gestore di evento a uaApplied
(OnUpdateRecord) oppure assegnare il valore true al parametro Applied
(BeforeUpdateRecord).
Facoltativamente, si possono convalidare o modificare i dati, oppure effettuare altre
operazioni che dipendono dallaggiornamento di ciascun record.
j
Se in un gestore di evento OnUpdateRecord si chiama il metodo ExecSQL o Apply di un
oggetto update, accertarsi di non impostare la propriet UpdateObject del dataset a
quelloggetto update, altrimenti seguir un secondo tentativo di aggiornare ogni
record.
Esecuzione delle istruzioni SQL
Quando si usano pi oggetti update, non si deve associarli a un dataset
impostandone la propriet UpdateObject. La conseguenza sarebbe che le istruzioni
appropriate non verrebbero eseguite automaticamente al momento di applicare gli
aggiornamenti. Invece, loggetto update va richiamato esplicitamente scrivendo un
codice.
Ci sono due modi per richiamare loggetto update. Il modo scelto dipende dal fatto se
listruzione SQL utilizza o meno dei parametri per rappresentare i valori del campo:
Se listruzione SQL da eseguire utilizza parametri, chiamare il metodo Apply.
Se listruzione SQL da eseguire non utilizza parametri, meglio chiamare il
metodo ExecSQL.
_
Se listruzione SQL utilizza parametri diverso dai tipi incorporati (sia per i valori del
campo originali che per quelli aggiornati), i valori del parametro vanno forniti
manualmente invece di basarsi sulla sostituzione di parametro fornita dal metodo
Apply. Per informazioni su come indicare manualmente i valori dei parametri, vedere
Utilizzo della propriet Query di un componente update a pagina 24-49.
Per informazioni sulla sostituzione dei parametri predefiniti nelle istruzioni SQL di
un oggetto update, vedere Sostituzione dei parametri nelle istruzioni di
aggiornamento SQL a pagina 24-44.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-48 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i B D E p e r g l i a g g i o r n a m e n t i i n c a c h e
Chiamata del metodo Apply
Il metodo Apply di un componente update applica manualmente gli aggiornamenti al
record attivo. Il rpocedimento si svolge in due fasi:
1 I valori iniziale e modificato del campo del record sono collegati a parametri
nellistruzione SQL appropriata.
2 Listruzione SQL viene eseguita.
Per applicare laggiornamento del record attivo nella cache di aggiornamento
chiamare il metodo Apply. Il metodo Apply chiamato molto spesso dallinterno di
un gestore di evento OnUpdateRecord del dataset o dal gestore di evento
BeforeUpdateRecord di un provider.
j
Se si utilizza la propriet UpdateObject del dataset per associare il dataset e loggetto
update, Apply viene chiamato automaticamente. In questo caso, non bisogna
chiamarlo in un gestore di evento OnUpdateRecord in quanto vi sarebbe un secondo
tentativo di applicare laggiornamento del record attivo.
I gestori di evento OnUpdateRecord indicano il tipo di aggiornamento da applicare
con un parametro UpdateKind di tipo TUpdateKind. Il parametro va passato al metodo
Apply per indicare quale istruzione SQL utilizzare. Il seguente codice lo illustra
utilizzando un gestore di evento BeforeUpdateRecord:
veIi __?aatcaII .cii.cc.c,.iccc.ccc .c.c,
ii.c .cc., s.cii.c ci., ,.ic. ,.ic., beeI ~,,c.
,.ic._>ii.c ci.,
ii.c ,.c. i,aaeIc_caat ii.c >.cc.,
,.ic._>iicisc.i.c ,.c.>iicisc.i.c,
,.ic._>.css.i.c ,.c.>.css.i.c,
,.ic._>~,,,.ic.,
~,,c. ttae,
Utilizzo di TBatchMove
TBatchMove incorpora alcune funzioni del Borland Database Engine (BDE) che
consentono di duplicare un dataset, di aggiungere a un dataset record presi da un
altro, di aggiornare i record di un dataset con record presi da un altro dataset e di
cancellare da un dataset record corrispondenti a record di un altro dataset.
TBatchMove viene usato principalmente per:
Trasferire dati da un server a un datasource locale per analizzarli o per svolgere
altre operazioni.
Spostare un database desktop in tabelle su un server remoto come parte di
unoperazione di upsizing.
Un componente batch move pu creare sulla destinazione tabelle corrispondenti alle
tabelle sorgente, mappando automaticamente i nomi di colonna e i tipi di dati,
secondo quanto opportuno.
Creazione di un componente batch move
Per creare un componente batch move:
1 Mettere su una scheda o in un modulo dati un componente tabella o query per il
dataset da cui si vogliono importare record (chiamato dataset Source).
2 Mettere nella scheda o nel modulo dati il dataset dove si vogliono spostare i record
(chiamato dataset Destination).
3 Mettere nel modulo dati o nella scheda un componente TBatchMove prendendolo
dalla pagina BDE della Component palette e dare alla sua propriet Name un
valore univoco, appropriato allapplicazione.
4 Impostare la propriet Source del componente batch move al nome della tabella
dove copiare, aggiungere o aggiornare i record. possibile selezionare le tabelle
desiderate nella lista a discesa dei componenti dataset disponibili.
5 Impostare la propriet Destination del dataset dove creare, aggiungere a o
aggiornare. Si pu selezionare una tabella di destinazione nella lista a discesa dei
componenti dataset disponibili.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-51
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
U t i l i z z o d i T B a t c h M o v e
In caso di aggiunta, aggiornamento o cancellazione, Destination deve essere una
tabella di database esistente.
Se si vuole copiare una tabella e Destination una tabella esistente, eseguendo lo
spostamento batch vengono sovrascritti tutti i dati correnti nella tabella di
destinazione.
Se si crea una tabella nuova copiando una tabella esistente, il nome della tabella
risultante quello specificato dalla propriet Name del componente tabella dal
quale si copia. Il tipo di struttura della tabella risultante sar appropriato al
server specificato dalla propriet DatabaseName.
6 Impostare la propriet Mode per indicare il tipo di operazione da svolgere. Le
operazioni valide sono batAppend (limpostazione predefinita), batUpdate,
batAppendUpdate, batCopy e batDelete. Per informazioni su questi modi, consultare
Specifica della modalit di un componente batch move a pagina 24-51.
7 Facoltativamente, impostare la propriet Transliterate. Se Transliterate true
(limpostazione predefinita), i dati di tipo carattere sono tradotti dal set di caratteri
del dataset Source al set di caratteri del dataset Destination, secondo quanto
opportuno.
8 Facoltativamente, impostare le mappature di colonna utilizzando la propriet
Mappings. Non necessario impostare la propriet se si desidera che nello
spostamento batch la corrispondenza tra le colonne sia basata sulla rispettiva
posizione nelle tabelle di origine e di destinazione. Per ulteriori informazioni sulla
mappatura delle colonne, vedere Mappatura dei tipi di dati a pagina 24-53.
9 Facoltativamente, specificare le propriet ChangedTableName, KeyViolTableName e
ProblemTableName. Durante lo spostamento batch i record che creano problemi
incontrati nel corso delloperazione vengono messi nella tabella specificata da
ProblemTableName. Quando si aggiorna una tabella Paradox mediante uno
spostamento batch, le violazioni di chiave si possono segnalare nella tabella
specificata in KeyViolTableName. ChangedTableName elenca tutti i record che sono
cambiati nella tabella di destinazione come conseguenza delloperazione di
spostamento batch. Non specificando queste propriet , le tabelle di errore non
vengono create n utilizzate. Per ulteriori informazioni sulla gestione di errori di
spostamento batch, consultare Gestione degli errori delle operazioni batch move
a pagina 24-54.
Specifica della modalit di un componente batch move
La propriet Mode specifica loperazione che un componente batch move esegue:
Tabella 24.8 Modalit di un componente batch move
Propriet Scopo
batAppend Aggiunge record alla tabella di destinazione.
batUpdate Aggiorna i record nella tabella di destinazione con record corrispondenti
presi nella tabella di origine. Laggiornamento si basa sullindice ativo della
tabella di destinazione.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-52 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i T B a t c h M o v e
Aggiunta di record
Per laggiunta di dati, il dataset di destinazione deve rappresentare una tabella
esistente. Durante loperazione di aggiunta, BDE converte i dati per adeguarli ai tipi e
alle dimensioni del dataset di destinazione, se necessario. Se la conversione non
possibile, viene sollevata uneccezione e i dati non vengono aggiunti.
Aggiornamento di record
Per laggiornamento dei dati, il dataset di destinazione deve rappresentare una
tabella esistente e deve avere un indice definito che consenta il confronto dei record.
Se per il confronto sono usati i campi indice primari, i record che nel dataset di
destinazione hanno campi indice corrispondenti ai campi indice dei record nel
dataset di origine vengono riscritti con i dati del dataset di origine. Durante
loperazione di aggiornamento, BDE converte i dati per adeguarli ai tipi e alle
dimensioni del dataset di destinazione, se necessario.
Aggiunta e aggiornamento di record
Per aggiungere e aggiornare dati, il dataset di destinazione deve rappresentare una
tabella esistente e deve avere un indice definito che consenta di confrontare i record.
Se per il confronto si utilizzano i campi dellindice principale, i record che nel dataset
destinazione hanno campi indice corrispondenti ai record del dataset di origine
vengono sovrascritti con i dati del dataset sorgente. In caso contrario, al dataset
destinazione vengono aggiunti i dati presi dal dataset sorgente. Durante loperazione
di aggiunta e di aggiornamento, BDE converte i dati per adeguarli ai tipi e alle
dimensioni del dataset di destinazione, se necessario.
Copia di dataset
Per copiare un dataset sorgente, il dataset di destinazione non deve rappresentare
una tabella esistente. In caso contrario, loperazione di spostamento batch sovrascrive
la tabella esistente con una copia del dataset di origine.
Se i dataset di origine e di destinazione sono gestiti da motori di database di tipo
diverso, (per esempio, Paradox e InterBase), BDE crea a destinazione un dataset la cui
struttura quanto pi possibile simile a quella del dataset sorgente ed esegue
automaticamente le conversioni di tipo e di dimensione dei dati, secondo quanto
necessario.
batAppendUpdate Se nella tabella di destinazione esiste un record corrispondente, lo aggiorna.
Altrimenti, aggiunge i record nella tabella di destinazione.
batCopy Crea la tabella di destinazione in base alla struttura della tabella di origine.
Se la tabella di destinazione esiste gi , viene accantonata e ricreata.
batDelete Cancella nella tabella di destinazione i record corrispondenti ai record nella
tabella di origine.
Tabella 24.8 Modalit di un componente batch move (continua)
Propriet Scopo
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-53
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
U t i l i z z o d i T B a t c h M o v e
_
TBatchMove non copia strutture di metadati come indici, vincoli e procedure
registrate. necessario ricreare questi oggetti di metadati sul server di database, o
attraverso lo SQL Explorer, secondo quanto necessario.
Cancellazione di record
Per cancellare dati nel dataset di destinazione, questo deve rappresentare una tabella
esistente e deve avere un indice definito che consenta il confronto dei record. Se per il
confronto si usano i campi dellindice principale, i record i cui campi indice nel
dataset destinazione corrispondono ai campi indice dei record nel dataset sorgente
vengono cancellati nella tabella di destinazione.
Mappatura dei tipi di dati
In modalit batAppend, un componente batch move crea la tabella di destinazione in
base ai tipi di dati della colonna della tabella di origine. Le colonne e i tipi vengono
confrontati in base alla rispettiva posizione nelle tabelle di origine e di destinazione.
In altre parole, la prima colonna della sorgente viene fatta corrispondere con la prima
colonna della destinazione, e cos via.
Per ridefinire le mappature di colonna predefinite, si ricorre alla propriet Mappings.
Mappings una lista di mappature di colonna (una per riga) che pu assumere due
forme. Per mappare una colonna della tabella sorgente con una colonna dallo stesso
nome nella tabella di destinazione, si pu usare un listato semplice che specifica il
nome della colonna da far corrispondere. Ad esempio, la seguente mappatura
specifica che una colonna chiamata ColName nella tabella sorgente va fatta
corrispondere con una colonna dello stesso nome nella tabella di destinazione:
.i.c
Per fare corrispondere una colonna chiamata SourceColName nella tabella sorgente
con una colonna chiamata DestColName nella tabella di destinazione, la sintassi :
cs.i.c .cc.i.c
Se i tipi di dati della colonna sorgente e di destinazione non sono uguali, loperazione
di spostamento batch prova ad applicare la migliore delle corrispondenze. Tronca i
dati di tipo carattere, se necessario, e tenta un po di conversione, se possibile. (Ad
esempio, mappando una colonna CHAR(10) verso una colonna CHAR(5) troncher
gli ultimi cinque caratteri della colonna sorgente.
Come esempio di conversione, se una colonna sorgente di dati di tipo carattere viene
fatta corrispondere con una colonna di destinazione di tipo integer, loperazione di
spostamento batch converte il carattere 5 nel corrispondente valore integer. Valori
che non possono essere convertiti generano errori. Per ulteriori informazioni sugli
errori, consultare Gestione degli errori delle operazioni batch move a pagina 24-54.
Quando sposta dati fra tabelle di tipo diverso, un componente batch move traduce
opportunamente i tipi di dati in base al tipo di server del dataset. Per conoscere le pi
recenti tabelle di mappatura tra i vati tipi server, consultare la guida BDE in linea.
_
Per gli spostamenti batch verso server di database SQL, bisogna avere il server di
database in questione e una versione di C++Builder sulla quale sia installato lo SQL
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-54 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i T B a t c h M o v e
Link appropriato, oppure si pu usare ODBC, se si dispone degli opportuni driver
ODBC.
Esecuzione di unoperazione batch move
In fase di esecuzione, per eseguire unoperazione batch precedentemente preparata si
utilizza il metodo Execute. Ad esempio, se BatchMoveAdd il nome di un componente
batch move, la seguente istruzione lo esegue:
ic.c~..>xccc,
Si pu anche eseguire uno spostamento batch in fase di progettazione facendo clic
con il pulsante destro su un componente batch move e poi selezionando Execute nel
menu di scelta rapida.
Negli spostamenti batch, la propriet MovedCount conteggia il numero di record
spostati.
La propriet RecordCount specifica il numero massimo di record da spostare. Se
RecordCount nullo, tutti i record vengono spostati, iniziando con il primo record nel
dataset sorgente. Se RecordCount un numero positivo, vengono spostati i record fino
a un massimo di RecordCount, iniziando dal record attivo nel dataset sorgente. Se
RecordCount maggiore del numero di record tra il record attivo nel dataset sorgente
e il suo ultimo record, lo spostamento batch termina quando si raggiunge la fine del
dataset sorgente. possibile esaminare MoveCount per determinare quanti record
sono stati effettivamente trasferiti.
Gestione degli errori delle operazioni batch move
Due tipi di errori possono verificarsi nelle operazioni batch move: gli errori di
conversione del tipo di dati e le violazioni di integrit . TBatchMove ha diverse
propriet per rilevare e gestire gli errori.
La propriet AbortOnProblem specifica se loperazione va interrotta quando si verifica
un errore di conversione di tipo dati. Se AbortOnProblem true, loperazione batch
move viene annullata quando si verifica un errore. Se false, loperazione continua.
possibile esaminare la tabella che si specifica in ProblemTableName per determinare
quali record hanno causato problemi.
La propriet AbortOnKeyViol indica se loperazione va interrotta quando si verifica
una violazione di chiave Paradox.
La propriet ProblemCount indica il numero di record che non hanno potuto essere
gestiti nella tabella di destinazione senza perdite di dati. Se AbortOnProblem true,
questo numero uno, poich loperazione viene interrotta non appena si verifica un
errore.
Le seguenti propriet permettono a un componente batch move di creare tabelle
aggiuntive che documentano loperazione di spostamento batch:
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-55
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
I l D a t a D i c t i o n a r y
ChangedTableName, se specificato, crea una tabella locale Paradox contenente tutti i
record nella tabella di destinazione che sono cambiati a seguito di unoperazione
di aggiornamento o di cancellazione.
KeyViolTableName, se specificato, crea una tabella locale Paradox che contiene tutti
i record dalla tabella sorgente che hanno determinato una violazione di chiave
quando lavoravano con una tabella Paradox. Se AbortOnKeyViol true, la tabella
conterr al massimo un voce poich loperazione viene interrotta al primo
problema incontrato.
ProblemTableName, se specificato, crea una tabella locale Paradox contenente tutti i
record che non stato possibile registrare nella tabella di destinazione a causa di
errori di conversione del tipo dati. Ad esempio, la tabella potrebbe contenere i
record dalla tabella di sorgente contenenti dati che, per essere inseriti nella tabella
di destinazione, dovevano essere troncati. Se AbortOnProblem true, la tabella
contiene al massimo un record poich loperazione stata interrotta al primo
problema incontrato.
_
Non specificando ProblemTableName, i dati nel record vengono troncati e inseriti nella
tabella di destinazione.
Il Data Dictionary
Quando si utilizza BDE per accedere ai dati, lapplicazione ha accesso al Data
Dictionary. Il Data Dictionary mette a disposizione unarea di memoria
personalizzabile, indipendente dalle applicazioni, dove possibile creare set di
attributi di campi estesi che descrivono il contenuto e laspetto dei dati.
Ad esempio, se si sviluppano frequentemente applicazioni finanziarie, possibile
creare un certo numero di set speciali di attributi di campo che descrivono vari
formati di visualizzazione delle valute. Quando i dataset dellapplicazione vengono
creati in fase di progetto, invece che impostando manualmente i campi delle valute in
ciascun dataset, si possono associare i campi in questione a un set esteso di attributi
di campo nel dizionario dati. Luso del dizionario dati assicura un aspetto coerente
dei dati allinterno delle singole applicazioni e tra unapplicazione e laltra.
In un ambiente client/server, il Data Dictionary pu risiedere su un server remoto, in
modo da consentire unulteriore condivisione delle informazioni.
Per imparare in che modo creare set estesi di attributi di campo utilizzando leditor
Fields in fase di progettazione, e come associarli ai campi di tutti i dataset di
unapplicazione, consultare Creazione di set di attributi per i componenti campo a
pagina 23-14. Per saperne di pi sulla creazione di un dizionario dati e degli attributi
di campo estesi con SQL e con Database Explorers, consultare i relativi file di guida
in linea.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-56 G u i d a a l l a p r o g r a mma z i o n e
S t r u m e n t i p e r o p e r a r e c o n B D E
Uninterfaccia di programmazione al Data Dictionary disponibile nel file header
drintf (situato nella directory include\VCL). Linterfaccia fornisce i seguenti metodi:
Strumenti per operare con BDE
Uno dei vantaggi di usare BDE come meccanismo di accesso di dati la ricchezza di
programmi di utilit di cui C++Builder dispone. Questi programmi di utilit
comprendono:
SQL Explorer e Database Explorer: C++Builder viene fornito con una di queste
due applicazioni, a seconda della versione acquistata. Entrambi consentono di
Esaminare le tabelle e le strutture di database esistenti. SQL Explorer permette
di esaminare e di eseguire query su database SQL remoti.
Tabella 24.9 Interfaccia del Data Dictionary
Routine Utilizzo
DictionaryActive Indica se il dizionario dati attivo.
DictionaryDeactivate Disattiva il dizionario dati.
IsNullID Indica se un certo ID un ID nullo
FindDatabaseID Restituisce lID di un database fornendo il suo alias.
FindTableID Restituisce lID di una tabella in un database specificato.
FindFieldID Restituisce lID di un campo in una tabella specificata.
FindAttrID Restituisce lID di un set di attributi dato.
GetAttrName Restituisce il nome di un set di attributi dato il suo ID.
GetAttrNames Esegue una callback per ogni attributo impostato nel dizionario.
GetAttrID Restituisce lID dellattributo impostato di un campo specificato.
NewAttr Crea un nuovo set di attributi da un componente campo.
UpdateAttr Aggiorna un set di attributi corrispondente alle propriet di un
campo.
CreateField Crea un componente campo in base agli attributi registrati.
UpdateField Modifica le propriet di un campo per farle corrispondere a un
set di attributi specificato.
AssociateAttr Associa un set di attributi allID specificato di un campo.
UnassociateAttr Rimuove un set di attributi dallID di un campo.
GetControlClass Restituisce la classe di controllo dellID specificato di un
attributo.
QualifyTableName Restituisce un nome di tabella per esteso (qualificato dal nome
utente).
QualifyTableNameByName Restituisce un nome della tabella per esteso (qualificato dal nome
utente).
HasConstraints Indica se il dataset ha vincoli nel dizionario.
UpdateConstraints Aggiorna i vincoli importati di un dataset.
UpdateDataset Aggiorna un dataset secondo le impostazioni e i vincoli attivi nel
dizionario.
U s o d i B o r l a n d D a t a b a s e E n g i n e 24-57
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
S t r u m e n t i p e r o p e r a r e c o n B D E
Riempire tabelle di dati
Creare set estesi di attributi di campo nel Data Dictionary o associarli ai campi
di unapplicazione.
Creare e gestire alias BDE.
SQL Explorer consente inoltre di:
Creare oggetti SQL, come procedure registrate su server di database remoti.
Visualizzare il testo ricostruito di oggetti SQL su server di database remoti.
Eseguire procedure SQL.
SQL Monitor: SQL Monitor permette di tenere sotto controllo le comunicazioni
fra il server di database remoto e BDE. Si possono filtrare i messaggi che si
desidera guardare, limitandoli solo alle categorie che interessano. SQL Monitor
molto utile in fase di debug delle applicazioni.
Programma di utilit BDE Administration: Il programma di utilit BDE
Administration permette di aggiungere nuovi driver di database, di configurare le
impostazioni predefinite dei driver esistenti e di creare nuovi alias BDE.
Database Desktop: Se si utilizzano tabelle Paradox o dBASE, Database Desktop
permette di visualizzare e di modificare i dati, di creare nuove tabelle e di
ristrutturare le tabelle esistenti. Il controllo consentito da Database Desktop
migliore di quello ottenuto utilizzando i metodi di un componente TTable (ad
esempio, permette di specificare i controlli di validit e i driver di linguaggio).
Inoltre, fornisce lunico meccanismo per ristrutturare le tabelle Paradox e dBASE
che non sia quello di fare chiamate dirette alla API di BDE.
Copyright 11/29/00, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
November 29, 2000 2:20 pm (J:\source\Devguide\BOOK\Delphonly\1_intro.fm5)
24-58 G u i d a a l l a p r o g r a mma z i o n e
S t r u m e n t i p e r o p e r a r e c o n B D E
O p e r a z i o n i c o n c o mp o n e n t i A D O 25-1
C a p i t o l o
25
Capitolo25Operazioni con componenti ADO
I componenti dbGo forniscono laccesso ai dati tramite il framework ADO. ADO
(acronimo di ActiveX Data Objects di Microsoft), una serie di oggetti COM che
consentono laccesso ai dati tramite un DB provider OLE. I componenti dbGo
incapsulano questi oggetti ADO nellarchitettura di database C++Builder.
Nelle applicazioni basate su ADO, lo strato ADO formato da Microsoft ADO 2.1, da
un DB provider OLE o da un driver ODBC per laccesso al datastore, dal software
client per lo specifico sistema di database utilizzato (nel caso di database SQL), da un
sistema di database back-end (per sistemi di database SQL) e da un database. Perch
lapplicazione sia completamente funzionale, tutti questi sistemi devono essere
accessibili allapplicazione basata su ADO.
Gli oggetti ADO pi importanti sono gli oggetti Connection, Command e Recordset.
Questi oggetti ADO sono rappresentati dai componenti TADOConnection,
TADOCommand, e dai componenti ADO dataset. Il framework ADO include altri
oggetti helper, come gli oggetti Field e Properties, ma solitamente non sono
utilizzati in modo diretto nelle applicazioni dbGo e non sono inglobati in componenti
dedicati.
Questo capitolo presenta i componenti dbGo e discute le funzionalit esclusive che
essi introducono nella comune architettura database di C++Builder. Prima di
affrontare le funzionalit caratteristiche dei componenti dbGo, bene imparare a
conoscere le funzionalit comuni dei componenti connection di database e dei
dataset descritti nel capitolo Capitolo 21, Connessione ai database e nel Capitolo
22, I dataset.
Panoramica dei componenti ADO
La pagina ADO page della Component palette contiene i componenti dbGo. Questi
componenti consentono ai programmatori di connettersi ad un datastore ADO e
quindi di eseguire comandi e recuperare dati dalle tabelle nel database utilizzando il
framework ADO. Sul computer host deve essere installato ADO 2.1 (o una versione
25-2 G u i d a a l l a p r o g r a mma z i o n e
C o n n e s s i o n e a d a t a s t o r e A D O
successiva). Inoltre, deve essere installato un software client per il sistema di
database di destinazione (come Microsoft SQL Server), oltre ad un driver OLE DB o
un driver ODBC specifico per quel particolare sistema di database.
La maggior parte dei componenti dbGo hanno delle controparti dirette nei
componenti disponibili per altri meccanismi di accesso ai dati: un componente
connection di database (TADOConnection) e diversi tipi di dataset. Inoltre, dbGo
include TADOCommand, un componente semplice che non un dataset ma che
rappresenta un comando SQL da eseguire sul datastore ADO.
In tabella sono elencati i componenti ADO.
Connessione a datastore ADO
Le applicazioni dbGo utilizzano ActiveX Data Objects (ADO) 2.1 di Microsoft per
interagire con un provider OLE DB che si collega a un datastore e accede ai suoi dati.
Uno degli elementi che un datastore pu rappresentare un database.
Unapplicazione basata su ADO richiede linstallazione di ADO 2.1 sul computer
client. ADO e OLE DB sono forniti da Microsoft e sono installati con Windows.
Un provider ADO uno dei vari tipi possibili di accesso, dai driver nativi OLE DB ai
driver ODBC. Questi driver devono essere installati sul computer client. I driver OLE
DB dei diversi sistemi di database sono forniti dal produttore del database o da terzi.
Tabella 25.1 Componenti ADO
Componente Uso
TADOConnection Un componente database connection per stabilire una connessione con
un datastore ADO; pi componenti dataset e command di ADO possono
condividere questa connessione per eseguire comandi, recuperare dati e
operare sui metadati.
TADODataSet Il dataset primario utilizzato per reperire e operare sui dati;
TADODataSet pu recuperare dati da una o pi tabelle; pu connettersi
a un datastore in modo diretto oppure tramite un componente
TADOConnection.
TADOTable Un dataset di tipo tabella per reperire e operare su un recordset prodotto
da una singola tabella di database; TADOTable pu connettersi a un
datastore in modo diretto oppure tramite un componente
TADOConnection.
TADOQuery Un dataset di tipo query per reperire e operare su un recordset prodotto
da unistruzione SQL valida; TADOQuery pu eseguire anche istruzioni
SQL DDL (data definition language). Pu connettersi a un datastore in
modo diretto o tramite un componente TADOConnection
TADOStoredProc Un dataset di tipo procedura registrata per eseguire procedure
registrate; TADOStoredProc esegue procedure registrate che recuperano
o non recuperano dati. Pu connettersi a un datastore in modo diretto o
tramite un componente TADOConnection.
TADOCommand Un semplice componente per eseguire comandi (istruzioni SQL che non
restituiscono set di risultati); TADOCommand pu essere utilizzato con
un componente dataset di supporto, o recuperare un dataset da una
tabella; pu connettersi a un datastore in modo diretto o tramite un
componente TADOConnection.
O p e r a z i o n i c o n c o mp o n e n t i A D O 25-3
C o n n e s s i o n e a d a t a s t o r e A D O
Se lapplicazione utilizza un database SQL, come Microsoft SQL Server o Oracle, il
software client del sistema di database deve essere installato anche sul computer
client. Il software client fornito dal produttore del database e viene installato dal
CD (o dal disco) del sistema di database).
Per collegare lapplicazione al datastore, si utilizza un componente connection ADO
(TADOConnection), che va configurato per limpiego di uno dei provider ADO
disponibili. Configurare il componente ADO connection in modo che utilizzi uno dei
provider ADO disponibili. Bench TADOConnection non sia strettamente necessario,
dato che il comando e i componenti dataset ADO possono connettersi utilizzando
direttamente la tloro propriet ConnectionString, possibile utilizzarlo per
condividere una sola connessione tra pi componenti ADO. In questo modo, si pu
ridurre la quantit di risorse utilizzate e si ha la possibilit di creare transazioni che
attraversano pi dataset.
Come altri componenti di connessione ai database, TADOConnection supporta queste
funzioni
Controllo delle connessioni
Controllo del login al server
Gestione delle transazioni
Operazioni con i dataset associati
Invio di comandi al server
Ottenimento di metadati
Oltre a queste funzionalit , comuni a tutti i componenti di connessione ai database,
TADOConnection supporta
Unampia gamma di opzioni utilizzabili per la messa a punto della connessione.
La capacit di elencare gli oggetti command che utilizzano la connessione.
Eventi ulteriori quando vengono eseguite operazioni comuni.
Connessione a un datastore mediante TADOConnection
Uno o pi componenti dataset e comandi ADO possono condividere una singola
connessione a un datastore mediante lutilizzo di TADOConnection. A questo scopo i
componenti dataset e comandi vengono associati al componente connessione
mediante le rispettive propriet Connection. In fase di progetto, selezionare
nellObject Inspector il componente connessione desiderato dallelenco a discesa
della propriet Connection. In fase di esecuzione, assegnare il riferimento alla
propriet Connection. Per esempio, il comando seguente associa un componente
TADODataSet con un componente TADOConnection.
~ii.c>cc ~cc,
Il componente connection rappresenta un oggetto di connessione ADO. Prima di
poterlo utilizzare per stabilire una connessione, necessario identificare il datastore a
cui ci si vuole collegare. Di solito, si forniscono informazioni mediante la propriet
ConnectionString, una stringa delimitata da punto e virgola che elenca uno o pi
parametri di connessione indicati con nome. ConnectionString una stringa separata
con punti e virgola che elenca uno o pi parametri di connessione con nome. Questi
parametri identificano il datastore specificando o il nome di un file contenente le
25-4 G u i d a a l l a p r o g r a mma z i o n e
C o n n e s s i o n e a d a t a s t o r e A D O
informazioni di connessione, o il nome di un provider ADO e un riferimento che
identifica il datastore. Per fornire le informazioni, si utilizzano i seguenti i nomi
predefiniti di parametro:
Cos, un valore tipico di ConnectionString si presenta in questo modo
..c..~._,ii .cc._L.
_
I parametri di connessione di ConnectionString non devono obbligatoriamente
includere il parametro Provider, o Remote Provider, se il provider ADO viene
specificato utilizzando la propriet Provider. Analogamente, non bisogna specificare
il parametro Data Source se si utilizza la propriet DefaultDatabase.
Inoltre, ai parametri elencati, ConnectionString pu aggiungere particolari parametri
di connessione richiesti dallo specifico provider ADO utilizzato. Questi parametri di
connessione aggiuntivi possono includere lID utente e la password, se si preferisce
immettere mediante codice le informazioni di login.
In progettazione, possibile utilizzare il Connection String Editor per generare una
stringa di connessione selezionando da elenchi gli elementi della connessione (come
il provider e il server). Fare clic nellObject Inspector sul pulsante ellissi della
propriet ConnectionString per attivare il Connection String Editor, che un editor di
propriet ActiveX fornito da ADO.
Una volta specificata la propriet ConnectionString (e, facoltativamente, la propriet
Provider), si pu utilizzare il componente connection ADO per connettersi al
datastore ADO o scollegarsi, sebbene in certi casi si preferisca prima utilizzare altre
propriet per mettere a punto la connessione. Quando si collega o si scollega dal
datastore, TADOConnection permette di rispondere ad alcuni eventi ulteriori, oltre
quelli comuni a tutti i componenti connection database. Questi eventi aggiuntivi
sono descritti in Eventi allo stabilirsi di una connessione a pagina 25-8 e Eventi
alla chiusura del collegamento a pagina 25-8.
_
Se non si attiva esplicitamente la connessione impostando a true la propriet
Connected del componente connessione, lattivazione avverr automaticamente non
appena si attiver il primo componente dataset oppure si eseguir per la prima volta
un comando usando un componente comandi ADO.
Accesso alloggetto connessione
Utilizzare la propriet ConnectionObject di TADOConnection per accedere
direttamente alloggetto connessione ADO sottostante. Utilizzando questo
riferimento, possibile accedere alle propriet e chiamare i metodi delloggetto ADO
Connection sottostante.
Parametro Descrizione
Provider Nome del provider locale ADO da utilizzare per la connessione.
Data Source Nome del datastore.
File name Nome del file contenente informazioni di connessione.
Remote Provider Nome del provider ADO residente su una macchina remota.
Remote Server Nome del server remoto quando si utilizza un provider remoto.
O p e r a z i o n i c o n c o mp o n e n t i A D O 25-5
C o n n e s s i o n e a d a t a s t o r e A D O
Luso delloggetto ADO Connection sottostante richiede una buona conoscenza
operativa degli oggetti ADO in generale e delloggetto ADO Connection in particolare.
Non si consiglia lutilizzo delloggetto Connection a meno che non si abbia familiarit
con le operazioni con gli oggetti Connection. Per informazioni specifiche sullutilizzo
degli oggetti Connection ADO, consultare la Guida di Microsoft Data Access SDK.
Messa a punto di una connessione
Uno dei vantaggi dellimpiego di TADOConnection per stabilire una connessione con
un datastore, invece di fornire semplicemente una stringa di connessione per i
componenti di comando e dataset ADO, che TADOConnection consente di
controllare molto efficacemente le condizioni e gli attributi della connessione.
Come forzare connessioni asincrone
Utilizzare la propriet ConnectOptions per forzare una connessione asincrona. Le
connessioni asincrone permettono a unapplicazione di continuare lelaborazione
senza attendere che la connessione sia aperta completamente.
Per impostazione predefinita, ConnectionOptions impostata a coConnectUnspecified
che consente al server di decidere il miglior tipo di connessione. Per rendere
asincrona la connessione in modo esplicito, impostare ConnectOptions a
coAsyncConnect.
Le routine di esempio riportate di seguito attivano e disattivano le connessioni
asincrone nel componente connessione specificato:
veIi __?aatcaII .~scccc.ccc .c.c
~cc>sc,
~cc>cc,s c~sccc,
~cc>,c,
~cc>sc,
~cc>cc,s cccs,cc.c.,
~cc>,c,
~cc>sc
. ~cc>~ccsisxi..ci
~cc>~ccs .ic~ccs xi..ci,
~cc>,c
~cc>sc
. ~cc>~ccsisxi..ci
~cc>~ccs .ic~ccs >> xi..ci,
~cc>,c
..i.. .,
..i.. ..,
. ~ii.c>..i.,
.s>~...,
~ii.c>.c,
.. ~ii.c>..i.,
.s>~....,
~ii.c>c..i.s~~...,..,
caae s...c.
.isi>.ics>Lc.s,>cx 'cic. cc.',
bteak,
caae s...c.
.isi>.ics>Lc.s,>cx 'ic. cc.',
bteak,
caae sccc.
.isi>.ics>Lc.s,>cx 'ccc. cc.',
bteak,
caae s.c.
.isi>.ics>Lc.s,>cx '.c. cc.',
bteak,
I? cxss'c.icc'
cccc'c.icc',
.isci>.ics>Lc.s,>cx '.ic .c .ccc.',
~ii.c>.icc'c.icc',
25-16 G u i d a a l l a p r o g r a mma z i o n e
U s o d i d a t a s e t A D O
veIi __?aatcaII .i.c.ccc .c.c
I? cxss'c.icc'
~ii.c>i..c'c.icc',
eIae
.isci>.ics>Lc.s,>cx '.ic .c .cs cxs',
~..i.>xccc,
~..i.>icc,
....,
.
Il codice seguente utilizza un TSQLDataSet per creare questa procedura registrata. Si
noti dellutilizzo della propriet ParamCheck per impedire al dataset di confondere i
parametri nella definizione della procedura registrata (:EMP_NO e :PROJ_ID) con un
parametro della query che crea la procedura registrata.
._ii.c>.ii.cc. ?aIae,
._ii.c>..i.,c c_c,
._ii.c>..i.cx ~ . _.._. .._. ..~L. .. ._L
-~ ~. L. . ._L . .._. - .._. .._. L.
._L ...., .,
._ii.c>xcc._,
Configurazione di cursor master/detail collegati
Esistono due modi per utilizzare cursor collegati al fine di impostare una relazione
master/detail che utilizza un dataset unidirezionale per il set di dettaglio. Il metodo
utilizzato dipende dal tipo di dataset unidirezionale che si utilizza. Una volta
impostata tale relazione, il dataset unidirezionale (la parte molti in una relazione
uno-a-molti) fornisce laccesso solo a quei record che corrispondono al record
corrente del set master (la parte uno in una relazione uno-a-molti).
TSQLDataSet e TSQLQuery richiedono che si utilizzi una query con parametri per
stabilire una relazione master/detail. Questa la tecnica per la creazione di tali
relazioni su tutti i dataset di tipo query. Per i dettagli sulla creazione delle relazioni
master/detail con dataset di tipo query, vedere Impostazione di relazioni master/
detail mediante parametri a pagina 22-49.
Per impostare una relazione master/detail dove il set di dettaglio unistanza di
TSQLTable, utilizzare le propriet MasterSource e MasterFields esattamente come si
farebbe con qualsiasi altro dataset di tipo tabella. Per i dettagli sulla creazione delle
relazioni master/detail con dataset di tipo tabella, vedere Impostazione di relazioni
master/detail mediante parametri a pagina 22-49.
Accesso a informazioni di schema
Esistono due modi per ottenere informazioni su ci che disponibile sul server.
Queste informazioni, dette informazioni di schema o metadati, includono
informazioni su quali tabelle e procedure registrate sono disponibili sul server e
informazioni su quelle tabelle e su quelle procedure registrate (come i campi
contenuti in una tabella, gli indici definiti e i parametri utilizzati da una procedura
registrata).
U s o d i d a t a s e t u n i d i r e z i o n a l i 26-13
A c c e s s o a i n f o r m a z i o n i d i s c h e m a
Il modo pi semplice per ottenere questi metadati quello di utilizzare i metodi di
TSQLConnection. Questi metodi riempiono una lista di stringhe esistente oppure un
oggetto list con i nomi di tabelle, di procedure registrate, di campi o di indici o con i
descrittori di parametro. Questa tecnica analoga a quella utilizzata con tutti gli altri
componenti di connessione database per riempire le liste con metadati. Questi
metodi sono descritti in Ottenimento di metadati a pagina 21-14.
Se si richiedono informazioni di schema pi dettagliate, possibile riempire un
dataset unidirezionale con metadati. Invece di riempire una semplice lista, il dataset
unidirezionale vine riempito con le informazioni di schema, in cui ogni record
rappresenta una singola tabella, una procedura registrata, un indice, un campo o un
parametro.
Prelievo di metadati in un dataset unidirezionale
Per riempire i dataset unidirezionali con i metadati ottenuti dal server di database,
necessario prima indicare quali dati si desidera vedere utilizzando il metodo
SetSchemaInfo. SetSchemaInfo accetta tre parametri:
Il tipo di informazioni di schema (metadati) che si desidera ottenere. Questo pu
essere una lista di tabelle (stTables), una lista di tabelle di sistema (stSysTables), una
lista di procedure registrate (stProcedures), una lista di campi in una tabella
(stColumns), una lista di indici (stIndexes) o una lista dei parametri utilizzati da una
procedura registrata (stProcedureParams). Ogni tipo di informazioni utilizza un set
diverso di campi per descrivere gli elementi nella lista. Per i dettagli sulle strutture
di questi dataset, vedere La struttura dei dataset di metadati a pagina 26-14.
Se si vogliono ottenere informazioni su campi, indici o parametri di una procedura
registrata, il nome della tabella o della procedura registrata a cui tali informazioni
si applicano. Se si vogliono ottenere altri tipi di informazioni di schema, questo
parametro NULL.
Un modello che deve trovare una corrispondenza per ogni nome restituito. Questo
modello un modello SQL come Cust%, che utilizza i caratteri jolly % (che
corrisponde a una stringa di caratteri arbitrari di qualsiasi lunghezza) e _ (che
corrisponde a un singolo carattere arbitrario). Per utilizzare nel modello un
simbolo percentuale o un carattere di sottolineatura, si deve raddoppiare il
carattere (%% o __). Se non si desidera utilizzare un modello, questo parametro
pu essere NULL.
_
Se si vogliono ottenere informazioni di schema sulle tabelle (stTables), le informazioni
di schema risultanti possono descrivere tabelle comuni, tabelle di sistema, viste e/o
sinonimi, a seconda del valore della propriet TableScope della connessione SQL.
La seguente chiamata richiede una tabella che elenca tutte le tabelle di sistema
(tabelle del server che contengono metadati):
._ii.c>.c.cc.iL.s.sicc, '', '',
Se si apre il dataset dopo questa chiamata a SetSchemaInfo, il dataset risultante
contiene un record per ogni tabella, con colonne che riportano il nome di tabella, il
26-14 G u i d a a l l a p r o g r a mma z i o n e
A c c e s s o a i n f o r m a z i o n i d i s c h e m a
tipo, il nome dello schema, e cos via. Se il server non utilizza tabelle di sistema per
memorizzare i metadati (ad esempio MySQL), il dataset non conterr alcun record.
Nellesempio precedente si utilizzato solo il primo parametro. Si supponga, invece,
di voler ottenere una lista di parametri di input per una procedura registrata di nome
MyProc. Si supponga, inoltre, che chi ha scritto quella procedura registrata abbia
chiamato tutti i parametri utilizzando un prefisso per indicare se erano parametri di
input o di output (inName, outValue e cos via). In questo caso, si potrebbe
chiamare SetSchemaInfo in questo modo:
._ii.c>.c.cc.iL.s.cc.c.ii.s, '..c', '`',
Il dataset risultante una tabella di parametri di input con colonne che descrivono le
propriet di ogni parametro.
Ottenimento dei dati dopo aver utilizzato il dataset per i metadati
Dopo aver effettuato una chiamata a SetSchemaInfo, esistono due modi per ritornare
con il dataset alle query o alle procedure registrate in esecuzione:
Modificare la propriet CommandText, specificando la query, la tabella o la
procedura registrata da cui si desidera ottenere i dati.
Chiamare SetSchemaInfo, impostando il primo parametro a stNoSchema. In questo
caso, il dataset ritorna a prendere i dati specificati dal valore corrente di
CommandText.
La struttura dei dataset di metadati
Per ogni tipo di metadati a cui possibile accedere utilizzando TSQLDataSet, esiste
un insieme predefinito di colonne (campi) che viene compilato con le informazioni
sugli elementi del tipo richiesto.
Informazioni sulle tabelle
Quando si richiedono informazioni sulle tabelle (stTables o stSysTables), il dataset
risultante include un record per ciascuna tabella. Ha le seguenti colonne:
Tabella 26.1 Colonne nelle tabelle di metadati che elencano tabelle
Nome della colonna
Tipo di
campo Contenuto
RECNO ftInteger Un numero di record che identifica in modo univocamente
ciascun record.
CATALOG_NAME ftString Il nome del catalogo (database) che contiene la tabella.
analogo al parametro Database di un componente connection
SQL.
SCHEMA_NAME ftString Il nome dello schema che identifica il proprietario della
tabella.
U s o d i d a t a s e t u n i d i r e z i o n a l i 26-15
A c c e s s o a i n f o r m a z i o n i d i s c h e m a
Informazioni sulle procedure registrate
Quando si richiedono informazioni sulle procedure registrate (stProcedures), il
dataset risultante include un record per ogni procedura registrata. Ha le seguenti
colonne:
TABLE_NAME ftString Il nome della tabella. Questo campo determina la sequenza di
ordinamento del dataset.
TABLE_TYPE ftInteger Identifica il tipo di tabella. la somma di uno o pi dei
seguenti valori:
1: Tabella
2: Vista
4: Tabella di sistema
8: Sinonimo
16: Tabella temporanea
32: Tabella locale.
Tabella 26.2 Colonne nelle tabelle di metadati che elencano procedure registrate
Nome della colonna
Tipo di
campo Contenuto
RECNO ftInteger Un numero di record che identifica in modo univocamente
ciascun record.
CATALOG_NAME ftString Il nome del catalogo (database) che contiene la procedura
registrata. analogo al parametro Database di un componente
connection SQL.
SCHEMA_NAME ftString Il nome dello schema che identifica il proprietario della
procedura registrata.
PROC_NAME ftString Il nome della procedura registrata. Questo campo determina la
sequenza di ordinamento del dataset.
PROC_TYPE ftInteger Identifica il tipo di procedura registrata. la somma di uno o
pi dei seguenti valori:
1: Procedura (nessun valore restituito)
2: Funzione (restituisce un valore)
4: Package
8: Procedura di sistema
IN_PARAMS ftSmallint Il numero di parametri di input
OUT_PARAMS ftSmallint Il numero di parametri di output.
Tabella 26.1 Colonne nelle tabelle di metadati che elencano tabelle
Nome della colonna
Tipo di
campo Contenuto
26-16 G u i d a a l l a p r o g r a mma z i o n e
A c c e s s o a i n f o r m a z i o n i d i s c h e m a
Informazioni sui campi
Quando si richiedono informazioni sui campi in una tabella specificata (stColumns), il
dataset risultante include un record per ciascun campo. Include le seguenti colonne:
Informazioni sugli indici
Quando si richiedono informazioni sugli indici su una tabella (stIndexes), il dataset
risultante include un record per ogni campo in ciascun record. (Gli indici multi-
Tabella 26.3 Colonne nelle tabelle di metadati che elencano campi
Nome della colonna
Tipo di
campo Contenuto
RECNO ftInteger Un numero di record che identifica in modo
univocamente ciascun record.
CATALOG_NAME ftString Il nome del catalogo (database) che contiene la tabella di
cui si stanno elencando i campi. analogo al parametro
Database di un componente connection SQL.
SCHEMA_NAME ftString Il nome dello schema che identifica il proprietario del
campo.
TABLE_NAME ftString Il nome della tabella che contiene i campi.
COLUMN_NAME ftString Il nome del campo. Questo valore determina la sequenza
di ordinamento del dataset.
COLUMN_POSITION ftSmallint La posizione della colonna nella rispettiva tabella.
COLUMN_TYPE ftInteger Identifica il tipo di valore nel campo. la somma di uno o
pi dei seguenti valori:
1: Identificativo della riga
2: Versione della riga
4: Campo ad incremento automatico
8: Campo con valore predefinito
COLUMN_DATATYPE ftSmallint Il tipo di dati della colonna. Questa una delle costanti
logiche di tipo field definite in sqllinks.h.
COLUMN_TYPENAME ftString Una stringa che descrive il tipo di dati. Queste sono le
stesse informazioni contenute in COLUMN_DATATYPE
e in COLUMN_SUBTYPE, ma nel formato utilizzato in
alcune istruzioni DDL.
COLUMN_SUBTYPE ftSmallint Un sottotipo per il tipo di dati della colonna. Questa una
delle costanti logiche di tipo subtype definite in sqllinks.h.
COLUMN_PRECISION ftInteger La dimensione del tipo di campo (numero di caratteri in
una stringa, byte in uno campo Byte, cifre significative in
un valore BCD, membri di un campo ADT, e cos via).
COLUMN_SCALE ftSmallint Il numero di cifre alla destra della virgola per valori BCD,
o discendenti su ADT e campi array.
COLUMN_LENGTH ftInteger Il numero di byte richiesti per memorizzare i valori del
campo.
COLUMN_NULLABLE ftSmallint Un Boolean che indica se il campo pu essere lasciato in
bianco (0 significa che il campo richiede un valore).
U s o d i d a t a s e t u n i d i r e z i o n a l i 26-17
A c c e s s o a i n f o r m a z i o n i d i s c h e m a
record vengono descritti utilizzando pi record):Tabella 26.4 Colonne nelle tabelle di
metadati che elencano indici:
Informazioni sui parametri delle procedure registrate
Quando si richiedono informazioni sui parametri di una procedura registrata
(stProcedureParams), il dataset risultante include un record per ogni parametro. Ha le
seguenti colonne:
Tabella 26.4 Colonne nelle tabelle di metadati che elencano indici
Nome della colonna
Tipo di
campo Contenuto
RECNO ftInteger Un numero di record che identifica in modo univocamente
ciascun record.
CATALOG_NAME ftString Il nome del catalogo (database) che contiene lindice.
analogo al parametro Database di un componente
connection SQL.
SCHEMA_NAME ftString Il nome dello schema che identifica il proprietario
dellindice.
TABLE_NAME ftString Il nome della tabella per cui lindice definito.
INDEX_NAME ftString Il nome dellindice. Questo campo determina la sequenza di
ordinamento del dataset.
PKEY_NAME ftString Indica il nome della chiave primaria.
COLUMN_NAME ftString Il nome del campo (colonna) nellindice.
COLUMN_POSITION ftSmallint La posizione di questo campo nellindice.
INDEX_TYPE ftSmallint Identifica il tipo di indice. la somma di uno o pi dei
seguenti valori:
1: Non-univoco
2: Univoco
4: Chiave primaria
SORT_ORDER ftString Indica che lindice ascendente (a) o discendente (d).
FILTER ftString Descrive una condizione di filtro che limita i record
indicizzati.
Tabella 26.5 Colonne nelle tabelle di metadati che elencano parametri
Nome della colonna
Tipo di
campo Contenuto
RECNO ftInteger Un numero di record che identifica in modo univocamente
ciascun record.
CATALOG_NAME ftString Il nome del catalogo (database) che contiene la procedura
registrata. analogo al parametro Database di un
componente connection SQL.
SCHEMA_NAME ftString Il nome dello schema che identifica il proprietario della
procedura registrata.
PROC_NAME ftString Il nome della procedura registrata che contiene il
parametro.
PARAM_NAME ftString Il nome del parametro. Questo campo determina la
sequenza di ordinamento del dataset.
26-18 G u i d a a l l a p r o g r a mma z i o n e
D e b u g d i a p p l i c a z i o n i d b E x p r e s s
Debug di applicazioni dbExpress
Mentre si esegue il debug dellapplicazione database, potrebbe rivelarsi utile
controllare i messaggi SQL che vengono inviati e ricevuti dal server di database
attraverso il componente connection, inclusi quelli generati automaticamente (ad
esempio da un componente provider o dal driver dbExpress).
Utilizzo di TSQLMonitor per controllare i comandi SQL
TSQLConnection utilizza un componente di appoggio, TSQLMonitor, per intercettare
questi messaggi e salvarli in una lista di stringhe. TSQLMonitor opera in modo simile
al programma di utilit SQL monitor che possibile utilizzare con BDE, tranne per il
fatto che controlla solo quei comandi che implicano un singolo componente
TSQLConnection invece di tutti i comandi gestiti da dbExpress.
Per utilizzare TSQLMonitor:
1 Aggiungere un componente TSQLMonitor alla scheda o al modulo dati che
contiene il componente TSQLConnection di cui si desidera controllare i comandi
SQL.
2 Impostare la propriet SQLConnection al componente TSQLConnection.
3 Impostare la propriet Active di SQL monitor a true.
PARAM_TYPE ftSmallint Identifica il tipo di parametro. analogo alla propriet
ParamType di un oggetto TParam.
PARAM_DATATYPE ftSmallint Il tipo di dati del parametro. Questa una delle costanti
logiche di tipo field definite in sqllinks.h.
PARAM_SUBTYPE ftSmallint Un sottotipo per il tipo di dati del parametro. Questa una
delle costanti logiche di tipo subtype definite in sqllinks.h.
PARAM_TYPENAME ftString Una stringa che descrive il tipo di dati. Queste sono le stesse
informazioni contenute in PARAM_DATATYPE e in
PARAM_SUBTYPE, ma in un formato utilizzato in alcune
istruzioni DDL.
PARAM_PRECISION ftInteger Il numero massimo di cifre nei valori a virgola mobile o di
byte (per stringhe e campi Bytes).
PARAM_SCALE ftSmallint Il numero di cifre alla destra della virgola in valori a virgola
mobile.
PARAM_LENGTH ftInteger Il numero di byte richiesti per memorizzare i valori del
parametro.
PARAM_NULLABLE ftSmallint Un Boolean che indica se il parametro pu essere lasciato in
bianco (0 significa che il parametro richiede un valore).
Tabella 26.5 Colonne nelle tabelle di metadati che elencano parametri
Nome della colonna
Tipo di
campo Contenuto
U s o d i d a t a s e t u n i d i r e z i o n a l i 26-19
D e b u g d i a p p l i c a z i o n i d b E x p r e s s
Man mano che i comandi SQL vengono inviati al server, la propriet TraceList di SQL
monitor viene aggiornata automaticamente elencando tutti i comandi SQL
intercettati.
possibile salvare questa lista in un file specificando un valore per la propriet
FileName e quindi impostando la propriet AutoSave a true. AutoSave fa in modo che
SQL monitor salvi in un file il contenuto della propriet TraceList ogni volta che
intercetta un nuovo messaggio.
Se non si desidera lappesantimento dovuto al salvataggio del file ogni volta che
viene intercettato un messaggio, possibile utilizzare il gestore di evento OnLogTrace
per salvare il file solo dopo lintercettazione di vari messaggi. Ad esempio, il
seguente gestore di evento salva il contenuto di TraceList ogni 10 messaggi,
cancellando il file di registrazione dopo averlo salvato in modo che la lista non
divenga mai troppo lunga:
veIi __?aatcaII .._.iccccc .c.c, veIi L.
c. c .c i.c
~s. c.i.c 'c',
c.i.c c.i.c - L.,.>i,
c.i.c c.i.c - 'x'
,.>i ,.>i - ,
.ic ccs . i. cci c s
,.>.iccc.i.c,
,.>iccs>ci,
_
Se si decidesse di utilizzare il gestore di evento precedente, alla chiusura
dellapplicazione sarebbe necessario salvare anche una eventuale lista parziale
(contenente meno di 10 voci.
Utilizzo di una callback per controllare i comandi SQL
Invece di utilizzare TSQLMonitor, possibile personalizzare il modo in cui
lapplicazione tiene traccia dei comandi SQL utilizzando il metodo
SetTraceCallbackEvent del componente SQL connection. SetTraceCallbackEvent accetta
due parametri: una callback di tipo TSQLCallbackEvent e un valore definito
dallutente che viene passato alla funzione callback.
La funzione callback accetta due parametri: CallType e CBInfo:
CallType un parametro riservato per un successivo utilizzo.
CBInfo un puntatore a un structure che include la categoria (la stessa di CallType),
il testo del comando SQL e il valore definito dallutente che viene passato al
metodo SetTraceCallbackEvent.
26-20 G u i d a a l l a p r o g r a mma z i o n e
D e b u g d i a p p l i c a z i o n i d b E x p r e s s
La callback restituisce un valore di tipo CBRType, di solito cbrUSEDEF.Il driver
dbExpress chiama la callback ogni volta che il componente SQL connection passa un
comando al server o il server restituisce un messaggio di errore.
j
Non chiamare SetTraceCallbackEvent se alloggetto TSQLConnection associato un
componente TSQLMonitor. TSQLMonitor utilizza il meccanismo di callback per
operare e TSQLConnection pu supportare una sola callback per volta.
U t i l i z z o d e i d a t a s e t c l i e n t 27-1
C a p i t o l o
27
Capitolo27Utilizzo dei dataset client
I dataset client sono dataset specializzati che conservano tutti i propri dati in
memoria. Il supporto per il trattamento dei dati che essi memorizzano in memoria
fornito da midas.dll. Il formato utilizzato dai dataset client per la memorizzazione di
dati indipendente ed facilmente trasportabile, il che consente ai dataset client di
Leggere e scrivere in file dedicati su disco, agendo come un dataset basato su file.
Le propriet e i metodi che supportano questo meccanismo sono descritti in Uso
di un dataset client con dati basati su file a pagina 27-35.
Memorizzare in cache gli aggiornamenti per i dati provenienti da un server di
database. Le funzioni dei dataset client che supportano gli aggiornamenti in cache
sono descritte in Utilizzo di un dataset client per registrare in cache gli
aggiornamenti a pagina 27-17.
Rappresentare i dati nella parte client di unapplicazione multi-tier. Per funzionare
in questo modo, il dataset client deve operare con un provider esterno, come
descritto in Uso di un dataset client con un provider di dati a pagina 27-26. Per
informazioni sulle applicazioni database multi-tier, consultare il Capitolo 29,
Creazione di applicazioni multi-tier.
Rappresentare i dati da una sorgente diversa da un dataset. Poich un dataset
client pu utilizzare i dati provenienti da un provider esterno, i provider
specializzati possono adattare una variet di fonti di informazioni per operare con
i dataset client. Ad esempio, possibile utilizzare un provider XML per consentire
a un dataset client di rappresentare le informazioni contenute in un documento
XML.
Sia che si utilizzino i dataset client per dati basati su file, per memorizzare in cache gli
aggiornamenti, per dati provenienti da un provider esterno (come nel caso di
operazioni con un documento XML o in unapplicazione multi-tier) o per una
combinazione di questi approcci come nel caso di unapplicazione modello
briefcase, possibile sfruttare i vantaggi offerti dalla vasta gamma di funzioni
supportate dai dataset client per operare con i dati.
27-2 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
Utilizzo dei dati tramite un dataset client
Come si fa con qualunque dataset, possibile utilizzare i dataset client per fornire i
dati per i controlli associati ai dati ricorrendo a un componente sorgente dati. Per
informazioni su come visualizzare i dati del database nei controlli data-aware,
consultare il Capitolo 19, Uso dei controlli dati.
I dataset client implementano tutte le propriet e i metodi ereditati da TDataSet. Per
una presentazione completa di questo comportamento generico dei dataset,
consultare il Capitolo 22, I dataset.
Inoltre, i dataset client implementano molte delle funzioni comuni ai dataset di tipo
tabella come:
Ordinamento dei record con indici.
Utilizzo di indici per la ricerca di record.
Limitazione dei record con gli intervalli.
Creazione di relazioni master/detail.
Controllo dellaccesso in lettura/scrittura
Creazione del dataset sottostante
Svuotamento del dataset
Sincronizzazione dei dataset client
Per i dettagli relativi a queste funzioni, consultare Utilizzo dei dataset di tipo tabella
a pagina 22-26.
I dataset client differiscono dagli altri dataset in quanto mantengono tutti i loro dati
in memoria. Pertanto, il loro supporto per alcune funzioni di database possono
comportare ulteriori capacit o considerazioni. Questo capitolo descrive alcune di
queste funzioni comuni e le differenze introdotte dai dataset client.
Come spostarsi tra i dati nei dataset client
Se unapplicazione utilizza controlli associati ai dati standard, un utente pu
spostarsi tra i record di un dataset client usando il comportamento nativo di questi
controlli. possibile spostarsi tra i record da programma utilizzando i metodi
standard dei dataset, quali First, Last, Next e Prior. Per ulteriori informazioni su questi
metodi, consultare Spostamenti nei dataset a pagina 22-5.
Diversamente dalla maggior parte dei dataset, i dataset client possono anche
posizionare il cursore su un record specifico del dataset utilizzando la propriet
RecNo. Generalmente, unapplicazione usa RecNo per determinare il numero di
record del record attivo. I dataset client possono, tuttavia, impostare RecNo a un
particolare numero di record per far s che quel record diventi attivo.
Come limitare i record da visualizzare
To Per limitare temporaneamente laccesso da parte degli utenti a un sottogruppo di
dati disponibili, le applicazioni possono utilizzare gli intervalli e i filtri. Quando si
applica un intervallo o un filtro, il dataset client non visualizza tutti i dati presenti
U t i l i z z o d e i d a t a s e t c l i e n t 27-3
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
nella sua memoria cache. Mostra, invece, solo i dati che soddisfano le condizioni
dellintervallo o del filtro. Per ulteriori informazioni sullutilizzo di filtri, consultare
Visualizzazione e modifica di un sottoinsieme di dati usando i filtri a pagina 22-13.
Per ulteriori informazioni sugli intervalli, consultare Limitazione dei record con gli
intervalli a pagina 22-32.
Con la maggior parte dei dataset le stringhe del filtro vengono suddivise in comandi
SQL che vengono poi implementati nel database server. Ne deriva che il dialetto SQL
del server limita le operazioni che possono essere utilizzate nelle stringhe del filtro. I
dataset client implementano un proprio supporto per i filtri, che include un maggior
numero di operazioni rispetto agli altri dataset. Per esempio, quando si utilizza un
dataset client, le espressioni filtro possono includere operatori stringa che
restituiscono sottostringhe, operatori che suddividono i valori data/ora, ed altro
ancora. I dataset client consentono, inoltre, luso di filtri sui campi BLOB o su tipi di
campi complessi come i campi ADT e i campi array.
Nella tabella seguente sono elencati gli operatori e le funzioni che i dataset client
possono utilizzare nei filtri, oltre a un confronto con altri dataset che supportano
filtri:
Tabella 27.1 Supporto per i filtri nei dataset client
Operatore o
funzione Esempio
Supportato
dagli altri
dataset Commento
Confronto
= State = 'CA' S
<> State <> 'CA' S
>= DateEntered >= '1/1/1998' S
<= Total <= 100,000 S
> Percentile > 50 S
< Field1 < Field2 S
BLANK State <> 'CA' or State = BLANK S I record vuoti non
vengono visualizzati a
meno che non siano
esplicitamente inclusi nel
filtro.
IS NULL Field1 IS NULL No
IS NOT NULL Field1 IS NOT NULL No
Operatori logici
and State = 'CA' and Country = 'US' S
or State = 'CA' or State = 'MA' S
not not (State = 'CA') S
Operatori
aritmetici
+ Total + 5 > 100 Dipende dal
driver
Vale per numeri, stringhe
o date (ore) + numero.
27-4 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
- Field1 - 7 <> 10 Dipende dal
driver
Vale per numeri, stringhe
o date (ore) - numero.
* Discount * 100 > 20 Dipende dal
driver
Vale solo per numeri.
/ Discount > Total / 5 Dipende dal
driver
Vale solo per numeri.
Funzioni di
stringa
Upper Upper(Field1) = 'ALWAYS' No
Lower Lower(Field1 + Field2) = 'josp' No
Substring Substring(DateFld,8) = '1998'
Substring(DateFld,1,3) = 'JAN'
No Il valore va dalla posizione
del secondo argomento
fino alla fine o fino al
numero di caratteri
specificato nel terzo
argomento. Il primo
carattere ha la posizione 1.
Trim Trim(Field1 + Field2)
Trim(Field1, '-')
No Rimuove il terzo
argomento dalla parte
iniziale e finale. Se non c
un terzo argomento,
elimina gli spazi.
TrimLeft TrimLeft(StringField)
TrimLeft(Field1, '$') <> ''
No Vedi Trim.
TrimRight TrimRight(StringField)
TrimRight(Field1, '.') <> ''
No Vedi Trim.
Funzioni
DateTime
Year Year(DateField) = 2000 No
Month Month(DateField) <> 12 No
Day Day(DateField) = 1 No
Hour Hour(DateField) < 16 No
Minute Minute(DateField) = 0 No
Second Second(DateField) = 30 No
GetDate GetDate - DateField > 7 No Rappresenta la data e lora
correnti.
Date DateField = Date(GetDate) No Restituisce la parte data di
un valore datetime.
Time TimeField > Time(GetDate) No Restituisce la parte ora di
un valore datetime.
Tabella 27.1 Supporto per i filtri nei dataset client (continua)
Operatore o
funzione Esempio
Supportato
dagli altri
dataset Commento
U t i l i z z o d e i d a t a s e t c l i e n t 27-5
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
Quando si applicano intervalli o filtri, il dataset client memorizza anche tutti i suoi
record in memoria. Lintervallo o il filtro determina semplicemente quali record sono
disponibili per i controlli che servono per visualizzare o per spostarsi tra i dati del
dataset client.
_
Quando si recuperano dati da un provider possibile anche limitare i dati
memorizzati nel dataset client fornendo dei parametri al provider. Per ulteriori
informazioni, consultare Limitazione dei record mediante parametri a
pagina 27-31.
Editing di dati
I dataset client rappresentano i propri dati come un pacchetto dati in memoria.
Questo pacchetto il valore della propriet Data del dataset client. Per impostazione
predefinita, tuttavia, le modifiche non vengono memorizzate nella propriet Data.
Invece, gli inserimenti, le cancellazioni e le modifiche (apportate dagli utenti o da
programma) vengono memorizzati in un registro interno delle modifiche,
rappresentato dalla propriet Delta. Luso di un registro delle modifiche serve a due
scopi:
Il registro delle modifiche necessario per applicare gli aggiornamenti a un server
di database o a un componente provider esterno.
Il registro delle modifiche fornisce un supporto sofisticato per lannullamento
delle modifiche.
La propriet LogChanges consente di disattivare temporaneamente la registrazione.
Quando LogChanges true, le modifiche vengono memorizzate nel registro. Quando
false, le modifiche vengono apportate direttamente alla propriet Data. possibile
disattivare il registro delle modifiche nelle applicazioni basate su file se il supporto
per lannullamento non necessario.
Varie
Like Memo LIKE '%filters%' No Funziona come in SQL -92
senza la clausola ESC. Se
applicato a campi BLOB,
FilterOptions determina se
viene tenuto conto di
maiuscole e minuscole.
In Day(DateField) in (1,7) No Funziona come in SQL-92.
Il secondo argomento
una lista di valori tutto
dello stesso tipo.
* State = 'M*' S Carattere jolly per
confronti parziali.
Tabella 27.1 Supporto per i filtri nei dataset client (continua)
Operatore o
funzione Esempio
Supportato
dagli altri
dataset Commento
27-6 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
Le modifiche rimangono nel registro finch non vengono rimosse dallapplicazione.
Le applicazioni rimuovono le modifiche quando
Vengono annullate
Vengono salvate
_
Il salvataggio del dataset client in un file non rimuove le modiche dal registro delle
modifiche. Quando si ricarica il dataset, le propriet Data e Delta rimangono
identiche a comerano quando i dati sono stati salvati.
Annullamento delle modifiche
Anche se la versione originale di un record rimane invariata in Data, ogni volta che
un utente modifica un record, lo lascia e vi ritorna, lutente vede la versione
modificata per ultima di un record. Se un utente o unapplicazione modifica un
record un certo numero di volte, ogni versione modificata del record viene
memorizzata nel registro delle modifiche come una voce separata.
La memorizzazione di ciascuna modifica apportata a un record rende possibile il
supporto di pi livelli di operazioni di annullamento di quante ne occorrerebbero per
ripristinare lo stato precedente di un record:
Per rimuovere lultima modifica apportata a un record, occorre chiamare
UndoLastChange. UndoLastChange accetta un parametro booleano, FollowChange,
che indica se riposizionare o no il cursore sul record ripristinato (true), o se
lasciare il cursore sul record corrente (false). Se a un record sono state apportate
diverse modifiche, ogni chiamata a UndoLastChange rimuove un livello di
modifiche. UndoLastChange restituisce un valore booleano che indica la riuscita o
meno delloperazione. Se la rimozione ha successo, UndoLastChange restituisce
true. Per determinare se ci sono ulteriori modifiche da annullare, si deve ricorrere
alla propriet ChangeCount. ChangeCount indica il numero di modifiche
memorizzate nel registro delle modifiche.
Anzich rimuovere ogni livello di modifica apportata a un singolo record,
possibile rimuoverle tutti contemporaneamente. Per rimuovere tutte le modifiche
di un record, occorre selezionarlo e chiamare RevertRecord. RevertRecord rimuove
dal registro delle modifiche tutti i cambiamenti apportati al record attivo.
Per ripristinare un record cancellato, per prima cosa impostare la propriet
StatusFilter a [usDeleted], il che rende visibili i record cancellati. Quindi,
spostarsi sul record che si desidera ripristinare e chiamare RevertRecord. Infine,
ripristinare la propriet StatusFilter a [usModified, usInserted, usUnmodified] in
modo che la versione modificata del dataset (ora contenente il record ripristinato)
sia nuovamente visibile.
In qualunque punto durante le modifiche possibile salvare lo stato attuale del
registro delle modifiche utilizzando la propriet SavePoint. La lettura di SavePoint
restituisce un marcatore nella posizione corrente del registro delle modifiche. In
seguito, se si vogliono annullare tutte modifiche apportate dopo la lettura del
punto in cui stato effettuato il salvataggio, occorre impostare SavePoint al valore
letto in precedenza. Lapplicazione pu ottenere valori per diversi punti di
salvataggio. Tuttavia, una volta effettuata la copia di riserva del registro delle
U t i l i z z o d e i d a t a s e t c l i e n t 27-7
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
modifiche in un punto di salvataggio, i valori di tutti i punti di salvataggio letti
successivamente dallapplicazione non sono validi.
Chiamando CancelUpdates, si possono abbandonare tutte le modifiche
memorizzate nel registro. CancelUpdates azzera il registro delle modifiche,
rimuovendo di fatto tutte le modifiche apportate ai record. CancelUpdates va,
pertanto, utilizzato con molta attenzione.Dopo aver chiamato CancelUpdates, non
possibile recuperare le modifiche che si trovavano nel registro.
Salvataggio delle modifiche
I dataset client utilizzano meccanismi diversi per incorporare le modifiche dal
registro delle modifiche, a seconda del fatto che i dataset client registrino i propri dati
in un file rappresentino dei dati ottenuti mediante un provider. Indipendentemente
dal meccanismo usato, il registro delle modifiche viene svuotato automaticamente
quando tutti gli aggiornamenti sono stati incorporati.
Le applicazioni autonome possono semplicemente fondere le modifiche nella cache
locale rappresentata dalla propriet Data. Esse non devono preoccuparsi di come
risolvere i problemi derivanti dalle modifiche locali con quelle apportate da altri
utenti. Per fondere il registro delle modifiche nella propriet Data, occorre chiamare il
metodo MergeChangeLog. Il paragrafo Fusione delle modifiche nei dati a
pagina 27-36 descrive questa procedura.
impossibile utilizzare MergeChangeLog se si utilizza il dataset client per
memorizzare in cache gli aggiornamenti o per rappresentare i dati da un componente
provider esterno. Le informazioni nel registro delle modifiche sono necessarie per la
risoluzione dei record aggiornati con i dati memorizzati nel database (o nel dataset
sorgente). In alternativa, si pu chiamare ApplyUpdates, che tenta di scrivere le
modifiche nel database server (o nel dataset sorgente) e aggiorna la propriet Data
solo quando le modifiche sono state inoltrate con successo. Per ulteriori informazioni
su questa procedura, consultare Applicazione degli aggiornamenti a pagina 27-22.
Definizione dei vincoli dei valori dati
I dataset client possono imporre dei vincoli alle modifiche apportabili da un utente ai
dati. Questi vincoli vengono applicati non appena lutente tenta di registrare le
modifiche nel registro delle modifiche. sempre possibile fornire vincoli
personalizzati. In questo modo possibile preparare dei propri vincoli, definiti
dallapplicazione, sui valori che gli utenti possono inviare a un dataset client.
Inoltre, quando i dataset client rappresentano dati di un server a cui si accede
mediante BDE, essi impongono anche i vincoli sui dati importati dal server di
database. Se il dataset client opera con un componente provider esterno, il provider
pu controllare se quei vincoli vengono inviati al dataset client e il dataset client pu
controllare se li utilizza. Per ulteriori informazioni su come il provider controlla se i
vincoli sono inclusi nei pacchetti dati, consultare Gestione dei vincoli del server a
pagina 28-13. Per i dettagli su come e perch il dataset client pu disattivare
limposizione dei vincoli del server, consultare Gestione dei vincoli dal server a
pagina 27-32.
27-8 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
Specifica di vincoli custom
possibile utilizzare le propriet dei componenti campo del dataset client per
imporre dei vincoli sui dati che lutente pu immettere. Ogni componente campo ha
due propriet che possibile utilizzare per specificare i vincoli:
La propriet DefaultExpression definisce un valore predefinito che viene assegnato
al campo nel caso in cui lutente non immetta un valore. Si noti che se anche il
database server, o il dataset sorgente, assegna al campo unespressione
predefinita, la versione del dataset client ha la precedenza perch viene assegnata
prima che laggiornamento sia applicato al database server o al dataset sorgente.
La propriet CustomConstraint consente di assegnare una condizione restrittiva che
deve essere soddisfatta prima di poter confermare il valore del campo. I vincoli
custom definiti in questo modo vengono imposti in aggiunta a tutte le restrizioni
importate dal server. Per ulteriori informazioni sulle operazioni con i vincoli
custom sui componenti campo, consultare Creazione di un vincolo custom a
pagina 23-22.
In aggiunta, tramite la propriet Constraints del dataset client, possibile creare
anche vincoli a livello di record. Constraints una raccolta di oggetti
TCheckConstraint, in cui ciascun oggetto rappresenta una condizione differente.
Utilizzare la propriet CustomConstraint di un oggetto TCheckConstraint per
aggiungere i propri vincoli che saranno controllati al momento della registrazione
dei record.
Ordinamento e indicizzazione
Luso degli indici fornisce diversi vantaggi alle applicazioni:
Consente ai dataset client di individuare rapidamente i dati.
Permettono di applicare gli intervalli per limitare i record disponibili.
Permettono alle applicazioni di impostare relazioni con altri dataset come tabelle
di consultazione o schede master/detail.
Consente di specificare lordine in cui devono apparire i record.
Se un dataset client rappresenta i dati di un server o utilizza un provider esterno,
eredita un indice e un criterio di ordinamento predefinito in base ai dati che riceve.
Lindice predefinito si chiama DEFAULT_ORDER. Si pu utilizzare questo
ordinamento, ma non possibile cambiare o cancellare lindice.
Oltre allindice predefinito, il dataset client mantiene un secondo indice, denominato
CHANGEINDEX, sui record modificati nel registro delle modifiche (propriet Delta).
CHANGEINDEX ordina tutti i record del dataset client come apparirebbero se
venissero applicate le modifiche specificate in Delta. CHANGEINDEX si basa
sullordinamento ereditato da DEFAULT_ORDER. Come avviene con
DEFAULT_ORDER, non possibile cambiare o cancellare lindice CHANGEINDEX.
possibile utilizzare altri indici esistenti o crearne di propri. Nelle sezioni seguenti
viene descritta la procedura per la creazione e luso degli indici con i dataset client.
U t i l i z z o d e i d a t a s e t c l i e n t 27-9
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
_
Potrebbe essere opportuno riesaminare gli argomenti relativi agli indici nei dataset di
tipo tabella, validi anche nel caso dei dataset client. Gli argomenti sono trattati nelle
sezioni Ordinamento dei record con indici a pagina 22-27 e Limitazione dei
record con gli intervalli a pagina 22-32.
Aggiunta di un nuovo indice
Esistono due modi per aggiungere indici ad un dataset client:
Per creare in fase di esecuzione un indice temporaneo che ordini i record del
dataset client possibile utilizzare la propriet IndexFieldNames. Indicare i nomi
dei campi, separandoli con il carattere punto e virgola. La sequenza con cui sono
indicati i campi nellelenco determina il loro ordine nellindice.
Questo il metodo meno efficiente per aggiungere indici. Non possibile
specificare indici discendenti, o che tengano conto di maiuscole e minuscole, e
lindice risultante non supporta il raggruppamento. Una volta chiuso il dataset,
questi indici non sono permanenti e non vengono salvati se si salva il dataset client
in un file.
Per creare in fase di esecuzione un indice utilizzabile per il raggruppamento,
chiamare il metodo AddIndex. AddIndex consente di specificare le propriet
dellindice, compresi:
Il nome dellindice. Questo pu essere utilizzato per cambiare gli indici in fase
di esecuzione.
I campi che costituiscono lindice. Lindice utilizza tali campi per ordinare i
record e per individuare i record che hanno valori specifici in quei campi.
La modalit secondo la quale lindice ordina i record. Per impostazione definita,
gli indici impongono un ordinamento crescente (basato sulla macchina locale).
Questo ordinamento predefinito tiene conto della differenza tra lettere
maiuscole e minuscole. possibile specificare delle opzioni che facciano s che
lintero indice ignori la differenza tra maiuscole e minuscole o che ordinino in
modo discendente. In alternativa, possibile fornire una lista di campi da
ordinare senza tener conto delle maiuscole\minuscole e una lista di campi da
ordinare in ordine discendendente.
Il livello predefinito di raggruppamento supportato per lindice.
Gli indici creati con AddIndex non permangono quando si chiude il dataset client.
(Ovvero, vanno persi quando si riapre il dataset client). Non possibile chiamare
AddIndex quando il dataset chiuso. Gli indici che vengono aggiunti tramite
AddIndex non vengono salvati quando si salva il dataset client in un file.
Il terzo modo per creare un indice consiste nel crearlo al momento della creazione
del dataset client. Prima di creare il dataset client, specificare gli indici desiderati
utilizzando la propriet IndexDefs. Gli indici vengono creati in un secondo
momento insieme al dataset associato quando si chiamer CreateDataSet. Per
ulteriori informazioni sulla creazione di dataset client, consultare Creazione e
cancellazione di tabelle a pagina 22-40.
27-10 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
Come con AddIndex, gli indici creati con il raggruppamento del supporto del
dataset possono eseguire lordinamento ascendente su alcuni campi e discendente
su altri, e possono tenere conto delle maiuscole/minuscole su alcuni campi e non
su altri. Gli indici cos creati permangono sempre e vengono salvati quando si
salva il dataset client in un file.
_
Lindicizzazione e lordinamento possono essere effettuati sono sui campi calcolati
internamente con i dataset client.
Cancellazione e cambio degli indici
Per rimuovere un indice creato per un dataset client, occorre chiamare DeleteIndex e
specificare il nome dellindice da rimuovere. Non possibile cancellare gli indici
DEFAULT_ORDER e CHANGEINDEX.
Per usare un indice diverso quando sono disponibili pi indici, si deve ricorrere alla
propriet IndexName per selezionare lindice da utilizzare. In progettazione, si pu
operare la scelta dagli indici disponibili nella casella a discesa della propriet
IndexName dellObject Inspector.
Uso degli indici per il raggruppamento dei dati
Quando si usa un indice nel dataset client, questo impone automaticamente un tipo
di ordinamento sui record. Dato questo ordinamento, i record adiacenti
generalmente contengono valori duplicati nei campi che costituiscono lindice. Per
esempio, si consideri il seguente frammento di una tabella ordini indicizzata sui
campi SalesRep e Customer:
Dato questo ordinamento, i valori adiacenti nella colonna SalesRep sono duplicati. Lo
stesso avviene allinterno dei record di SalesRep 1, i cui valori adiacenti della colonna
Customer sono duplicati.Cio, i dati sono raggruppati per SalesRep e allinterno del
gruppo SalesRep sono raggruppati per Customer. Ogni raggruppamento ha un
livello associato. In questo caso il gruppo SalesRep ha il livello 1 (in quanto non
annidato in nessun altro gruppo), mentre il gruppo Customer ha come livello 2 (in
quanto annidato nel gruppo con il livello 1). Il livello di raggruppamento
corrisponde allordine dei campi nellindice.
I dataset client consentono di determinare dove sta il record attivo allinterno di un
determinato livello di raggruppamento. Ci consente allapplicazione di visualizzare
i record in modo differente, a seconda che si tratti del primo record del gruppo, della
parte centrale di un gruppo o dellultimo record di un gruppo. Per esempio, si
potrebbe voler visualizzare il valore di un campo solo se il primo record del
SalesRep Customer OrderNo Amount
1 1 5 100
1 1 2 50
1 2 3 200
1 2 6 75
2 1 1 10
2 3 4 200
U t i l i z z o d e i d a t a s e t c l i e n t 27-11
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
gruppo, eliminando i valori duplicati. Questa operazione con la tabella precedente
produce il seguente risultato:
Per determinare dove cade il record attivo allinterno di un gruppo, si deve ricorrere
al metodo GetGroupState. GetGroupState accetta un integer corrispondente al livello
del gruppo e restituisce un valore che indica dove cade il valore corrente nel gruppo
(primo record, secondo record o nessuno dei due).
Quando si crea un indice, si pu specificare il livello di raggruppamento supportato
(fino al numero dei campi dellindice). GetGroupState non in grado di fornire
informazioni sui gruppi oltre quel livello, anche se lindice ordina i record
utilizzando campi aggiuntivi.
Rappresentazione dei valori calcolati
Come con qualunque dataset, possibile aggiungere campi calcolati al dataset client.
Questi sono campi i cui valori vengono calcolati in modo dinamico, generalmente
sulla base dei valori di altri campi dello stesso record. Per ulteriori informazioni
sulluso dei campi calcolati, consultare Definizione di un campo calcolato a
pagina 23-7.
I dataset client, tuttavia, consentono lottimizzazione quando i campi vengono
calcolati utilizzando i campi calcolati internamente. Per maggiori informazioni sui
campi calcolati internamente, consultare il paragrafo successivo Uso di campi
calcolati internamente nei dataset client.
anche possibile comunicare ai dataset client di creare campi calcolati che sommino i
dati di diversi record utilizzando le aggregazioni di manutenzione. Per ulteriori
informazioni sulla aggregazioni di manutenzione, consultare Uso delle
aggregazioni di manutenzione a pagina 27-12.
Uso di campi calcolati internamente nei dataset client
Negli altri dataset lapplicazione deve calcolare il valore dei campi calcolati ogni
volta che cambia il record o lutente modifica dei campi del record attivo. Ci avviene
in un gestore di evento OnCalcFields.
Anche se ancora possibile procedere in questo modo, i dataset client consentono di
ridurre al minimo il numero di volte in cui i campi calcolati devono essere ricalcolati,
salvandoli nei dati del dataset client. Quando i valori calcolati vengono salvati con il
dataset client, essi devono ancora essere ricalcolati quando lutente modifica il record
SalesRep Customer OrderNo Amount
1 1 5 100
2 50
2 3 200
6 75
2 1 1 10
3 4 200
27-12 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
attivo, ma lapplicazione non richiede il ricalcolo dei valori ogni volta che cambia il
record attivo. Per salvare i valori calcolati nei dati del dataset client, si devono
utilizzare i campi calcolati ulteriormente al posto dei campi calcolati.
I campi calcolati internamente, esattamente come i campi calcolati, vengono elaborati
in un gestore di evento OnCalcFields. Tuttavia, possibile ottimizzare il gestore di
evento contrassegnando la propriet State del dataset client. Quando State
dsInternalCalc, occorre ricalcolare i campi calcolati internamente. Quando State
dsCalcFields, occorre ricalcolare i campi calcolati normali.
Per usare i campi calcolati internamente, occorre definire i campi come tali prima di
creare il dataset client. A seconda che si utilizzino i campi persistenti o le definizioni
di campo, loperazione viene svolta in uno dei seguenti modi:
Se si utilizzano campi persistenti, si devono definire i campi come calcolati
internamente selezionando InternalCalc nel Fields editor.
Se si utilizzano le definizioni dei campi, impostare a true la propriet
InternalCalcField della definizione rilevante del campo.
_
Altri tipi di dataset utilizzano campi calcolati internamente. Tuttavia, con gli altri
dataset questi valori non vengono calcolati in un gestore di evento OnCalcFields.
Invece, vengono calcolati automaticamente tramite da BDE o da un server di
database remoto.
Uso delle aggregazioni di manutenzione
I dataset client forniscono il supporto per il riepilogo dei dati provenienti da gruppi
di record. Dal momento che questi riepiloghi vengono aggiornati automaticamente
quando si modificano i dati del dataset, questi dati riepilogati vengono definiti una
aggregazione di manutenzione.
Nella loro forma pi semplice le aggregazioni di manutenzione consentono di
ottenere informazioni come la somma di tutti i valori di una colonna del dataset
client. Esse sono, comunque, sufficientemente flessibili per supportare un grande
numero di calcoli di somma e di fornire totali parziali di gruppi di record definiti in
un indice che supporta il raggruppamento.
Specifica delle aggregazioni
Per specificare che si vogliono calcolare riepiloghi di record di un dataset client, si
deve ricorrere alla propriet Aggregates. Aggregates una raccolta di specifiche di
aggregazione (TAggregate). possibile aggiungere tali specifiche al dataset client
utilizzando il Collection Editor in progettazione o il metodo Add di Aggregates in
esecuzione. Se si vogliono creare componenti campo per le aggregazioni, occorre
creare campi persistenti per i valori di aggregazione nel Fields Editor.
_
Quando si creano campi di aggregazione, alla propriet Aggregates del dataset client
vengono aggiunti automaticamente gli oggetti appropriati di aggregazione. Non
occorre aggiungerli in modo esplicito durante la creazione dei campi persistenti di
aggregazione. Per ulteriori dettagli sulla creazione dei campi persistenti di
aggregazione, consultare Definizione di un campo di aggregazione a pagina 23-10.
U t i l i z z o d e i d a t a s e t c l i e n t 27-13
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
Per ciascuna aggregazione la propriet Expression indica il calcolo di riepilogo che
rappresenta. Expression pu contenere una semplice espressione di riepilogo come
..c.
oppure unespressione complessa che abbina informazioni di campi diversi, come
.._ .cc ..~..i.
Le espressioni di aggregazione includono uno o pi degli operatori di riepilogo
riportati nella Tabella 27.2
Gli operatori di riepilogo agiscono sui valori dei campi o sulle espressioni costruite
dai valori dei campi utilizzando gli stessi operatori usati per creare i filtri.(In ogni
caso non si possono annidare operatori di riepilogo). possibile creare espressioni
utilizzando operatori su valori di riepilogo con altri valori di riepilogo, o su valori di
riepilogo e costanti. Tuttavia, non consentito combinare valori di riepilogo e valori
di campo, in quanto tali espressioni sono ambigue (non ci sono indicazioni su quale
record deve fornire il valore del campo). Queste regole vengono illustrate nelle
espressioni seguenti:
Aggregazione di gruppi di record
Per impostazione predefinita, le aggregazioni di manutenzione vengono calcolate in
modo che effettuino il riepilogo di tutti i record nel dataset client. Tuttavia, si pu
anche specificare che si vuole effettuare il riepilogo sui record di un gruppo. Ci
consente di fornire riepiloghi intermedi, come dei totali parziali per gruppi di record
che condividono un valore di campo comune.
Prima che sia possibile specificare unaggregazione di manutenzione su un gruppo
di record, bisogna ricorrere a un indice che supporti il raggruppamento appropriato.
Per informazioni sul supporto per il raggruppamento, consultare Uso degli indici
per il raggruppamento dei dati a pagina 27-10.
Tabella 27.2 Operatori di riepilogo per le aggregazioni di manutenzione
Operatore Uso
Sum Calcola il totale dei valori di un campo numerico o di unespressione
Avg Calcola il valore mezzo di un campo numerico o data-ora oppure di unespressione
Count Specifica il numero di valori non vuoti per un campo o unespressione
Min Indica il valore minimo per un campo stringa, numerico o data-ora oppure per
unespressione
Max Indica il valore massimo per un campo stringa, numerico o data-ora oppure per
unespressione
.._ .cc ceaaeatIte c, . cs,cssc s ci.,
.ixc. .ixc.. ceaaeatIte cs,cssc s c,
~scic ceaaeatIte cs,cssc . c, c csic
...c. aea ceaaeatIte c, i.i
c. c.. aea ceaaeatIte cs,cssc . c, c ci.,
27-14 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
Una volta che si in possesso di un indice che raggruppa in dati nel modo che si
vuole che vengano riepilogati, occorre specificare le propriet IndexName e
GroupingLevel dellaggregazione per indicare quale indice utilizza e quale gruppo o
sottogruppo di quel indice definisce i record da riepilogare.
Per esempio, si consideri il frammento seguente di una tabella ordini che
raggruppare per SalesRep e, allinterno di SalesRep, per Customer:
Il codice seguente imposta unaggregazione di manutenzione che indica la quantit
complessiva per ogni rivenditore:
~>x,css '..~.',
~>L.cx.i.c '.icss',
~>,cc ,
~>~cic.i.c 'i . c,',
Per aggiungere unaggregazione che effettui il riepilogo per ogni cliente allinterno di
un determinato rivenditore, occorre creare unaggregazione di manutenzione con
livello 2.
Le aggregazioni di manutenzione che effettuano il riepilogo su un gruppo di record
vengono associate con un indice specifico. La propriet Aggregates pu includere
aggregazioni che utilizzano indici diversi. Tuttavia, solo le aggregazioni che
effettuano il riepilogo sullintero dataset e quelle che utilizzano lindice corrente sono
valide. Il cambiamento dellindice corrente cambia le aggregazioni valide. Per
determinare quali aggregazioni sono valide in qualunque momento, bisogna
ricorrere alla propriet ActiveAggs.
Ottenimento dei valori di aggregazione
Per ottenere il valore di unaggregazione di manutenzione, occorre chiamare il
metodo Value delloggetto TAggregate che rappresenta laggregazione. Value
restituisce laggregazione di manutenzione del gruppo che contiene il record corrente
del dataset client.
Quando si effettua il riepilogo dellintero dataset client, si pu chiamare in
qualunque momento Value per ottenere laggregazione di manutenzione. Tuttavia,
quando si effettua il riepilogo su informazioni raggruppate, occorre verificare che il
record attivo si trovi nel gruppo che si intende riepilogare. Pertanto, consigliabile
ottenere valori di aggregazione in tempi chiaramente specificati, come quando si
passa sul primo record di un gruppo o ci si sposta sullultimo. Per determinare dove
cade il record attivo allinterno di un gruppo, si deve utilizzare il metodo
GetGroupState.
SalesRep Customer OrderNo Amount
1 1 5 100
1 1 2 50
1 2 3 200
1 2 6 75
2 1 1 10
2 3 4 200
U t i l i z z o d e i d a t a s e t c l i e n t 27-15
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
Per visualizzare le aggregazioni di manutenzione nei controlli associati ai dati, si
deve utilizzare il Fields editor per creare un componente campo persistente di
aggregazione. Quando si specifica un campo di aggregazione nel Fields editor,
Aggregates del dataset client viene aggiornato automaticamente, in modo da
includere la specifica di aggregazione appropriata. La propriet AggFields contiene il
nuovo componente campo di aggregazione, che viene restituito dal metodo FindField.
Copia di dati da un altro dataset
Per copiare in progettazione i dati da un altro dataset, fare clic con il pulsante destro
sul dataset e scegliere Assign Local Data. Apparir una finestra di dialogo con
lelenco di tutti i dataset disponibili nel progetto. Selezionare quello di cui si vogliono
copiare dati e struttura e scegliere OK. Quando si copia il dataset sorgente, viene
attivato automaticamente il dataset client.
Per copiare dati da un altro dataset in fase di esecuzione, possibile assegnare
direttamente i dati, oppure, se il sorgente un altro dataset client, clonare il cursor.
Assegnazione diretta dei dati
La propriet Data del dataset client pu essere utilizzato per assegnare a un dataset
client i dati di un altro dataset. Data un pacchetto dati sotto forma di OleVariant. Un
pacchetto dati pu derivare da un altro dataset client, o da qualunque altro dataset
utilizzando un provider. Una volta che un pacchetto dati stato assegnato a Data, il
suo contenuto viene visualizzato automaticamente nei controlli associati ai dati
connessi al dataset client tramite un componente datasource.
Quando si apre un dataset client che rappresenta i dati di un server o che utilizza un
componente provider esterno, i pacchetti dati vengono assegnati automaticamente a
Data.
Quando il dataset client non usa un provider, possibile copiare i dati da un altro
dataset nel modo seguente:
cii.c>ii cii.c.>ii,
_
Quando si copia la propriet Data di un altro dataset client, si copia anche il registro
delle modifiche, ma la copia non riflette i filtri o gli intervalli che sono stati applicati.
Per includere i filtri o gli intervalli, occorre clonare il cursor del dataset sorgente.
Se si effettua la copia da un dataset alternativo rispetto ad un dataset client, si pu
creare un componente provider del dataset, collegarlo al dataset sorgente e poi
copiarne i dati:
c.,..c aev ii.c..c.,
c.,..c>ii.c .ccii.c,
cii.c>ii c.,..c>ii,
ieIete c.,..c,
_
Quando si assegnano direttamente i dati alla propriet Data, il nuovo pacchetto dati
viene fuso nei dati esistenti. Tutti i dati precedenti vengono, invece, sostituiti.
Se si intendono fondere le modifiche ricavandole da un altro dataset, anzich
copiarne i dati, si deve utilizzare un componente provider. Creare un provider di
27-16 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d e i d a t i t r a m i t e u n d a t a s e t c l i e n t
dataset come nellesempio precedente, ma associarlo al dataset di destinazione e,
anzich copiare la propriet Data, utilizzare il metodo ApplyUpdates:
c.,..c aev ii.c..c.,
c.,..c>ii.c cii.c,
c.,..c>~,,,.ics.ccii.c>ci, , ,
ieIete c.,..c,
Clonazione di un cursor di un dataset client
I dataset client utilizzano il metodo CloneCursor per permettere di gestire in fase di
esecuzione una seconda vista dei dati. CloneCursor consente a un secondo dataset
client di condividere i dati del dataset client originale. Ci meno oneroso della copia
di tutti i dati originali, ma, dal momento che i dati sono condivisi, il secondo dataset
client non pu modificare i dati senza influenzare il dataset client originale.
CloneCursor richiede tre parametri: Source specifica il dataset client da clonare. Gli
ultimi due parametri (Reset e KeepSettings) indicano se copiare informazioni diverse
dai dati. Queste informazioni comprendono tutti i filtri, lindice attivo, i collegamenti
a una tabella master (quando il dataset sorgente un set di dettaglio), la propriet
ReadOnly e tutti i collegamenti a un componente connessione o a un interfaccia
provider.
Quando Reset e KeepSettings sono false, viene aperto un dataset client clonato e
vengono utilizzate le impostazioni del dataset sorgente per definire le propriet della
destinazione. Quando Reset true, alle propriet del dataset di destinazione vengono
attribuiti i valori predefiniti (non viene specificato nessun indice o filtro, nessuna
tabella master, nessun componente connessione o provider, e ReadOnly false).
Quando KeepSettings true, le propriet del dataset di destinazione non vengono
modificate.
Aggiunta di informazioni specifiche per lapplicazione ai dati
Gli sviluppatori di applicazioni possono aggiungere informazioni personalizzate alla
propriet Data del dataset client. Dal momento che queste informazioni vengono
fornite insieme al pacchetto dati, esse vengono incluse quando si salvano i dati in un
file o in un flusso. Esse vengono copiate quando si copia i dati in un altro dataset.
Opzionalmente, possono essere incluse con la propriet Delta in modo che un
provider possa leggerle quando riceve gli aggiornamenti dai dataset client.
Per salvare con la propriet Data informazioni specifiche per lapplicazione, si deve
usare il metodo SetOptionalParam. Questo consente di memorizzare un OleVariant
che contiene i dati con un nome specifico.
Per recuperare queste informazioni specifiche dellapplicazione, si deve ricorrere al
metodo GetOptionalParam, passando il nome utilizzato quando sono state
memorizzate le informazioni.
U t i l i z z o d e i d a t a s e t c l i e n t 27-17
U t i l i z z o d i u n d a t a s e t c l i e n t p e r r e g i s t r a r e i n c a c h e g l i a g g i o r n a m e n t i
Utilizzo di un dataset client per registrare in cache gli
aggiornamenti
Per impostazione predefinita, quando si modificano i dati nella maggior parte dei
dataset, ogni volta che si cancella o si registra un record, il dataset genera una
transazione, cancella o scrive quel record nel server di database e convalida la
transazione. Se nello scrivere le modifiche nel database si verifica un problema,
lapplicazione viene immediatamente informata: il dataset solleva uneccezione
quando si registra il record.
Se il dataset utilizza un server di database remoto, questo approccio pu degradare le
prestazioni a causa del traffico di rete tra lapplicazione e il server ogni volta che ci si
sposta a un nuovo record dopo avere modificato il record corrente. Per minimizzare
il traffico di rete, potrebbe essere opportuno memorizzare gli aggiornamenti nella
cache locale.Quando si memorizzano gli aggiornamenti nella cache, lapplicazione
preleva i dati dal database, li memorizza nella cache e lo modifica in locale e quindi
applica gli aggiornamenti in cache al database con una singola transazione. Se si
utilizzano gli aggiornamenti in cache, le modifiche a un dataset (come la
registrazione delle modifiche o la cancellazione di record) vengono memorizzate in
locale invece di essere scritte direttamente nella tabella associata al dataset. Una volta
completate le modifiche, lapplicazione chiama un metodo che scrive nel database le
modifiche memorizzate nella cache e azzera la cache.
Gli aggiornamenti in cache possono ridurre al minimo la durata della transazione e
limitare il traffico nella rete.Tuttavia, i dati nella cache sono locali rispetto
allapplicazione e non sono sotto il controllo della transazione. Tuttavia, i dati nella
cache sono locali allapplicazione e non sono sotto il controllo della transazione. Ci
significa che mentre si lavora sulla propria copia locale in memoria dei dati, altre
applicazioni potrebbero modificare i dati nella tabella di database sottostante. Inoltre,
non sono in grado di vedere alcuna modifica finch gli aggiornamenti memorizzati
in cache non saranno applicati. Per questo motivo, luso degli aggiornamenti in cache
potrebbe non essere appropriato per applicazioni che operano con dati volatili, dal
momento che si potrebbero causare o incontrare troppi conflitti non appena si
cercher di fondere le modifiche nel database.
Bench BDE e ADO forniscano meccanismi alternativi per la memorizzazione in
cache degli aggiornamenti, lutilizzo di un dataset client a tale scopo presenta diversi
vantaggi:
Lapplicazione degli aggiornamenti quando i dataset sono collegati mediante
relazioni master/detail gestita automaticamente. Questo fatto garantisce che gli
aggiornamenti a pi dataset collegati vengano applicati nellordine corretto.
I dataset client offrono il massimo controllo sul processo di aggiornamento.
possibile impostare delle propriet per influire sulle istruzioni SQL generate per
laggiornamento di record, per specificare la tabella da utilizzare durante
laggiornameto di record provenienti da una join su pi tabelle, o addirittura
applicare gli aggiornamenti manualmente mediante da un gestore di evento
BeforeUpdateRecord.
27-18 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i u n d a t a s e t c l i e n t p e r r e g i s t r a r e i n c a c h e g l i a g g i o r n a m e n t i
Se durante lapplicazione al server di database degli aggiornamenti in cache si
verificano degli errori, solo i dataset client (e i provider di dataset) sono in grado
di fornire informazioni sul valore attuale del record nel server di database, oltre al
valore originale (non modificato) presente nel dataset e al nuovo valore
(modificato) dellaggiornamento che non andato a buon fine.
I dataset client permettono di specificare il numero di errori di aggiornamento che
si desidera tollerare prima che lintero aggiornamento venga annullato.
Panoramica sullutilizzo degli aggiornamenti in cache
Per utilizzare gli aggiornamenti in cache, le varie fasi elaborative devono avvenire in
unapplicazione secondo lordine seguente:
1 Indicare i dati che si vogliono modificare. La modalit operativa dipende dal tipo
di dataset client utilizzato:
Se si utilizza TClientDataSet, specificare il componente provider che rappresenta
i dati che si vogliono modificare. Loperazione descritta in Specifica di un
provider a pagina 27-27.
Se si utilizza un dataset client associato a un particolare meccanismo di accesso
di dati, necessario
- Identificare il server di database impostando la propriet DBConnection a un
componente connection appropriato.
- Indicare quali dati si vogliono vedere specificando le propriet
CommandTexte CommandType. La propriet CommandType indica se
CommandText rappresenta unistruzione SQL da eseguire, il nome di una
procedura registrata oppure il nome di una tabella. Se CommandText una
query o una procedura registrata, utilizzare la propriet Params per fornire
tutti i parametri di input.
- Facoltativamente, utilizzare la propriet Options per indicare se i set di
dettaglio annidati e i dati BLOB devono essere inclusi nei pacchetti dati o
recuperati separatamente, se determinati tipi di modifiche (inserimenti,
modifiche o cancellazioni) devono essere disattivati, se un singolo
aggiornamento pu influire su pi record del server e se i record del dataset
client devono essere aggiornati allatto dellapplicazione degli
aggiornamenti. La propriet Options identica alla propriet Options del
provider. Pertanto, essa permette di impostare anche opzioni che non sono
pertinenti o appropriate. Ad esempio, non c alcun motivo di includere
poIncFieldProps, in quanto il dataset client non recuperara i propri dati da un
dataset con campi persistenti. Per contro, non si vorr escludere
poAllowCommandText, incluso per default, perch ci disattiverebbe la
propriet CommandText utilizzata da dataset client per specificare i dati da
ottenere. Per informazioni sulla propriet Options del provider, consultare il
paragrafo Impostazione di opzioni che influenzano i pacchetti dati a
pagina 28-5.
2 Visualizzare e modificare i dati, permettere linserimento di nuovi record e
supportare la cancellazione di record esistenti. Sia la copia originale di ogni record
U t i l i z z o d e i d a t a s e t c l i e n t 27-19
U t i l i z z o d i u n d a t a s e t c l i e n t p e r r e g i s t r a r e i n c a c h e g l i a g g i o r n a m e n t i
che tutte le modifiche vengono conservate in memoria. Questo procedimento
descritto in Editing di dati a pagina 27-5.
3 Prelevare altri record in base alle necessit. Per impostazione predefinita, i
dataset client prelevano tutti i record e li conservano in memoria. Se un dataset
contiene molti record o record con grandi campi BLOB, potrebbe essere opportuno
modificare questo comportamento in modo che il dataset client prelevi solo la
quantit necessaria di record da visualizzare e ne prelevi successivamente altri se
necessario. Per i dettagli su come controllare il processo di prelievo dei record,
vedere Richiesta di dati da un dataset sorgente o da un documento a
pagina 27-28.
4 A propria scelta, aggiornare i record. Man mano che il tempo trascorre, altri utenti
potrebbero modificare i dati sul server di database. Ci fa s che i dati del dataset
client siano sempre pi differenti dai dati sul server, accrescendo la possibilit che
si verifichino errori al momento dellapplicazione degli aggiornamenti. Per
attenuare questo problema, possibile aggiornare i record che non sono stati
ancora modificati. Per i dettagli, vedere Rinnovo dei record a pagina 27-33.
5 Applicare i record nella cache locale al database o annullare gli aggiornamenti.
Per ogni record scritto nel database, viene innescato un evento BeforeUpdateRecord.
Se si verifica un errore nel momento in cui viene scritto nel database un singolo
record, un evento OnUpdateError permette allapplicazione di correggere lerrore,
se possibile, e di continuare laggiornamento. Una volta completati gli
aggiornamenti, tutti gli aggiornamenti applicati con successo vengono rimossi
dalla cache locale. Per ulteriori informazioni sullapplicazione degli aggiornamenti
al database, vedere Aggiornamento dei record a pagina 27-21.
Invece di applicare aggiornamenti, unapplicazione pu annullare gli
aggiornamenti, svuotando il registro delle modifiche senza scrivere le modifiche
nel database. possibile annullare gli aggiornamenti chiamando il metodo
CancelUpdates. Tutti i record cancellati presenti nella cache vengono ripristinati, i
record modificati assumono i valori originali e i record appena inseriti spariscono.
Scelta del tipo di dataset per gli aggiornamenti in cache
C++Builder include alcuni componenti dataset client specializzati per gli
aggiornamenti in cache. Ogni dataset client associato a un particolare meccanismo
di accesso di dati. Essi vengono elencati nella Tabella Tabella 27.3:
Inoltre, possibile memorizzare in cache gli aggiornamenti utilizzando il dataset
client generico (TClientDataSet) con un provider e un dataset sorgente esterni. Per
Tabella 27.3 Dataset client specializzati per gli aggiornamenti in cache
Dataset client
Meccanismo di accesso ai
dati
TBDEClientDataSet Borland Database Engine
TSQLClientDataSet dbExpress
TIBClientDataSet InterBase Express
27-20 G u i d a a l l a p r o g r a mma z i o n e
U t i l i z z o d i u n d a t a s e t c l i e n t p e r r e g i s t r a r e i n c a c h e g l i a g g i o r n a m e n t i
informazioni sulluso di TClientDataSet con un provider esterno, consultare Uso di
un dataset client con un provider di dati a pagina 27-26.
_
Anche i dataset client specializzati associati a un particolare meccanismo di accesso ai
dati in effetti utilizzano un provider e un dataset sorgente. Tuttavia, sia il provider
che il dataset sorgente sono interni al dataset client.
pi semplice utilizzare uno dei dataset client specializzati per gli aggiornamenti in
cache. A volte, tuttavia, preferibile utilizzare TClientDataSet con un provider
esterno:
Se si utilizza un meccanismo di accesso di dati che non ha un dataset client
specializzato, necessario utilizzare TClientDataSet con un componente provider
esterno. Ad esempio, se i dati provengono da un documento XML o da un dataset
custom.
Se si opera con tabelle collegate mediante una relazione master/detail, si dovrebbe
utilizzare TClientDataSet e connetterlo, utilizzando un provider, alla tabella master
dei due dataset sorgente collegati con una relazione master/detail. Il dataset client
vede il dataset di dettaglio come un campo di dataset annidato. Questa modalit
operativa necessaria per poter applicare gli aggiornamenti alle tabelle master e
detail nellordine corretto.
Se si vogliono creare gestori di evento che rispondono alla comunicazione fra il
dataset client e il provider (ad esempio, prima e dopo che il dataset client ha
prelevato i record dal provider), necessario utilizzare TClientDataSet con un
componente provider esterno. I dataset client specializzati pubblicano gli eventi
pi importanti per lapplicazione degli aggiornamenti (OnReconcileError,
BeforeUpdateRecord e OnGetTableName), ma non pubblicano gli eventi inerenti alla
comunicazione fra il dataset client e il suo provider, in quanto sono destinati
principalmente alle applicazioni multi-tier.
Se si utilizza BDE, potrebbe essere opportuno utilizzare un provider e un dataset
sorgente esterni perch potrebbe essere necessario utilizzare un oggetto update.
Bench sia possibile codificare un oggetto update a partire dal gestore di evento
BeforeUpdateRecord di TBDEClientDataSet, molto pi semplice assegnare
semplicemente la propriet UpdateObject del dataset sorgente. Per informazioni
sullutilizzo di oggetti update, vedere Aggiornamento di dataset mediante
oggetti update a pagina 24-41.
Indicazione dei record modificati
Mentre lutente modifica un dataset client, pu essere utile fornire un riscontro sulle
modiche apportate. In particolar modo utile nel caso si voglia permettere allutente
di annullare determinate modifiche, ad esempio, spostandosi sulla modifica e
facendo clic su un pulsante Annulla.
Il metodo UpdateStatus e le propriet StatusFilter sono utili quando si vuole fornire un
riscontro degli aggiornamenti effettuati:
UpdateStatus indica il tipo di aggiornamento, se vi stato, che stato apportato al
record corrente. Pu assumere uno dei seguenti valori:
U t i l i z z o d e i d a t a s e t c l i e n t 27-21
U t i l i z z o d i u n d a t a s e t c l i e n t p e r r e g i s t r a r e i n c a c h e g l i a g g i o r n a m e n t i
usUnmodified indica che il record corrente invariato.
usModified indica che il record corrente stato modificato.
usInserted indica un record che stato inserito dallutente.
usDeleted indica un record che stato cancellato dallutente.
StatusFilter controlla quali tipi di aggiornamento sono visibili nel registro delle
modifiche. StatusFilter opera sui record nella cache in modo simile a quanto fanno
i filtri sui normali dati. StatusFilter un set, e pertanto pu contenere una qualsiasi
combinazione dei seguenti valori:
usUnmodified indica un record invariato.
usModified indica un record modificato.
usInserted indica un record inserito.
usDeleted indica un record cancellato.
Per impostazione predefinita, StatusFilter il set [usModified, usInserted,
usUnmodified]. A questo set possibile aggiungere usDeleted in modo da fornire un
riscontro sui record cancellati.
_
UpdateStatus e StatusFilter sono utili anche nei gestori di evento BeforeUpdateRecord e
OnReconcileError. Per informazioni su BeforeUpdateRecord, vedere Interventi durante
lapplicazione degli aggiornamenti a pagina 27-23. Per informazioni su
OnReconcileError, consultare Riconciliazione degli errori di aggiornamento a
pagina 27-25.
Il seguente esempio mostra come fornire un riscontro sullo stato di aggiornamento
dei record utilizzando il metodo UpdateStatus. Lesempio parte dallassunto che la
propriet StatusFilter sia stata modificata includendo usDeleted, permettendo cos la
visualizzazione nel dataset dei record cancellati. Inoltre presuppone che al dataset sia
stato aggiunto un campo calcolato di nome Status.
veIi __?aatcaII .cii.cicc.sii.c ii.c
avItca ii.c>,.ic.is
caae s...c.
cii.c.is>ic ., bteak,
caae s...c.
cii.c.is>ic '.', bteak,
caae sLscc.
cii.c.is>ic 'L', bteak,
caae sccc.
cii.c.is>ic '', bteak,
I? cii.c>,.ic.is s...c.
cii.c>c.cscc.,
~i.s,.,
~i.s, ,
~i.s, ,
.,ccs i~icic~i.s, , iii,
ii ics,,
ics, ii'.c..c.',
ics, ii..,
ics,. iittae,
.,ccs, i~i.ics,.,
ics, ii'icc..c',
ics, iiii.c>cc.,
ics,. ii?aIae,
.,ccs, i~i.ics,.,
Quando il dataset client applica gli aggiornamenti, lora in cui sono stati forniti i
record originali pu essere letta nellevento OnUpdateData del provider:
veIi __?aatcaII .ii..c..c,.iciiccc .c.c, s.cii.c
ii.c
ii c..c. ii.c>c,i.ii.'.c..c.',
...
28-8 G u i d a a l l a p r o g r a mma z i o n e
R i s p o s t a a l l e r i c h i e s t e d i d a t i d e l c l i e n t
Risposta alle richieste di dati del client
Solitamente le richieste di dati da parte del client vengono gestite automaticamente.
Un dataset client o un broker XML richiede un pacchetto dati chiamando GetRecords
(in modo indiretto, mediante linterfaccia IAppServer). Il provider risponde
automaticamente prelevando i dati dal dataset o dal documento XML associato,
creando un pacchetto dati e inviandolo al client.
Il provider ha la facolt di modificare i dati dopo che sono stati assemblati in un
pacchetto, ma prima che il pacchetto venga inviato al client. Per esempio, si potrebbe
voler rimuovere i record dal pacchetto in base a determinati criteri (come il livello di
accesso dellutente), o, in unapplicazione multi-tier, si potrebbe voler crittografare
dati particolarmente delicati prima che siano inviato al client.
Per effettuare lediting del pacchetto dati prima di inviarlo al client, occorre scrivere
un gestore di evento OnGetData event handler. Il gestore di evento OnGetData
fornisce il pacchetto dati come un parametro sotto forma di dataset client. Usando i
metodi di questo dataset client, possibile modificare i dati prima di inviarli al client.
Come per tutte le chiamate ai metodi effettuate tramite linterfaccia IAppServer, il
provider ha la possibilit di comunicare informazioni di stato persistenti con un
dataset client prima e dopo la chiamata a GetRecords. Questa comunicazione avviene
utilizzando i gestori di evento BeforeGetRecords e AfterGetRecords. Per una trattazione
delle informazioni di stato persistenti negli application server, consultare Supporto
delle informazioni di stato nei moduli dati remoti a pagina 29-20.
Risposta alle richieste di aggiornamento del client
Un provider applica gli aggiornamenti ai record del database sulla base di un
pacchetto dati Delta ricevuto da un dataset client o da un broker XML. Il client
richiede gli aggiornamenti chiamando il metodo ApplyUpdates (in modo indiretto,
mediante linterfaccia IAppServer).
Come per tutte le chiamate ai metodi effettuate tramite linterfaccia IAppServer, il
provider ha la possibilit di comunicare informazioni di stato persistenti con un
dataset client prima e dopo la chiamata a ApplyUpdates. Questa comunicazione
avviene utilizzando i gestori di evento BeforeApplyUpdates e AfterApplyUpdates. Per
una trattazione delle informazioni di stato persistenti negli application server,
consultare Supporto delle informazioni di stato nei moduli dati remoti a
pagina 29-20.
Se si utilizza un provider di dataset, sono disponibili molti altri eventi che
consentono un maggore controllo:
Quando un provider di dataset riceve una richiesta di aggiornamento, genera un
evento OnUpdateData, in cui possibile modificare il pacchetto Delta prima che
venga scritto nel dataset o che influenzi il modo in cui vengono applicati gli
aggiornamenti. Dopo levento OnUpdateData, il provider scrive le modifiche nel
database o nel dataset sorgente.
U s o d i c o mp o n e n t i p r o v i d e r 28-9
R i s p o s t a a l l e r i c h i e s t e d i a g g i o r n a m e n t o d e l c l i e n t
Il componente provider esegue laggiornamento record per record. Prima di
applicare gli aggiornamenti a ciascun record, il provider genera un evento
BeforeUpdateRecord, con il quale possibile vagliare gli aggiornamenti prima che
vengano applicati. Se si verifica un errore durante laggiornamento di un record, il
provider riceve un evento OnUpdateError in cui pu risolvere lerrore. Solitamente,
gli errori si verificano perch la modifica non rispetta un vincolo del server o perch
il record del database stato modificato da unapplicazione differente in una fase
successiva al suo recupero da parte del provider, ma prima della richiesta del dataset
client di applicare gli aggiornamenti.
Gli errori di aggiornamento possono essere elaborati dal provider di dataset o dal
dataset client. Se il provider fa parte di unapplicazione multi-tier dovrebbe gestire
tutti gli errori di aggiornamento che non richiedono uninterazione con lutente per la
loro risoluzione. Se il provider non riesce a risolvere una condizione di errore,
memorizza temporaneamente una copia del record che ha problemi. Completata
lelaborazione del record il provider restituisce al dataset client il numero di errori
incontrati e copia i record non risolti in un pacchetto risultato che viene restituito al
dataset client per unulteriore riconciliazione.
I set di aggiornamenti vengono trasmessi ai gestori di evento di tutti gli eventi del
provider come dataset client. Se il gestore di evento si occupa solo di alcuni tipi di
aggiornamenti, possibile filtrare il dataset in base allo stato di aggiornamento dei
record. Filtrando i record, il gestore di evento non deve riordinare i record che non
utilizzer. Per filtrare il dataset client in base allo stato di aggiornamento dei suoi
record, impostare la sua propriet StatusFilter.
_
Le applicazioni devono fornire un supporto pi efficace nel caso in cui gli
aggiornamenti siano indirizzati su un dataset che non rappresenta una singola
tabella. Per i dettagli sulle operazioni da compiere, consultare la sezione
Applicazione di aggiornamenti a dataset che non rappresentano una singola
tabella a pagina 28-12.
Modifica dei pacchetti delta prima dellaggiornamento del database
Prima di applicare gli aggiornamenti al database, esso genera un evento
OnUpdateData. Il gestore di evento OnUpdateData riceve una copia del pacchetto
Delta come parametro. Questo un dataset client.
Nel gestore di evento OnUpdateData si pu usare qualsiasi propriet e metodo del
dataset client per modificare il pacchetto Delta prima che venga scritto nel dataset.
Una propriet particolarmente utile UpdateStatus. UpdateStatus indica quale tipo di
modifica rappresenta il record corrente del pacchetto delta. Pu assumere uno dei
valori elencati nella Tabella 28.3.
Tabella 28.3 Valori di UpdateStatus
Valore Descrizione
usUnmodified Il contenuto del record non stato modificato
usModified Il contenuto del record stato modificato
28-10 G u i d a a l l a p r o g r a mma z i o n e
R i s p o s t a a l l e r i c h i e s t e d i a g g i o r n a m e n t o d e l c l i e n t
Per esempio, il seguente gestore di evento OnUpdateData inserisce la data corrente in
ogni nuovo record inserito nel database:
veIi __?aatcaII .ii..c..c,.iciiccc .c.c, s.cii.c
ii.c
ii.c>s,
vaIIe ii.c>.
I? ii.c>,.ic.is sLscc.
ii.c>.,
ii.c>c..i.c'iccic.'>~sic.c ic,
ii.c>.s,
ii.c>.cx,
ii.c>c..i.c'...'>..cisci,
ii.c>c..i.c'...'>..cis ,.L-cc ,.Lc,
ii.c>c..i.c'L'>..cisci,
ii.c>c..i.c'L'>..cis ,.L,.ic,
ii.c>c..i.c'.'>..cisci,
ii.c>c..i.c'.'>..cis ,.Lcc,
_
possibile usare la propriet UpdateFlags per influenzare il modo in cui vengono
applicati gli aggiornamenti anche si sta aggiornando un dataset senza usare
istruzioni SQL generate dinamicamente. Anche questi flag determinano quali campi
vengono usati per individuare i record e quali campi vengono aggiornati.
Vaglio dei singoli aggiornamenti
Immediatamente prima che ciascun aggiornamento venga applicato, il provider di
dataset riceve un evento BeforeUpdateRecord. Questo evento pu essere usato per
modificare i record prima vengano applicati, analogamente a come si usa levento
OnUpdateData per modificare interi pacchetti delta. Ad esempio, il provider non
confronta i campi BLOB (come i memo) quando esegue il controllo su conflitti di
aggiornamento. Se si vogliono controllare eventuali errori di aggiornamento relativi
a campi BLOB, possibile utilizzare levento BeforeUpdateRecord.
Tabella 28.5 Valori di ProviderFlags
Valore Descrizione
pfInWhere Il campo appare nella clausola WHERE delle istruzioni INSERT, DELETE e
UPDATE generate quando UpdateMode upWhereAll oppure upWhereChanged.
pfInUpdate Il campo appare nella clausola UPDATE delle istruzioni UPDATE generate.
pfInKey Il campo viene usato nella clausola WHERE delle istruzioni generate quando
UpdateMode upWhereKeyOnly.
pfHidden Il campo viene incluso nei record per assicurare lunivocit, ma non pu essere
visto o usato sul lato client.
28-12 G u i d a a l l a p r o g r a mma z i o n e
R i s p o s t a a l l e r i c h i e s t e d i a g g i o r n a m e n t o d e l c l i e n t
Inoltre, si pu usare questo evento per applicare personalmente gli aggiornamenti o
per vagliare e rigettare gli aggiornamenti. Il gestore dellevento BeforeUpdateRecord
permette di segnalare che un aggiornamento gi stato gestito e non deve essere
applicato. Il provider quindi salta quel record, ma non lo considera come un errore di
aggiornamento. Per esempio, questo evento fornisce a una procedura memorizzata
(che non pu essere aggiornata automaticamente) un meccanismo per applicare gli
aggiornamenti, consentendo al provider di saltare qualsiasi elaborazione automatica
dal momento che il record viene aggiornato dallinterno del gestore di evento.
Risoluzione degli errori di aggiornamento sul provider
Quando si determina una condizione di errore non appena il provider di dataset
tenta di inviare un record nel pacchetto delta, si verifica un evento OnUpdateError. Se
il provider non riesce a risolvere un errore di aggiornamento, memorizza
temporaneamente una copia del record che ha generato lerrore. Completata
lelaborazione del record, il provider restituisce il numero di errori incontrati e copia
i record non risolti in un pacchetto dati risultato che viene ripassato al client per
unulteriore riconciliazione.
Nelle applicazioni multi-tiered, questo meccanismo permette di gestire qualsiasi
errore di aggiornamento che possibile risolvere automaticamente sullapplication
server, pur consentendo ancora linterazione con lutente sullapplicazione client per
correggere le condizioni di errore.
Il gestore OnUpdateError riceve una copia del record che non pu essere modificato,
un codice di errore dal database e unindicazione del fatto che il resolver stesse
cercando di inserire, cancellare o aggiornare il record. Il record problematico viene
restituito in un dataset client. Su questo dataset non si devono mai usare i metodi per
lo spostamento tra i dati. Tuttavia, per ciascun campo del dataset, possibile usare le
propriet NewValue, OldValue e CurValue per determinare la causa del problema e
apportare tutte le modifiche necessarie per risolvere lerrore di aggiornamento. Se il
gestore di evento OnUpdateError pu correggere il problema, imposta il parametro
Response in modo che venga applicato il record corretto.
Applicazione di aggiornamenti a dataset che non rappresentano una
singola tabella
Quando un provider di dataset genera istruzioni SQL che applicano gli
aggiornamenti direttamente su un server di database, necessario fornire il nome
della tabella di database che contiene i record. Questo compito pu essere gestito in
modo automatico per molti dataset, come i dataset di tipo tabella o i componenti
TQuery aggiornati in diretta. Gli aggiornamenti automatici, tuttavia, rappresentano
un problema nel caso il provider debba applicare gli aggiornamenti ai dati sottostanti
una procedura registrata a partire da un set risultato o da una query su pi tabelle.
Non esiste un modo semplice per accertare il nome della tabella a cui dovrebbero
essere applicati gli aggiornamenti.
Se la query o la procedura registrata un dataset BDE (TQuery o TStoredProc) a cui
associato un oggetto update, il provider utilizzer loggetto update. Tuttavia, se non
U s o d i c o mp o n e n t i p r o v i d e r 28-13
R i s p o s t a a g l i e v e n t i g e n e r a t i d a l c l i e n t
esiste un oggetto update, possibile fornire da programma il nome della tabella in un
gestore di evento OnGetTableName. Una volta che il gestore di evento ha fornito il
nome della tabella, il provider in grado di generare le opportune istruzioni SQL per
applicare gli aggiornamenti.
Il passaggio del nome della tabella funziona solamente se il destinatario degli
aggiornamenti una singola tabella di database (vale a dire, necessario aggiornare
solo i record di una tabella). Se gli aggiornamenti devono apportare modifiche a pi
tabelle di database sottostanti, necessario applicare gli aggiornamenti in modo
esplicito nel codice utilizzando levento BeforeUpdateRecord del provider. Dopo che il
gestore di evento ha applicato un aggiornamento, si deve impostare a true il
parametro Applied del gestore di evento in modo che il provider non generi un errore.
_
Se il provider associato a un dataset BDE, possibile utilizzare nel gestore di evento
BeforeUpdateRecord un oggetto update per applicare gli aggiornamenti mediante
istruzioni SQL personalizzate. Per i dettagli, consultare Aggiornamento di dataset
mediante oggetti update a pagina 24-41 for details.
Risposta agli eventi generati dal client
I componenti provider implementano un evento di tipo generico che permette di
creare proprie chiamate dai dataset client direttamente al provider. Si tratta
dellevento OnDataRequest.
OnDataRequest non fa parte del normale funzionamento del provider. solo un
aggancio per consentire ai dataset client di comunicare direttamente con i provider. Il
gestore di evento accetta come parametro in ingresso un OleVariant e restituisce un
OleVariant. Usando gli OleVariant, linterfaccia sufficientemente generica per
contenere quasi tutte le informazioni che si vogliono passare al o dal provider.
Per generare un evento OnDataRequest, lapplicazione client chiama direttamente il
metodo DataRequest del dataset client.
Gestione dei vincoli del server
La maggior parte dei sistemi di gestione dei database relazionali implementa vincoli
sulle tabelle per far rispettare lintegrit dei dati. Un vincolo una regola che governa
i valori dei dati nelle tabelle e nelle colonne, o le relazioni tra i dati tra le colonne di
tabelle differenti. Per esempio, la maggior parte dei database relazionali conformi a
SQL-92 supporta i seguenti vincoli:
NOT NULL, per garantire che un valore fornito a una colonna abbia un valore.
NOT NULL UNIQUE, per garantire che il valore della colonna abbia un valore e
non duplichi un altro valore presente in quella colonna per un altro record.
CHECK, per garantire che un valore fornito a una colonna cada allinterno di un
determinato intervallo, o appartenga a un insieme finito di possibili valori.
28-14 G u i d a a l l a p r o g r a mma z i o n e
G e s t i o n e d e i v i n c o l i d e l s e r v e r
CONSTRAINT, un vincolo di controllo a livello di tabella che si applica a pi
colonne.
PRIMARY KEY, per designare una o pi colonne come chiave principale della
tabella per lindicizzazione.
FOREIGN KEY, per designare una o pi colonne di una tabella che fanno
riferimento a unaltra tabella.
_
Questo elenco non esclusivo. Il server di database pu supportare alcuni o tutti
questi vincoli, in parte o completamente, nonch ulteriori vincoli. Per ulteriori
informazioni sui vincoli supportati, consultare la documentazione del server.
I vincoli del database server duplicano ovviamente molti tipi di controlli sui dati
normalmente gestiti dalle tradizionali applicazioni database desktop. Nelle
applicazioni database multi-tier possibile sfruttare i vantaggi dei vincoli del server
Se il provider opera con un dataset BDE, la propriet Constraints consente di replicare
e applicare i vincoli del server ai dati passati e ricevuti dai dataset client. Se
Constraints true (impostazione predefinita), i vincoli del server memorizzati nel
dataset sorgente vengono inclusi nei pacchetti dati e hanno effetto sui tentativi del
client di aggiornare i dati.
_
Prima che il provider server possa trasferire ai dataset client le informazioni sui
vincoli, deve recuperare i vincoli dal server di database. Per ottenere dal server i
vincoli sul database, utilizzare SQL Explorer per importare nel Data Dictionary i
vincoli del server di database e le espressioni predefinite. I vincoli e le espressioni
predefinite inclusi nel Data Dictionary sono resi automaticamente disponibili ai
dataset BDE.
A volte si potrebbe non voler applicare i vincoli del server ai dati inviati a un dataset
client. Per esempio, un dataset client che riceve dati in pacchetti e consente
laggiornamento in locale dei record prima di prelevare altri record, potrebbe aver
bisogno di disattivare alcuni vincoli del server che potrebbero essere attivati per la
presenza di un set di dati momentaneamente incompleto. Per impedire la replica dei
vincoli dal provider al dataset client, impostare Constraints a false. Si noti, inoltre, che
i dataset client possono disattivare e attivare i vincoli usando i metodi
DisableConstraints e EnableConstraints. Per ulteriori informazioni sullattivazione e
sulla disattivazione dei vincoli da parte del dataset client, consultare Gestione dei
vincoli dal server a pagina 27-32.
C r e a z i o n e d i a p p l i c a z i o n i mu l t i - t i e r 29-1
C a p i t o l o
29
Capitolo29Creazione di applicazioni multi-tier
Questo capitolo descrive come creare unapplicazione database multi-tier client/
server. Unapplicazione multi-tier client/server partizionata in unit logiche che
vengono eseguite insieme su macchine distinte. Le applicazioni multi-tier
condividono i dati e comunicano con le altre applicazioni in una rete locale o anche
su Internet. Esse forniscono molti vantaggi, come la logica di gestione centralizzata e
le applicazioni thin client.
Nella sua forma pi semplice, detta anche modello three-tier, unapplicazione
multi-tier suddivisa in tre parti:
Applicazione client: fornisce uninterfaccia utente nella macchina dellutente
stesso.
Application server: risiede in una postazione centrale della rete accessibile a tutti i
client e fornisce servizi comuni per i dati.
Server di database remoto: fornisce il sistema relazionale di gestione del database
(RDBMS)
In questo modello three-tier lapplication server gestisce il flusso dei dati tra i client e
il database server remoto, perci a volte viene chiamato data broker. Solitamente si
creano solo lapplication server e i suoi client, ma, volendo, si pu anche creare un
database di back end personalizzato.
Nelle applicazioni multi-tier pi complesse i servizi aggiuntivi risiedono tra un client
e un database server remoto. Per esempio, potrebbero esservi un broker di servizi di
sicurezza per gestire in modo sicuro le transazioni Internet, o dei servizi di bridge per
gestire la condivisione dei dati con database su altre piattaforme.
Il supporto della VCL e della CLX per lo sviluppo di applicazioni multi-tier un
ampliamento del modo in cui i dataset client comunicano con un componente
provider utilizzando pacchetti dati trasportabili. In questo capitolo viene
specificatamente descritta la creazione di unapplicazione database three-tier. Dopo
aver capito come creare e gestire unapplicazione three-tier, si pu passare a creare e
ad aggiungere ulteriori livelli di servizi, a seconda delle necessit.
29-2 G u i d a a l l a p r o g r a mma z i o n e
V a n t a g g i d i u n m o d e l l o d a t a b a s e m u l t i - t i e r
Vantaggi di un modello database multi-tier
Il modello database multi-tier suddivide unapplicazione database in parti logiche.
Lapplicazione client pu occuparsi della visualizzazione dei dati e delle interazioni
con lutente. Teoricamente, lapplicazione non sa nulla del modo in cui vengono
memorizzati o conservati i dati. Lapplication server (il tier intermedio) coordina ed
elabora le richieste e gli aggiornamenti da parte di pi client. Gestisce, inoltre, tutti i
dettagli della definizione dei dataset e dellinterazione con il server di database.
I vantaggi di questo modello multi-tier comprendono:
Incapsulamento della logica di gestione in un tier intermedio condiviso.
Applicazioni client differenti accedono tutte alle stesso tier intermedio. Ci
consente di evitare la ridondanza (e i costi di manutenzione) della duplicazione
delle regole di gestione per ogni singola applicazione client.
Applicazioni thin client. Le applicazioni client possono essere scritte in modo da
occupare poco spazio, delegando la maggior parte dellelaborazione ai tier
intermedi. Non solo si hanno applicazioni client pi piccole, ma anche pi facili da
distribuire, in quanto non necessario preoccuparsi della loro installazione,
configurazione e della manutenzione del software per la connettivit al database
(come con Borland Database Engine e con i server di database lato client). Le
applicazioni thin client possono anche essere distribuite su Internet per una
maggior flessibilit.
Elaborazione distribuita dei dati. Distribuendo il lavoro di unapplicazione su
pi macchine, possibile migliorare le prestazioni grazie al bilanciamento del
carico, e consentire ai sistemi ridondanti di subentrare quando un server si blocca.
Maggiori possibilit di sicurezza. possibile isolare le funzioni riservate e
delicate in tier che hanno restrizioni di accesso differenti. Ci fornisce livelli
flessibili e configurabili di sicurezza. I tier intermedi possono limitare i punti di
accesso al materiale riservato, consentendo di controllare pi facilmente laccesso.
Se si usa HTTP o COM+, si possono sfruttare i vantaggi dei modelli di sicurezza
che tali tecnologie supportano.
Applicazioni multi-tier basate su provider
Le applicazioni multi-tier si basano sulluso dei componenti delle pagine DataSnap,
Data Access e possibilmente WebServices della Component palette, oltre a un
modulo dati remoto che viene creato da un wizard presente sulla pagina Multitier o
WebServices della finestra di dialogo New Items. Essi si basano sulla capacit dei
componenti provider di assemblare dati in pacchetti dati trasportabili e di gestire gli
aggiornamenti ricevuti come pacchetti delta trasportabili.
C r e a z i o n e d i a p p l i c a z i o n i mu l t i - t i e r 29-3
A p p l i c a z i o n i m u l t i - t i e r b a s a t e s u p r o v i d e r
I componenti necessari per unapplicazione multi-tier sono descritti nella Tabella
29.1:
Il provider e i componenti dataset client necessitano di midas.dll o midaslib.dcu, che
gestisce i dataset memorizzati come pacchetti dati. (Notare che, poich il provider
utilizzato sullapplication server e il dataset client utilizzato sullapplicazione client,
se si utilizza midas.dll, necessario distribuirla sia sullapplication server che
sullapplicazione client.)
Se si utilizzano dataset BDE, lapplication server potrebbe richiedere anche luso di
SQL Explorer per agevolare lamministrazione del database e per importare nel Data
Dictionary i vincoli del server, in modo da poterli controllare a qualsiasi livello
dellapplicazione multi-tier.
_
Per distribuire lapplication server necessario acquistare le licenze per il server.
Una panoramica dellarchitettura in cui sono inseriti questi componenti presentata
in Utilizzo di unarchitettura multi-tier a pagina 18-13.
Panoramica di unapplicazione three-tier
Le seguenti fasi illustrano una normale sequenza di eventi per unapplicazione three-
tier basata su provider:
1 Un utente avvia lapplicazione client. Il client si collega allapplication server (che
pu essere specificato in fase di progettazione o di esecuzione). Se lapplication
server non gi in esecuzione, viene avviato. Il client riceve uninterfaccia
IAppServer per la comunicazione con lapplication server.
2 Il client richiede dati dallapplication server. Un client pu richiedere i dati in
ununica soluzione o pochi per la volta per tutta la sessione (prelievo su richiesta).
3 Lapplication server recupera i dati (stabilendo innanzi tutto, se necessario, una
connessione al database), crea i pacchetti dati per il client e li restituisce al client.
Altre informazioni, (ad esempio, le caratteristiche di visalizzazione dei campi)
Tabella 29.1 Componenti usati nelle applicazioni multi-tier
Componente Descrizione
Moduli dati remoti Moduli dati specialistici che operano con Automation server COM e con
unapplicazione Web Service per fornire laccesso delle applicazioni client a
tutti i provider che contengono. Vengono usati negli application server.
Componente
Provider
Un broker di dati che fornisce i dati tramite la creazione di pacchetti dati e
risolve gli aggiornamenti del client. Viene usato negli application server.
Componente
dataset Client
Un dataset specializzato che usa midas.dll per gestire i dati memorizzati
nei pacchetti dati. Il dataset client utilizzato nellapplicazione client.
Memorizza gli aggiornamenti nella cache locale e li applica in pacchetti
delta allapplication server.
Componenti
connection
Una famiglia di componenti che individua il server, le connessioni della
scheda e rende disponibile ai dataset client linterfaccia IAppServer. Ogni
componente connection specializzato per usare un particolare protocollo
di comunicazione.
29-4 G u i d a a l l a p r o g r a mma z i o n e
A p p l i c a z i o n i m u l t i - t i e r b a s a t e s u p r o v i d e r
possono essere incluse nei metadati del pacchetto dati. Questo processo di
inglobamento dei dati in pacchetti viene chiamato fornitura.
4 Il client decodifica il pacchetto dati e visualizza i dati allutente.
5 Man mano che lutente interagisce con lapplicazione client, i dati vengono
aggiornati (vengono aggiunti, cancellati o modificati record). Queste modifiche
vengono memorizzate in un registro delle modifiche dal client.
6 Infine il client applica i suoi aggiornamenti allapplication server, normalmente in
risposta a unazione dellutente. Per applicare questi aggiornamenti, il client
compone in un pacchetto il suo registro delle modifiche e lo invia come un
pacchetto dati al server.
7 Lapplication server decodifica il pacchetto dati e invia gli aggiornamenti (se il
caso, nel contesto di una transazione). Se un record non pu essere inviato al
server (per esempio, perch unaltra applicazione ha modificato il record, dopo
che il record era stato richiesto da un client e prima che questultimo applicasse i
suoi aggiornamenti), lapplication server tenta di riconciliare le modifiche del
client con i dati correnti, oppure salva i record che potrebbero non essere inoltrati.
Questo processo di invio dei record e di memorizzazione nella cache dei record
problematici viene chiamato risoluzione.
8 Quando lapplication server termina il processo di risoluzione, restituisce tutti i
record non inoltrati al client per unulteriore risoluzione.
9 Il client riconcilia i record non risolti. Esistono molti modi in cui un client pu
riconciliare i record non risolti. Normalmente, il client cerca di correggere la
situazione che impedisce ai record di essere inviati o scarta le modifiche. Se la
situazione di errore pu essere rettificata, il client applica di nuovo gli
aggiornamenti.
10 Il client effettua laggiornamento dei suoi dati dal server.
Struttura dellapplicazione client
Per lutente finale lapplicazione client di unapplicazione multi-tier appare e si
comporta in modo non diverso da una tradizionale applicazione two-tier che utilizza
aggiornamenti in cache. Linterazione con lutente ha luogo tramite i controlli
standard associati ai dati, che visualizzano i dati da un componente TClientDataSet.
Per informazioni dettagliate sulluso delle propriet, degli eventi e dei metodi dei
dataset client, consultare il Capitolo 27, Utilizzo dei dataset client.
TClientDataSet preleva i dati da un componente provider e vi applica gli
aggiornamenti, esattamente come nelle applicazioni two-tier che utilizzano un
dataset client con un provider esterno. Per i dettagli sui componenti provider, vedere
il Capitolo 28, Uso di componenti provider. Per i dettagli sulle funzioni dei dataset
client che ne agevolano la comunicazione con un provider, vedere Uso di un dataset
client con un provider di dati a pagina 27-26
Il dataset client comunica con il provider attraverso linterfaccia IAppServer. Esso
ottiene questa interfaccia da un componente connection. Il componente connection
stabilisce la connessione allapplication server. Sono disponibili differenti
C r e a z i o n e d i a p p l i c a z i o n i mu l t i - t i e r 29-5
A p p l i c a z i o n i m u l t i - t i e r b a s a t e s u p r o v i d e r
componenti connection per usare protocolli di comunicazione diversi. Questi
componenti connection sono riassunti nella seguente tabella:
_
La pagina DataSnap della Component palette include anche un componente
connection che non si collega affatto a un application server, ma fornisce invece
uninterfaccia IAppServer che deve essere utilizzata dai dataset client durante la
comunicazione con provider presenti nella stessa applicazione. Questo componente,
TLocalConnection, non necessario, ma semplifica un successivo ampliamento a
multi-tier dellapplicazione.
Per ulteriori informazioni sulluso dei componenti connection, consultare
Connessione allapplication server a pagina 29-24.
La struttura dellapplication server
Quando un application server viene impostato ed eseguito, non stabilisce alcuna
connessione con le applicazioni client. Sono invece le applicazioni client che iniziano
e mantengono la connessione. Unapplicazione client usa un componente connection
per stabilire una connessione con lapplication server e utilizza linterfaccia
dellapplication server per comunicare con un provider selezionato. Tutto ci
avviene automaticamente, senza che si debba scrivere del codice per gestire le
richieste in arrivo o fornire le interfacce.
La base di un application server un modulo dati remoto, che un modulo dati
specializzato che supporta linterfaccia IAppServer (per gli application server che
funzionano anche come Web Service, il modulo dati remoto supporta anche
linterfaccia IAppServerSOAP e la preferisce a IAppServer.) Le applicazioni client
utilizzano linterfaccia del modulo dati remoto per comunicare con i provider
sullapplication server. Quando il modulo dati remoto usa IAppServerSOAP, il
componente connection lo adatta a uninterfaccia di IAppServer che i dataset client
sono in grado di utilizzare.
Esistono due tipi di moduli dati remoto:
I moduli dati remoti basati su COM sono moduli dati che utilizzano un oggetto
associato, detto oggetto di implementazione, che deriva da
REMOTEDATAMODULE_IMPL(). REMOTEDATAMODULE_IMPL una macro
definita in Atlvcl.h che elenca gli antenati delloggetto di implementazione. Questi
includono le classi CComObjectRootEx e CComCoClass di ATL, oltre che linterfaccia
IAppServer. Se si sta creando un application server che sia in grado di sfruttare i
servizi distribuiti per le applicazioni forniti da MTS o COM+,
REMOTEDATAMODULE_IMPL include inoltre linterfaccia IObjectControl,
Tabella 29.2 Componenti connection
Componente Protocollo
TDCOMConnection DCOM
TSocketConnection Windows sockets (TCP/IP)
TWebConnection HTTP
TSOAPConnection SOAP (HTTP and XML)
29-6 G u i d a a l l a p r o g r a mma z i o n e
A p p l i c a z i o n i m u l t i - t i e r b a s a t e s u p r o v i d e r
necessaria per tutti gli oggetti transazionali. La classe di implementazione,
generata automaticamente da un wizard, ha accesso a uninterfaccia
IObjectContext, messa a disposizione dal sistema per suo conto, e che viene
utilizzata dallinterfaccia per gestire transazioni, liberare risosrse o sfruttare il
supporto per la sicurezza.
I moduli dati SOAP sono moduli dati che implementano linterfaccia
IAppServerSOAP come interfaccia richiamabile. Questi moduli dati vengono
aggiunti a unapplicazione Web Service e consentono ai client di accedere ai dati
come un Web Service. Per informazioni sulle applicazioni Web Service, vedere il
Capitolo 36, Utilizzo dei Web Services.
_
Se lapplication server deve essere distribuito in ambiente MTS o COM+, il modulo
dati remoto include degli eventi legati allattivazione o alla disattivazione
dellapplication server. Ci consente allapplication server di acquisire le connessioni
ai database al momento della sua attivazione e di rilasciarle quando viene disattivato.
Contenuti del modulo dati remoto
Come con qualsiasi altro modulo dati, nel modulo dati remoto possibile includere
qualsiasi componente non visuale. Vi sono tuttavia alcuni componenti che
necessario includere:
Se il modulo dati remoto espone le informazioni provenienti da un server di
database, deve includere un componente dataset per rappresentare i record da
quel server di database. Possono essere necessari altri componenti, come un
componente database connection di qualsiasi tipo, per permettere al dataset di
interagire con un server di database. Per informazioni sui dataset, consultare il
Capitolo 22, I dataset. Per informazioni sui componenti database connection,
veder il Capitolo 21, Connessione ai database.
Per ogni dataset che il modulo dati remoto espone ai client, deve includere un
provider di dataset. Un provider di dataset assembla i dati in pacchetti dati che
vengono inviati ai dataset client e applica aggiornamenti ricevuti dai dataset client
a un dataset sorgente o a un server di database. Per ulteriori informazioni sui
provider di dataset, vedere il Capitolo 28, Uso di componenti provider.
Per ogni documento XML che il modulo dati remoto espone ai client, deve
includere un provider XML. Un provider XML agisce come un provider di dataset,
salvo che preleva i dati da un documento XML invece che da un server di database
e vi applica aggiornamenti. Per ulteriori informazioni sullutilizzo di provider
XML, consultare Impiego di un documento XML come origine di un provider a
pagina 30-8.
_
Non confondere un componente per la connessione ai database, che connette i
dataset a un server di database, con il componente connection usato dalle
applicazioni client nelle applicazioni multi-tier. I componenti connection per le
applicazioni multi-tier sono inclusi sulle pagine DataSnap o WebServices della
Component palette.
C r e a z i o n e d i a p p l i c a z i o n i mu l t i - t i e r 29-7
A p p l i c a z i o n i m u l t i - t i e r b a s a t e s u p r o v i d e r
Uso di moduli dati transazionali
possibile scrivere application server in grado di sfruttare i servizi speciali per le
applicazioni distribuite messi a disposizione da MTS (prima di Windows 2000) o da
COM+ (in ambiente Windows 2000 e successivi). Per fare ci, invece di un comune
modulo dati remoto, si crea un modulo dati transazionale.
Quando si usa un modulo dati a transazionale, lapplicazione pu sfruttare i seguenti
servizi speciali:
Sicurezza. MTS e COM+ forniscono allapplication server un servizio per la
sicurezza basato sui ruoli. Ai client vengono assegnati dei ruoli che determinano
se essi possono accedere o meno allinterfaccia dellapplication server. Per
accedere a questi servizi di sicurezza, possibile utilizzare linterfaccia
IObjectContext a cui si accede mediante la classe di implementazione. Per ulteriori
informazioni sulla sicurezza MTS e COM+, consultare il paragrafo Sicurezza
basata sul ruolo a pagina 44-17.
Condivisione degli handle del database. I moduli dati transazionali condividono
automaticamente le connessioni al database effettuate tramite ADO o (se si sta
utilizzando MTS e si attiva MTS POOLING) BDE. Quando un client ha completato
una connessione al database, un altro client pu riutilizzarla. Questa tecnica riduce
il traffico di rete, in quanto il tier intermedio non ha bisogno di sconnettersi dal
database server remoto e di registrarsi poi di nuovo. Quando si condividono gli
handle del database, il componente di conessione al database deve impostare la
sua propriet KeepConnection a false, in modo che lapplicazione consenta la
massima condivisione delle connessioni. Per ulteriori informazioni sulla
centralizzazione per la gestione del database, consultare Distributori di risorse di
database a pagina 44-6.
Transazioni. Quando si utilizza un modulo dati transazionale, possibile fornire
un supporto per le transazioni ancora pi evoluto di quello disponibile con una
singola connessione database.I moduli dati transazionali possono partecipare a
transazioni che coinvolgono pi database, o includere funzioni che non
coinvolgono affatto i database. Per ulteriori informazioni sul supporto
transazionale fornito dagli oggetti transazionali, come i moduli dati transazionali,
consultare Gestione delle transazioni nelle applicazioni multi-tiered a
pagina 29-18.
Attivazione just-in-time e disattivazione as-soon-as-possible. possibile
scrivere il proprio server in modo che le istanze vengano attivate e disattivate
quando necessario.Quando si usa lattivazione just-in-time e la disattivazione as-
soon-as-possible, lapplication server viene istanziato solo quando necessario
gestire le richieste del client. Ci impedisce di bloccare le risorse come gli handle
del database quando non vengono usati.
Luso dellattivazione just-in-time e della disattivazione as-soon-as-possible
fornisce una soluzione intermedia tra il routing di tutti i client tramite una singola
istanza del modulo dati remoto e la creazione di unistanza distinta per ogni
connessione del client. Con ununica istanza lapplication server deve gestire tutte
le chiamate al database tramite una singola connessione al database. Ci agisce
come un collo di bottiglia, e pu avere effetti sulle prestazioni quando ci sono
molti client. Con pi istanze del modulo dati remoto, ciascuna istanza pu
29-8 G u i d a a l l a p r o g r a mma z i o n e
A p p l i c a z i o n i m u l t i - t i e r b a s a t e s u p r o v i d e r
mantenere una distinta connessione al database, evitando pertanto la necessit di
serializzare laccesso al database. Tuttavia, ci monopolizza le risorse perch gli
altri client non possono usare la connessione al database mentre associata al
modulo dati remoto di un altro client.
Per sfruttare i vantaggi delle transazioni, dellattivazione just-in-time e della
disattivazione as-soon-as-possible, le istanze del modulo dati remoto devono essere
senza stato.Ci significa che occorre fornire un supporto ulteriore nel caso in cui il
client si appoggi alle informazioni di stato. Per esempio, durante lesecuzione di un
recupero dati incrementale, il client deve passare le informazioni relative al record
corrente. Ci significa che occorre fornire un supporto ulteriore nel caso in cui il
client si appoggi alle informazioni di stato. Per maggiori informazioni sulle
informazioni di stato e sui moduli dati remoto nelle applicazioni multi-tier,
consultare la sezione Supporto delle informazioni di stato nei moduli dati remoti a
pagina 29-20.
Per impostazione predefinita, tutte le chiamate generate automaticamente a un
modulo dati sono transazionali (cio , partono dal presupposto che, al termine della
chiamata, sia possibile disattivare il modulo dati e confermare o annullare tutte le
transazioni attive). possibile scrivere un modulo dati transazionale, che dipende
dalle informazioni di stato persistenti, impostando a false la propriet AutoComplete
per lattivazione just-in-time, anche se non supporter le transazioni, o per la
disattivazione as-soon-as-possible a meno che non si usi uninterfaccia custom.
j
Gli application server contenenti moduli dati transazionali non dovrebbero aprire le
connessioni ai database finch non viene attivato il modulo dati. In fase di
progettazione bisogna accertarsi che tutti i dataset non siano attivi e che il database
non sia collegato prima di eseguire lapplicazione. Nellapplicazione stessa
aggiungere il codice, per aprire le connessioni al database quando il modulo dati
viene attivato, e chiuderlo quando viene disattivato.
Centralizzazione di moduli dati remoti
La centralizzazione di oggetti consente di creare una cache di application server che
vengono condivisi dai rispettivi client, risparmiando in tal modo risorse. La modalit
di funzionamento dipende dal tipo di modulo dati remoto e dal protocollo di
connessione.
Se si sta creando un modulo dati transazionale che verr installato in ambiente
COM+, possibile usare il COM+ Component Manager per installare lapplication
server come oggetto centralizzato. Per maggiori informazioni, consultare
Condivisione degli oggetti a pagina 44-10.
Anche se non si sta utilizzando un modulo dati transazionale, si pu trarre vantaggio
dalla centralizzazione degli oggetti se la connessione viene stabilita mediante il
protocollo TWebConnection. In questo secondo tipo di centralizzazione di oggetti, si
limita il numero di istanze che vengono create dellapplication server. In questo
modo si limita il numero di connessioni database che necessario conservare, oltre a
tutte le altre risorse utilizzate dallapplication server.
Quando lapplicazione Web Server (che passa le chiamate allapplication server)
riceve richieste dal client, le passa al primo application server disponibile nel sistema
centralizzato. Se non c un application server, disponibile, ne crea uno nuovo (fino al
C r e a z i o n e d i a p p l i c a z i o n i mu l t i - t i e r 29-9
A p p l i c a z i o n i m u l t i - t i e r b a s a t e s u p r o v i d e r
numero massimo specificato). In questo modo si fornisce una via di mezzo tra
lindirizzamento di tutti i client su una singola istanza dellapplication server (che
pu comportarsi da collo di bottiglia), e la creazione di unistanza separata per ogni
connessione client (che pu richiedere molte risorse).
Se unistanza dellapplication server nel sistema centralizzato non riceve nessuna
richiesta dai client per un certo periodo di tempo, viene automaticamente resa
disponibile. In questo si impedisce al sistema centralizzato di monopolizzare risorse
a meno che non siano utilizzate.
Per impostare la centralizzazione degli oggetti utilizzando una connessione Web
(HTTP), fare quanto segue:
1 Individuare il metodo UpdateRegistry della classe di implementazione. Questo
metodo appare nel file header della unit di implementazione:
atatIc -. L.~.L ,.iccs ccsc
ii.c>is, .c c is cc.
.,c ,..c .i.c_cis.,c >.c.c,
,..c>i ii.c>c.ics,'._.',
Il provider invia questo ultimo valore CUST_NO al client dopo avere mandato il
pacchetto dati:
c.cii..cii.c..c~.cccc.sccc .c.c, cii .cii
Infine, sul server, il provider utilizza lultimo CUST_NO inviato come valore
minimo nella query:
c.cii..cii.c..cc.cccc.sccc .c.c, cii .cii
I? iLs.,.cii
Lc.icciicc>.,cci.c.i,c,
I? L. '.i.c'
ic '',
I? .c..cis...cs
..c ..ccx.c,
ic ic - ~s.' ',
ic ic - ~s...c.cic,
,..c>c..c_s, ..c,
__?IaaII,
ieIete ,..c,
ptetectei
pabIIc
~ccL.,ceaat caat ccc_i.c.,
~.i ciicc,
,
-eaiI?
Si potrebbero aggiungere a questa definizione di classe altri membri dati o metodi
potrebbero occorre per limplementazione. Per esempio:
-I?aie? Lc.icc.cc-
-ie?Iae Lc.icc.cc-
-IacIaie 'icc_s'
ptetectei
~?Ieat _ci,
pabIIc
veIi Li.c~?Ieat sici, iiicc ccs
~ccL.,ceaat caat ccc_i.c.,
~?Ieat ciicc,
,
-eaiI?
Questi metodi e propriet aggiuntivi sono rese disponibili dallapplicazione server
ma non accessibili dai client.
Completare nel file .cpp generato il corpo principale della classe
dellimplementazione, in modo da ottenere un oggetto CORBA funzionante:
~ccL.,~ccL.,ceaat caat ccc_i.c
_s._~ccccc_i.c
~?Ieat ~ccL.,ciicc
tetata _ci,
,
veIi Li.c~?Ieat sici iiicc ccs
_ci sici,
31-12 G u i d a a l l a p r o g r a mma z i o n e
S c r i t t u r a d i s e r v e r C O R B A
_
A partire dal server CORBA, possibile scrivere del codice in grado di interagire col
BOA. Per esempio, utilizzando il BOA, possibile nascondere temporaneamente, o
disattivare, gli oggetti server e successivamente riattivarli. Per maggiori informazioni
su come scrivere del codice in grado di interagire col BOA, consultare il manuale
VisiBroker Programmers Guide.
Protezione da conflitti di thread
Per impostazione predefinita, le applicazioni CORBA sono multi-thread. Ci
significa che quando si implementano gli oggetti CORBA necessario cautelarsi da
eventuali conflitti di thread.
A meno che si specifichi altrimenti, il BOA unisce i thread client, il che significa che
tali richieste dei client possono utilizzare qualsiasi thread disponibile. possibile,
tuttavia, fare in modo che ciascun client utilizzi sempre lo stesso thread avviando il
BOA imponendo un certo numero di thread per sessione. Se ciascun client utilizza
sempre lo stesso thread, possibile memorizzare le informazioni persistenti del client
in variabili di thread. Per informazioni su come impostare la politica di threading
quando si avvia BOA, consultare il manuale VisiBroker Programmers Guide.
La libreria VisiBroker include delle classi che possono essere daiuto nel proteggere il
codice da eventuali conflitti di thread. Queste vengono definite nel file header
vthread.h, installato nella directory dei file include di VisiBroker. Le classi di
supporto per il thread di VisiBroker includono un mutex (VisMutex), una variabile di
condizione (VISCondition) e un blocco in lettura/scrittura che funziona, pi o meno,
come il sincronizzatore multi-read/exclusive-write della VCL (VISRWLock). Uno dei
benefici derivanti dallutilizzo di queste classi che sono portabili su tutte le
piattaforme supportate da VisiBroker.
Per esempio, possibile proteggere dati di istanza aggiungendo un campo VisMutex
alla classe dellimplementazione:
cIaaa ~
L..cx _.x,
tt,
Li.c c
~_i c ~_ic, i,
..ccc_i cccc ..ccc_c.'Lsicc.i.c',
catcaceaat ~xcc, c
cc c c.,
tetata,
tetata ,
j
Se si copia il codice che esegue il bind a un oggetto del server in unaltra parte
dellapplicazione, bene accertarsi che la variabile stub sia una variabile locale
oppure il membro dati di una classe. Le variabili stub globali sono abbastanza
delicate in quanto non possono rilasciare il proprio contatore dei riferimenti di
CORBA prima che venga rilasciata la variabile orb. Se si deve utilizzare
necessariamente una variabile stub globale, assicurarsi di annullare il bind
impostando la variabile a NULL prima di rilasciare lorb.
Se lapplicazione client include solamente la unit client generata (BaseName_c), non
possibile utilizzare il wizard CORBA Object per eseguire il bind a oggetti del server.
Tale codice dovr essere generato dal programmatore. Si potrebbe anche voler
scrivere del codice personale per eseguire il bind in modo da sfruttare le opzioni di
bind di VisiBroker. (Per esempio, si potrebbe voler specificare un determinato server,
disattivare la funzione che tenta automaticamente di rieseguire il bind a un server nel
caso vada perda la connessione CORBA, e cos via). Per maggiori informazioni sulla
scrittura di codice per eseguire il bind a oggetti del server, consultare la
documentazione di VisiBroker.
Utilizzo dellinterfaccia di chiamata dinamica
Linterfaccia di chiamata dinamica (DII) consente alle applicazioni client di chiamare
gli oggetti server senza utilizzare una classe stub che coordini in modo esplicito le
chiamate dellinterfaccia. Poich DII deve codificare tutte le informazioni di tipo
prima che il client invii una richiesta e quindi deve decodificare tali informazioni sul
server, il processo risulta pi lento rispetto allutilizzo di una classe stub.
Per utilizzare la DII in unapplicazione client, si deve
1 Creare un oggetto CORBA generico, che funziona come un oggetto stub, tranne
per il fatto che la sua implementazione non include il codice per coordinare le
richieste. Sar necessario fornire lID del repository delloggetto per indicare quale
oggetto dovrebbe ricevere le richieste della DII:
~ccc_i .c,
tt,
.c c>c.'L.ccc',
S c r i t t u r a d i a p p l i c a z i o n i C O R B A 31-17
C o l l a u d o d i s e r v e r C O R B A
catca ceaat ~xcc,
i.c c c. cxcc,
_
Se si cambia nome al progetto durante il processo di salvataggio, quel nome non
viene automaticamente modificato. Ogni volta che si rinomina il progetto,
necessario modificare il nome del modulo nel file di progetto in modo che
corrisponda al nome del progetto. Le definizioni del contenuto e del gestore
dovrebbero cambiare automaticamente una volta che il nome del modulo viene
modificato.
Per informazioni sullutilizzo nei file di configurazione Apache delle definizioni di
modulo, contenuto e gestore, vedere la documentazione sul sito Web di Apache
httpd.apache.org.
Web App Debugger
I tipi di server summenzionati presentano vantaggi e svantaggi per gli ambienti di
siluppo, ma nessuno di loro particolarmente adatto per eseguire il debug. La
distribuizione dellapplicazione e la configurazione del debugger pu rendere il
debug dellapplicazione per Web server unoperazione di gran lunga pi noiosa
rispetto al debug di altri tipi di applicazione.
Per fortuna, il debug di unapplicazione per Web server non necessariamente cos
complessa. C++Builder include un Web App Debugger che semplifica le operazioni
di debug. Web App Debugger agisce sulla macchina di sviluppo come un server
Web. Se si esegue il build dellapplicazione per Web server come un eseguibile di
Web App Debugger, la distribuzione viene portata a termine in automatico durante il
processo di build. Per eseguire il debug dellapplicazione, sufficiente avviarla
mediante il comando Run|Run. Poi, selezionare Tools|Web App Debugger, fare clic
sullURL predefinito e selezionare lapplicazione nel browser Web che viene
visualizzato. Lapplicazione verr avviata nella finestra del browser e sar possibile
utilizzare lIDE per impostare i breakpoint e ottenere le informazioni di debug.
Non appena lapplicazione sar pronta per essere collaudata o distribuita in un
ambiente di produzione, sar possibile convertire il progetto Web App Debugger in
uno degli altri tipi di destinazione utilizzando la procedura discritta di seguito.
_
Quando si crea un progetto Web App Debugger, sar necessario fornire al progetto
un CoClass Name. Questo semplicemente un nome utilizzato da Web App
Debugger per fare riferimento allapplicazione. Quasi tutti gli sviluppatori utilizzano
come CoClass Name il nome dellapplicazione.
C r e a z i o n e d i a p p l i c a z i o n i s e r v e r p e r I n t e r n e t 32-9
D e b u g d i a p p l i c a z i o n i s e r v e r
Conversione del tipo di destinazione per applicazioni Web server
Una potente funzionalit di Web Broker e WebSnap costituita dal fatto che essi
offrono vari tipi di server di destinazione. C++Builder consente di eseguire
facilmente la conversione da un tipo di destinazione a un altro.
Poich Web Broker e WebSnap hanno filosofie di progettazione leggermente
differenti, necessario utilizzare un diverso metodo di conversione per ogni
architettura. Per convertire il tipo di destinazione dellapplicazione Web Broker, fare
quanto segue:
1 Fare clic destro sul modulo Web e scegliere il comando Add To Repository.
2 Nella finestra di dialogo Add To Repository, assegnare al modulo Web un titolo,
una descrizione di testo, la pagina del Repository (probabilmente Data Modules),
un nome di autore e unicona.
3 Scegliere OK per salvare il modulo Web come modello.
4 Dal menu principale, scegliere il comando File|New e selezionare lopzione Web
Server Application. Nella finestra di dialogo New Web Server Application
scegliere il tipo di destinazione opportuno.
5 Cancellare il modulo Web generato automaticamente.
6 Dal menu principale, scegliere il comando File|New e selezionare il modello
salvato al punto 3. Il modello sar presente nella pagina specificata al punto 2.
Per convertire il tipo di destinazione di unapplicazione WebSnap:
1 Caricare un progetto nellIDE.
2 Visualizzare Project Manager utilizzando il comando View|Project Manager.
Espandere il progetto in modo da rendere visibili tutte le unit.
3 In Project Manager, fare clic sul pulsante New per creare un nuovo progetto di
applicazione per Web server. Fare doppio clic nella pagina WebSnap
sullelemento WebSnap Application. Selezionare le opzioni appropriate per il
progetto, compreso il tipo server che si desidera utilizzare, quindi fare clic su OK.
4 Espandere il nuovo progetto in Project Manager. Selezionare tutti i file visualizzati
e cancellarli.
5 Uno alla volta, selezionare ogni singolo file nel progetto (tranne il file di scheda in
progetto Web App Debugger) e trascinarlo sul nuovo progetto. Appena appare
una finestra di dialogo che chiede se si desidera aggiungere quel file al nuovo
progetto, fare clic su Yes.
Debug di applicazioni server
Il debug di applicazioni per server Web presenta alcuni problemi specifici, perch
esse vengono eseguite per rispondere a messaggi provenienti da un server Web. Non
possibile lanciare semplicemente lapplicazione dallIDE, perch cos facendo si
32-10 G u i d a a l l a p r o g r a mma z i o n e
D e b u g d i a p p l i c a z i o n i s e r v e r
lascia il server Web fuori dal ciclo e lapplicazione non trover il messaggio di
richiesta che si aspettava.
Gli argomenti successivi descrivono le tecniche utilizzabili per eseguire il debug di
applicazioni per Web server.
Utilizzo di Web Application Debugger
Web Application Debugger permette di controllare in modo modo semplice le
richieste HTTP, le risposte e i tempi di risposta. Il Web Application Debugger
sostituisce il server Web. Una volta eseguito il debug dellapplicazione, possibile
convertirla in uno dei tipi supportati di applicazione Web e installarla in un server
Web commerciale.
Per utilizzare Web Application Debugger, necessario per prima cosa creare
lapplicazione Web come un eseguibile Web Application Debugger. Sia che si utilizzi
Web Broker o WebSnap, il wizard che crea lapplicazione per Web server include
questa possibilit come unopzione da selezionare non appena si inizia
lapplicazione. In questo modo viene creata unapplicazione per Web server che
anche un server COM.
Per informazioni su come scrivere questa applicazione per Web server utilizzando
Web Broker, vedere il Capitolo 33, Utilizzo di Web Broker. Per ulteriori
informazioni sullutilizzo di WebSnap, vedere il Capitolo 34, Creazione di
applicazioni Web Server con WebSnap.
Avvio dellapplicazione con Web Application Debugger
Una volta sviluppata lapplicazione per Web server, possibile eseguirla e farne il
debug nel seguente modo:
1 Caricato il progetto nellIDE, impostare tutti i breakpoint in modo che sia possibile
fare il debug dellapplicazione esattamente come con qualsiasi altro eseguibile.
2 Scegliere il comando Run|Run. Viene visualizzata la finestra della console del
server COM che lapplicazione per Web server. La prima volta che si esegue
lapplicazione, il server COM viene registrato in modo che il Web Application
debugger vi possa accedere.
3 Selezionare il comando Tools|Web App Debugger.
4 Fare clic sul pulsante Start. Viene visualizzata la pagina ServerInfo nel Browser
predefinito.
5 La pagina ServerInfo contiene una lista a discesa di tutti gli eseguibili Web
Application Debugger registrati. Selezionare lapplicazione dallelenco a discesa.
Se lapplicazione non presente in questa lista a discesa, provare a eseguire
lapplicazione come un normale eseguibile. Lapplicazione deve essere eseguita
C r e a z i o n e d i a p p l i c a z i o n i s e r v e r p e r I n t e r n e t 32-11
D e b u g d i a p p l i c a z i o n i s e r v e r
almeno una volta in modo che possa effettuare la registrazione. Se anche dopo
questa operazione lapplicazione non inclusa nella lista a discesa, provare ad
aggiornare la pagina web. (A volte il browser Web memorizza questa pagina nella
cache, impedendo di vedere le modifiche pi recenti.)
6 Dopo aver selezionato lapplicazione nella lista a discesa, fare clic sul pulsante Go.
In questo modo si avvia lapplicazione nel Web Application Debugger, il quale
fornisce i dettagli relativi ai messaggi di richiesta e di risposta che passano fra
lapplicazione e il Web Application Debugger.
Conversione dellapplicazione in un altro tipo di applicazione per Web server
Terminato il debug dellapplicazione per Web server con Web Application
Debugger, sar necessario convertirla in un altro tipo di applicazione Web che pu
essere installata su un server Web commerciale. Per maggiori informazioni sulla
conversione delle proprie applicazioni, consultare Conversione del tipo di
destinazione per applicazioni Web server a pagina 32-9.
Debug di applicazioni Web sotto forma di DLL
Le applicazioni ISAPI, NSAPI, e Apache sono in effetti DLL che contengono punti
dingresso predefiniti. Il server Web passa i messaggi di richiesta allapplicazione
facendo chiamate a questi punti dingresso. Poich queste applicazioni sono DLL,
possibile eseguirne il debug impostando i parametri di esecuzione dellapplicazione
per avviare il server.
Per configurare i parametri di esecuzione dellapplicazione, scegliere il comando
Run|Parameters e impostare Host Application e il Run Parameters in modo da
specificare leseguibile per il server Web e tutti i parametri necessari nel momento in
cui lo si avvia. Per maggiori informazioni sui valori per il proprio server Web,
consultare la documentazione fornita dal produttore del Web Server.
_
Per alcuni Web Servers necessario apportare ulteriori modifiche prima che si abbia
il diritto di avviare lHost Application in questo modo. Per i dettagli, consultare la
documentazione fornita dal produttore del Web Server.
_
Se si utilizza Windows 2000 con IIS 5, i dettagli su tutte le modifiche che necessario
apportare per configurare correttamente i diritti sono descritte sul sito Web seguente:
,c..ci.c.icc,1,..1,.
Una volta configurate le opzioni Host Application e Run Parameters, possibile
configurare i breakpoint in modo che, non appena il server passa un messaggio di
richiesta alla DLL, uno di questi breakpoint venga intercettato e si possa eseguire il
debug normalmente.
_
Prima di avviare il server Web usando i parametri di esecuzione dellapplicazione,
assicurarsi che il server non sia gi in esecuzione.
32-12 G u i d a a l l a p r o g r a mma z i o n e
D e b u g d i a p p l i c a z i o n i s e r v e r
Diritti utente necessari per il debug di DLL
In ambiente Windows, si devono avere i diritti di utenza adeguati per eseguire il
debug di una DLL. possibile ottenere i diritti nel seguente modo:
1 Nella parte Administrative Tools del Control Panel, fare clic su Local Security
Policy. Espandere Local Policies e fare doppio clic su User Rights Assignment.
Fare doppio clic sullopzione Act as part of the operating system nella parte destra
del pannello.
2 Selezionare Add per aggiungere un utente allelenco. Aggiungere lutente
corrente.
3 Riavviare il sistema in modo da rendere operative le modifiche.
U t i l i z z o d i We b B r o k e r 33-1
C a p i t o l o
33
Capitolo33Utilizzo di Web Broker
I componenti di Web Broker (situati sulla pagina Internet della Component palette)
permettono di creare gestori di evento che sono associati a uno specifico Uniform
Resource Identifier (URI). A elaborazione conclusa, possibile impostare da
programma documenti HTML o XML e trasferirli al client. I componenti WEb Broker
si possono utilizzare per lo sviluppo di applicazioni per pi piattaforme.
Spesso, il contenuto delle pagine web tratto da dei database. possibile utilizzare
dei componenti Internet per gestire automaticamente le connessioni ai database, il
che consente a un singolo DLL di gestire numerose connessioni database thread-safe.
Nelle prossime sezioni di questo capitolo viene spiegato come si usano i componenti
Web Broker per creare unapplicazione per Web server.
Creazione di applicazioni per Web server con Web Broker
Per creare una nuova applicazione per Web server utilizzando larchitettura Web
Broker:
1 Selezionare File|New|Other.
2 Nella finestra di dialogo New Items, selezionare la pagina New e scegliere Web
Server Application.
3 Viene visualizzata una finestra di dialogo, dove possibile selezionare uno dei tipi
di applicazione Web server:
ISAPI and NSAPI: Selezionando questo tipo di applicazione si configura il
progetto come un DLL, con i metodi esportati previsti dal Web server. Include
inoltre i file header appropriati per la generazione dellapplicazione.
Apache: Selezionando questo tipo di applicazione si configura il progetto come un
DLL, con i metodi esportati previsti dal Web server Apache. Include inoltre i file
header appropriati per la generazione dellapplicazione.
33-2 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i a p p l i c a z i o n i p e r W e b s e r v e r c o n W e b B r o k e r
CGI stand-alone: La selezione di questo tipo di applicazione imposta il progetto
come unapplicazione per console e include i file header appropriati.
Win-CGI stand-alone: La selezione di questo tipo di applicazione imposta il
progetto come unapplicazione per Windows e include i file header appropriati.
Web Application Debugger stand-alone executable: La selezione di questo tipo di
applicazione configura un ambiente per sviluppare e provare applicazioni per
Web server. Questo tipo di applicazione non destinato allimpiego.
Scegliere il tipo di Web Server Application capace di comunicare con il tipo di Web
Server che lapplicazione utilizzer. In questo modo, si crea un nuovo progetto
configurato per utilizzare i componenti Internet e contenente un modulo Web vuoto.
Il modulo Web
Il modulo Web (TWebModule) un discendente di TDataModule e pu essere
utilizzato nello stesso modo: fornire il controllo centralizzato delle regole di gestione
e dei componenti non visuali nellapplicazione Web.
Si aggiunge poi qualsiasi produttore di contenuti che lapplicazione utilizza per
generare messaggi di risposta. Questi possono essere i produttori di contenuti
incorporati, come TPageProducer, TDataSetPageProducer, TDataSetTableProducer,
TQueryTableProducer e TInetXPageProducer oppure discendenti realizzati ad hoc di
TCustomContentProducer. Se lapplicazione genera messaggi di risposta comprendenti
materiale tratto da database, si possono aggiungere componenti di accesso ai dati o
componenti speciali per scrivere un Web server che si comporti da cliente in
unapplicazione per database multi-tier.
Oltre registrare i componenti non visuali e le regole di gestione, il modulo Web
agisce anche come dispatcher, e fa corrispondere i messaggi di richiesta HTTP in
arrivo a elementi di azione che generano le risposte alle richieste.
A volte, si dispone gi di un modulo dati contenente molti dei componenti e delle
regole di gestione non visuali che si intendono usare nellapplicazione Web.
possibile sostituire il modulo Web con il proprio modulo dati preesistente.
sufficiente cancellare il modulo Web generato automaticamente e sostituirlo con il
proprio modulo dati. Quindi, si aggiunge al modulo dati un componente
TWebDispatcher, in modo che possa eseguire il dispatch di messaggi di richiesta a
elementi di azione, secondo le modalit previste per i moduli Web. Se si desidera
modificare il modo in cui gli elementi di azione sono selezionati per rispondere a
messaggi di richiesta HTTP in arrivo, far derivare un nuovo componente dispatcher
da TCustomWebDispatcher e aggiungerlo al modulo dati al posto dellaltro.
Il progetto pu contenere solamente un dispatcher. Questo pu essere sia il modulo
Web generato automaticamente quando si crea il progetto, sia il componente
TWebDispatcher aggiunto a un modulo dati in sostituzione del modulo Web. Se in
fase di lesecuzione si crea un secondo modulo dati contenente un dispatcher,
lapplicazione per Web server genera un errore di esecuzione.
_
Il modulo Web impostato in fase di progetto in effetti un modello. Nelle
applicazioni ISAPI e NSAPI, ogni messaggio di richiesta genera un thread distinto e
U t i l i z z o d i We b B r o k e r 33-3
S t r u t t u r a d e l l e a p p l i c a z i o n i W e b B r o k e r
per ogni thread vengono create dinamicamente ricorrenze distinte del modulo Web e
del suo contenuto.
j
Il modulo Web di unapplicazione per Web server basata su DLL viene messo in
cache per migliorare il tempo di risposta quando viene riutilizzato. Lo stato del
dispatcher e della sua lista di azioni non viene reinizializzato tra due richieste
successive. Lattivazione o la disattivazione di elementi di azione in fase di
esecuzione pu produrre risultati inattesi, quando il modulo utilizzato per
successive richieste client.
Loggetto Application Web
Il progetto configurato per lapplicazione Web contiene una variabile globale
chiamata Application. Application un discendente di TWebApplication
(TISAPIApplication,TApacheApplication o TCGIApplication) adeguato al tipo di
applicazione che si sta creando. Viene eseguito in risposta a messaggi di richiesta
HTTP provenienti dal Web server.
j
Nel file di progetto non includere Forms.hpp dopo listruzione include relativa a
CGIApp.hpp o a ISAPIApp.hpp. Forms.hpp dichiara tra laltro una variabile globale
di nome Application, e se tale variabile appare dopo CGIApp.hpp o ISAPIApp.hpp,
Application verr inizializzata a un oggetto di tipo errato.
Struttura delle applicazioni Web Broker
Quando lapplicazione Web riceve un messaggio di richiesta HTTP, crea un oggetto
TWebRequest che rappresenta il messaggio di richiesta HTTP e un oggetto
TWebResponse per rappresentare la risposta da restituire. Lapplicazione quindi passa
questi oggetti al dispatcher Web (che pu essere il modulo Web o un componente
TWebDispatcher).
Il dispatcher Web controlla il flusso dellapplicazione per Web server. Il dispatcher
gestisce un assortimento di elementi di azione (TWebActionItem) che sanno come
gestire certi tipi di messaggi di richiesta HTTP. Il dispatcher identifica gli elementi di
azione appropriati o i componenti auto-dispatching capaci di gestire il messaggio di
richiesta HTTP e passa gli oggetti di richiesta e di risposta al gestore identificato per
consentirgli di eseguire lazione richiesta o di formulare un messaggio di risposta.
Tutto ci viene spiegato in dettaglio nella sezione Il dispatcher Web a pagina 33-4.
33-4 G u i d a a l l a p r o g r a mma z i o n e
I l d i s p a t c h e r W e b
Figura 33.1 Struttura di unapplicazione server
Gli elementi di azione hanno la responsabilit di leggere la richiesta e di mettere
insieme il messaggio di risposta. I produttori di contenuti specializzati affiancano gli
elementi di azione nel generare dinamicamente il contenuto dei messaggi di risposta,
che possono comprendere un codice HTML ad hoc, o altro contenuto MIME. I
produttori di contenuti possono fare uso di altri produttori o discendenti di
THTMLTagAttributes, per aiutarli a compilare il messaggio di risposta. Per maggiori
informazioni sui produttori di contenuti, consultare Generazione del contenuto dei
messaggi di risposta on pagina 33-14.
Se si crea il Web Client in unapplicazione per database multi-tier, lapplicazione per
Web server pu includere altri componenti auto-dispatching che rappresentano
informazioni di database codificate in XML e classi di manipolazione di database
codificate in javascript. Se si crea un server che implementa un Web Service,
lapplicazione per Web server pu includere un componente auto-dispatching che
passa messaggi basati su SOAP a un invoker che li interpreta e li esegue. Il dispatcher
invita i componenti auto-dispatching a gestire il messaggio di richiesta, dopo averci
provato con tutti i suoi elementi di azione.
Quando tutti gli elementi di azione (o i componenti per il dispatch automatico)
hanno terminato di creare la risposta riempiendo loggetto TWebResponse, il
dispatcher restituisce il risultato allapplicazione Web. Lapplicazione trasmette la
risposta al client tramite il server Web.
Il dispatcher Web
Se si utilizza un modulo Web, questo agisce come un dispatcher Web. Se si utilizza
un modulo dati esistente, bisogna aggiungervi un singolo componente dispatcher
(TWebDispatcher). Il dispatcher gestisce un assortimento di elementi di azione in
grado di gestire certi tipi di messaggi di richiesta. Quando lapplicazione Web passa
un oggetto di richiesta e un oggetto di risposta al dispatcher, seleziona anche uno o
pi elementi di azione per rispondere alla richiesta.
Web Module (Dispatcher)
Web
Server
Action
Item
Content
Producer
Web
Application
Web
Response
Action
Item
Content
Producer
Content
Producer
Web
Request
U t i l i z z o d i We b B r o k e r 33-5
I l d i s p a t c h e r W e b
Aggiunta di azioni al dispatcher
Si apre laction editor di Object Inspector facendo clic sui puntini di sospensione della
propriet Actions del dispatcher. Gli elementi di azione possono essere aggiunti al
dispatcher facendo clic sul pulsante Add nellAction editor.
Si aggiungono azioni al dispatcher per rispondere a vari metodi di richiesta o agli
URI di destinazione. Vi sono diversi modi di impostare gli elementi di azione. Si pu
cominciare da quelli che preelaborano le richieste e terminano con unazione
predefinita che verifica se la risposta completa e invia la risposta, oppure restituisce
un codice di errore. Si pu anche aggiungere un elemento di azione distinto per ogni
tipo di richiesta. In questo caso, ciascun elemento di azione gestisce
indipendentemente la propria richiesta.
Gli elementi di azione sono discussi dettagliatamente in Elementi di azione on
pagina 33-6.
Dispatch dei messaggi di richiesta
Quando il dispatcher riceve la richiesta client, genera un evento BeforeDispatch.
Questo d allapplicazione la possibilit di preelaborare il messaggio di richiesta
prima che sia visto da un elemento di azione.
Quindi, il dispatcher cerca nellelenco degli elementi di azione un elemento che
coincida con la porzione PathInfo dellURL di destinazione del messaggio di richiesta
e che possa fornire il servizio specificato come metodo del messaggio di richiesta.
Allo scopo, confronta le propriet PathInfo e MethodType delloggetto TWebRequest
con le propriet dello stesso nome presenti nellelemento di azione.
Quando il dispatcher trova un elemento di azione appropriato, lo attiva. Lelemento
di azione una volta attivato, fa una delle cose seguenti:
Compila il contenuto della risposta e lo invia, oppure segnala che la richiesta
completamente gestita.
Aggiunge qualcosa alla risposta e poi permette ad altri elementi di azione di
completare il lavoro.
Passa la richiesta ad altri elementi di azione.
Se, dopo avere controllato tutti i suoi elementi di azione, il messaggio non stato
gestito, il dispatcher controlla ogni componente auto-dispatching registrato in modo
speciale che non utilizza elementi di azione. Questi componenti sono specifici per le
applicazioni database multi-tiered e sono descritti nella sezione Creazione di
applicazioni Web con InternetExpress a pagina 29-33
Se, dopo avere controllato tutti gli elementi di azione e qualsiasi componente auto-
dispatching registrato in modo speciale, il messaggio di richiesta non stato ancora
completamente gestito, il dispatcher chiama lelemento di azione predefinito.
Lelemento di azione predefinito non ha bisogno di corrispondere n allURL di
destinazione n al metodo della richiesta.
33-6 G u i d a a l l a p r o g r a mma z i o n e
E l e m e n t i d i a z i o n e
Quando il dispatcher ha raggiunto la fine della lista di azioni (tra cui lazione
predefinita, se prevista) e nessuna azione stata attivata, al server non viene inviato
nulla. Il server si limita a interrompere la connessione con il client.
Se la richiesta gestita dagli elementi di azione, il dispatcher genera un evento
AfterDispatch. Questo offre allapplicazione lultima opportunit di verificare la
risposta fornita e di applicare modifiche allultimo minuto.
Elementi di azione
Ogni elemento di azione (TWebActionItem) esegue unoperazione specifica in risposta
a un certo tipo di messaggio di richiesta.
Gli elementi di azione possono rispondere completamente a una richiesta, o eseguire
parte della risposta lasciando poi che siano altri elementi di azione a completare il
lavoro. Gli elementi di azione possono inviare il messaggio HTTP di risposta alla
richiesta, o semplicemente impostare una parte della risposta che viene poi
completata da altri elementi di azione. Se una risposta completata dagli elementi di
azione ma non viene inviata, lapplicazione per Web server invia il messaggio di
risposta.
Determinazione dellattivazione degli elementi di azione
La maggior parte delle propriet di un elemento di azione determinano quando il
dispatcher lo seleziona per gestire un messaggio di richiesta HTTP. Per impostare le
propriet di un elemento di azione, necessario attivare prima lAction editor: si
seleziona la propriet Actions del dispatcher nellObject Inspector e si fa clic sui
puntini di sospensione. Quando unazione selezionata nellAction editor, se ne
possono modificare le propriet nellObject Inspector.
LURL di destinazione
Il dispatcher confronta la propriet PathInfo di un elemento di azione con il PathInfo
del messaggio di richiesta. Il valore di questa propriet dovrebbe essere la parte
riguardante le informazioni di percorso dellURL per tutte le richieste che lelemento
di azione preparato a gestire. Ad esempio, dato questo URL:
,....cc.iic..i..isi.i.ccic.
e supponendo che la parte ic. indichi lapplicazione per Web server, la parte
riguardante le informazioni di percorso
.i..is
Le informazioni di percorso sono utili per indicare dove lapplicazione Web deve
cercare le informazioni quando esegue le richieste o per dividere lapplicazione Web
in sottoinsiemi logici.
U t i l i z z o d i We b B r o k e r 33-7
E l e m e n t i d i a z i o n e
La propriet Method Type
La propriet MethodType di un elemento di azione indica quale tipo di messaggi di
richiesta pu elaborare. Il dispatcher confronta la propriet MethodType di un
elemento di azione al MethodType del messaggio di richiesta. MethodType pu
assumere uno dei seguenti valori:
Attivazione e disattivazione di elementi di azione
Ogni elemento di azione ha una propriet Enabled che pu essere utilizzata per
attivarlo o disattivarlo. Impostando Enabled a false, si disattiva lelemento di azione
facendo s che esso non venga preso in considerazione dal dispatcher quando ricerca
un elemento di azione per gestire una richiesta.
Un gestore di evento BeforeDispatch pu controllare quali elementi di azione devono
elaborare una richiesta modificando la loro propriet Enabled, prima che il dispatcher
cominci a farli corrispondere al messaggio di richiesta.
j
Modificare la propriet Enabled durante lesecuzione di unazione pu determinare
risultati inattesi nelle richieste successive. Se lapplicazione per Web server un DLL
che mette in cache i moduli Web, alla richiesta successiva non verr ripristinato lo
stato iniziale. Per riportare tutti gli elementi di azione allo stato iniziale opportuno si
utilizza levento BeforeDispatch.
Scelta di un elemento di azione predefinito
Solo uno degli elementi di azione pu essere lelemento di azione predefinito.
Lelemento di azione predefinito viene selezionato impostandone la propriet Default
a true. Quando la propriet Default di un elemento di azione viene impostata a true,
la propriet Default del precedente elemento di azione predefinito (se previsto) viene
impostata a false.
Quando il dispatcher esamina la lista di elementi di azione per sceglierne uno che
sappia gestire una richiesta, memorizza il nome dellelemento di azione predefinito.
Se la richiesta non stata gestita completamente quando il dispatcher ha raggiunto la
fine della lista di elementi di azione, viene eseguito lelemento di azione predefinito.
Il dispatcher non controlla le propriet PathInfo o MethodType dellelemento di azione
predefinito. Il dispatcher non controlla neanche la propriet Enabled. Pertanto, si pu
Tabella 33.1 Valori di MethodType
Valore Significato
mtGet La richiesta chiede alle informazioni associate allURI di destinazione di essere
restituita in un messaggio di risposta.
mtHead La richiesta richiede le propriet dellintestazione di una risposta, come se
rispondesse a una richiesta mtGet, ma omettendo il contenuto della risposta.
mtPost La richiesta fornisce informazioni da inviare allapplicazione Web.
mtPut La richiesta chiede che la risorsa associata allURI di destinazione sia sostituita dal
contenuto del messaggio di richiesta.
mtAny Corrisponde a qualsiasi tipo di metodo di richiesta, tra cui mtGet, mtHead, mtPut e
mtPost.
33-8 G u i d a a l l a p r o g r a mma z i o n e
E l e m e n t i d i a z i o n e
essere certi che lelemento di azione predefinito venga chiamato solamente alla fine,
impostandone la propriet Enabled a false.
Lelemento di azione predefinito dovrebbe essere preparato a gestire qualsiasi
richiesta che incontra, anche se solo per restituire un codice di errore indicante una
URI o un MethodType non validi. Se lelemento di azione predefinito non gestisce la
richiesta, nessuna risposta inviata al client Web.
j
Modificare la propriet Default di unazione durante lesecuzione potrebbe produrre
risultati inattesi per la richiesta corrente. Se la propriet Default di unazione gi
attivata impostata a true, lazione non viene riesaminata e il dispatcher non la attiva
nuovamente quando raggiunge la fine della lista di azioni.
Risposta a messaggi di richiesta mediante elementi di azione
Il lavoro effettivo di unapplicazione per Web server viene svolto dagli elementi di
azione quando vengono eseguiti. Quando il dispatcher Web attiva un elemento di
azione, questo pu reagire in due modi al messaggio di richiesta corrente:
Se allelemento di azione associato come valore della sua propriet Producer un
componente produttore, questo assegna automaticamente il Content del messaggio
di risposta utilizzando il proprio metodo Content. La pagina Internet della
Component palette contiene molti componenti produttori di contenuti utili a
costruire una pagina HTML contenente il messaggio di risposta.
Dopo che il produttore ha assegnato il contenuto della risposta (se c un
produttore associato), lelemento di azione riceve un evento OnAction. Al gestore
di evento OnAction vengono passati loggetto TWebRequest rappresentante il
messaggio di richiesta HTTP e un oggetto TWebResponse per compilare le
informazioni di risposta.
Se il contenuto dellelemento di azione pu essere generato da un unico produttore
di contenuti, pi semplice assegnarlo come propriet Producer dellelemento di
azione.Tuttavia, mediante il gestore di evento OnAction si pu sempre accedere
anche a qualsiasi produttore di contenuti. Il gestore di evento OnAction consente pi
flessibilit , in modo che sia possibile utilizzare pi produttori di contenuti, stabilire
le propriet dei messaggi di risposta, e cos via.
Per rispondere ai messaggi di richiesta sia il componente produttore di contenuti che
il gestore di evento OnAction possono utilizzare qualsiasi oggetto e qualsiasi metodo
di libreria. Infatti, possono accedere a database, eseguire calcoli, comporre o
selezionare documenti HTML e cos via. Per maggiori informazioni sulla generazione
di contenuti di risposta utilizzando componenti produttori di contenuti, consultare la
sezione Generazione del contenuto dei messaggi di risposta a pagina 33-14.
Invio della risposta
Un gestore di evento OnAction pu spedire la risposta al client Web utilizzando i
metodi delloggetto TWebResponse. Tuttavia, se nessun elemento di azione invia la
risposta al client, questa verr spedita dallapplicazione per Web server fino a
quando lultimo elemento di azione che esaminer la richiesta non indicher che essa
stata portata a termine.
U t i l i z z o d i We b B r o k e r 33-9
A c c e s s o a l l e i n f o r m a z i o n i d e l l a r i c h i e s t a c l i e n t
Utilizzo di pi elementi di azione
possibile rispondere a una richiesta usando un singolo elemento di azione, oppure
ripartendo il lavoro tra pi elementi. Se lelemento di azione non termina
completamente la preparazione del messaggio di risposta, deve segnalare questo
stato nel gestore di evento OnAction mediante limpostazione a false del parametro
Handled.
Se molti elementi di azione si suddividono il compito di rispondere ai messaggi di
richiesta, ciascuno impostando Handled a false in modo da consentire agli altri di
continuare, assicurarsi che lelemento di azione predefinito lasci il parametro Handled
impostato a true. Altrimenti, al client Web non verr inviata nessuna risposta.
Quando si ripartisce il lavoro tra pi elementi di azione, il gestore di evento OnAction
dellelemento di azione predefinito oppure il gestore di evento AfterDispatch del
dispatcher devono verificare se lincombenza stata portata a termine e riportare il
codice di errore appropriato in caso contrario.
Accesso alle informazioni della richiesta client
Quando lapplicazione per Web server riceve un messaggio di richiesta HTTP,
lintestazione della richiesta client viene caricata nelle propriet di un oggetto
TWebRequest. Nelle applicazioni NSAPI e ISAPI, il messaggio di richiesta
incorporato in un oggetto TISAPIRequest. Le applicazioni CGI di console utilizzano
oggetti TCGIRequest, mentre le applicazioni Windows CGI utilizzano oggetti
TWinCGIRequest.
Le propriet delloggetto di richiesta sono di sola lettura. Queste possono essere
utilizzate per raccogliere tutte delle informazioni disponibile nella richiesta client.
Propriet contenenti informazioni dello header della richiesta
In un oggetto di richiesta, la maggior parte delle propriet contengono informazioni
riguardanti la richiesta indicate nello header della richiesta HTTP. Non tutte le
richieste forniscono il valore di ognuna di queste propriet. Inoltre, alcune richieste
possono comprendere campi di intestazione che non affiorano in una propriet
delloggetto di richiesta, soprattutto perch lo standard HTTP in costante
evoluzione. Per ottenere il valore di un campo dello header della richiesta non
identificato come propriet delloggetto richiesta, si ricorre al metodo
GetFieldByName.
Propriet che identificano la destinazione
La destinazione completa di un messaggio di richiesta data dalla sua propriet
URL. Di solito, una URL che si pu suddividere in protocollo (HTTP), Host (sistema
server), ScriptName (applicazione server), PathInfo (ubicazione sullhost) e Query.
Ogni segmento emerge nella propria propriet. Il protocollo sempre HTTP, mentre
Host e ScriptName identificano lapplicazione per Web server. Il dispatcher utilizza la
parte PathInfo quando fa corrispondere elementi di azione ai messaggi di richiesta.
33-10 G u i d a a l l a p r o g r a mma z i o n e
A c c e s s o a l l e i n f o r m a z i o n i d e l l a r i c h i e s t a c l i e n t
Query utilizzato da alcune richieste per specificare i dettagli delle informazioni
chieste. Il suo valore viene analizzato come la propriet QueryFields.
Propriet che descrivono il client Web
La richiesta include anche molte propriet che forniscono informazioni sullorigine
della richiesta. Queste includono tutte le informazioni disponibili, dallindirizzo di
posta elettronica del mittente (propriet From) allURI da cui ha avuto origine il
messaggio (propriet Referer o RemoteHost). Se la richiesta include un contenuto non
proveniente dalla URI da cui proviene la richiesta, lorigine del contenuto data dalla
propriet DerivedFrom. Si possono anche determinare lindirizzo IP del client (la
propriet RemoteAddr) e il nome e la versione dellapplicazione che ha inviato la
richiesta (la propriet UserAgent).
Propriet che identificano lo scopo della richiesta
La propriet Method una stringa che descrive quello che il messaggio di richiesta
chiede di fare allapplicazione server. Lo standard HTTP 1.1 definisce i seguenti
metodi:
La propriet Method pu indicare qualsiasi altro metodo che il client Web richiede al
server.
Lapplicazione per Web server non deve fornire una risposta a ogni possibile valore
di Method. Lo standard HTTP vuole per che esso tratti sia le richieste GET che quelle
HEAD.
La propriet MethodType indica se il valore di Method GET (mtGet), HEAD (mtHead),
POST (mtPost), PUT (mtPut) o unaltra stringa (mtAny). Il dispatcher fa
corrispondere il valore della propriet MethodType al MethodType di ogni elemento di
azione.
Propriet che descrivono la risposta prevista
La propriet Accept indica i tipi di supporto mediatico che il client Web accetta come
contenuto del messaggio di risposta. La propriet IfModifiedSince specifica se il client
vuole solo informazioni che sono cambiate recentemente. La propriet Cookie include
Valore Che cosa richiede il messaggio
OPTIONS Informazioni sulle opzioni di comunicazione disponibili.
GET Informazioni identificate dalla propriet URL.
HEAD Informazioni di intestazione da un messaggio equivalente GET, senza il
contenuto della risposta.
POST Allapplicazione server di registra i dati inclusi nella propriet Content, come
appropriato.
PUT Allapplicazione server di sostituire nella risorsa indicata dalla propriet URL i
dati presenti nella propriet Content.
DELETE Allapplicazione server di cancellare o nascondere la risorsa identificata dalla
propriet URL.
TRACE Allapplicazione server di inviare una ricevuta di ritorno per confermare di
aver ricevuto la richiesta.
U t i l i z z o d i We b B r o k e r 33-11
C r e a z i o n e d i m e s s a g g i d i r i s p o s t a H T T P
informazioni di stato (di solito aggiunte precedentemente dallapplicazione) che
possono modificare la risposta.
Propriet che descrivono il contenuto
La maggior parte delle richieste sono prive di contenuto, in quanto chiedono solo
informazioni. Tuttavia, alcune richieste, come le richieste POST, forniscono un
contenuto che si prevede verr utilizzato dallapplicazione per Web server. Il tipo di
supporto del contenuto fornito nella propriet ContentType e la sua lunghezza nella
propriet ContentLength. Se il contenuto del messaggio stato codificato (ad esempio,
per la compressione dati), queste informazioni si trovano nella propriet
ContentEncoding. Il nome e il numero di versione dellapplicazione che ha prodotto il
contenuto specificato dalla propriet ContentVersion. Anche la propriet Title pu
fornire informazioni sul contenuto.
Il contenuto dei messaggi di richiesta HTTP
Oltre ai campi di intestazione, alcuni messaggi di richiesta includono una porzione di
contenuto che lapplicazione per Web server deve elaborare in qualche modo. Ad
esempio, una richiesta POST pu includere informazioni da aggiungere a un
database gestito dallapplicazione per Web server.
Il valore non elaborato del contenuto dato dalla propriet Content. Se questo pu
essere suddiviso in campi separati da simboli (&), una versione scomposta
disponibile nella propriet ContentFields.
Creazione di messaggi di risposta HTTP
Quando lapplicazione per Web server crea un oggetto TWebRequest in risposta a un
messaggio di richiesta HTTP in arrivo, crea anche un oggetto corrispondente
TWebResponse che rappresenta il messaggio di risposta che sar inviato. Nelle
applicazioni NSAPI e ISAPI, il messaggio di risposta incorporato in un oggetto
TISAPIResponse. Le applicazioni CGI di console utilizzano oggetti TCGIResponse,
mentre le applicazioni Windows CGI utilizzano oggetti TWinCGIResponse.
Gli elementi di azione che generano la risposta a una richiesta Web client riempiono
le propriet delloggetto di risposta. In alcuni casi, una cosa semplice, come
restituire un codice di errore, o inoltrare la richiesta a un altro URI. In altri casi,
possono essere necessari calcoli complessi che richiedono allelemento di azione di
prelevare informazioni da altre sorgenti e di dare loro una forma finita. La maggior
parte dei messaggi di richiesta richiedono una risposta, anche se se si tratta solo della
conferma che lazione richiesta stata eseguita.
Compilazione dellintestazione della risposta
La maggior parte delle propriet delloggetto TWebResponse rappresentano le
informazioni di intestazione del messaggio di risposta HTTP inviato al client Web.
33-12 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i m e s s a g g i d i r i s p o s t a H T T P
Un elemento di azione imposta queste propriet prendendole dal proprio gestore di
evento OnAction.
Non tutti i messaggi di risposta devono specificare il valore di ciascuna propriet
dellintestazione. Le propriet da impostare dipendono dalla natura della richiesta e
dallo stato della risposta.
Indicazione dello stato della risposta
Ogni messaggio di risposta deve includere un codice di stato che indica lo stato della
risposta. Il codice di stato si imposta mediante la propriet StatusCode. Lo standard
HTTP definisce molti codici di stato standard dal significato predefinito. Inoltre, si
possono definire codici di stato non standard utilizzando qualsiasi valore inutilizzato
ammissibile.
Ogni codice di stato un numero di tre cifre dove la cifra pi significativa indica la
classe della risposta, come segue:
1xx: Informational (la richiesta stata ricevuta ma non stata elaborata
completamente).
2xx: Success (la richiesta stata ricevuta, capita e accettata).
3xx: Redirection (unulteriore iniziativa da parte del client necessaria per
completare la richiesta).
4xx: client Error (la richiesta non comprensibile o non pu essere eseguita).
5xx: Server Error (la richiesta era valida ma il server non ha potuto gestirla).
A ogni codice di stato associata una stringa che ne spiega il significato. Si tratta
della propriet ReasonString. Nel caso dei codici di stato predefiniti, non necessario
impostare la propriet ReasonString. Se invece si definiscono codici di stato non
standard, bene impostare la propriet ReasonString.
Indicazione della necessit di azione da parte del client
Quando il codice di stato compreso nellintervallo 300-399, il client deve eseguire
unulteriore azione prima che lapplicazione per Web server possa portare a termine
la sua richiesta. Se necessario dirigere il client verso un altro URI, o indicare che per
gestire la richiesta stato creato un nuovo URI, si deve impostare la propriet
Location. Se il client deve fornire una password prima che sia possibile procedere, si
imposta la propriet WWWAuthenticate.
Descrizione dellapplicazione server
Alcune delle propriet di intestazione della risposta descrivono le possibilit
dellapplicazione per Web server.La propriet Allow indica i metodi a cui
lapplicazione pu rispondere. La propriet Server d il nome e il numero di versione
dellapplicazione utilizzata per generare la risposta. La propriet Cookies pu ospitare
informazioni di stato sullutilizzo da parte del client dellapplicazione server
contenuta nei successivi messaggi di richiesta.
U t i l i z z o d i We b B r o k e r 33-13
C r e a z i o n e d i m e s s a g g i d i r i s p o s t a H T T P
Descrizione del contenuto
Numerose propriet descrivono il contenuto della risposta. ContentType indica il tipo
di supporto mediatico della risposta e ContentVersion il numero di versione relativo
a quel tipo di supporto. ContentLength d la lunghezza della risposta. Se il contenuto
codificato (come nel caso di una compressione dati), lo si segnala tramite la
propriet ContentEncoding. Se il contenuto proviene da un altro URI, lo si indica nella
propriet DerivedFrom. Se il valore del contenuto dipende dal tempo, la propriet
LastModified e la propriet Expires indicano se il valore ancora valido. La propriet
Title fornisce informazioni descrittive sul contenuto.
Impostazione del contenuto della risposta
Per alcune richieste, la risposta al messaggio di richiesta contenuta completamente
nelle propriet dellintestazione della risposta. Comunque, nella maggior parte dei
casi, lelemento di azione assegna parte dei contenuti al messaggio di risposta. Tali
contenuti possono essere informazioni statiche registrate in un file o informazioni
prodotte dinamicamente dallelemento di azione o dal proprio produttore di
contenuti.
possibile impostare il contenuto del messaggio di risposta utilizzando la propriet
Content oppure la propriet ContentStream.
La propriet Content una AnsiString. Le AnsiString di C++Builder non sono
limitate a valori del testo, e pertanto il valore della propriet Content pu essere una
stringa di comandi HTML, oppure contenuti grafici sotto forma di stream di bit, o
qualsiasi altro contenuto di tipo MIME.
Si utilizza la propriet ContentStream se il contenuto del messaggio di risposta pu
essere letto da un flusso. Ad esempio, se il messaggio di risposta deve inviare il
contenuto di un file, si utilizza un oggetto TFileStream per la propriet ContentStream.
Come nel caso della propriet Content, ContentStream pu fornire una stringa di
comandi HTML o un altro tipo di contenuto MIME. Quando viene usata la propriet
ContentStream, non c bisogno di liberare esplicitamente il flusso. E loggetto di
risposta Web che lo libera automaticamente.
_
Se il valore della propriet ContentStream non NULL, la propriet Content viene
ignorata.
Invio della risposta
Se si ha la certezza che non c altro lavoro da fare per rispondere a un messaggio di
richiesta, si pu far spedire la risposta direttamente da un gestore di evento
OnAction. Loggetto di risposta ha due metodi per inviarla: SendResponse e
SendRedirect. Si chiama SendResponse per mandare la risposta utilizzando il contenuto
specificato e tutte le propriet dellintestazione delloggetto TWebResponse. Se basta
reindirizzare il client Web a un altro URI, il metodo SendRedirect pi efficiente.
Se nessuno dei gestori di evento invia la risposta, loggetto Web application la invia
quando il dispatcher ha finito. Tuttavia, se nessun elemento di azione segnala di aver
33-14 G u i d a a l l a p r o g r a mma z i o n e
G e n e r a z i o n e d e l c o n t e n u t o d e i m e s s a g g i d i r i s p o s t a
gestito la risposta, lapplicazione chiude la connessione con il client Web senza
inviare nessuna risposta.
Generazione del contenuto dei messaggi di risposta
C++Builder fornisce una serie di oggetti per assistere gli elementi di azione nella
produzione dei contenuti dei messaggi HTTP di risposta. Si possono usare per
generare stringhe di comandi HTML che vengono salvati in un file o inviati
direttamente al client Web. Si possono scrivere dei generatori di contenuti facendoli
derivare da TCustomContentProducer o da uno dei suoi discendenti.
TCustomContentProducer fornisce uninterfaccia generica per la creazione di qualsiasi
tipo MIME, come il contenuto di un messaggio di risposta HTTP. Tra i suoi
discendenti vi sono produttori di pagine e produttori di tabelle:
I produttori di pagine analizzano i documenti HTML cercando tag particolari che
vengono sostituiti da un codice HTML ad hoc. Vengono illustrati nella prossima
sezione.
I produttori di tabelle creano comandi HTML in base alle informazioni presenti in
un dataset. Sono descritti nel paragrafo Utilizzo nelle risposte di informazioni di
database a pagina 33-18.
Utilizzo di componenti produttori di pagine
I produttori di pagine (TPageProducer e discendenti) prendono un modello HTML e
lo convertono sostituendo tag speciali non visibili da HTML con codice
personalizzato HTML. Si pu memorizzare un insieme dei modelli risposta standard
che vengono compilati dai produttori di pagine quando bisogna generare la risposta
a un messaggio di richiesta HTTP. Si possono concatenare pi produttori di pagine e
costruire iterativamente un documento HTML con successivi affinamenti dei tag
HTML trasparenti.
Modelli HTML
Un modello HTML una sequenza di comandi HTML e di tag HTML trasparenti. Un
tag HTML trasparente ha la forma
-i.i.c .ii.ic .ii..ic. >
Le parentesi angolari (< e >) definiscono lintero campo dazione del tag. Il simbolo
(#) segue immediatamente la parentesi angolare aperta (<) senza spazi vuoti tra luna
e laltra. Il simbolo # segnala al produttore di pagine che si tratta di un tag HTML
trasparente. Il nome del tag segue immediatamente il simbolo #. Il nome del tag pu
essere qualsiasi identificativo valido e individua il tipo di conversione che il tag
rappresenta.
Dopo il nome del tag, il tag HTML trasparente pu includere facoltativamente
parametri che specificano i dettagli della conversione da effettuare. Ogni parametro
U t i l i z z o d i We b B r o k e r 33-15
G e n e r a z i o n e d e l c o n t e n u t o d e i m e s s a g g i d i r i s p o s t a
ha il formato ParamName=Value, senza spazi vuoti tra il nome del parametro, il
simbolo (=) e il valore. I parametri sono separati da spazi vuoti.
Le parentesi angolari (< e >) rendono il tag trasparente ai browser HTML che non
riconoscono il costrutto #TagName.
Bench sia possibile creare dei marcatori HTML-trasparenti personalizzati per
rappresentare qualsiasi tipo di informazione trattato dal proprio produttore di
pagine, esistono svariati nomi di marcatori predefiniti associati a valori del tipo dati
TTag. Questi nomi di marcatori predefiniti corrispondono ai comandi HTML che
abbastanza probabile trovare nei messaggi di risposta. Questi nomi del tag
predefiniti corrispondono a comandi HTML che facilmente variano in relazione ai
messaggi di risposta e che sono riportati nella seguente tabella:
Qualsiasi altro nome di marcatore viene associato a tgCustom. Il produttore di pagine
non fornisce nessuna elaborazione intrinseca dei nomi di marcatore predefiniti. Il
produttore di pagine non elabora in alcun modo i nomi di tag predefiniti, che
servono solo per aiutare le applicazioni a organizzare il processo di conversione in
molte delle attivit pi comuni.
_
I nomi di tag predefiniti non riconoscono la differenza tra maiuscole e minuscole.
Specifica del modello HTML
I produttori di pagine offrono molte possibilit per specificare il modello HTML. Si
pu dare alla propriet HTMLFile il nome di un file contenente il modello HTML. Si
pu impostare la propriet HTMLDoc a un oggetto TStrings contenente il modello
HTML. Utilizzando per specificare il modello o la propriet HTMLFile o la propriet
HTMLDoc, possibile generare i comandi convertiti HTML chiamando il metodo
Content.
Inoltre, possibile chiamare il metodo ContentFromString per convertire direttamente
un modello HTML passatogli come parametro sotto forma di una singola AnsiString.
possibile anche chiamare il metodo ContentFromStream per leggere il modello
Nome del tag
Valore di
TTag In che cosa va convertito il tag
Link tgLink Collegamento ipertestuale. Il risultato una sequenza HTML
che inizia con il tag <A> e finisce con il tag </A>.
Image tgImage Immagine grafica. Il risultato il tag HTML <IMG>.
Table tgTable Tabella HTML. Il risultato una sequenza HTML che inizia
con il tag <TABLE> e finisce con il tag </TABLE>.
ImageMap tgImageMap Immagine grafica con zone calde associate. Il risultato una
sequenza HTML che inizia con il tag <MAP> e finisce con il
tag </MAP>.
Object tgObject Un oggetto incorporato ActiveX. Il risultato una sequenza
HTML che inizia con il tag <OBJECT> e finisce con il tag </
OBJECT>.
Embed tgEmbed DLL di add-in conforme a Netscape -. Il risultato una
sequenza HTML che inizia con il tag <EMBED> e finisce con il
tag </EMBED>.
33-16 G u i d a a l l a p r o g r a mma z i o n e
G e n e r a z i o n e d e l c o n t e n u t o d e i m e s s a g g i d i r i s p o s t a
HTML da un flusso. Cos, ad esempio, si potrebbero memorizzare tutti i modelli
HTML in un campo memo di un database e utilizzare il metodo ContentFromStream
per ottenere i comandi convertiti HTML, leggendo il modello direttamente da un
oggetto TBlobStream.
Conversione dei tag HTML trasparenti
Se si chiama uno dei suoi metodi Content, il produttore di pagine converte il modello
HTML. Quando Content incontra un tag HTML trasparente, attiva levento
OnHTMLTag. Per determinare il tipo di tag incontrato e sostituirlo con contenuto
personalizzato necessario scrivere un gestore di evento.
Non creando il gestore di evento OnHTMLTag del produttore di pagine, i tag HTML
trasparenti sono sostituiti da una stringa vuota.
Utilizzo dei produttori di pagine da un elemento di azione
In un impiego tipico, un componente produttore di pagine utilizza la propriet
HTMLFile per specificare un file contenente un modello HTML. Il gestore di evento
OnAction chiama il metodo Content per convertire il modello in una sequenza HTML
definitiva:
veIi __?aatcaII cc..c.~cc-i.cccc .c.c,
ccccs ccs, cccs,sc cs,sc, beeI -i.c.
.ic..cc>-.c cc.,
cs,sc>c .ic..cc>c,
I? .,iccxi.,sc.i.c
c,icccx .ic..cc .c.c>s,icc>ccs>c,
Se il contenuto del messaggio di richiesta fosse la stringa Mr. Ed, il valore di Response-
>Content sarebbe
-.>
-~>L> i. .c. cc .cL>-~>
>
-c . . cc.c cc sc
>
-.>
U t i l i z z o d i We b B r o k e r 33-17
G e n e r a z i o n e d e l c o n t e n u t o d e i m e s s a g g i d i r i s p o s t a
_
Questo esempio utilizza un gestore di evento OnAction per chiamare il produttore di
contenuti e assegnare il contenuto del messaggio di risposta. Non necessario
scrivere un gestore di evento OnAction se la propriet HTMLFile del produttore di
pagine viene assegnata in fase di progettazione. In questo caso, basta assegnare
PageProducer1 come valore della propriet Producer dellelemento di azione per
ottenere leffetto ottenuto dal gestore di evento OnAction qui sopra.
Concatenamento di produttori di pagine
Il testo di sostituzione di un gestore di evento OnHTMLTag non deve
necessariamente essere la sequenza HTML da utilizzare nel messaggio HTTP di
risposta. In certi casi, si utilizzano pi produttori di pagine, nei quali loutput di uno
linput del successivo.
Il modo pi semplice per concatenare dei produttori di pagine quello di associare
ogni produttore di pagine a un elemento di azione separato, dove tutti gli elementi di
azione hanno gli stessi PathInfo e MethodType. Il primo elemento di azione imposta il
contenuto del messaggio di risposta Web dal suo produttore di contenuti, ma il suo
gestore di evento OnAction si assicura che il messaggio non sia considerato gestito.
Lelemento di azione successivo utilizza il metodo ContentFromString del suo
produttore associato per trattare il contenuto del messaggio di risposta Web, e cos
via. Gli elementi di azione dopo il primo utilizzano un gestore di evento OnAction
come il seguente:
veIi __?aatcaII cc..c~c.~cccc .c.c,
ccccs ccs, cccs,sc cs,sc, beeI -i.c.
cs,sc>c .ic..cc.>c..cs,sc>c,
Per una descrizione dettagliata delle interfacce DOM, vedere le dichiarazioni nello
header della unit XMLDOM, la documentazione fornita dal produttore DOM o le
specifiche fornite sul sito Web di W3C (www.w3.org).
Potrebbe per risultare pi conveniente utilizzare le classi XML invece di operare
direttamente con le interfacce DOM. Queste classi sono descritte di seguito.
Operazioni con i componenti XML
La VCL (o la CLX) definisce molte classi e interfacce per operare con i documenti
XML. Questi semplificano il processo di caricamento, modifica e salvataggio dei
documenti XML.
Utilizzo di TXMLDocument
Il punto di partenza per operare con un documento XML il componente
TXMLDocument. I seguenti punti descrivono come utilizzare TXMLDocument per
operare direttamente con un documento XML:
1 Aggiungere un componente TXMLDocument alla scheda o al modulo dati.
TXMLDocument presente sulla pagina Internet della Component palette.
2 Impostare la propriet DOMVendor per specificare limplementazione DOM che si
vuole venga utilizzata dal componente per lanalisi sintattica e la modifica di un
35-4 G u i d a a l l a p r o g r a mma z i o n e
O p e r a z i o n i c o n i c o m p o n e n t i X M L
documento XML. LObject Inspector elenca tutti i produttori DOM attualmente
registrati. Per informazioni sulle implementazioni DOM, consultare Utilizzo del
Document Object Model a pagina 35-2.
3 A seconda dellimplementazione, si potrebbe voler impostare la propriet
ParseOptions in modo da configurare in che modo limplementazione DOM
sottostante analizza il documento XML.
4 Se si sta operando con un documento XML esistente, specificare il documento:
Se il documento XML memorizzato in un file, impostare la propriet FileName
al nome di quel file.
Utilizzando invece la propriet XML possibile specificare il documento XML
come una stringa.
5 Impostate la propriet Active a true.
Una volta che si ha un oggetto TXMLDocument attivo, possibile esaminare la
gerarchia dei suoi nodi oltre che leggere o impostare i rispettivi valori. Il nodo radice
di questa gerarchia disponibile come propriet DocumentElement.
Operazioni con i nodi XML
Una volta che un documento XML stato analizzato da unimplementazione DOM, i
dati che esso rappresenta sono disponibili sotto forma di gerarchia di nodi. Ogni
nodo corrisponde a un elemento marcato nel documento. Ad esempio, dato il
seguente XML:
x. cs'' cc.'' si.ic'' >
. .c.-.s ... 's..'>
.c.-.s>
.c. cxcic'.~.~_'>
i.c>i.i.c>
,cc>,cc>
s.c>s.c>
sics>sics>
.c.>
.c. cxcic'..'>
i.c>...ci.c>
,cc>1.,cc>
s.c>.s.c>
sics ,c',c.cc.'>.sics>
.c.>
.c.-.s>
TXMLDocument genererebbe una gerarchia di nodi di questo tipo: La radice della
gerarchia sarebbe il nodo StockHoldings. StockHoldings avrebbe due nodi figlio, che
corrispondono alle due marcatori Stock. Ognuno di questi due nodi figlio avrebbe
quattro nodi figlio propri (name, price, symbol e shares). Quei quattro nodi figlio
agirebbero come nodi foglia. Il testo che essi contengono verrebbe visualizzato come
il valore di ognuno dei nodi foglia.
O p e r a z i o n i c o n d o c u me n t i X ML 35-5
O p e r a z i o n i c o n i c o m p o n e n t i X M L
_
Questa divisione in nodi leggermente diversa dal modo in cui unimplementazione
DOM genera i nodi per un documento XML. In particolare, un parser DOM tratta
tutti gli elementi marcati come nodi interni. Per i valori dei name, price, symbol e shares
verrebbero creati dei nodi aggiuntivi (di tipo nodo di testo). Questi nodi di testo
sarebbero quindi visualizzati come figli dei nodi name, price, symbol e shares.
Ad ogni nodo si accede attraverso uninterfaccia IXMLNode a partire dal nodo radice,
che il valore della propriet DocumentElement.
Operazioni con il valore di un nodo
Data uninterfaccia IXMLNode, possibile controllare se rappresenta un nodo interno
o un nodo foglia controllando la propriet IsTextElement.
Se rappresenta un nodo foglia, possibile leggerne o impostarne il valore
utilizzando la propriet Text.
Se rappresenta un nodo interno, possibile accedere ai suoi nodi figlio utilizzando
la propriet ChildNodes.
Cos, ad esempio, utilizzando il documento XML visto in precedeza, possibile
leggere il prezzo dellazione Borland nel seguente modo:
_._L....c i..c. ..c.c>c.cc.c>...cs>c..c,
~s. .cc i..c.>...cs>..cs,.c.',cc'>cx,
Operazioni con gli attributi di un nodo
Se il nodo include eventuali attributi, possibile operare su di essi utilizzando la
propriet Attributes. possibile leggere o modificare il valore di un attributo
specificando il nome di un attributo esistente. Quando si imposta la propriet
Attributes possibile aggiungere nuovi attributi specificando un nuovo nome di
attributo:
_._L....c i..c. ..c.c>c.cc.c>...cs>c..c,
i..c.>...cs>..cs,.c.'sics'>~ccs,.c.',c'
'c..',
Aggiunta e cancellazione di nodi figlio
possibile aggiungere nodi figlio utilizzando il metodo AddChild. AddChild crea
nuovi nodi che corrispondono a elementi contrassegnati nel documento XML. Tali
nodi sono chiamati nodi elemento.
Per creare un nuovo nodo elemento, specificare il nome che apparir nel nuovo
marcatore e, volendo, la posizione in cui dovrebbe essere visualizzato il nuovo nodo.
Ad esempio, il seguente codice aggiunge un nuovo titolo azionario al documento
visto in precedenza:
_._L....c .c..c. ..c.c>c.cc.c>~....c.'sc.',
.c..c.>~ccs,.c.'cxcic' '.~.~_',
_._L....c ic..c .c..c.>~....c.'i.c',
ic..c>cx .c.'sc .sc.s',
ic..c .c..c.>~....c.',cc',
ic..c>cx .c.'.',
ic..c .c..c.>~....c.'s.c',
35-6 G u i d a a l l a p r o g r a mma z i o n e
A s t r a z i o n e d i d o c u m e n t i X M L c o n D a t a B i n d i n g w i z a r d
ic..c>cx .c.'.',
ic..c .c..c.>~....c.'sics',
ic..c>cx .c.'.',
Una versione ridefinita di AddChild permette di specificare il namespace URI in cui
definito il nome del marcatore.
possibile cancellare i nodi figlio utilizzando i metodi della propriet ChildNodes.
ChildNodes uninterfaccia IXMLNodeList, che gestisce i figli di un nodo. possibile
utilizzare il metodo Delete per cancellare un singolo nodo figlio identificato in base
alla posizione o al nome. Ad esempio, il seguente codice cancella lultimo titolo
azionario nel documento visto in precedenza:
_._L....c .c.s ..c.c>c.cc.c,
.c.s>...cs>ccc.c.s>...cs> ,
Astrazione di documenti XML con Data Binding wizard
Bench sia possibile operare con un documento XML utilizzando solo il componente
TXMLDocument e linterfaccia IXMLNode, che fa emergere i nodi in quel documento,
o, addirittura, operare esclusivamente con le interfacce DOM (evitando anche
TXMLDocument), mediante lutilizzo di XML Data Binding wizard possibile
scrivere del codice molto pi semplice e pi facilmente leggibile.
Data Binding wizard prende uno schema XML o un file di dati e genera un set di
interfacce che ne tracciano una mappa. (Uninterfaccia una classe che contiene solo
membri pure virtual). Si supponga di avere, ad esempio, una serie di dati XML simile
alla seguente:
cs.c .>
i.c>.i.i.c>
,c> 1,c>
cs.c>
Data Binding wizard genera la seguente interfaccia (oltre a una classe per
implementarla):
__Iatet?ace L.~_L'..1c..~11' Ls.c
pabIIc L....c
pabIIc
vIttaaI Iat __?aatcaII c.veIi ,
vIttaaI .. __?aatcaII ci.cveIi ,
vIttaaI .. __?aatcaII c,cveIi ,
vIttaaI veIi __?aatcaII .c.Iat ic ,
vIttaaI veIi __?aatcaII .ci.c.. ic ,
vIttaaI veIi __?aatcaII .c,c.. ic ,
__ptepett, Iat . teaic., vtIte.c.,
__ptepett, .. i.c teaici.c, vtIte.ci.c,
__ptepett, .. ,c teaic,c, vtIte.c,c,
,
Ogni nodo figlio viene fatto corrispondere a una propriet, il cui nome corrisponde al
nome del marcatore del nodo figlio e il cui valore linterfaccia del nodo figlio (nel
O p e r a z i o n i c o n d o c u me n t i X ML 35-7
A s t r a z i o n e d i d o c u m e n t i X M L c o n D a t a B i n d i n g w i z a r d
caso il nodo figlio sia un nodo interno) o con il valore del nodo figlio (nel caso di nodi
foglia). Anche ogni attributo di nodo viene fatto corrispondere con una propriet, in
cui il nome della propriet il nome dellattributo e il valore della propriet il
valore dellattributo.
Oltre alla creazione di interfacce (e delle classi di implementazione discendenti) per
ogni elemento contrassegnato incluso nel documento XML, il wizard crea una
funzione globale per ottenere linterfaccia verso il nodo radice. Ad esempio, se lo
XML di cui sopra provenisse da un documento al cui nodo radice era associato il
marcatore <Customers>, Data Binding wizard creerebbe le seguente routine globali:
exteta .~~ _._Ls.cs __?aatcaII cs.cs..c.c ..c,
exteta .~~ _._Ls.cs __?aatcaII cs.cs_._L..c.c ..c,
exteta .~~ _._Ls.cs __?aatcaII i.s.csceaat .c. c.i.c,
exteta .~~ _._Ls.cs __?aatcaII .c.s.csveIi,
La funzione Get... accetta il wrapper dellinterfaccia di unistanza TXMLDocument (o
di un puntatore a quellistanza di TXMLDocument). La funzione Load... crea
dinamicamente unistanza di TXMLDocument e carica il file XML specificato come
suo valore prima di restituire un puntatore allinterfaccia. La funzione New... crea
una nuova istanza (vuota) di TXMLDocument e restituisce linterfaccia al nodo radice.
Lutilizzo delle interfacce generate semplifica il codice, perch riflettono la struttura
del documento XML in modo pi diretto. Ad esempio, invece di scrivere del codice
simile al seguente:
_._L....c sL. ..c.c>c.cc.c,
s.i.c sL.>...cs>..cs>c..c>...cs>..cs,.c.'i.c'
>ic,
Il codice sarebbe invece:
_._Ls.cs sL. cs.cs..c.c,
s.i.c sL.>..cs>c..c>.i.c,
Si noti che le interfacce generate da Data Binding wizard discendono tutte da
IXMLNode. Ci significa che sempre possibile aggiungere e cancellare i nodi figlio
secondo le stesse modalit di quando non si utilizza Data Binding wizard. (Vedere
Aggiunta e cancellazione di nodi figlio a pagina 35-5). Inoltre, quando i nodi figlio
rappresentano elementi ripetitivi (quando tutti i figli di un nodo sono dello stesso
tipo), al nodo genitore vengono assegnati due metodi, Add e Insert, per laggiunta di
ulteriori ripetizioni. Questi metodi sono pi semplici rispetto allutilizzo di AddChild,
perch non necessario specificare il tipo di nodo da creare.
Utilizzo di XML Data Binding wizard
Per utilizzare Data Binding wizard,
1 Scegliere File|New|Other e selezionare licona con letichetta XML Data Binding
nella zona inferiore della pagina New.
2 Viene visualizzato XML Data Binding wizard.
35-8 G u i d a a l l a p r o g r a mma z i o n e
A s t r a z i o n e d i d o c u m e n t i X M L c o n D a t a B i n d i n g w i z a r d
3 Sulla prima pagina del wizard specificare il documento o lo schema XML per cui si
desidera generare interfacce. Questo pu essere un documento XML di esempio,
un file Document Type Definition (.dtd), un file Reduced XML Data (.xdr) o un file
di schema XML (.xsd.
4 Fare clic sul pulsante Options per specificare le strategie per lassegnazione dei
nomi che si vuole vengano utilizzate dal wizard durante la generazione delle
interfacce e delle classi di implementazione e la mappatura predefinita dei tipi
definiti nello schema in tipi di dati nativi.
5 Passare alla seconda pagina del wizard. Questa pagina permette di fornire
informazioni dettagliate su ogni tipo di nodo nel documento o nello schema. Alla
sinistra c una vista ad albero che visualizza che tutto i tipi di nodo presenti nel
documento. Per nodi complessi (nodi che hanno figli), la vista albero pu essere
estesa in modo da visualizzare gli elementi figlio. Quando si seleziona un nodo
nella vista ad albero, il lato destro della finestra di dialogo visualizza le
informazioni su quel nodo e permette di specificare come si desidera che il wizard
tratti quel nodo.
Il controllo Source Name visualizza il nome del tipo di nodo nello schema XML.
Il controllo Source Datatype visualizza il tipo del valore del nodo, come
specificato nello schema XML.
Il controllo Documentation permette di aggiungere commenti allo schema per
descrivere lutilizzo o lo scopo del nodo.
Se il wizard genera del codice per il nodo selezionato (cio, se un tipo
complesso per il quale il wizard genera uninterfaccia e una classe di
implementazione oppure se uno degli elementi figlio di un tipo complesso per
il quale il wizard genera una propriet sullinterfaccia del tipo complesso),
possibile utilizzare la casella di controllo Generate Binding per specificare se si
desidera che il wizard generi codice per il nodo. Se si deseleziona Generate
Binding, il wizard non genera linterfaccia o la classe di implementazione per
un tipo complesso oppure non crea una propriet nellinterfaccia genitore di un
elemento o di un attributo figlio.
La sezione Binding Options permette di influire sul codice generato dal wizard
per lelemento selezionato. Per qualsiasi nodo, possibile specificare lIdentifier
Name (il nome dellinterfaccia o della propriet generata).Inoltre, per le
interfacce, necessario indicare quale rappresenta il nodo radice del
documento. Per nodi che rappresentano propriet, possibile specificare il tipo
della propriet e, se la propriet non uninterfaccia, se una propriet a sola
lettura.
6 Una volta specificato quale codice si desidera che il wizard generi per ogni nodo,
passare alla terza pagina. Questa pagina permette di scegliere alcune opzioni
globali relative a come il wizard genera il codice, permette di vedere in anteprima
il codice che sar generato e permette di dire al wizard come salvare le scelte fatte
per un successivo utilizzo.
Per vedere in anteprima il codice generato dal wizard, selezionare
uninterfaccia nella lista Binding Summary e visualizzare la definizione di
interfaccia risultante nel controllo Code Preview.
O p e r a z i o n i c o n d o c u me n t i X ML 35-9
A s t r a z i o n e d i d o c u m e n t i X M L c o n D a t a B i n d i n g w i z a r d
Utilizzare Data Binding Settings per indicare come il wizard dovrebbe salvare
le scelte. possibile memorizzare le impostazioni come annotazioni in un file
di schema, associato al documento (il file di schema specificato nella prima
pagina della finestra di dialogo) oppure possibile dare un nome a un file di
schema indipendente, utilizzato solo dal wizard.
7 Appena si fa clic su Finish, Data Binding wizard genera una nuova unit che
definisce le interfacce e le classi di implementazione per tutti i tipi di nodo presenti
nel documento XML. Inoltre, crea una funzione globale che prende un oggetto
TXMLDocument e restituisce linterfaccia per il nodo radice della gerarchia dati.
Utilizzo del codice generato da XML Data Binding wizard
Una volta che il wizard ha generato un insieme di interfacce e di classi di
implementazione, possibile utilizzarle per operare con documenti XML che
corrispondono alla struttura del documento o dello schema fornito al wizard.
Esattamente come quando si utilizzano solo i componenti XML nativi, il punto di
partenza il componente TXMLDocument presente sulla pagina Internet della
Component palette.
Per operare con un documento XML, fare quanto segue:
1 Ottenere uninterfaccia per il nodo radice del documento XML. possibile farlo in
tre modi:
Collocare un componente TXMLDocument sulla scheda o nel modulo dati.
Collegare il componente TXMLDocument a un documento XML impostando la
propriet FileName. (Come metodo alternativo, possibile utilizzare una stringa
XML impostando la propriet XML in esecuzione). Poi, nel codice, chiamare la
funzione globale creata dal wizard per ottenere uninterfaccia per il nodo radice
del documento XML. Ad esempio, se lelemento radice del documento XML era
il marcatore <StockList>, per impostazione predefinita, il wizard genera una
funzione GetStockListType, che restituisce uninterfaccia IStockListType:
..c.c>c.i.c '.c.sx.',
_._L.c.s,c .c.s c.c.s,c..c.c,
Chiamare la funzione generata Load... per creare e collegare listanza di
TXMLDocument e ottenere la sua interfaccia in un solo passaggio. Ad esempio,
utilizzando lo stesso documento XML descritto in precedenza:
_._L.c.s,c .c.s i..c.s,c'.c.sx.',
Chiamare la funzione New... generata per creare listanza di TXMLDocument di
un documento vuoto quando si vogliono creare tutti i dati nellapplicazione:
_._L.c.s,c .c.s .c..c.s,c,
2 Questa interfaccia ha propriet che corrispondono ai sottonodi dellelemento
radice del documento, oltre a propriet che corrispondono agli attributi di
quellelemento radice. possibile utilizzare queste propriet per percorrere la
gerarchia del documento XML, modificare i dati nel documento, e cos via.
35-10 G u i d a a l l a p r o g r a mma z i o n e
A s t r a z i o n e d i d o c u m e n t i X M L c o n D a t a B i n d i n g w i z a r d
3 Per salvare tutte le modifiche apportate utilizzando le interfacce generate dal
wizard, chiamare il metodo SaveToFile del componente TXMLDocument o leggerne
la propriet XML.
_
Se si imposta la propriet Options delloggetto TXMLDocument in modo da includere
doAutoSave non necessario chiamare esplicitamente il metodo SaveToFile.
U t i l i z z o d e i We b S e r v i c e s 36-1
C a p i t o l o
36
Capitolo36Utilizzo dei Web Services
I Web Services sono applicazioni modulari indipendenti che possono essere
pubblicate e richiamate da Internet. I Web Services mettono a disposizione interfacce
ben definite che descrivono i servizi forniti. A differenza delle applicazioni per Web
server che generano pagine web per i browser client, le applicazioni Web Services
non sono progettate per linterazione diretta con lutente. Ad esse invece si accede
mediante il codice dalle applicazioni client.
I Web Services sono progettati per consentire un accoppiamento flessibile tra client e
server. Ci significa che le implementazioni server non chiedono che i client
utilizzino una piattaforma o un linguaggio di programmazione specifici. Oltre a
definire le interfacce in un modo indipendente dal linguaggio, essi sono progettati
per consentire anche pi meccanismi di comunicazione.
Il supporto di C++Builder per i Web Services stato concepito per funzionare
utilizzando SOAP (Simple Object Access Protocol). SOAP un protocollo standard
leggero per lo scambio di informazioni in un ambiente decentrato e distribuito. Esso
utilizza XML per codificare le chiamate a procedura remote e, come protocollo di
comunicazione, di solito utilizza HTTP. Per ulteriori informazioni su SOAP, vedere
le specifiche SOAP disponibili allindirizzo
,.....~.
_
Bench i componenti che supportano i Web Services siano stati concepiti per
utilizzare SOAP e HTTP, il framework sufficientemente generico da poter essere
ampliato in modo da utilizzare altri protocolli di codifica e di comunicazione.
Oltre a consentire la costruzione di applicazioni Web Service basate su SOAP
(server), C++Builder fornisce il supporto per i client dei Web Services che utilizzano
una codifica SOAP o uno stile Document Literal. Lo stile Document Literal
utilizzato nei Web Services .Net.
I componenti che supportano i Web Services sono disponibili sia in Windows che in
Linux, e pertanto possibile utilizzarli come elementi base per applicazioni
distribuite multipiattaforma. Non occorre installare alcun particolare software client
runtime, come quando si distribuiscono le applicazioni che utilizzano CORBA.
36-2 G u i d a a l l a p r o g r a mma z i o n e
L e i n t e r f a c c e r i c h i a m a b i l i
Poich questa tecnologia si basa sui messaggi HTTP, presenta il vantaggio che
ampiamente disponibile su una vasta gamma di macchine. Il supporto per i Web
Services si fonda sullarchitettura di applicazioni per Web server (Web Broker).
Le applicazioni Web Service pubblicano mediante un documento WSDL (Web
Service Definition Language) informazioni sulle interfacce disponibili e su come
chiamarle. Sul lato server, lapplicazione pu pubblicare un documento WSDL che
descrive il Web Service. Sul lato client, un wizard o programma di utilit a riga di
comando pu importare un documento WSDL pubblicato, fornendo le definizioni
delle interfacce e le informazioni di connessione necessarie. Se gi si possiede un
documento WSDL che descrive il servizio Web che si desidera implementare,
possibile generare il codice lato server anche quando si importa il documento WSDL.
Le interfacce richiamabili
I server che supportano i Web Services sono costruiti utilizzando interfacce
richiamabili. Le interfacce richiamabili sono classi pure virtual (classi che includono
solo metodi pure virtual) che vengono compilate in modo da includere informazioni
di tipo in esecuzione (RTTI). Sul server, queste RTTI vengono utilizzate durante
linterpretazione delle chiamate ai metodo in arrivo dai client in modo che possano
essere smistate correttamente. Sui client, queste RTTI vengono utilizzate per generare
dinamicamente una tabella dei metodi per effettuare chiamate ai metodi
dellinterfaccia.
Per creare uninterfaccia richiamabile, necessario dichiarare la classe dellinterfaccia
utilizzando la parola chiave _declspec , utilizzando il modificatore delphirtti. Anche il
discendente di qualsiasi interfaccia richiamabile a sua volta richiamabile. Tuttavia,
se uninterfaccia richiamabile discende da unaltra classe di interfaccia che non
richiamabile, il Web Service pu solo utilizzare i metodi definiti nellinterfaccia
richiamabile e nei suoi discendenti. I metodi ereditati da antenati non richiamabili
non vengono compilati con le informazioni di tipo e non possono essere cos
utilizzati come parte del Web Service.
_
Per informazioni sulle classi di interfaccia in C++Builder, vedere Eredit e
interfacce a pagina 13-2.
Il file header sysmac.h definisce uninterfaccia richiamabile di base, IInvokable, da cui
possibile derivare qualsiasi interfaccia esposta ai client da un server Web Service.
IInvokable identica allinterfaccia di base (IInterface), tranne per il fatto che
compilata utilizzando lopzione _declspec (delphirtti) in modo che essa e tutti i suoi
discendenti includano le RTTI.
Ad esempio, il seguente codice definisce uninterfaccia richiamabile che contiene due
metodi per codificare e decodificare valori numerici:
__Iatet?ace L.~_L'.1c~1.' Lc.ccc.c
pabIIc LL.icc
pabIIc
vIttaaI ieabIe __aticaII c.cicIat ic ,
vIttaaI Iat __aticaII cc.cicieabIe ic ,
U t i l i z z o d e i We b S e r v i c e s 36-3
L e i n t e r f a c c e r i c h i a m a b i l i
,
_
In questo esempio, si noti lutilizzo di __interface nella dichiarazione. Questa non
una vera parola chiave ma piuttosto una macro che viene utilizzata per convenzione
con le interfacce. mappata sulla parola chiave class. La macro INTERFACE_UUID
assegna allinterfaccia un identificativo globalmente univoco (GUID). Si noti che la
classe dellinterfaccia contiene solo metodi pure virtual.
Prima che unapplicazione Web Service possa utilizzare questa interfaccia
richiamabile, deve essere registrata con il file di registro delle chiamate. Sul server, l
elemento del registro delle chiamate consente al componente invoker
(THTTPSOAPCppInvoker) di identificare una classe di implementazione da utilizzare
per lesecuzione delle chiamate allinterfaccia. Sulle applicazioni client, un elemento
del registro delle chiamate permette agli oggetti remoti interfacciati (THTTPRio) di
cercare informazioni che identifichino linterfaccia richiamabile e forniscano
informazioni su come chiamarla.
Di solito, il client o il server Web Service crea il codice per definire le interfacce
richiamabili o importando un documento WSDL o utilizzando il Web Service wizard.
Per impostazione predefinita, quando limportatore di WSDL o il Web Service
wizard generano uninterfaccia, la definizione viene aggiunta a un file header avente
lo stesso nome del Web Service. Il corrispondente file .cpp contiene il codice per
registrare linterfaccia (oltre che una classe di implementazione nel caso si stia
scrivendo un server). Per linterfaccia descritta in precedenza, questo codice di
registrazione assomiglia al seguente:
atatIc veIi c,cs
c.,ccs>csc..L.__atta,t,peIa?e ic.c~i,
..i.c.,icc, 'ii', 'ii',
Lcs>cscLc.icc__ieIpaItttI L.c.cccs,
_
Non utilizzare pi tipi dynamic array che mappano tutti lo stesso tipo di elemento
sottostante. Poich il compilatore li tratta come tipi trasparenti che possono essere
convertiti implicitamente in un altro tipo, non in grado di distinguere le rispettive
informazioni di tipo in esecuzione.
Il primo parametro di RegisterXSInfo linformazione di tipo per il tipo che si sta
registrando. Il secondo parametro lURI del namespace per il namespace in cui il
tipo definito. Se si omette questo parametro o si fornisce una stringa vuota, il
registro genera automaticamente un namespace. Il terzo parametro il nome del tipo
come appare nel codice nativo C++. necessario fornire un valore per questo
parametro. Lultimo parametro il nome del tipo come appare nei documenti WSDL.
Se si omette questo parametro o si fornisce una stringa vuota, il registro utilizza il
nome del tipo nativo (il terzo parametro).
36-6 G u i d a a l l a p r o g r a mma z i o n e
L e i n t e r f a c c e r i c h i a m a b i l i
La registrazione di una classe remotable simile, tranne per il fatto che si fornisce un
riferimento di classe invece che un puntatore alle informazioni di tipo. Ad esempio, il
seguente codice registra una classe remotable di nome TXSRecord:
veIi c,cs
c.,ccs>csc..L.
cs.c.cc,cL.__cIaaaIi..,c_,cL.-.c, '__,,,c',
..i.c.,icc, '..,c',
ptIvate
beeI isc.csc,
beeI .c.,
isscs,cics ,cics,
.sc..~i .s,
pabIIc
veIi __?aatcaII ~ssisscs.s .ccs,
veIi __?aatcaII ~ssisscs.s css,
__pabIIaaei
__ptepett, beeI isc.csc teaiisc.csc, vtIteisc.csc,
__ptepett, beeI .c. teai.c., vtIte.c.,
__ptepett, isscs,cics ,cics teai,cics, vtIte,cics,
__ptepett, .sc..~i .s teai.s, vtIte.s,
Si noti che TRemotableStringList esiste solo come classe di trasporto. Pertanto, bench
abbia una propriet Sorted (per trasportare il valore di una propriet Sorted di un
elenco di stringhe), non necessario che ordini le stringhe che memorizza ma deve
solo memorizzare se le stringhe devono essere ordinate o meno. In questo modo
limplementazione risulta molto semplice. necessario solo implementare i metodi
Assign e AssignTo , che si convertono da un elenco di stringhe e viceversa:
veIi __?aatcaII c.icc.s~ssisscs.s .ccs
.cc.s, .ccs>,
?et Iat , .ccs>, --
.s, .ccs>.s,,
isc.csc .ccs>isc.csc,
.c. .ccs>.c.,
,cics .ccs>,cics,
css>ci,
css>i,ic c.s,
css>isc.csc isc.csc,
css>.c. .c.,
36-10 G u i d a a l l a p r o g r a mma z i o n e
S c r i t t u r a d i s e r v e r c h e s u p p o r t a n o i W e b S e r v i c e s
css>,cics ,cics,
?et Iat , c.s, --
css>~...s,,
c.,ccs>csc..ciss__cIaaaIic.icc.s, ..i.c.,icc,
'ss', '', ?aIae,
I? c.ccc.c
eb) c.ccc.c,
_
Nellesempio precedente, FEncodeDecodeInterface una variabile di tipo
_di_IEncodeDecode.
Si registra la procedura di fabbrica con una classe di implementazione fornendola
come secondo parametro alla chiamata che registra la classe con il registro delle
chiamate. Individuare Per prima cosa, si deve individuare la chiamata che il wizard
ha generato per registrare la classe di implementazione. Questa apparir nel metodo
RegTypes alla fine della unit che definisce la classe. Dovrebbe assomigliare a
qualcosa del genere:
Lcs>cscL.icciss__cIaaaIic.ccc.cL.,,
Aggiungere a questa chiamata un secondo parametro che specifichi la procedura
factory:
Lcs>cscL.icciss__cIaaaIic.ccc.cL.,, cicc.ccc.c,
Utilizzo di Web Services Importer
Per utilizzare Web Services Importer, scegliere File|New|Other e alla pagina
WebServices fare doppio clic sullicona Web Services Importer. Nella finestra di
dialogo visualizzata, specificare il nome di file di un documento WSDL (o di un file
XML) oppure specificare lURL in cui quel documento pubblicato.
Se il documento WSDL su un server che necessita di autenticazione (o deve essere
raggiunto utilizzando un proxy server che richiede lautenticazione), prima che il
wizard possa acquisire il documento WSDL necessario fornire un nome utente e
una password. Per fornire queste informazioni, fare clic sul pulsante Options e
fornire le opportune informazioni di connessione.
U t i l i z z o d e i We b S e r v i c e s 36-15
S c r i t t u r a d i s e r v e r c h e s u p p o r t a n o i W e b S e r v i c e s
Quando si fa clic sul pulsante Next, Web Services Importer mostra il codice,
compatibile con il framework di Web Services, che esso genera per ogni definizione
nel documento WSDL. Ci significa che utilizza solo quei tipi di porta che hanno un
binding SOAP. Facendo clic sul pulsante Options e scegliendo le opzioni desiderate,
possibile configurare il modo in cui limportatore genera il codice.
Web Services Importer pu essere utilizzato quando si scrive un server o
unapplicazione client. Quando si scrive un server, fare clic sul pulsante Options e
nella finestra di dialogo risultante, attivare lopzione che dice allimportatore di
generare i codice per il server. Quando si seleziona questa opzione, limportatore
genera le classi di implementazione per le interfacce richiamabili ed necessario solo
completare i corpi dei metodi.
j
Se si importa un documento WSDL per creare un server che implementa un Web
Service che gi stato definito, sempre necessario pubblicare il documento WSDL
per quel servizio. Fra il documento WSDL importato e limplementazione generata vi
possono essere delle differenze secondarie. Ad esempio, se il documento WSDL o file
di schema XML utilizza identificativi che sono anche parole chiave del linguaggio
C++, limportatore adatta automaticamente i loro nomi in modo che il codice
generato possa essere compilato.)
Non appena si fa clic su Finish, limportatore crea nuove unit che definiscono e
registrano le interfacce richiamabili per le operazioni definite nel documento, e che
definiscono e registrano le classi remotable per i tipi definiti dal documento.
Come metodo alternativo, possibile utilizzare invece limporter WSDL per la riga
comandi. Per un server, chiamare limportatore della riga comandi con lopzione -S,
nel seguente modo:
.L.. . ..c.s.
Per unapplicazione client, chiamare limportatore della riga comandi senza
lopzione -S:
.L.. ..c.s.
Creazione di classi di eccezione custom per Web Services
Nel caso lapplicazione Web Service sollevi uneccezione mentre sta cercando di
eseguire una richiesta SOAP, essa codifica automaticamente le informazioni per
quelleccezione in un pacchetto di errore SOAP, che viene restituito al posto dei
risultati della chiamata al metodo. Lapplicazione client quindi solleva leccezione.
Per impostazione predefinta, lapplicazione client solleva uneccezione generica di
tipo ERemotableExceptionwith con le informazioni relative al pacchetto di errore
SOAP. Se si deriva un discendente ERemotableException, possibile trasmettere
ulteriori informazioni specifiche per lapplicazione. I valori di tutte le propriet
pubblicate che vengono aggiunte alla classe di eccezione vengono inclusi nel
pacchetto di errore SOAP in modo che il client possa sollevare uneccezione
equivalente.
Per utilizzare un discendente di ERemotableException , necessario registrarlo con il
registro dei tipi remotable. Nella unit che definisce il discendente di
36-16 G u i d a a l l a p r o g r a mma z i o n e
S c r i t t u r a d i s e r v e r c h e s u p p o r t a n o i W e b S e r v i c e s
ERemotableException necessario includere InvokeRegistry.hpp e aggiungere una
chiamata al metodo RegisterXSClass delloggetto restituito dalla funzione globale
RemTypeRegistry.
Se anche il client definisce e registra il discendente di ERemotableException, quando
riceve il pacchetto di errore SOAP, solleva automaticamente unistanza della classe di
eccezione appropriata, con tutte le propriet impostate ai valori inclusi nel pacchetto
di errore SOAP.
Generazione di documenti WSDL per unapplicazione Web Service
Per consentire alle applicazioni client di sapere quali sono i Web Services resi
disponibili dallapplicazione, possibile pubblicare un documento WSDL che
descrive le interfacce richiamabili e indica come chiamarle.
_
sempre necessario pubblicare un documento WSDL per lapplicazione Web
Service, anche se si implementato un servizio importato o se il client stato scritto
utilizzando C++Builder.
Per pubblicare un documento WSDL che descrive il Web Service, includere nel Web
Module un componente TWSDLHTMLPublish. (SOAP Server Application wizard
aggiunge questo componente automaticamente). TWSDLHTMLPublish un
componente auto-dispatching, il che significa che risponde automaticamente ai
messaggi in arrivo che richiedono un elenco di documenti WSDL per il Web Service.
Per specificare le informazioni di percorso dellURL che i client devono utilizzare per
accedere allelenco di documenti WSDL, utilizzare la propriet WebDispatch. Il Web
browser pu richiedere quindi lelenco dei documenti WSDL specificando unURL
che costituito dallubicazione dellapplicazione server seguita dal percorso
specificato nella propriet WebDispatch. LURL assomiglia a quello mostrato di
seguito:
,....cc...ccc..
_
Se si desidera invece utilizzare un file fisico WSDL, possibile visualizzare il
documento WSDL nel Web browser e quindi salvarlo in modo da generare un file di
documento WSDL.
Non necessario pubblicare il documento WSDL dalla stessa applicazione che
implementa il Web Service. Per creare unapplicazione che si limita a pubblicare il
documento WSDL, omettere il codice che implementa e registra gli oggetti di
implementazione e includere solo il codice che definisce e registra le interfacce
richiamabili, le classi remotable che rappresentano i tipi complessi e le eventuali
eccezioni remotable.
Per impostazione predefinita, quando si pubblica un documento WSDL, esso indica
che i servizi sono disponibili allo stesso URL su cui stato pubblicato il documento
WSDL (anche se con un percorso diffrente). Se si stanno distribuendo pi versioni
dellapplicazione Web Service oppure se si pubblica il documento WSDL da
unapplicazione diversa da quella che implementa il Web Service, sar necessario
modificare il documento WSDL in modo che includa le informazioni aggiornate su
dove individuare il Web Service.
U t i l i z z o d e i We b S e r v i c e s 36-17
S c r i t t u r a d i c l i e n t p e r W e b S e r v i c e s
Per modificare lURL, utilizzare il WSDL administrator. La prima operazione
consiste nellattivare lamministratore. Loperazione viene condotta impostando la
propriet AdminEnabled del componente TWSDLHTMLPublish a true. In seguito,
quando si utilizzer il browser per visualizzato lelenco dei documenti WSDL, esso
includer anche un pulsante che ne consentir la gestione. Utilizzare il WSDL
administrator per specificare le ubicazioni (URL) su cui stata distribuita
lapplicazione Web Service.
Scrittura di client per Web Services
C++Builder fornisce un supporto sul lato client per chiamare i Web Services che
utilizzano un binding basato su SOAP. Questi Web Services possono essere forniti da
un server scritto in C++Builder o da un qualsiasi altro server che definisce il proprio
Web Service mediante un documento WSDL.
Importazione di documenti WSDL
Prima di potere utilizzare un Web Service, lapplicazione deve definire e registrare le
interfacce e i tipi richiamabili inclusi nellapplicazione Web Service. Per ottenere
queste definizioni, possibile importare un documento WSDL (o un file XML) che
definisce il servizio. Web Services crea una unit che definisce e registra le interfacce e
i tipi che necessario utilizzare. Per i dettagli sullutilizzo di Web Services Importer,
vedere Utilizzo di Web Services Importer a pagina 36-14.
Chiamata a interfacce richiamabili
Per chiamare uninterfaccia richiamabile, lapplicazione client deve includere tutti gli
header che definiscono le interfacce richiamabili e tutte le classi remotable che
implementano tipi complessi.
Una volta che lapplicazione client ha la dichiarazione di uninterfaccia richiamabile,
creare unistanza di THTTPRio per linterfaccia desiderata:
. aev -..,
_
importante che non si distrugga esplicitamente listanza di THTTPRio. Se stato
creato senza un Owner (come nella riga di codice vista in precedenza), esso si libera
automaticamente non appena viene rilasciata la sua interfaccia. Se stato creato con
un Owner, lOwner che si fa carico di liberare listanza di THTTPRio.
Quindi, fornire alloggetto THTTPRio le informazioni necessarie per identificare
linterfaccia del server e individuare il server. Vi sono due modi per fornire queste
informazioni:
Se non si fa affidamento sullURL per il Web Service o sui namespace e sugli
header Soap che loggetto deve modificare, possibile specificare semplicemente
lURL per il Web Service a cui si vuole accedere. THTTPRio utilizza questo URL
per cercare la definizione dellinterfaccia, oltre a tutte le informazioni sui
namespace e sgli header, in base alle informazioni contenute nel registro delle
36-18 G u i d a a l l a p r o g r a mma z i o n e
S c r i t t u r a d i c l i e n t p e r W e b S e r v i c e s
chiamate. Specificare lURL impostando la propriet URL allubicazione del
server:
.> ',....cc...ccc..~.L.ccLc.icc',
Se si desidera cercare dinamicamente in fase di esecuzione lURL, il namespace o il
Soap Action header nel documento WSDL, possibile utilizzare le propriet
WSDLLocation, Service e Port e loggetto estrarr le informazioni necessarie dal
documento WSDL:
..ci ',i,.s.',
..ccc ',i,',
.. '.i,c.ccc.c',
Una volta che si specificato come individuare il server e identificare linterfaccia,
possibile utilizzare il metodo QueryInterface per ottenere un puntatore allinterfaccia
per linterfaccia richiamabile. In questo modo viene creata dinamicamente in
memoria una vtable per linterfaccia associata, consentendo cos di effettuare
chiamate allinterfaccia:
_._Lc.ccc.c Lc.icciicc,
.>_cLc.iccLc.icciicc,
I? Lc.icciicc
.c Lc.icciicc>c.cic,
Lc.icciicc .,
38-22 G u i d a a l l a p r o g r a mma z i o n e
I m p l e m e n t a z i o n e d i o g g e t t i C O M c o n i w i z a r d
La Tabella 38.2 elenca i vari wizard e le interfacce da essi implementate:
Tabella 38.2 Wizard di C++Builder per limplementazione di oggetti COM, Automation e ActiveX
Wizard Interfacce implementate Che cosa fa il wizard
COM server IUnknown (e IDispatch se si
seleziona uninterfaccia
predefinita che deriva da
IDispatch)
Esporta le routine per gestire la registrazione
del server, la registrazione della classe, il
caricamento e lo scaricamento del server, e
listanziazione di un oggetto.
Crea e gestisce le class factory per gli oggetti
implementati nel server.
Prepara gli elementi del file di registro per
quegli oggetti che specificano il modello di
threading selezionato.
Offre il supporto lato-server per la generazione
di eventi, se necessario.
Dichiara i metodi che implementano una
interfaccia selezionata, e preparando la
struttura base delle implementazioni che il
programmatore dovr poi completare.
Fornisce una libreria di tipi.
Permette di selezionare uninterfaccia
arbitraria, registrata nella libreria di tipi, e di
implementarla. Se lo si fa, necessario
utilizzare una libreria di tipi.
Automation
server
IUnknown, IDispatch Esegue le funzioni di un wizard per server
COM (descritto in precedenza), e inoltre:
Implementa linterfaccia specificata, duale o
dispatch.
Active Server
Object
IUnknown, IDispatch,
(IASPObject)
Esegue le funzioni di un wizard per oggetti
Automation (descritto in precedenza) e genera
facoltativamente una pagina .ASP che pu
essere caricata in un browser Web. Lascia
aperto il Type Library editor per consentire, se
occorre, la modifica delle propriet delloggetto
e dei metodi.
Mette a disposizione le caratteristiche
intrinseche di ASP sotto forma di propriet in
modo da semplificare il reperimento delle
informazioni relative allapplicazione ASP e ai
messaggi HTTP che lhanno avviata.
ActiveX Control IUnknown, IDispatch,
IPersistStreamInit,
IOleInPlaceActiveObject,
IPersistStorage, IViewObject,
IOleObject, IViewObject2,
IOleControl,
IPerPropertyBrowsing,
IOleInPlaceObject,
ISpecifyPropertyPages
Esegue le funzioni del wizard per Automation
server (descritti in precedenza), e inoltre:
Genera una CoClass di implementazione che
corrisponde al controllo della VCL su cui
basato il controllo ActiveX e che implementa
tutte le interfacce ActiveX.
Lascia aperto leditor del codice sorgente in
modo che si possa modificare la classe di
implementazione.
P a n o r a mi c a s u l l e t e c n o l o g i e C O M 38-23
I m p l e m e n t a z i o n e d i o g g e t t i C O M c o n i w i z a r d
possibile aggiungere altri oggetti COM o reimplementare una loro
implementazione esistente. Per aggiungere un nuovo oggetto, la cosa pi semplice
utilizzare nuovamente un wizard. Questo perch il wizard imposta unassociazione
fra la libreria di tipi e una classe di implementazione, in modo che le modifiche
apportate alla libreria di tipi vengano applicate automaticamente alloggetto di
implementazione.
Codice generato dai wizard
I wizard di C++Builder generano codice che utilizza il linguaggio ATL (Active
Template Library) di Microsoft come base per il supporto COM. ATL un
framework di classi modello che gestiscono parecchi dettagli implementativi dello
sviluppo di applicazioni COM.Poich ATL si basa su modelli, non possibile
eseguire il link in DLL. Il progetto includer, invece, i file header di ATL che saranno
ActiveForm Stesse interfacce di ActiveX
Control
Esegue le funzioni del wizard per controlli
ActiveX, e inoltre:
Crea un discendente di TActiveForm che
sostituisce la classe VCL preesistente nel
wizard ActiveX control. Questa nuova classe
consente di progettare la Active Form con le
stesse modalit usate per progettare una
scheda in una applicazione Windows.
Transactional
object
IUnknown, IDispatch,
IObjectControl
Aggiunge al progetto corrente una nuova unit
che contiene la definizione delloggetto MTS o
COM+. Inserisce nella libreria di tipi GUID
proprietari in modo che C++Builder possa
installare correttamente loggetto, lasciando
aperto il Type Library editor per consentire la
definizione delle interfacce che loggetto
espone ai client. Loggetto deve essere
installato separatamente dopo averlo generato.
Property Page IUnknown, IPropertyPage Crea una nuova pagina di propriet che
possibile progettare nel Forms designer.
COM+ Event
object
Nessuna, per impostazione
predefinita
Crea un oggetto evento COM+ che possibile
definire usando il Type Library editor. A
differenza dei wizard per gli altri oggetti,
COM+ Event object wizard non crea una unit
di implementazione in quanto gli oggetti
evento non hanno implementazione (che
fornita dalloggetto subscriber dellevento).
COM+
Subscription
object
Nessuna, per impostazione
predefinitadefault
Crea un oggetto subscriber COM+ che
implementa linterfaccia di evento scelta.
Type Library Nessuna, per impostazione
predefinita
Crea una nuova libreria di tipi e la associa al
progetto attivo.
ActiveX library Nessuna, per impostazione
predefinita
Crea un nuovo ActiveX o server Com DLL ed
espone le necessarie funzioni di esportazione.
Tabella 38.2 Wizard di C++Builder per limplementazione di oggetti COM, Automation e ActiveX (continua)
Wizard Interfacce implementate Che cosa fa il wizard
38-24 G u i d a a l l a p r o g r a mma z i o n e
I m p l e m e n t a z i o n e d i o g g e t t i C O M c o n i w i z a r d
compilati in codice oggetto. I wizard di C++Builder generano le istruzioni include
per questi file header in una unit con suffisso _ATL (Per esempio, Project1_ATL.cpp e
Project1_ATL.h).
_
I file header ATL presenti nella directory Include/ATL di C++Builder differiscono
leggermente dai file header di ATL forniti da Microsoft. Queste differenze sono
necessarie affinch il compilatore di C++Builder possa compilare gli header. Non
possibile sostituire questi header con unaltra versione di ATL, pena la non corretta
compilazione.
Oltre alle istruzioni include per i file ATL (e per i file aggiuntivi che consentono alle
classi ATL di operare con le classi VCL), lo header della unit _ATL generato include
anche la dichiarazione di una variabile globale di nome _Module. _Module
unistanza della classe ATL CComModule che isola il resto dellapplicazione dalle
differenze tra DLL e EXE nel modo in cui sono gestiti gli aspetti relativi al threading e
alla registrazione. Nel file di progetto (Project1.cpp), _Module viene assegnata a
unistanza di TComModule, un discendente di CComModule che supporta lo stile di
C++Builder per la registrazione di COM. Di solito, non sar necessario utilizzare
direttamente questo oggetto.
Il wizard aggiunge al file di progetto anche una mappa di oggetti. Questa una serie
di macro ATL che assomigliano a quanto segue:
L.__.~.ccc.i,
_..L_.c, .cL.,
.__.~.
Ogni elemento tra le linee BEGIN_OBJECT_MAP e END_OBJECT_MAP definisce
unassociazione tra un ID di classe e la sua classe di implementazione ATL. Loggetto
_Module usa questa mappa per registrare i componenti. La mappa di oggetti
utilizzata anche dalle classi creatore di oggetti ATL. Se si aggiunge allapplicazione
un qualsiasi oggetto COM senza laiuto di un wizard, si dovr aggiornare la mappa
degli oggetto affinch possano essere registrati e creati nel corretto. Per fare ci,
aggiungere unaltra linea che utilizzi la macro OBJECT_ENTRY, assegnando come
parametri lID di classe e il nome della classe di implementazione.
I wizard generano una unit di implementazione per il particolare tipo di oggetto
COM che si sta creando. Lunit di implementazione contiene la dichiarazione della
classe che implementa loggetto COM. Questa classe un discendente (diretto o
indiretto) della classe ATL CComObjectRootEx, della classe ATL CComCoClass, e di
altre classi che dipendono dal tipo di oggetto che si sta creando.
CComCoClass fornisce il supporto class factory necessario per la creazione della
classe. Utilizza la mappa di oggetti che era stata aggiunta al file di progetto.
CComObjectRootEx una classe modello che fornisce il supporto necessario per
IUnknown. Essa implementa il metodo QueryInterface facendo uso di una mappa di
interfacce che possibile trovare nellheader della unit di implementazione. La
mappa di interfacce assomiglia a quanto segue:
L._._.~..cL.,
._L.~_.L.c
._._.~.
P a n o r a mi c a s u l l e t e c n o l o g i e C O M 38-25
I m p l e m e n t a z i o n e d i o g g e t t i C O M c o n i w i z a r d
Ogni elemento nella mappa di interfacce uninterfaccia che viene esposta dal
metodo QueryInterface. Se si aggiungono alla classe di implementazione ulteriori
interfacce, sar necessario aggiungerle alla mappa di interfacce (utilizzando la macro
COM_INTERFACE_ENTRY), e aggiungerle come altri antenati della classe di
implementazione.
CComObjectRootEx fornisce il supporto necessario per il conteggio dei riferimenti.
Tuttavia, non dichiara i metodi AddRef e Release. Questi metodi vengono aggiunti alla
classe di implementazione tramite la macro END_COM_MAP() alla fine della mappa
di interfacce.
_
Per maggiori informazioni su ATL, consultare la documentazione di Microsoft. Si
noti, comunque, che il supporto COM di C++Builder non utilizza ATL per la
registrazione, per i controlli ActiveX (che sono invece basati su oggetti della VCL), o
per il supporto di pagina di propriet.
I wizard generano anche una libreria di tipi e la relativa unit associata, il cui nome
assume il formato Project1_TLB.La unit Project1_TLB include le definizioni che
lapplicazione ha bisogno di utilizzare, le definizioni di tipo e le interfacce definite
nella libreria di tipi. Per maggiori informazioni sui contenuti di questo file, consultare
Codice generato durante limportazione delle informazioni di una libreria di tipi a
pagina 40-5.
possibile modificare linterfaccia generata dal wizard utilizzando il Type Library
editor. Se si apportano modifiche, la classe di implementazione viene
automaticamente aggiornata in modo da tener conto di tali modifiche. Per
completare limplementazione, sar necessario solamente completare il corpo dei
metodi generati.
38-26 G u i d a a l l a p r o g r a mma z i o n e
I m p l e m e n t a z i o n e d i o g g e t t i C O M c o n i w i z a r d
F u n z i o n a me n t o d e l l e l i b r e r i e d i t i p i 39-1
C a p i t o l o
39
Capitolo39Funzionamento delle librerie di tipi
Questo capitolo descrive come creare e modificare le librerie di tipi usando leditor di
Type Library di C++Builder. Le librerie di tipi sono file che includono informazioni
sui tipi di dati, sulle interfacce, sulle funzioni membro e sulle classi di oggetti esposte
da un oggetto COM. Le librerie di tipi forniscono un modo per identificare quali tipi
di oggetti e di interfacce sono disponibili su un server. Per una panoramica
dettagliata sul perch e su quando usare le librerie di tipi, consultare Librerie di
tipi a pagina 38-17.
Una libreria di tipi pu contenere:
Informazioni sui tipi di dati personalizzati come gli alias, gli enumerativi, le
strutture e le union.
Descrizioni su uno o pi elementi COM, come uninterfaccia, dispinterface, o una
CoClass. A ciascuna di queste descrizioni viene generalmente fatto riferimento
come informazioni di type.
Descrizioni delle costanti e dei metodi definiti in moduli esterni.
Riferimenti alle descrizioni di tipo di altre librerie di tipi.
Includendo una libreria di tipi con lapplicazione COM o con la libreria ActiveX, si
rendono disponibili le informazioni sugli oggetti dellapplicazione ad altre
applicazioni e ad altri strumenti di programmazione tramite gli strumenti per le
librerie di tipi e le interfacce di COM.
Con i tradizionali strumenti di sviluppo, possibile preparare librerie di tipi creando
script in IDL (Interface Definition Language), quindi eseguendoli tramite un
compilatore. Il Type Library editor automatizza alcuni di questi processi, rendendo
molto meno complessa ed onerosa la creazione di proprie librerie di tipi.
Quando si crea un server COM di qualsiasi tipo (controllo ActiveX, oggetto
Automation, modulo dati remoto e cos via) utilizzando i wizard di C++Builder, il
wizard genera automaticamente una libreria di tipi. La maggior parte del lavoro che
si fa per personalizzare loggetto generato inizia con la libreria di tipi, poich in essa
che si definiscono le propriet e i metodi che la libreria espone ai client: si modifica
39-2 G u i d a a l l a p r o g r a mma z i o n e
T y p e L i b r a r y e d i t o r
linterfaccia della CoClass generata dal wizard utilizzando il Type Library editor. Il
Type Library editor aggiorna automaticamente la unit di implementazione
delloggetto, e tutto ci che si dovr fare sar completare il corp dei metodi generati.
Type Library editor
Il Type Library editor uno strumento che consente agli sviluppatori di esaminare e
di creare informazioni di tipo per gli oggetti COM. Lutilizzo del Type Library editor
pu semplificare enormemente lo sviluppo di oggetti COM centralizzando la
definizione di interfacce, CoClasses, e tipi, lottenimento dei GUID per le nuove
interfacce, lassociazione di interfacce alle CoClasses, laggiornamento della unit di
implementazione e cos via.
Il Type Library editor genera due tipi di file che rappresentano i contenuti della
libreria di tipi:
Tabella 39.1 File di Type Library editor
File Descrizione
.TLB file Il file binario della libreria di tipi. Per impostazione predefinita, non sar necessario
utilizzare questo file, poich la libreria di tipi viene compilata automaticamente
nellapplicazione come risorsa. Comunque, sar possibile utilizzare questo file per
compilare esplicitamente la libreria di tipi in un altro progetto o per distribuire
separatamente la libreria di tipi dallEXE o dallOCX. Per maggiori informazioni,
consultare Apertura di una libreria di tipi esistente a pagina 39-14 and
Distribuzione delle librerie di tipi a pagina 39-20.
_TLB unit Questa unit (file .cpp e .h) interpreta i contenuti della libreria di tipi per luso
nellapplicazione. Contiene tutte le dichiarazioni che occorrono allapplicazione per
utilizzare gli elementi definiti nella libreria di tipi. Sebbene sia possibile aprire
questo file nel Code editor, non lo si dovr mai modificare -- la manutenzione
affidata al Type Library editor, e pertanto tutte le modifiche apportate saranno
sovrascritte dal Type Library editor. Per maggiori informazioni sui contenuti di
questo file, consultare Codice generato durante limportazione delle informazioni
di una libreria di tipi a pagina 40-5.
F u n z i o n a me n t o d e l l e l i b r e r i e d i t i p i 39-3
T y p e L i b r a r y e d i t o r
Elementi del Type Library editor
Gli elementi principali del Type Library editor sono elencati nella Tabella 39.2:
Tali parti sono illustrate nella Figura 39.1, che mostra il Type Library editor che
visualizza le informazioni di tipo per un oggetto COM di nome cyc.
Figura 39.1 Type Library editor
Barra strumenti
La barra strumenti del Type Library editor, posizionata nella parte superiore del
Type Library editor, contiene i pulsanti che possibile selezionare per aggiungere
alla libreria di tipi nuovi oggetti.
Il primo gruppo di pulsanti consente di aggiungere elementi alla libreria di tipi. Se si
fa clic su un pulsante della barra strumenti, nel pannello Object list appaiono le icone
Tabella 39.2 Parti di Type Library editor
Parte Descrizione
Barra strumenti Include pulsanti per aggiungere alla libreria di tipi nuovi tipi, CoClass,
interfacce e membri dellinterfaccia. La barra strumenti include anche pulsanti
per aggiornare la unit di implementazione, registrare la libreria di tipi, e
salvare un file IDL contenente le informazioni incluse nella libreria di tipi.
Pannello Object
list
Mostra tutti gli elementi esistenti nella libreria di tipi. Quando si fa clic su uno
degli elementi nel pannello, vengono visualizzate la pagine valide relative a
quelloggetto.
Barra di stato Visualizza gli errori di sintassi se si cerca di aggiungere tipi non validi alla
libreria di tipi.
Pagine Visualizzano informazioni sulloggetto selezionato. Le pagine visualizzate
dipendono dal tipo di oggetto selezionato.
39-4 G u i d a a l l a p r o g r a mma z i o n e
T y p e L i b r a r y e d i t o r
relative a quel certo elemento. possibile personalizzarne gli attributi utilizzando il
pannello di destra. A seconda dellicona selezionata, sulla destra appaiono pagine di
informazioni differenti.
La tabella seguente elenca gli elementi che possibile aggiungere alla libreria di tipi:
Quando si seleziona nel pannello Object list uno degli elementi elencati in
precedenza, il secondo gruppo di pulsanti visualizza i membri che risultano validi
per quel certo elemento. Per esempio, quando si seleziona Interface, le icone Method
e Property nel secondo riquadro diventano attive poich possibile aggiungere alla
definizione di interfaccia metodi e propriet. Quando si seleziona Enum, il secondo
gruppo di pulsanti cambia per visualizzare il membro Const, che lunico membro
valido per le informazioni di tipo Enum.
La tabella seguente elenca i membri che possibile aggiungere agli elementi nel
pannello Object list
Icona Significato
Una descrizione di interfaccia.
Una descrizione di dispinterface.
Una CoClass.
Una enumerazione.
Un alias.
Un record.
Una union.
Un modulo.
Icona Significato
Un metodo dellinterfaccia, della dispinterface o un entry point in un modulo.
Una propriet di uninterfaccia o di una dispinterface.
Una propriet a sola scrittura. (disponibile dallelenco a discesa sul pulsante della
propriet)
Una propriet in lettura/scrittura. (disponibile dallelenco a discesa sul pulsante della
propriet)
Una propriet a sola lettura. (disponibile dallelenco a discesa
sul pulsante della propriet)
F u n z i o n a me n t o d e l l e l i b r e r i e d i t i p i 39-5
T y p e L i b r a r y e d i t o r
Nel terzo riquadro possibile aggiornare, registrare o esportare la propria libreria di
tipi (salvandola come file IDL) come descritto nel paragrafo Salvataggio e
registrazione delle informazioni della libreria di tipi a pagina 39-19.
Pannello Object list
Il pannello Object list mostra tutti gli elementi della libreria di tipi attiva utilizzando
una vista ad albero. La radice dellalbero rappresenta la libreria ed rappresentata
con la seguente icona:
Dal nodo della libreria di tipi si diramano verso il basso gli elementi inclusi nella
libreria di tipi:
Figura 39.2 Pannello Object list
Quando si seleziona uno di questi elementi (incluso la stessa libreria di tipi), le
pagine relative alle informazioni di tipo riportate alla destra si modificano riportando
solo le informazioni pertinenti per quel certo elemento. possibile utilizzare queste
pagine per modificare la definizione e le propriet dellelemento scelto.
possibile intervenire sugli elementi nel pannello Object list facendo clic destro in
modo da richiamare il menu contestuale. In questo menu sono inclusi comandi che
permettono di utilizzare gli Appunti di Windows per spostare o copiare gli elementi
esistenti, oltre a comandi per aggiungere nuovi elementi o per personalizzare
laspetto del Type Library editor.
Barra di stato
Quando si effettua lediting o il salvataggio di una libreria di tipi, la sintassi, gli errori
di traduzione e i messaggi di segnalazione vengono elencati nel pannello Status.
Per esempio, se si specifica un tipo IDL non supportato dal Type Library editor, viene
visualizzato un errore di sintassi. Per un elenco completo dei tipi supportati dal type
Library editor, consultare Tipi consentiti a pagina 39-12.
Un campo in un record o in una union.
Una costante in una enumerazione o in un modulo.
39-6 G u i d a a l l a p r o g r a mma z i o n e
T y p e L i b r a r y e d i t o r
Pagine di informazioni di tipo
Quando si seleziona un elemento nel pannello Object list, nel Type Library editor
appaiono le pagine di informazioni di tipo che sono valide per lelemento
selezionato. Quali pagine appariranno dipende dallelemento selezionato nel
pannello Object list:
Tabella 39.3 Pagine del Type Library editor
Elemento
Type Info
Pagina di
informazione di
tipo Contenuto della pagina
Type library Attributes Nome, versione e GUID della libreria di tipi, oltre a
informazioni per il collegamento alla Guida.
Uses Elenco di altre librerie di tipi che contengono definizioni da
cui questa libreria dipende.
Flags Flag che determinano come le altre applicazioni possono
utilizzare la libreria di tipi.
Text Tutte le definizioni e le dichiarazioni che definiscono la
libreria di tipi in oggetto (vedere di seguito).
Interface Attributes Denominate, versione e GUID dellinterfaccia, il nome
dellinterfaccia da cui deriva, e informazioni utili per il link
dellinterfaccia.
Flags Flag che indicano se linterfaccia nascosta, duale,
compatibile con Automation e/o estensibile.
Text Le definizioni e le dichiarazioni per lInterface (trattatta nel
prosieguo del capitolo).
Dispinterface Attributes Nome, versione e GUID dellinterfaccia, e informazioni per il
collegamento alla Guida.
Flags Flag che indicano se la Dispinterface nascosta, duale, e/o
estensibile.
Text Le definizioni e le dichiarazioni della Dispinterface. (vedere
di seguito).
CoClass Attributes Nome, versione e GUID della CoClass e informazioni per il
collegamento alla Guida.
Implements Un elenco di interfacce implementate dalla CoClass e dei
rispettivi attributi.
COM+ Gli attributi di oggetti transazionali, come il modello della
transazione, la sincronizzazione delle chiamate, lattivazione
just-in-time, la centralizzazione di oggetti e cos via. Include
anche gli attributi degli oggetti evento di COM+.
Flags Flag che indicano i vari attributi della CoClass, incluso come i
client possono creare e utilizzare istanze, se visualizzabile
dagli utenti in un browser, se un controllo ActiveX, e se pu
essere aggregato (agisce come parte di un composito).
Text Le definizioni e le dichiarazioni per la CoClass (trattatta nel
prosieguo del capitolo).
Enumeration Attributes Nome, versione e GUID della enumerazione, e informazioni
per il collegamento alla Guida.
Text Le definizioni e le dichiarazioni per il tipo enumerativo
(trattatto nel prosieguo del capitolo).
F u n z i o n a me n t o d e l l e l i b r e r i e d i t i p i 39-7
T y p e L i b r a r y e d i t o r
Alias Attributes Nome, versione e GUID della enumerazione, il tipo che lalias
rappresenta e informazioni per il collegamento alla Guida.
Text Le definizioni e le dichiarazioni per lalias (trattatto nel
prosieguo del capitolo).
Record Attributes Nome, versione e GUID del record e informazioni per il
collegamento alla Guida.
Text Le definizioni e le dichiarazioni per il record (trattatto nel
prosieguo del capitolo).
Union Attributes Nome, versione e GUID della union e informazioni per il
collegamento alla Guida.
Text Le definizioni e le dichiarazioni per la union (trattatta nel
prosieguo del capitolo).
Module Attributes Nome, versione, GUID e DLL associata per il modulo e
informazioni per il collegamento alla Guida.
Text Le definizioni e le dichiarazioni per il modulo (trattatto nel
prosieguo del capitolo).
Method Attributes Nome, ID di smistamento o punto dingresso della DLL e
informazioni per il collegamento alla Guida.
Parameters Tipo restituito del metodo, e un elenco di tutti i parametri con
relativi tipi ed eventuali modificatori.
Flags Flag che indicano come i client possono vedere e utilizzare il
metodo, se questo un metodo predefinito per linterfaccia e
se ricollocabile.
Text Le definizioni e le dichiarazioni per il metodo (trattatto nel
prosieguo del capitolo).
Property Attributes Nome, ID di smistamento, tipi di metodo di accesso alla
propriet (getter o setter) e informazioni per il collegamento
alla Guida.
Parameters Tipo restituito del metodo di accesso alla propriet e un
elenco di tutti i parametri con relativi tipi ed eventuali
modificatori.
Flags Flag che indicano come i client possono vedere e utilizzare la
propriet, se questa unimpostazione predefinita per
linterfaccia, se la propriet ricollocabile, collegabile, e cos
via.
Text Le definizioni e le dichiarazioni per il metodo di accesso alle
propriet (trattatto nel prosieguo del capitolo).
Const Attributes Nome, valore, tipo (per const di modulo) e informazioni per il
collegamento alla Guida.
Flags Flag che indicano come i client possono vedere e utilizzare la
costante, se questa rappresenta un valore predefinito, se la
costante collegabile, e cos via.
Text Le definizioni e le dichiarazioni per la costante (trattatta nel
prosieguo del capitolo).
Field Attributes Nome, tipo e informazioni per il collegamento alla Guida.
Tabella 39.3 Pagine del Type Library editor
Elemento
Type Info
Pagina di
informazione di
tipo Contenuto della pagina
39-8 G u i d a a l l a p r o g r a mma z i o n e
T y p e L i b r a r y e d i t o r
_
Per informazioni pi particolareggiate sulle varie opzioni che possibile impostare
nelle pagine delle informazioni di tipo, consultare la Guida in linea del Type Library
editor.
possibile utilizzare tutte le pagine delle informazioni di tipo per vedere o
modificare i valori in esse visualizzate.La maggior parte delle pagine organizza le
informazioni in una serie di controlli, consentendo sia limmissione di valori sia la
loro selezione da un elenco, senza dover necessariamente conoscere la sintassi delle
dichiarazioni corrispondenti. In questo modo possibile prevenire molti piccoli
errori come quelli di battitura durante la specifica di valori da una serie limitata.
Tuttavia, per alcuni potrebbe risultare pi rapido immettere direttamente le
dichiarazioni. Per fare ci, utilizzare la pagina Text.
Tutti gli elementi della libreria di tipi hanno una pagina di testo che visualizza la
sintassi dellelemento. Questa sintassi appare in un subset dellIDL dellInterface
Definition Language di Microsoft. Qualsiasi modifica apportata in altre pagine
dellelemento viene riportata nella pagina di testo. Se si aggiunge del codice
direttamente nella pagina Text, le modifiche vengono riportate nelle altre pagine del
Type Library editor.
Il Type Library editor genera errori di sintassi se si aggiungono identificatori che non
sono supportati attualmente dalleditor; leditor supporta attualmente solamente
quegli identificatori che fanno riferimento al supporto per le libreria di tipi (non
supportano RPC n i costrutti utilizzati dal compilatore IDL di Microsoft per la
generazione di codice sorgente C++ o per il supporto del marshaling).
Elementi del Type Library editor
A prima vista, linterfaccia del Type Library editor pu sembrare molto complicata.
Ci dovuto al fatto che presenta informazioni su un elevato numero di elementi,
ognuno dei quali ha caratteristiche proprie. Comunque, molte di queste
caratteristiche sono comuni a tutti gli elementi. Ad esempio, ogni elemento (incluso
la stessa libreria di tipi) ha le seguenti caratteristiche:
AUn Name, utilizzato per descrivere lelemento e per fare riferimento allelemento
nel codice.
Un GUID (identificatore globalmente univoco), un valore globalmente univoco a
128-bit utilizzato da COM per identificare lelemento. Questo dovrebbe essere
sempre fornito per la stessa libreria di tipi, per le CoClass e per le interfacce.
Altrimenti facoltativo.
Flags Flag che indicano come i client possono vedere e utilizzare il
campo, se questo rappresenta un valore predefinito, se il
campo collegabile, e cos via.
Text Le definizioni e le dichiarazioni per il campo (trattatto nel
prosieguo del capitolo).
Tabella 39.3 Pagine del Type Library editor
Elemento
Type Info
Pagina di
informazione di
tipo Contenuto della pagina
F u n z i o n a me n t o d e l l e l i b r e r i e d i t i p i 39-9
T y p e L i b r a r y e d i t o r
Un Version number, per distingue tra pi versioni dellelemento. Questo sempre
facoltativo, ma dovrebbe essere fornito per CoClass e interfacce, poich senza di
esso alcuni strumenti non sono in grado di utilizzarli.
Informazioni che collegano lelemento a un argomento della Guida. Queste
includono un valore Help String, Help Context o Help String Context. Help
Context utilizzato per un sistema di Guida tradizionale di Windows, in cui la
libreria di tipi ha un file di Guida a s stante. Help String Context si utilizza
quando la Guida fornita invece da una DLL separata. Help Context o Help String
Context fa riferimento a un file di Guida o a una DLL specificate nella pagina
Attributes della libreria di tipi. Linformazione sempre facoltativa.
Interfacce
Un interfaccia descrive i metodi (e qualsiasi propriet espressa come funzione get e
set) per un oggetto a cui si deve accedere tramite una tabella virtuale delle funzioni
(Vtable). Se uninterfaccia contrassegnata come duale, erediter da IDispatch, e
loggetto, tramite OLE automation, sar in grado di eseguire il binding anticipato, di
accedere alla vtable e di eseguire il binding in esecuzione. Per impostazione
predefinita, la libreria di tipi contrassegna come duali tutte le interfacce aggiunte
dallutente.
Le interfacce possono essere membri assegnati: metodi e propriet. Questi appaiono
nel pannello Object list come figli del nodo dellinterfaccia. Le propriet delle
interfacce sono rappresentate dai metodi get e set utilizzati per leggere e scrivere i
dati associati alla propriet. Esse vengono rappresentate nella vista ad albero
mediante delle icone particolari che ne indicano lo scopo.
_
Se una propriet specificata come Write By Reference, vuol dire che viene passata
come puntatore piuttosto che per valore. Alcune applicazioni, come Visual Basic,
usano Write By Reference, se presente, per ottimizzare le prestazioni. Per passare la
propriet solamente per riferimento invece che per valore, utilizzare il tipo di
propriet By Reference Only. Per passare la propriet per riferimento e per valore,
scegliere Read|Write|Write By Ref. Per richiamare questo menu, selezionare sulla
barra strumenti la freccia accanto allicona della propriet.
Una volta aggiunte le propriet o i metodi utilizzando il pulsante della barra
strumenti o il menu contestuale del pannello Object list, se ne descrivono sintassi e
attributi selezionando la propriet o il metodo e utilizzando le pagine delle
informazioni di tipo.
La pagina Attributes consente di assegnare alla propriet o al metodo un nome e lID
di smistamento (in modo da poterla chiamare utilizzando IDispatch). Per le propriet,
si deve assegnare anche un tipo. La firma della funzione viene creata utilizzando la
pagina Parameters, in cui possibile aggiungere, rimuovere e riordinare parametri,
impostarne il tipo ed eventuali modificatori, e specificare i tipi restituiti della
funzione.
Si noti che quando si assegnano propriet e metodi a uninterfaccia, essi vengono
assegnati implicitamente alla CoClass associata. Ci dovuto al fatto che il Type
Library editor non consente di aggiungere direttamente propriet e metodi a una
CoClass.
39-10 G u i d a a l l a p r o g r a mma z i o n e
T y p e L i b r a r y e d i t o r
Dispinterface
Le interfacce sono utilizzate pi frequentemente delle dispinterface per descrivere
propriet e metodi di un oggetto. Le dispinterface sono accessibili solamente tramite
binding dinamico, mentre le interfacce possono disporre del bind statico tramite una
vtable.
possibile aggiungere metodi e propriet alle dispinterfaces secondo le stesse
modalit usate per le interfacce. Comunque, quando si crea una propriet per una
dispinterface, non possibile specificare il genere della funzione o i tipi dei
parametri.
CoClass
Una CoClass descrive un oggetto COM univoco che implementa un o pi interfacce.
Quando si definisce una CoClass, necessari specificare qual linterfaccia
implementata predefinita delloggetto e, facoltativamente, quale dispinterface la
sorgente predefinita per gli eventi. Notare che nel Type Library editor non si
aggiungono propriet o metodi a una CoClass. Propriet e metodi vengono esposti ai
client dalle interfacce, che a loro volta vengono associate alle CoClass usando la
pagina Implements.
Definizioni di tipo
Enumerativi, alias, record e union dichiarano tutti tipi che potrebbero essere quindi
utilizzati altrove nella libreria di tipi.
Gli Enums sono costituiti da un elenco di costanti, ognuno delle quali deve essere
numerica. Linput numerico normalmente un intero in formato decimale o
esadecimale. Per impostazione predefinita, il valore di base zero. possibile
aggiungere costanti allenumerativo selezionandolo nel pannello Object list e facendo
clic sul pulsante Const sulla barra strumenti, oppure selezionando il comando New|
Const nel menu contestuale del pannello Object list.
_
Si raccomanda vivamente di prevedere una serie di stringhe di guida per gli
enumerativi, in modo da renderne chiaro il significato. Qui di seguito viene riportato
un esempio di immissione di un tipo enumerativo per il pulsante di un mouse e
include una stringa di guida per ogni elemento enumerativo.
,c.c. c. x.sc
,c,s'.cc.
.cc. ,
,c,s'.c
.c
,c,s'.c...c
.c...c .
x.sc,
Un alias crea un alias (typedef) per un tipo. possibile utilizzare lalias per definire
tipi che si vogliono utilizzare in altre informazioni di tipo quali record o union.
Associare lalias con la relativa definizione di tipo impostando lattributo Type nella
pagina Attributes.
F u n z i o n a me n t o d e l l e l i b r e r i e d i t i p i 39-11
T y p e L i b r a r y e d i t o r
Un record una struttura in stile C. Un record costituito da una lista di membri
della struttura o campi. Una union definisce una union in stile C. Analogamente a un
record, una union costituita da una lista di membri della struttura o campi.
Comunque, diversamente dai membri dei record, ogni membro di una union occupa
lo stesso indirizzo fisico, e pertanto possibile memorizzare un solo valore logico.
Aggiungere i campi a un record o a una union selezionandolo nel pannello Object list
e facendo clic sul pulsante del campo sulla barra strumenti, oppure facendo clic
destro e scegliendo dal menu contestuale del pannello Object list lopzione Field.
Ogni campo ha un nome e un tipo che viene assegnato selezionando il campo e
assegnandogli dei valori tramite la pagina Attributes. Record e union possono essere
definite con un tag facoltativo, come con uno struct del C.
I membri possono essere di un qualsiasi tipo incorporato; anche possibile
specificarne uno usando un alias prima di definire il record.
_
C++Builder non supporta il marshaling delle parole chiave correlate a structs e union,
come switch_type, first_is, last_is ecc.
Moduli
Un modulo definisce un gruppo di funzioni, di solito una serie di punti dingresso
nelle DLL. Un modulo pu essere definito
Specificando sulla pagina degli attributi la DLL che esso rappresenta.
Aggiungendo metodi e costanti tramite la barra strumenti o il menu contestuale
del pannello Object list. Per ogni metodo o costante, necessario poi definirne gli
attributi selezionandolo nel pannello Object list e impostandone i valori sulla
pagina Attributes.
Per i metodi di modulo, si deve assegnare un nome e un punto di ingresso per la DLL
utilizzando la pagina degli attributi. Dichiarare i parametri e il tipo restituito della
funzione usando la pagina dei parametri.
Per costanti di modulo, utilizzare la pagina Attributes per specificare un nome, un
tipo e un valore.
_
Il Type Library editor non genera nessuna dichiarazione o implementazione relativa
a un modulo. La DLL specificata deve essere creata come progetto separato.
Uso del Type Library editor
Utilizzando leditor delle librerie di tipi, possibile creare nuove librerie di tipi o
modificare quelle esistenti. Di solito, chi sviluppa applicazioni utilizza un wizard per
creare gli oggetti esposti nella libreria di tipi, demandando a C++Builder la
generazione automatica della libreria di tipi. Quindi, la libreria di tipi generata
automaticamente viene aperta nel Type Library editor in modo da definire (o
modificare) le interfacce, aggiungere definizioni di tipo, e cos via.
Comunque, anche se non si utilizza un wizard per definire gli oggetti, possibile
utilizzare il Type Library editor per definire una nuova libreria di tipi. In questo caso,
si devono creare tutte le classi di implementazione, poich il Type Library editor non
39-12 G u i d a a l l a p r o g r a mma z i o n e
T y p e L i b r a r y e d i t o r
genera codice per le CoClass che non sono state associate mediante un wizard a una
libreria di tipi.
Leditor supporta un sottoinsieme di tipi validi in una libreria di tipi come descritto
di seguito.
Gli argomenti finali in questa sezione descrivono come:
Creare una nuova libreria di tipi
Aprire una libreria di tipi esistente
Aggiungere uninterfaccia alla libreria di tipi
Modificare uninterfaccia
Aggiungere propriet e metodi alla libreria di tipi
Aggiungere un CoClass alla libreria di tipi
Aggiungere uninterfaccia a una CoClass
Aggiungere un enumerativo alla libreria di tipi
Aggiungere un alias alla libreria di tipi
Aggiungere un record o una union alla libreria di tipi
Aggiungere un modulo alla libreria di tipi
Salvare e registrare le informazioni della libreria di tipi
Tipi consentiti
Il Type Library editor supporta in una libreria di tipi i seguenti tipi IDL. La colonna
Compatibile con Automation specifica se il tipo pu essere utilizzato o meno da
uninterfaccia i cui flag Automation o Dispinterface sono stati selezionati. Questi
sono i tipi di cui COM in grado di eseguire il marshaling automatico tramite la
libreria di tipi.
Tipo IDL Tipo variant
Compatibile
con
Automation Descrizione
short VT_I2 S Integer con segno a 2 byte
long VT_I4 S Integer con segno a 4 byte
single VT_R4 S Real a 4 byte
double VT_R8 S Real a 8 byte
CURRENCY VT_CY S Valuta
DATE VT_DATE S data
BSTR VT_BSTR S Stringa binaria
IDispatch VT_DISPATCH S Puntatore allinterfaccia IDispatch
SCODE VT_ERROR S Codice di errore OLE
VARIANT_BOOL VT_BOOL S True = 1, False = 0
VARIANT VT_VARIANT S Puntatore a OLE Variant
IUnknown VT_UNKNOWN S Puntatore allinterfaccia IUnknown
DECIMAL VT_DECIMAL S virgola fissa a 16-byte
byte VT_I1 No* Integer con segno a 1 byte
unsigned char VT_UI1 S Integer senza segno a 1 byte
unsigned short VT_UI2 No* Integer senza segno a 2 byte
F u n z i o n a me n t o d e l l e l i b r e r i e d i t i p i 39-13
T y p e L i b r a r y e d i t o r
* Potrebbero essere compatibili con Automation con alcune applicazioni.
_
Il tipo unsigned char (VT_UI1) compatibile con Automation, ma non ne
consentito luso in un Variant o OleVariant poich molti server Automation non
gestiscono correttamente questo valore.
_
Per i tipi consentiti nello sviluppo di applicazioni CORBA, consultare Definizione
delle interfacce delloggetto a pagina 31-5.
A parte questi tipi IDL, in una definizione della libreria di tipi si pu usare qualsiasi
interfaccia e tipo definiti nella libreria o nelle librerie collegate.
Il Type Library editor memorizza nel file generato di libreria di tipi (.TLB) le
informazioni di tipo in formato binario.
SafeArray
COM richiede che gli array siano passati tramite un tipo di dati speciale noto come
SafeArray. I SafeArray possono essere creati e distrutti chiamando speciali funzioni
COM , e tutti gli elementi di un SafeArray devono essere tipi consentiti e compatibili
con Automation.
Nel Type Library editor, un SafeArray deve specificare il tipo dei suoi elementi. Per
esempio, la linea seguente prelevata dalla pagina Text dichiara un metodo con un
parametro che un SafeArray, il cui tipo dellelemento long:
aksscL: _aticaII -cs.~~~ cs,
_
Sebbene sia necessario specificare il tipo dellelemento quando si dichiara un tipo
SafeArray nel Type Library editor, la dichiarazione nella unit _TLB generata non
indica il tipo dellelemento.
Creazione di una nuova libreria di tipi
Potrebbe essere necessario creare una libreria di tipi indipendente di un particolare
oggetto COM. Per esempio, si potrebbe voler definire una libreria di tipi che
unsigned long VT_UI4 No* Integer senza segno a 4 byte
__int64 VT_I8 No Real con segno a 8 byte
uint64 VT_UI8 No Real senza segno a 8 byte
int VT_INT No* Integer dipendente dal sistema
(Win32=Integer)
unsigned int VT_UINT No* Integer senza segno dipendente dal
sistema
void VT_VOID S VOID in stile C
HRESULT VT_HRESULT No Codice di errore a 32 bit
SAFEARRAY VT_SAFEARRAY S OLE Safe Array
LPSTR VT_LPSTR No Stringa terminata con null
LPWSTR VT_LPWSTR No Wide string terminata con null
Tipo IDL Tipo variant
Compatibile
con
Automation Descrizione
39-14 G u i d a a l l a p r o g r a mma z i o n e
T y p e L i b r a r y e d i t o r
contenga definizioni di tipo che si utilizzano in molte altre librerie di tipi. In questo
casi si pu creare una libreria di tipi di definizioni di base e aggiungerla alla pagina
Uses di altre librerie di tipi.
anche possibile creare anche una libreria di tipi per un oggetto non ancora
implementato. Una volta che la libreria di tipi contiene la definizione dellinterfaccia,
possibile utilizzare il COM Object wizard per generare una CoClass e
limplementazione.
Per creare una nuova libreria di tipi:
1 Scegliere File|New|Other per aprire la finestra di dialogo New Items.
2 Scegliere la pagina ActiveX.
3 Selezionare licona Type Library.
4 Scegliere OK.
Il Type Library editor appare con la richiesta di immettere un nome per la libreria
di tipi.
5 Immettere il nome desiderato. Continuare ad aggiungere alla libreria di tipi gli
elementi desiderati.
Apertura di una libreria di tipi esistente
Quando si usano i wizard per creare un controllo ActiveX, un oggetto Automation,
ActiveForm, oggetti COM, oggetti transazionali, moduli dati remoti o moduli dati
transazionali module, viene creata automaticamente una libreria di tipi con una unit
di implementazione. Inoltre, si potrebbero avere librerie di tipi associate ad altri
prodotti (server) disponibili nel sistema.
Per aprire una libreria di tipi che non fa parte del progetto corrente:
1 Scegliere il comando File|Open dal menu principale dellIDE.
2 Nella finestra di dialogo Open, impostare la casella File Type a type library.
3 Selezionare la libreria di tipi desiderata e scegliere Open.
Per aprire una libreria di tipi associata al progetto corrente:
1 Scegliere il comando View|Type Library.
A questo punto, possibile aggiungere interfacce, CoClass e altri elementi della
libreria di tipi, come enumerazioni, propriet e metodi.
_
Quando si scrivono applicazioni client, non necessario aprire la libreria di tipi.
Occorre solamente la unit Project_TLB che il Type Library editor crea a partire da una
libreria di tipi, e non la libreria di tipi. possibile aggiungere direttamente questo file
a un progetto client, oppure, se la libreria di tipi registrata nel sistema, si pu
utilizzare la finestra di dialogo Import Type Library (comando Project|Import Type
Library).
Aggiunta di uninterfaccia alla libreria di tipi
Per aggiungere uninterfaccia:
F u n z i o n a me n t o d e l l e l i b r e r i e d i t i p i 39-15
T y p e L i b r a r y e d i t o r
1 Nella barra strumenti fare clic sullicona dellinterfaccia.
Al pannello dellelenco degli oggetti viene aggiunta uninterfaccia e compare la
richiesta di inserire un nome.
2 Scrivere un nome per linterfaccia.
La nuova interfaccia contiene gli attributi predefiniti che, se necessario, possono
essere modificati.
possibile aggiungere propriet (rappresentate dalle funzioni getter/setter) e
metodi adatti alla funzione dellinterfaccia.
Modifica di uninterfaccia con il Type Library editor
Esistono vari modi per modificare, una volta creata, uninterfaccia o una
dispinterface.
possibile modificare gli attributi dellinterfaccia utilizzando la pagina Type
information che contiene le informazioni che si desiderano modificare. Selezionare
linterfaccia nel pannello Object list ed utilizzate i controlli sulla pagina opportuna
delle informazioni di tipo. Per esempio, si potrebbe voler modificare linterfaccia
del genitore utilizzando la pagina Attributes, oppure utilizzare la pagina Flags per
indicare se linterfaccia duale o meno.
possibile modificare direttamente la dichiarazione dellinterfaccia selezionando
linterfaccia nel pannello Object list e modificando quindi le dichiarazioni sulla
pagina Text.
possibile aggiungere propriet e metodi allinterfaccia (vedere pi avanti).
possibile modificare le propriet e metodi gi presenti nellinterfaccia
modificandone le informazioni di tipo.
possibile associarla a una CoClass selezionando la CoClass nel pannello Object
list, facendo clic destro sulla pagina Implements e scegliendo Insert Interface.
Se linterfaccia associata a una CoClass generata da un wizard, possibile fare in
modo che il Type Library editor applichi le modifiche al file di implementazione
facendo clic sul pulsante Refresh sulla barra strumenti.
Aggiunta di propriet e metodi ad una interface o dispinterface
Per aggiungere propriet o metodi a una interface o dispinterface:
1 Selezionare linterfaccia, e scegliere licona delle propriet o dei metodi dalla barra
strumenti. Se si sta aggiungendo una propriet, si pu fare clic direttamente
sullicona della propriet per creare una propriet di lettura/scrittura (con un
getter e un setter), oppure fare clic sulla freccia verso il basso per visualizzare un
menu di tipi della propriet.
Viene richiesta laggiunta di un nome; ci fatto, i membri del metodo per accesso
alla propriet o il membro del metodo vengono aggiunti al pannello Object list.
2 Scrivere un nome per il membro.
39-16 G u i d a a l l a p r o g r a mma z i o n e
T y p e L i b r a r y e d i t o r
Il nuovo membro contiene impostazioni predefinite, visibili sulle pagine Attributes,
Parameters e Flags, che possibile modificare per adattarle al membro. Per esempio,
potrebbe essere necessario assegnare un tipo a una propriet usando la pagina
Attributes. Se si sta aggiungendo un metodo, potrebbe essere necessario specificarne
i suoi parametri sulla pagina Parameters.
Come metodo alternativo, possibile aggiungere propriet e metodi scrivendo
direttamente nella pagina Text e usando la sintassi IDL. Per esempio, nella pagina
Text di uninterfaccia possibile scrivere la seguente dichiarazione di propriet:
,
.~~.11.,
cs,
.i,
ci.i
xcc.c.>ccc,
C r e a z i o n e d i c l i e n t C O M 40-9
C o n t r o l l o d i u n o g g e t t o i m p o r t a t o
In questo esempio, il gestore di evento assegna il workbook a un componente
ExcelWorkbook, (ExcelWorkbook1). Lesempio mostra come connettere un wrapper
di componente a uninterfaccia esistente utilizzando il metodo ConnectTo. Il metodo
ConnectTo viene aggiunto al codice generato per il wrapper del componente.
I server che hanno un oggetto applicazione espongono su quelloggetto un metodo
Quit per consentire ai client di terminare la connessione. Quit espone di solito
funzionalit che sono equivalenti allutilizzo del menu File per terminare
lapplicazione. Il codice per chiamare il metodo Quit viene generato nel metodo
Disconnect del componente. Se possibile chiamare il metodo Quit senza parametri, il
wrapper del componente ha anche una propriet AutoQuit. AutoQuit fa in modo che
il controller chiami il metodo Quit nel momento in cui il componente viene liberato.
Se si vuole effettuare la disconnessione in un altro momento, oppure se il metodo
Quit richiede dei parametri, necessario chiamarlo esplicitamente. Quit appare nel
componente generato come un metodo pubblico.
Uso di controlli ActiveX associati ai dati
Quando si utilizza un controllo ActiveX associato ai dati in unapplicazione
C++Builder, necessario associarlo al database di cui ne rappresenta i dati. Per fare
ci, necessario un componente data source, esattamente come necessario un data
source quando si utilizza un qualsiasi controllo VCL associato ai dati.
Dopo aver collocato il controllo ActiveX associato ai dati nel Form Designer,
assegnare la propriet DataSource alla sorgente dati che rappresenta il dataset
desiderato. Dopo aver specificato un data source, si pu utilizzare il DataBindings
editor per collegare la propriet relativa ai dati di un controllo a un campo del
dataset.
Per visualizzare il Data Bindings editor, fare clic destro sul controllo ActiveX
associato ai dati in modo da visualizzare un elenco di opzioni. Oltre alle opzioni di
base, apparir anche la voce aggiuntiva Data Bindings. Selezionare lelemento per
visualizzare il Data Bindings editor che elenca i nomi dei campi nel dataset e le
propriet collegabili del controllo ActiveX.
Per collegare un campo a una propriet:
1 Nella finestra di dialogo Data Bindings Editor di ActiveX, selezionare un campo e
un nome di propriet.
Field Name elenca i campi del database e Property Name elenca le propriet del
controllo ActiveX che possono essere collegate a un campo del database. Il dispID
della propriet racchiuso tra parentesi, ad esempio Value(12).
2 Fare clic su Bind e poi su OK.
_
Se nella finestra di dialogo non appare alcuna propriet, significa che il controllo
ActiveX non contiene propriet associate ai dati. Per attivare lassociazione di dati
semplici per una propriet di un controllo ActiveX, utilizzare la libreria di tipi come
descritto in Attivazione dellassociazione di dati semplici con la libreria di tipi a
pagina 43-12.
40-10 G u i d a a l l a p r o g r a mma z i o n e
C o n t r o l l o d i u n o g g e t t o i m p o r t a t o
Lesempio seguente illustra passo passo lutilizzo di un controllo ActiveX associato ai
dati nel contenitore di C++Builder. Questo esempio utilizza il controllo Calendar di
Microsoft che disponibile se sul sistema installato Microsoft Office 97.
1 Dal menu principale di Delphi, scegliere lopzione Component|Import ActiveX
Control.
2 Selezionare un controllo ActiveX associato ai dati, come Microsoft Calendar
control 8.0 e modificare il nome della classe in TCalendarAXControl, quindi fare clic
su Install.
3 Nella finestra di dialogo Install, fare clic su OK per aggiungere il controllo al
package utente predefinito rendendo cos il controllo disponibile sulla Palette.
4 Scegliere il comando Close All e, successivamente, File|New|Application per
iniziare una nuova applicazione.
5 Dalla pagina ActiveX della Component Palette, trascinare sulla scheda un oggetto
TCalendarAXControl che stato appena aggiunto alla Palette.
6 Trascinare sulla scheda un oggetto DataSource dalla pagina Data Access e un
oggetto Table dalla pagina BDE.
7 Selezionare loggetto DataSource e impostarne la propriet DataSet a Table1.
8 Selezionare loggetto Table e fare quanto segue:
Impostare la propriet DatabaseName a BCDEMOS
Impostare la propriet TableName a EMPLOYEE.DB
Impostate la propriet Active a true
9 Selezionare loggetto TCalendarAXControl e impostarne la propriet DataSource a
DataSource1.
10 Selezionare loggetto TCalendarAXControl, fare clic destro e scegliere il comando
Data Bindings per richiamare il Data Bindings Editor del controllo ActiveX.
Field Name elenca tutti i campi nel database attivo. Property Name elenca quelle
propriet del Controllo ActiveX che sono collegabili ad un campo del database. Il
dispID della propriet racchiuso tra parentesi.
11 Selezionare il campo HireDate e il nome della propriet Value, scegliere Bind,
quindi fare clic su OK.
Il nome di campo e la propriet risultano ora collegati.
12 Dalla pagina Data Controls, trascinare sulla scheda un oggetto DBGrid e
impostarne la propriet DataSource a DataSource1.
13 Dalla pagina Data Controls, trascinare sulla scheda un oggetto DBNavigator e
impostarne la propriet DataSource a DataSource1.
14 Eseguire lapplicazione.
15 Collaudare lapplicazione come segue:
C r e a z i o n e d i c l i e n t C O M 40-11
C o n t r o l l o d i u n o g g e t t o i m p o r t a t o
Col campo HireDate visualizzato nelloggetto DBGrid, spostarsi nel database
utilizzando loggetto Navigator. Le date nel controllo ActiveX dovrebbero
modificarsi man mano che ci si sposta nel database.
Esempio: stampa di un documento con Microsoft Word
La seguenti fasi mostrano come creare un controller Automation che stampa un
documento usando Microsoft Word 8 da Office 97.
Prima di iniziare: Creare un nuovo progetto costituito da una scheda, da un pulsante
e da una finestra di dialogo per lapertura di file (TOpenDialog). Questi controlli
costituiscono il controller Automation.
Fase 1: preparazione di C++Builder per lesempio
Per comodit, C++Builder include nella Component Palette diversi server molto
comuni, come Word, Excel e PowerPoint. Per dimostrare come si importa un server
si utilizzer Word.Poich gi incluso nella Component palette, la prima cosa da fare
sar quella di rimuovere il package che contiene Word in modo che sia possibile
installarlo nuovamente nella tavolozza. La Fase 4 descrive come riportare la
Component palette allo stato originario.
Per rimuovere Word dalla Component Palette:
1 Selezionare il comando Component|Install packages.
2 Fare clic su Borland C++Builder COM Server Components Sample Package e
scegliere Remove.
La pagina Servers della Component palette non conterr pi nessuno dei server
forniti con C++Builder. (Se non sono stati importati altri server, anche la pagina
Servers sar rimossa.)
Fase 2: importazione della libreria di tipi di Word
Per importare la libreria di tipi di Word:
1 Scegliere il comando Project|Import Type Library.
2 Nella finestra di dialogo Import Type Library,
1 Selezionare Microsoft Office 8.0 Object Library.
Se Word (Versione 8) non incluso nellelenco, fare clic sul pulsante Add,
passare alla directory Programmi\Microsoft Office\Office, selezionare il file
della libreria di tipi di Word, MSWord8.olb, fare clic su Add e selezionare
finalmente Word (Versione 8) dallelenco.
2 Per lopzione Palette Page, selezionare Servers.
3 Fare clic su Install.
Apparir la finestra di dialogo Install. Selezionare la pagina Into New Packages
e scrivere WordExample per creare un nuovo package che conterr la libreria di
tipi selezionata.
40-12 G u i d a a l l a p r o g r a mma z i o n e
C o n t r o l l o d i u n o g g e t t o i m p o r t a t o
3 Selezionare la pagina Servers della Component Palette, selezionare
WordApplication e collocarlo su una scheda.
4 Scrivere un gestore di evento per loggetto pulsante come descritto nel paragrafo
successivo.
Fase 3: uso di un oggetto interfaccia VTable o dispatch per il controllo di
Microsoft Word
Per controllare Microsoft Word, possibile usare uno dei due oggetti seguenti.
Uso di un oggetto interfaccia VTable
Trascinando sulla scheda unistanza delloggetto WordApplication sar possibile
accedere in modo molto semplice al controllo utilizzando un oggetto interfaccia
VTable. Sar sufficiente chiamare i metodi della classe appena creata. Nel caso di
Word, questa la classe TWordApplication.
1 Selezionare il pulsante, fare doppio clic sul suo gestore di eventi OnClick e scrivere
il seguente codice di gestione dellevento:
veIi __?aatcaII .c.ccc .c.c
I? ,ci>xccc
ii c.i.c ,ci>c.i.cc_s,
.~,,ci>c.cs>,cc.i.c,
.~,,ci>~ccc.c>.,
. ,ci>xccc
ii c.i.c ,ci>c.i.cc_s,
_~,,cis, ..,
....L_.~,,ci,
C r e a z i o n e d i c l i e n t C O M 40-13
C o n t r o l l o d i u n o g g e t t o i m p o r t a t o
c.css, .cs ..>c.cs,
.cs>,cc.i.c,
_c.cs, .~ccc ..>~ccc.c,
.~ccc>.,
..>_,
tt,
catcaxcc, c
tetata ._,
,
..-L.. .L.,sc_i,. ic
tt,
catcaxcc, c
tetata ._,
,
Di solito, possibile implementare questi metodi semplicemente delegandoli al
controllo VCL associato, a cui si pu accedere utilizzando il membro m_VclCtl della
classe del wrapper:
..-L.. .L.,c_i,. ic
C r e a z i o n e d i u n c o n t r o l l o A c t i v e X 43-11
P e r s o n a l i z z a z i o n e d e l l i n t e r f a c c i a d e l c o n t r o l l o A c t i v e X
tt,
ic .c.._c>i,,,
catcaxcc, c
tetata c.cssicc_s, LL_L.,
tetata ._,
,
..-L.. .L.,sc_i,. ic
tt,
._c>i, ~s.ic,
catcaxcc, c
tetata ._,
,
In alcuni casi, potrebbe essere necessario aggiungere del codice per convertire i tipi di
dati COM in tipi C++ nativi. Lesempio precedente gestisce questa conversione di
tipo.
Aggiunta di eventi
Il controllo ActiveX pu scatenare eventi nel suo contenitore nello stesso modo in cui
un oggetto Automation scatena eventi nei client. Questo meccanismo descritto in
Esposizione di eventi ai client a pagina 41-11.
Se il controllo VCL utilizzato come base del controllo ActiveX non ha alcun evento
pubblicato, i wizard aggiungono automaticamente il supporto necessario per gestire
un elenco di eventi del client da convogliare alla classe del wrapper ActiveX e
definiscono la dispinterface uscente che i client devono implementare per rispondere
agli eventi.
Per scatenare eventi sul contenitore, la classe del wrapper ActiveX deve
implementare un gestore di evento per levento sulloggetto VCL. Questo gestore di
evento chiama il metodo Fire_EventName, implementato dalla classe
TEvents_CoClassName definita nella unit _TLB:
veIi __?aatcaII .L.,c.csscccc .c.c, caat c
aaett c.,c,
c.,c aaettc,
c_c.cssc.,c,
c aaettc.,c,
,
Si dovr in seguito assegnare questo gestore di evento al controllo VCL in modo che
venga chiamato al verificarsi dellevento. Per fare ci, aggiungere levento al metodo
43-12 G u i d a a l l a p r o g r a mma z i o n e
P e r s o n a l i z z a z i o n e d e l l i n t e r f a c c i a d e l c o n t r o l l o A c t i v e X
InitializeControl che appare nella dichiarazione della classe del wrapper (nella header
della unit di implementazione):
veIi Li.c
._c>c. c.c,
._c>c.css c.cssc,
sc._ci c.,c,
ceaat L..L .s,. , s s c .s,ic . . c .iic. ,,c
I? cccs..s,. ._~. is. cic . c.s .
c , . c.s ., cicc c .c,css .cssic
tetata,
c.,c sc._cic,
c_c.cssc.,c, s ..i.s c c.css cc .c c cic
c sc._cic.,c,
,
Il wrapper ActiveX deve anche notificare al contenitore se i dati hanno subito
modifiche. Per fare ci, non appena i valori del controllo di editing vengono
modificati, chiama il metodo FireOnChanged (ereditato da TVclComControl).
FireOnChanged notifica al controllo che c qualcosa di diverso. Quando i dati nel
controllo vengono modificati, il contenitore pu mettere il dataset associato in
modalit modifica. FireOnChanged consente anche la modifica in tempo reale dei
campi di dati. Il codice seguente mostra il gestore di evento OnChange modificato:
veIi __?aatcaII .~.ic.L.,iccccc .c.c
Default Bindable Indica la singola propriet bindable che meglio rappresenta
loggetto. Le propriet che hanno lattributo default bindable
devono avere anche lattributo bindable. Non possibile
specificare lattributo su pi di una propriet di una dispinterface.
Immediate Bindable Consente alle singole propriet bindable su una scheda di
specificare questo comportamento. Quando questo bit risulta
impostato, tutte le modifiche verranno notificate. Affinch questo
bit attributo abbia effetto, necessario impostare i bit di attributo
bindable e request edit.
Attributo Descrizione
43-14 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n a p a g i n a d i p r o p r i e t p e r u n c o n t r o l l o A c t i v e X
L,.is.>cx ccccc.,cc'..is.',
43-16 G u i d a a l l a p r o g r a mma z i o n e
R e g i s t r a z i o n e d i u n c o n t r o l l o A c t i v e X
_
anche possibile scrivere una pagina di propriet che rappresenti pi di un controllo
ActiveX. In questo caso, non si utilizza la propriet OleObject. Invece, si deve scorrere
in sequenza un elenco delle interfacce, che conservato nella propriet OleObjects.
Aggiornamento delloggetto
Il metodo UpdateObject viene chiamato quando lutente apporta dei cambiamenti ai
controlli sulla pagina di propriet. Per impostare le propriet del controllo ActiveX ai
loro nuovi valori, occorre aggiungere del codice al metodo UpdateObject.
Ancora una volta si utilizzer la propriet OleObject per accedere al controllo
ActiveX.
Per esempio, il codice seguente imposta la propriet EditMask del controllo ActiveX
usando il valore del controllo della casella di testo della pagina di propriet
(InputMask):
veIi __?aatcaII .,c.ic,.iccccveIi
,.ic cccc .. c
ccccc.,c.c.c.>'..is.', .c.L,.is>cx,,
. s.c sc. . c c
.is,
L~.ic>LsicLc.'.iic', .is,
j
Utilizzare il metodo Get_ObjectContext di TMtsDll al posto della macro
GetObjectContext definita in comsvcs.h. Questultima non definita negli header della
VCL per evitare la ridefinizione del metodo GetObjectContext di TDatabase.
_
Il membro m_spObjectContext viene assegnato utilizzando il metodo TMtsDll, che
funziona sia in ambiente MTS sia in ambiente COM+.
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-5
G e s t i o n e d e l l e r i s o r s e
Attivazione just-in-time
La possibilit per un oggetto di essere disattivato e riattivato mentre i client
contengono riferimenti ad esso, viene chiamata attivazione just-in-time. Dal punto
di vista del client, solo una singola istanza delloggetto esiste dal momento in cui il
client lo crea al momento in cui lo rilascia definitivamente. In realt, possibile che
loggetto sia stato disattivato e riattivato molte volte. Avendo disattivato gli oggetti, i
client possono contenere riferimenti alloggetto per un tempo illimitato senza
influenzare le risorse di sistema. Quando un oggetto viene disattivato, ne rilascia
tutte le risorse. Per esempio, se si disattiva un oggetto, potrebbe rilasciare la sua
connessione al database, consentendo cos ad altri oggetti di utilizzarlo.
Un oggetto transazionale viene creato in un stato disattivato e diviene attivo alla
ricezione di una richiesta del client. Quando si crea un oggetto transazionale, viene
anche creato il corrispondente oggetto contesto. Questo oggetto contesto esiste per
tutta la durata delloggetto transazionale, attraverso uno o pi cicli di riattivazione.
Loggetto contesto, a cui si accede tramite linterfaccia IObjectContext, tiene traccio
delloggetto durante la disattivazione e coordina le transazioni.
Gli oggetti transazionali vengono disattivati non appena possibile farlo in tutta
sicurezza. Questo comportamento chiamato disattivazione as-soon-as-possible.
Un oggetto transazionale viene disattivato quando si verifica una delle seguenti
condizioni:
Loggetto richiede la disattivazione con SetComplete o SetAbort: Un oggetto
chiama il metodo IObjectContext SetComplete quando ha completato con successo il
suo lavoro e non occorre salvare il suo stato interno per la successiva chiamata da
parte del client. Un oggetto chiama SetAbort per indicare che non pu completare
con successo il suo lavoro e che il suo stato non ha bisogno di essere salvato. Cio,
lo stato delloggetto ritorna alla situazione in cui si trovava prima della
transazione corrente. Spesso gli oggetti possono essere progettati per essere senza
stato, questo vuol dire che vengono disattivati al ritorno da ogni metodo.
Una transazione viene effettuata o abbandonata: Quando la transazione di un
oggetto viene effettuata o abbandonata, loggetto viene disattivato. Di questi
oggetti disattivati, gli unici che continuano ad esistere sono quelli che sono oggetto
di riferimento da parte dei client allesterno della transazione. Le successive
chiamate a questi oggetti li riattivano, consentendo la loro esecuzione nella nuova
transazione.
Lultimo client rilascia loggetto: Naturalmente, quando un client rilascia
loggetto, questo viene disattivato, ed anche il contesto delloggetto viene
rilasciato.
_
Se si installa loggetto transazionale in ambiente COM+ dallIDE, possibile
specificare se loggetto supporta lattivazione just-in-time utilizzando la pagina
COM+ del Type Library editor. sufficiente selezionare loggetto (CoClass) nel Type
Library editor, andare alla pagina COM+, e selezionare o deselezionare la casella Just
In Time Activation. Altrimenti, un amministratore di sistema deve specificare questo
attributo utilizzando COM+ Component Manager o MTS Explorer.
(Lamministratore di sistema pu anche ridefinire qualsiasi impostazione specifica
utilizzando il Type Library editor.)
44-6 G u i d a a l l a p r o g r a mma z i o n e
G e s t i o n e d e l l e r i s o r s e
Condivisione delle risorse
Dal momento che le risorse inattive di sistema vengono liberate durante la
disattivazione, le risorse liberate sono disponibili per gli altri oggetti server. Per
esempio, una connessione al database che non pi utilizzata da un oggetto server
pu essere riutilizzata da un altro client. Questa tecnica viene chiamata condivisione
delle risorse. Le risorse condivise sono gestite da un distributore di risorse.
Un distributore di risorse mette in cache le risorse, in modo che tutti gli oggetti
transazionali installati possano condividerle. Il distributore di risorse gestisce anche
le informazioni di stato non permanenti condivise. In questo senso, i distributori di
risorse sono simili ai manager di risorse degli SQL Server, ma senza la garanzia di
durabilit.
Quando si scrive un oggetto transazionale, possibile sfruttare i due tipi di
distributori di risorse gi forniti:
Distributori di risorse di database
Shared Property manager
Prima che altri oggetti possano utilizzare le risorse condivise, necessario rilasciarle
esplicitamente.
Distributori di risorse di database
Lapertura e la chiusura di connessioni a un database possono utilizzare molto
tempo. Se si utilizza un distributore di risorse per raccogliere le connessioni al
database, loggetto pu riutilizzare le connessioni al database esistenti invece di
crearne di nuove. Per esempio, se in unapplicazione di manutenzione del cliente
sono attivi un componente per la consultazione del database e un componente per
laggiornamento del database, possibile installare insieme quei componenti, in
modo che possano condividere le connessioni al database. In questo modo
lapplicazione non avr bisogno di molte connessioni e le nuove istanze degli oggetto
potranno accedere pi rapidamente ai dati utilizzando una connessione gi aperta
ma non utilizzata.
Se si stanno utilizzando componenti BDE per connettersi ai dati, il distributore di
risorse Borland Database Engine (BDE). Questo distributore di risorse
disponibile solo quando loggetto transazionale installato con MTS. Per attivare
il distributore di risorse, utilizzare BDE Administrator per impostare a ON il
parametro MTS POOLING nellarea di configurazione System/Init.
Se si stano utilizzando componenti database di ADO per connettersi ai dati, il
distributore di risorse fornito da ADO.
_
Se si stanno utilizzando componenti InterbaseExpress per laccesso al database, non
esiste alcun sistema precostituito per la condivisione delle risorse.
Per i moduli dati transazionali remoti, le connessioni vengono automaticamente
impostate in base alle transazioni di un oggetto, e il distributore di risorse pu
ricuperare e riutilizzare automaticamente le connessioni.
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-7
G e s t i o n e d e l l e r i s o r s e
Shared property manager
Lo Shared Property Manager un distributore di risorse che possibile utilizzare per
condividere lo stato tra pi oggetti allinterno di un processo del server. Utilizzando
Shared Property manager, si evita laggiunta allapplicazione di molto codice per
gestire i dati condivisi: Shared Property manager li gestisce automaticamente
implementando blocchi e semafori in modo da proteggere le propriet condivise da
accessi simultanei. Shared Property manager elimina le collisioni sui nomi mettendo
a disposizione gruppi di propriet condivise che stabiliscono spazi di nome univoci
per le propriet condivise in essi contenute.
Per utilizzare la risorsa dello Shared Property manager, si deve per prima cosa usare
la funzione helper CreateSharedPropertyGroup per creare un gruppo di propriet
condivise. Poi si possono scrivere tutte le propriet in quel gruppo e leggerle da quel
gruppo. Utilizzando un gruppo di propriet condivise, le informazioni di stato
vengono salvate tutte le volte che si disattiva un oggetto transazionale. Inoltre, le
informazioni di stato possono essere condivise tra tutti gli oggetti transazionali
installati nello stesso package MTS o nella stessa applicazione COM+. possibile
installare oggetti transazionali in un package secondo la modalit descritta nel
paragrafo Installazione di oggetti transazionali a pagina 44-29.
Affinch gli oggetti condividano lo stato, devono essere eseguiti tutti nello stesso
processo. Se si desidera che istanze di componenti diversi condividano propriet,
necessario installarli nello stesso package MTS o nella stessa applicazione COM+.
Poich c il rischio che gli amministratori spostino componenti da un package a un
altro, pi sicuro limitare luso di un gruppo di propriet condivise a istanze di
oggetti definiti nella stessa DLL o nello stesso EXE.
Gli oggetti che condividono propriet devono avere lo stesso attributo di attivazione.
Se due componenti nello stesso package hanno attributi di attivazione differenti,
normalmente non potranno condividere le propriet. Per esempio, se un componente
configurato per funzionare nel processo di un client e laltro configurato per
funzionare in un processo del server, i loro oggetti di solito saranno eseguiti in
processi diversi, anche se sono inclusi nello stesso package MTS o nella stessa
applicazione COM+.
Lesempio seguente mostra come aggiungere del codice per supportare lo Shared
Property manager in un oggetto transazionale:
Esempio: Condivisione di propriet tra istanze di un oggetto transazionale
Questo esempio crea un gruppo di propriet di nome MyGroup per contenere le
propriet da condividere tra oggetti e istanze di oggetti. In questo esempio c una
propriet Counter che viene condivisa. Lesempio utilizza la funzione helper
CreateSharedPropertyGroup per creare il manager del gruppo di propriet e il gruppo
di propriet, e poi utilizza il metodo CreateProperty delloggetto Group per creare una
propriet di nome Counter.
Per ottenere il valore di una propriet, si utilizza il metodo PropertyByName
delloggetto Group, come mostrato di seguito. anche possibile utilizzare il metodo
PropertyByPosition.
-IacIaie '.cc_-'
-ie?Iae _.._._L.
44-8 G u i d a a l l a p r o g r a mma z i o n e
G e s t i o n e d e l l e r i s o r s e
-IacIaie c.s,>
cIaaa ~_._~ .ic..,cxi.,cL.,
pabIIc .cccx..cci...c>,
pabIIc .iss.ic..,cxi.,cL.,, .L_.ic..,cxi.,c>,
pabIIc Lccc,
pabIIc Ls,icL.,L.ic..,cxi.,c, LL_L.ic..,cxi.,c, LL_.cc>
ptIvate
L.ic..,c,.iic .iic,
L.ic..,c, .,
L.ic..,c c,
pabIIc
.ic..,cxi.,cL.,
~_-~L._.~,i.c,
~_.L'.cc.ic..,cxi.,c',
~_.L.L.'',
atatIc -. L.~.L ,.iccs ccsc
,c...cccsi.ic..,cxi.,cL.,>
cccccc.L, c.L, ccsc,,
tetata cc,.iccsccsc,
~_._~~~.ic..,cxi.,cL.,
L._._.~..ic..,cxi.,cL.,
._L.~_.L.ic..,cxi.,c
._L.~_.Lccc
._L.~_.Ls,ic
._._.~.
pabIIc
..-~cic,
..-Lcc.cc,
..-_, ic.c.,
..-_veIi, cicic,
..Lccccx> ._s,ccccx,
pabIIc
,
.-~...~..L.. L.,c.ci . .ic..,cxi.,cL.,
-IacIaie c>
-ptaea .s,
-IacIaie '.-~...~..L..-'
..-L.. .ic..,cxi.,cL.,~cic
atatIc .s .s,
-. _~L,
.sc_ccccx._s,ccccx,
I? .
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-9
G e s t i o n e d e l l e r i s o r s e
c>,_icii,
tetata ._,
tetata ,
..-L.._ .ic..,cxi.,cL.,ic.c.
tetata ~.,
..-L.._. .ic..,cxi.,cL.,cicic
.>ccisc,
.iic>ccisc,
._s,ccccxccisc,
..-L.. .ic..,cxi.,cL.,Lcc.cc
tt,
ii c.,,
c>c_icc.,,
c.,Iatc.,-,,
c>,_icc.,,
catcaxcc, c
tetata ._,
,
Rilascio delle risorse
Il programmatore si deve far carico di rilasciare le risorse di un oggetto. Di solito,
questa operazione viene effettuata chiamando i metodi IObjectContext, SetComplete e
SetAbort dopo aver soddisfatto le richieste di servizio dei client. Questi metodi
rilasciano le risorse allocate dal distributore di risorse.
Contemporaneamente occorre rilasciare i riferimenti a tutte le altre risorse, inclusi i
riferimenti ad altri oggetti (compresi gli oggetti transazionali e gli oggetti contestuali)
e la memoria occupata da tutte le istanze del componente (liberando il componente).
44-10 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o d e l l e t r a n s a z i o n i M T S e C O M +
Lunico caso in cui non necessario includere queste chiamate quando si desidera
conservare lo stato tra le chiamate del client. Per informazioni dettagliate, consultare
Oggetti con e senza stato a pagina 44-13.
Condivisione degli oggetti
Esattamente come possibile costituire un fondo di risorse, in ambiente COM+
possibile costituire un fondo di oggetti. Al momento della disattivazione di un
oggetto, COM+ chiama il metodo CanBePooled dellinterfaccia IObjectControl, il quale
indica se loggetto pu essere condiviso per il riutilizzo. Se CanBePooled restituisce
true, anzich essere distrutto al momento della disattivazione, loggetto viene
spostato fra quelli che possono essere condivisi. Esso rimane nel fondo comune degli
oggetti per un periodo di tempo specificato, durante il quale resta disponibile per
lutilizzo da parte di un qualsiasi client che ne faccia richiesta. Solo quando il fondo
comune di oggetti vuoto viene creata una nuova istanza delloggetto. Gli oggetti
che restituiscono false o che non supportano linterfaccia IObjectControl al momento
della disattivazione vengono distrutti.
La condivisione degli oggetti non disponibile in ambiente MTS. MTS chiama
CanBePooled come descritto, ma non ha luogo alcuna condivisione. A causa di ci,
quando il wizard crea gli oggetti transazionali, il metodo CanBePooled generato
restituisce sempre false. Se loggetto sar eseguito solamente in ambiente COM+ e si
vuole consentire la costituzione di un fondo di oggetti, si deve individuare questo
metodo nella unit di implementazione e modificarlo in modo che restituisca true.
Anche se il metodo CanBePooled di un oggetto restituisce true, pu essere configurato
in odo che COM+ non sposti nel fondo comune degli oggetti. Se si installa loggetto
transazionale in ambiente COM+ dallIDE, utilizzando la pagina COM+ del Type
Library editor, possibile specificare se COM+ pu tentare di includere loggetto nel
fondo comune. sufficiente selezionare loggetto (la CoClass) nelleditor della
libreria di tipi, andare alla pagina COM+, e selezionare o deselezionare la casella
Object Pooling. Altrimenti, un amministratore di sistema deve specificare questo
attributo utilizzando COM+ Component Manager o MTS Explorer.
Analogamente, possibile configurare per quanto tempo un oggetto disattivato pu
restare nel fondo comune degli oggetti prima di essere liberato. Se lo si sta
installando dallIDE, possibile specificare questa durata utilizzando limpostazione
Creation TimeOut disponibile sulla pagina COM+ delleditor della libreria di tipi. In
alternativa, questo attributo pu essere specificato da un amministratore di sistema
utilizzando COM+ Component Manager o MTS Explorer.
Supporto delle transazioni MTS e COM+
Il supporto delle transazioni, che d il nome agli oggetti transazionali, consente di
raggruppare azioni in transazioni. Per esempio, in unapplicazione di record clinici,
se ci fosse un componente Transfer per trasferire i record da un medico allaltro, si
potrebbero includere i metodi Add e Delete nella stessa transazione. In questo modo,
o il trasferimento avverrebbe senza problemi oppure il tutto verrebbe riportato allo
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-11
S u p p o r t o d e l l e t r a n s a z i o n i M T S e C O M +
stato precedente. Le transazioni semplificano il recupero degli errori per le
applicazioni che devono accedere a pi database.
Le transazioni assicurano che:
Tutti gli aggiornamenti di una singola transazione vengono effettuati oppure
vengono abbandonati e riportati al loro stato precedente. Questa operazione viene
detta atomicit.
Una transazione una trasformazione corretta dello stato di un sistema, che
preserva gli invarianti di stato. Questa operazione viene detta consistenza.
Le transazioni concorrenti non vedono i rispettivi risultati parziali e non
completati, il che potrebbe creare incompatibilit nello stato dellapplicazione.
Questa operazione viene detta isolamento. I gestori delle risorse usano protocolli
di sincronizzazione basati sulle transazioni per isolare il lavoro non completato
delle transazioni attive.
Gli aggiornamenti effettuati alle risorse gestite (come i record di un database)
sopravvivono ai guasti, compresi i problemi di comunicazione, di processo e del
sistema server. Questa operazione viene detta durabilit. La registrazione
transazionale consente di recuperare lo stato durevole dopo un guasto dei
supporti di memorizzazione su disco.
Un oggetto contesto associato ad un oggetto indica se loggetto eseguito allinterno
di una transazione e, in tal caso, lidentit della transazione. Quando un oggetto fa
parte di una transazione, i servizi che i manager di risorse e i distributori di risorse
compiono per suo conto vengono eseguite anchessi nella stessa transazione. I
distributori di risorse utilizzano loggetto contesto per fornire servizi basati sulla
transazione. Per esempio, quando un oggetto, eseguito allinterno di una transazione,
alloca una connessione al database utilizzando il distributore di risorse ADO o BDE,
la connessione assimilata automaticamente nella transazione. Tutti gli
aggiornamenti al database che utilizzano questa connessione diventano parte della
transazione, e vengono o confermati o annullati.
Le operazioni derivanti da pi oggetti possono essere composti in una singola
transazione. La possibilit per un oggetto di esistere nella propria transazione o di
essere parte di un pi vasto gruppo di oggetti, appartenenti a una singola
transazione, uno dei maggiori vantaggi offerti da MTS e COM+. Essa consente di
utilizzare un oggetto in vari modi, tanto che chi sviluppa applicazioni pu
riutilizzare il codice dellapplicazione in applicazioni diverse senza riscrivere la
logica dellapplicazione. Infatti, gli sviluppatori possono determinare come saranno
utilizzati gli oggetti nelle transazioni al momento dellinstallazione delloggetto
transazionale. Essi possono modificare il comportamento della transazione
semplicemente aggiungendo un oggetto a un package MTS o ad unapplicazione
COM+ differente. Per maggiori informazioni sullinstallazione di oggetti
transazionali, consultare il paragrafo Installazione di oggetti transazionali a
pagina 44-29.
44-12 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o d e l l e t r a n s a z i o n i M T S e C O M +
Attributi di transazione
Ciascun oggetto transazionale ha un attributo di transazione che viene registrato nel
catalogo MTS o memorizzato con COM+.
C++Builder consente di impostare lattributo di transazione in fase di progetto
utilizzando il wizard delloggetto transazionale o il Type Library editor.
Ciascun attributo di transazione pu essere impostato con questi parametri:
Impostazione dellattributo di transazione
possibile impostare un attributo di transazione al momento della creazione di un
oggetto transazionale utilizzando Transactional Object wizard.
anche possibile impostare (o modificare) lattributo di transazione utilizzando il
Type Library editor. Per modificare lattributo di transazione con il Type Library
editor:
Requires a
transaction
Gli oggetti devono essere eseguiti allinterno del campo dazione di
una transazione. Quando viene creato un nuovo oggetto, il suo
contesto eredita la transazione dal contesto del client. Se il client
non ha un contesto di transazione, ne crea automaticamente uno
nuovo.
Requires a new
transaction
Gli oggetti devono essere eseguiti allinterno delle loro transazioni.
Quando viene creato un nuovo oggetto, una nuova transazione
viene creata automaticamente per loggetto, indipendentemente
dal fatto che il suo client abbia una transazione. Un oggetto non
viene mai eseguito allinterno del campo dazione della
transazione del suo client. Il sistema, invece, crea sempre
transazioni indipendenti per i nuovi oggetti.
Supports
transactions
Gli oggetti possono essere eseguiti allinterno del campo dazione
delle transazioni del loro client. Quando viene creato un nuovo
oggetto, il suo contesto eredita la transazione dal contesto del
client. Questo attributo rende possibile la composizione di pi
oggetti in ununica transazione. Se il client non ha una
transazione, anche il nuovo contesto viene creato senza.
Transactions
Ignored
Gli oggetti non vengono eseguiti nel campo dazione delle transazioni.
Quando si crea un nuovo oggetto, il suo contesto di oggetto viene
creato senza una transazione, indipendentemente da fatto che il
client abbia una transazione. Questa impostazione disponibile
solamente in ambiente COM+.
Does not support
transactions
Il significato di questa impostazione varia, in base al fatto che si
stia installando loggetto in ambiente MTS o COM+. In ambiente
MTS, questa impostazione ha lo stesso significato di Transactions
Ignored in ambiente COM+. In ambiente COM+, non solo il
contesto delloggetto viene creato senza una transazione, ma
questa impostazione impedisce di attivare loggetto se il client ha
una transazione.
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-13
S u p p o r t o d e l l e t r a n s a z i o n i M T S e C O M +
1 Scegliere il comando View|Type Library per attivare il Type Library editor.
2 Selezionare la classe corrispondente alloggetto transazionale.
3 Fare clic sulla pagina COM+ e scegliere lattributo di transazione desiderato.
j
Quando si imposta lattributo di transazione, C++Builder inserisce uno speciale
GUID per lattributo specificato sotto forma di dato custom nella libreria di tipi.
Questo valore non riconosciuto al di fuori di C++Builder. Pertanto, ha un effetto
solamente se si installa loggetto transazionale dallIDE. In alternativa, questo valore
pu essere impostato da un amministratore di sistema utilizzando COM+
Component Manager o MTS Explorer.
_
Quando si modifica lattributo di transazione, se loggetto transazionale gi
installato, occorre prima disinstallarlo e successivamente reinstallarlo. Per eseguire
queste operazioni, utilizzare i comandi Use Run|Install MTS objects o Run|Install
COM+ objects.
Oggetti con e senza stato
Come qualsiasi altro oggetto COM, gli oggetti transazionali possono mantenere lo
stato interno per diverse interazioni con un client. Per esempio, il client potrebbe
impostare un valore di una propriet durante una chiamata, e aspettarsi che quel
valore di propriet rimanga immutato alla chiamata successiva. Tale oggetto detto
essere con stato. Gli oggetti transazionali possono essere anche senza stato, il che
vuol dire che non contengono stati intermedi durante lattesa della chiamata
successiva da parte di un client.
Quando una transazione viene completata o abbandonata, tutti gli oggetti che sono
coinvolti nella transazione vengono disattivati, causando la perdita di qualsiasi stato
acquisito nel corso della transazione. Questa operazione aiuta a garantire
lisolamento della transazione e la coerenza del database; inoltre, libera le risorse del
server affinch siano utilizzate in altre transazioni. Il completamento di una
transazione consente di reclamare le risorse utilizzate da un oggetto al momento
della sua disattivazione. Per informazioni su come controllare quando viene
rilasciato lo stato di una oggetto, consultare la sezione seguente.
Il mantenimento dello stato su un oggetto richiede che loggetto rimanga attivato,
conservando risorse potenzialmente preziose come le connessione ad un database.
Come influenzare la modalit di completamento delle transazioni
Un oggetto transazionale utilizza i metodi di IObjectContext come mostrato nella
tabella seguente per influenzare la modalit di completamento di una transazione.
44-14 G u i d a a l l a p r o g r a mma z i o n e
S u p p o r t o d e l l e t r a n s a z i o n i M T S e C O M +
Questi metodi, insieme allattributo di transazione delloggetto, consentono di
includere uno o pi oggetti in ununica transazione.
Inizio di transazioni
Le transazioni possono essere controllate in tre modi:
Possono essere controllate dal client.
I client possono avere un controllo diretto sulle transazioni utilizzando un oggetto
contesto di transazione (utilizzando linterfaccia ITransactionContext).
Possono essere controllate dal server.
I server possono controllare le transazioni creando esplicitamente per esse un
oggetto contesto. Quando il server crea un oggetto in tal modo, loggetto creato
viene assimilato automaticamente nella transazione corrente.
Le transazioni possono verificarsi automaticamente come risultato dellattributo
di transazione delloggetto.
Tabella 44.1 Metodi IObjectContext per il supporto delle transazioni
Metodo Descrizione
SetComplete Indica che loggetto ha completato con successo le operazioni relative alla
transazione. Loggetto viene disattivato al ritorno dal metodo che prima ha
immesso il contesto. Loggetto viene riattivato alla successiva chiamata che
richiede lesecuzione delloggetto.
SetAbort Indica che il lavoro delloggetto non potr mai essere effettuato e la
transazione dovrebbe essere ripristinata allo stato originale. Loggetto viene
disattivato al ritorno dal metodo che prima ha immesso il contesto. Loggetto
viene riattivato alla successiva chiamata che richiede lesecuzione delloggetto.
EnableCommit Indica che il lavoro delloggetto non necessariamente eseguito, ma che gli
aggiornamenti transazionali possono essere completati nella loro forma
attuale. Utilizzare questo metodo per ritenere lo stato tra pi chiamate
successive di un client, consentendo al contempo il completamento delle
transazioni. Loggetto non viene disattivato finch non chiama SetComplete o
SetAbort.
EnableCommit lo stato predefinito quando un oggetto viene attivato. Questo
si verifica perch un oggetto chiamer sempre SetComplete o SetAbort prima di
ritornare da un metodo, a meno che loggetto non mantenga il suo stato interno
per la chiamata successiva da un client.
DisableCommit Indica che il lavoro delloggetto inconsistente e che non pu essere
completato finch non vengono ricevute ulteriori chiamate del metodo dal
client. Questo metodo deve essere chiamato prima di restituire il controllo al
client per mantenere lo stato tra pi chiamate successive del client
mantenendo attiva al contempo la transazione corrente.
DisableCommit impedisce la disattivazione delloggetto ed il rilascio delle sue
risorse al ritorno da una chiamata a un metodo. Una volta che un oggetto ha
chiamato DisableCommit, se un client cerca di effettuare la transazione prima
che loggetto abbia chiamato EnableCommit o SetComplete, la transazione
viene abbandonata.
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-15
S u p p o r t o d e l l e t r a n s a z i o n i M T S e C O M +
Gli oggetti transazionali possono essere dichiarati in modo che i rispettivi oggetti
siano sempre eseguiti allinterno di una transazione, indipendentemente da come
gli oggetti sono stati creati. In questo modo, gli oggetti non devono includere
alcuna logica per gestire le transazioni. Questa caratteristica riduce anche il carico
sulle applicazioni client. I client non dovranno iniziare una transazione
semplicemente perch il componente che stanno utilizzando lo richiede.
Impostazione di un oggetto transazionale sul lato client
Unapplicazione basata su client pu controllare il contesto della transazione tramite
linterfaccia ITransactionContextEx. Lesempio di codice che segue mostra come
unapplicazione client utilizza CreateTransactionContextEx per creare il contesto della
transazione. Questo metodo restituisce uninterfaccia per questo oggetto.
-IacIaie c.s,>
Iat .iIat ic, caat i,
ii .iicisc 'i.c',
ii cc. '.ii',
ii .i,
.s_cc,.icii.iicisc, cc., .i,
.i .>.. .>~c,
eIae
tetata ,
I? ._s,ccccx>LsLisic
.Lisic.ccxi.,c c,
._s,ccccx>cicLsicc.L_isic.ccxi.,c,
LL_Lisic.ccxi.,c, veIic,
c>isiccx.isc,
i.. .ii icccss c.c cc .ii_icccss_scccc.c. cc. s
i .,c.cc. ,icc.c
.ii_icccss_scccc.c. ._s,ccccx>icc..
._s,ccccx>sicc..,
eIae
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-17
S i c u r e z z a b a s a t a s u l r u o l o
Durata della transazione
La durata della transazione imposta per quanto tempo (in secondi) pu rimanere
attiva una transazione. Il sistema annulla automaticamente le transazioni che
risultano ancora attive alla scadenza di tale intervallo temporale. Per impostazione
predefinita, il valore della durata 60 secondi. possibile disattivare la durata delle
transazioni specificando un valore 0, il che utile durante il debug degli oggetti
transazionali.
Per impostare il valore di time-out sul computer:
1 In MTS Explorer o in COM+ Component Manager, selezionare Computer, My
Computer.
Per impostazione predefinita, My Computer corrisponde al computer locale.
2 Fare clic con il tasto destro e scegliere Properties e quindi la pagina Options.
La pagina Options viene usata per impostare la propriet di time-out della
transazione del computer.
3 Cambiare il valore di time-out in 0 per disattivare la durata delle transazioni.
4 Fare clic su OK per salvare limpostazione.
Per ulteriori informazioni sul debug di applicazioni MTS, consultare Debug e
collaudo di oggetti transazionali a pagina 44-28.
Sicurezza basata sul ruolo
Attualmente MTS e COM+ forniscono la sicurezza basata sul ruolo, che prevede
appunto lassegnazione di un ruolo ad un gruppo logico di utenti. Per esempio,
unapplicazione di informazioni mediche potrebbe definire i ruoli dei medici, dei
radiologi e dei pazienti.
Si deve definire lautorizzazione per ciascun oggetto e interfaccia assegnando i ruoli.
Per esempio, nellapplicazione per i medici, solo il medico pu essere autorizzato a
vedere tutti i record clinici, mentre il radiologo pu vedere solo le radiografie e i
pazienti possono vedere solo i propri record.
Normalmente, i ruoli vengono definiti durante lo sviluppo dellapplicazione e
vengono assegnati a ciascun package MTS o applicazione COM+. Questi ruoli
vengono quindi assegnati agli specifici utenti quando lapplicazione viene
distribuita. Gli amministratori possono configurare i ruoli usando MTS Explorer o
COM+ Component Manager.
Se si vuole controllare laccesso per bloccare il codice invece dellintero oggetto,
possibile introdurre una sicurezza ancora pi mirata utilizzando il metodo
IsCallerInRole di IObjectContext. Tale metodo funziona sole se la sicurezza attivata,
cosa che pu essere controllata chiamando il metodo IsSecurityEnabled di
IObjectContext. Ad esempio:
I? ._s,ccccxLs.ccicc. ccc. . scc s cicc.
44-18 G u i d a a l l a p r o g r a mma z i o n e
P a n o r a m i c a s u l l a c r e a z i o n e d i o g g e t t i t r a n s a z i o n a l i
I? ._s,ccccxLsicLc'.sci' ccc. cics c
L. i ,sci, . s.c i,,,ic cc
eIae
cxccc c ci .i
_
Per le applicazioni che necessitano di una sicurezza pi forte, gli oggetti contesto
implementano linterfaccia ISecurityProperty, i cui metodi consentono il reperimento
dellidentificatore di sicurezza di Window (SID) del chiamante diretto e del creatore
delloggetto, oltre che del SID dei client che stanno utilizzando loggetto.
Panoramica sulla creazione di oggetti transazionali
Il processo di creazione di un oggetto transazionale il seguente:
1 1 Usare Transactional Object wizard per creare un oggetto transazionale.
2 Aggiungere i metodi e le propriet allinterfaccia delloggetto usando il Type
Library editor. Per informazioni dettagliate sullaggiunta di metodi e propriet
usando il Type Library editor, consultare il Capitolo 39, Funzionamento delle
librerie di tipi.
3 Durante limplementazione dei metodi delloggetto possibile utilizzare
linterfaccia IObjectContext per gestire le transazioni, lo stato permanente e la
sicurezza.Inoltre, se si passano riferimenti a oggetti, necessario porre particolare
attenzione affinch siano gestiti in modo corretto. (Consultare Passaggio di
riferimenti a oggetti on page 27.)
4 Correggere e collaudare loggetto transazionale.
5 Installare loggetto transazionale in un package MTS o in unapplicazione COM+.
6 Amministrare gli oggetti usando MTS Explorer o COM+ Component Manager.
Uso di Transactional Object wizard
Transactional Object wizard viene utilizzato per creare oggetti COM in grado di
sfruttare i vantaggi derivanti dalla gestione delle risorse, dallelaborazione delle
transazioni e dalla sicurezza basata sui ruoli, messi a disposizione da MTS o COM+.
Per visualizzare Transactional Object wizard:
1 Scegliere il comando File|New|Other.
2 Selezionare la pagina ActiveX.
3 Fare doppio clic sullicona Transactional Object.
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-19
U s o d i T r a n s a c t i o n a l O b j e c t w i z a r d
Nel wizard si deve specificare quanto segue:
Un modello di thread che indichi come le applicazioni client possano chiamare
linterfaccia delloggetto. Il modello di thread scelto determina come viene
registrato loggetto. Chi programma deve accertarsi che limplementazione
delloggetto sia coerente con il modello selezionato. Per ulteriori informazioni sui
modelli di thread, consultare Scelta di un modello di threading per un oggetto
transazionale a pagina 44-19.
Un modello transazionale
Una indicazione del fatto che loggetto notifichi o meno gli eventi ai client. Il
supporto degli eventi previsto solo per eventi tradizionali, non per eventi COM.
Una volta completata questa procedura, viene aggiunta una nuova unit al progetto
attivo che contiene la definizione per loggetto transazionale. Inoltre, il wizard
aggiunge un progetto di libreria di tipi e la apre nel Type Library editor. A questo
punto possibile mostrare le propriet e i metodi dellinterfaccia tramite la libreria di
tipi. Linterfaccia viene definita come se si stesse definendo un qualsiasi oggetto
COM, secondo le modalit descritte in Definizione dellinterfaccia di un oggetto
COM a pagina 41-9.
Loggetto transazionale implementa uninterfaccia duale, che supporta sia il binding
anticipato (in fase di compilazione) tramite vtable, sia il binding differito (in fase di
esecuzione) tramite linterfaccia IDispatch.
Loggetto transazionale generato implementa i metodi dellinterfaccia IObjectControl,
Activate, Deactivate e CanBePooled.
Non strettamente necessario utilizzare il Transactional Object wizard. possibile
convertire qualsiasi oggetto Automation in un oggetto transazionale COM+ (e
qualsiasi oggetto Automation in-process in un oggetto transazionale MTS)
utilizzando la pagina COM+ del Type Library editor ed installando poi loggetto in
un package MTS o in unapplicazione COM+. Tuttavia, il Transactional Object
wizard offre alcuni benefici:
Implementa automaticamente linterfaccia IObjectControl, aggiungendo alloggetto
gli eventi OnActivate e OnDeactivate, in modo da consentire la creazione di gestori
di evento che rispondano al momento dellattivazione o disattivazione
delloggetto.
Genera automaticamente un membro m_spObjectContext semplificando cos
alloggetto laccesso ai metodi di IObjectContext per controllare lattivazione e le
transazioni.
Scelta di un modello di threading per un oggetto transazionale
Lambiente di runtime MTS o COM+ gestisce automaticamente i thread. Gli oggetti
transazionali non creano thread. Inoltre non devono mai interrompere un thread che
effettua una chiamata in una DLL.
44-20 G u i d a a l l a p r o g r a mma z i o n e
U s o d i T r a n s a c t i o n a l O b j e c t w i z a r d
Quando nel Transactional object wizard si specifica il modello di threading, si
specifica come gli oggetti vengono assegnati ai thread per lesecuzione dei metodi.
_
Questi modelli di threading sono simili a quelli definiti dagli oggetti COM. Tuttavia,
poich lambiente MTS e COM+ forniscono un maggiore supporto di base per i
thread, il significato di ciascun modello di threading qui diverso. Inoltre, i modelli
free threading non si applicano agli oggetti transazionali a causa del supporto
residente delle attivit.
Attivit
Oltre al modello di threading, gli oggetti transazionali supportano la concorrenzialit
tramite le attivit. Le attivit sono registrate nel contesto delloggetto e lassociazione
Tabella 44.2 Modelli di threading per oggetti transazionali
Modello di
threading Descrizione
Vantaggi e svantaggi
dellimplementazione
Single Non supporta alcun thread. Le
richieste del client vengono
serializzate tramite il meccanismo
di chiamata.
Tutti gli oggetti di un componente
single-threaded vengono eseguiti
sul thread principale.
Questo compatibile con il
modello di threading COM
predefinito, che viene usato per i
componenti che non hanno un
attributo Threading Model
Registry o per i componenti COM
che non sono rientranti.
Lesecuzione del metodo viene
serializzata in tutti gli oggetti del
componente e in tutti i componenti
di un processo.
Consente ai componenti di usare le
librerie che non sono rientranti.
Scalabilit molto limitata.
I componenti a thread singolo con
stato sono soggetti a blocchi critici.
possibile eliminare questo problema
usando oggetti senza stato e
chiamando SetComplete prima di
ritornare da un qualsiasi metodo.
Apartment
(or Single-threaded
apartment)
Ogni oggetto viene assegnato ad
un thread, che vale per lintera
durata delloggetto; comunque, si
possono usare pi thread per pi
oggetti. Questo un modello COM
standard di simultaneit. Ogni
apartment viene collegato ad un
specifico thread ed ha una sorgente
di messaggi Windows.
Fornisce miglioramenti significativi
rispetto alla concorrenza nel modello
di threading Single.
Due oggetti possono essere eseguiti
contemporaneamente finch non
svolgono la stessa attivit.
Simile ad un apartment COM, tranne
per il fatto che gli oggetti possono
essere distribuiti su pi processi.
Both Identico ad Apartment, tranne per
il fatto che le calback ai client sono
serializzate.
Stessi vantagggi di Apartment.
Inoltre, questo modello necessario
nel caso si voglia usare lObject
Pooling.
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-21
U s o d i T r a n s a c t i o n a l O b j e c t w i z a r d
tra un oggetto ed unattivit non pu essere cambiata. Unattivit include loggetto
transazionale creato dal client base, oltre a tutti gli oggetti MTS creati da
quelloggetto e dai suoi discendenti. Questi oggetti possono essere distribuiti in uno
o pi processi, che vengono eseguiti su uno o pi computer.
Per esempio, lapplicazione clinica per i medici pu avere un oggetto transazionale
per aggiungere gli aggiornamenti e rimuovere i record ai vari database medici,
ciascuno rappresentato da un oggetto diverso. Questo record aggiunto pu usare
anche altri oggetti, come un oggetto ricezione per registrare la transazione. Ci
genera diversi oggetti transazionali che sono direttamente o indirettamente sotto il
controllo di un client base. Questi oggetti appartengono tutti alla stessa attivit.
MTS o COM+ tengono la traccia del flusso desecuzione in ciascuna attivit,
impedendo cos che il parallelismo involontario danneggi lo stato dellapplicazione.
Questa caratteristica genera un singolo thread logico di esecuzione per tutta una serie
di oggetti potenzialmente distribuiti. Avendo un thread logico, le applicazioni sono
notevolmente pi facili da scrivere.
Quando un oggetto transazionale viene creato da un contesto esistente, tramite un
oggetto contestuale di transazione o un contesto di oggetto, il nuovo oggetto diventa
un membro della stessa attivit. In altre parole, il nuovo contesta eredita
lidentificatore di attivit del contesto usato per crearlo.
permesso solo un singolo thread logico di esecuzione allinterno dellattivit.
Questo comportamento simile a quello di un modello di threading COM di tipo
apartment, tranne per il fatto che gli oggetti possono essere distribuiti in pi processi.
Quando un client base chiama in unattivit, tutte le altre richieste di lavoro
dellattivit (provenienti, per esempio, da un altro thread del client) vengono bloccate
finch il thread iniziale di esecuzione non ritorna di nuovo al client.
In ambiente MTS, ogni oggetto transazionale appartiene a unattivit. In ambiente
COM+, possibile configurare il modo in cui loggetto partecipa alle attivit
impostando la sincronizzazione della chiamata. Sono disponibili le opzioni
seguenti:
Tabella 44.3 Opzioni di sincronizzazione della chiamata
Opzione Significato
Disabled COM+ non assegna attivit alloggetto ma pu ereditarle col contesto del
chiamante. Se il chiamante non ha alcuna transazione o contesto di oggetto,
loggetto non viene assegnato a unattivit. Il risultato come se loggetto non
fosse installato nellapplicazione COM+. Questa opzione non si dovrebbe
utilizzare se un qualsiasi oggetto nellapplicazione utilizza un manager di
risorse o se loggetto supporta transazioni o attivazione just-in-time.
Not Supported COM+ non assegna mai loggetto a unattivit, indipendentemente dallo stato
del suo chiamante. Questa opzione non si dovrebbe utilizzare se un qualsiasi
oggetto nellapplicazione utilizza un manager di risorse o se loggetto
supporta transazioni o lattivazione just-in-time.
Supported COM+ assegna loggetto alla stessa attivit del suo chiamante. Se il chiamante
non appartiene a unattivit, anche loggetto si comporter in modo analogo.
Questa opzione non si dovrebbe utilizzare se un qualsiasi oggetto
nellapplicazione utilizza un manager di risorse o se loggetto supporta
transazioni o lattivazione just-in-time.
44-22 G u i d a a l l a p r o g r a mma z i o n e
G e n e r a z i o n e d i e v e n t i i n a m b i e n t e C O M +
Generazione di eventi in ambiente COM+
Molte tecnologie basate su COM, come il motore di script di ActiveX e i controlli
ActiveX, utilizzano i convogliatori di eventi e le interfacce dei punti di connessione di
COM per generare eventi. I convogliatori di eventi e i punti di connessione sono
esempi di un modello ad eventi molto unito. In tale modello, le applicazioni che
generano eventi (detti publisher nella terminologia COM+ e convogliatori nella
precedente terminologia COM) sono consapevoli di quali sono le applicazioni che
rispondono agli eventi (dette subscriber), e vice versa. La durata dei publisher e dei
subscriber coincide; essi devono essere attivi contemporaneamente. La raccolta di
subscriber e il meccanismo che notifica loro il verificarsi degli eventi, devono essere
gestiti e implementati nel publisher.
COM+ ha introdotto un nuovo sistema per la gestione degli eventi. Invece di
appesantire ogni publisher con la gestione e con la notifica di ciascun subscriber,
interviene il sistema sottostante (COM+) e prende il controllo di questo processo. Il
modello a eventi di COM+ scarsamente interdipendente, consentendo lo sviluppo,
la distribuizione e lattivazione di publisher e subscriber in modo indipendente luno
dallaltro.
Bench il modello a eventi di COM+ semplifichi notevolmente la comunicazione fra
publisher e subscriber, introduce anche alcune attivit amministrative aggiuntive per
gestire il nuovo strato di software che ora esiste tra di loro. Le informazioni sugli
eventi e sui subscriber sono conservate in una parte del COM+ Catalog detta anche
event store. Per eseguire questi compiti amministrativi vengono utilizzati strumenti
come Component Services Manager. Lo strumento Component Services supporta
completamente gli script, consentendo lautomazione di gran parte dei compiti
amministrativi. Ad esempio, una procedura di installazione potrebbe eseguire queste
operazioni durante la sua esecuzione. Inoltre, levent store pu essere gestito da
programma utilizzando loggetto TComAdminCatalog. I componenti COM+ possono
essere installati anche direttamente da C++Builder, selezionando il comando Run|
Install COM+ object.
Come nel caso del modello a eventi strettamente interdipendenti, un evento
semplicemente un metodo in uninterfaccia. Pertanto, necessario per prima cosa
creare uninterfaccia per i metodi dellevento. possibile utilizzare COM+ Event
Object wizard di C++ Builder per creare un progetto contenente un oggetto evento di
COM+. Quindi, utilizzando lo strumento amministrativo Component Services (o
TComAdminCatalog o lIDE), creare unapplicazione COM+ che contenga un
componente della classe evento. Quando si crea nellapplicazione COM+ il
Required COM+ assegna sempre loggetto a unattivit, creandone una se occorre.
Questa opzione si deve utilizzare se lattributo di transazione Supported o
Required.
Requires New COM+ assegna sempre loggetto a una nuova attivit, distinta da quella del
suo chiamante.
Tabella 44.3 Opzioni di sincronizzazione della chiamata
Opzione Significato
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-23
G e n e r a z i o n e d i e v e n t i i n a m b i e n t e C O M +
componente della classe evento, si selezioner loggetto evento. La classe evento il
collante utilizzato da COM+ per collegare il publisher alla lista dei subscriber.
La cosa interessante su un oggetto evento di COM+ che esso non contiene alcuna
implementazione dellinterfaccia dellevento. Un oggetto evento di COM+ definisce
semplicemente linterfaccia che utilizzeranno i publisher e i subscriber per
comunicare. Quando si crea con C++Builder un oggetto evento di COM+, per
definire linterfaccia si utilizzer il Type Library editor. Linterfaccia viene
implementata quando si crea unapplicazione COM+ e il relativo componente della
classe evento. La classe evento, quindi, contiene un riferimento e consente laccesso
allimplementazione fornita da COM+. In esecuzione, il publisher crea unistanza
della classe evento con i soliti meccanismi COM (per esempio CoCreateInstance).
Limplementazione COM+ dellinterfaccia tale per cui tutto ci che un publisher
deve fare chiamare un metodo dellinterfaccia (attraverso listanza della classe
evento) per generare un evento che notoficher a tutti i subscriber.
Nota: Un publisher non deve essere necessariamente esso stesso un componente
COM. Un publisher semplicemente una qualsiasi applicazione che crea unistanza
della classe evento e genera eventi chiamando i metodi presenti nellinterfaccia
dellevento.
Anche il componente subscriber deve essere installato nel COM+ Catalog. Anche in
questo caso, loperazione pu essere svolta sia da programma utilizzando
TComAdminCatalog, sia dallIDE sia mediante lo strumento amministrativo gestione
Component Services. Il componente subscriber pu essere installato in
unapplicazione separata COM+ oppure pu essere installato nella stessa
applicazione utilizzata per contenere il componente della classe evento. Dopo avere
installato il componente, per ogni interfaccia di evento supportata dal componente si
deve creare una subscription. Dopo avere creato la subscription, selezionare quelle
classi evento (cio i publisher) che si desidera siano ricevute dal componente. Un
componente subscriber pu selezionare singole classi evento oppure tutte le classi
evento.
A differenza delloggetto evento di COM+, un oggetto subscription di COM+
contiene la propria implementazione di uninterfaccia di evento; questa la
posizione in cui viene svolto il lavoro effettivo per rispondere allevento nel
momentoin cui viene generato. Il COM+ Event Subscription Object wizard di C++
Builder pu essere utilizzato per creare un progetto che contiene un componente
subscriber.
44-24 G u i d a a l l a p r o g r a mma z i o n e
G e n e r a z i o n e d i e v e n t i i n a m b i e n t e C O M +
La figura seguente rappresenta linterazione fra publisher, subscriber e il Catalog di
COM+:
Figura 44.1 Il sistema a eventi di COM+
Uso di Event Object wizard
possibile creare oggetti event utilizzando Event Object wizard. Il wizard per prima
cosa controlla se il progetto corrente contiene del codice di implementazione, in
quanto i progetti che contengono oggetti evento di COM+ non includono
unimplementazione. Possono contenere solamente definizioni delloggetto
evento.(In un singolo progetto possibile, tuttavia, includere pi oggetti evento di
COM+)
Per attivare Event Object wizard:
1 Scegliere il comando File|New |Other.
2 Selezionare la pagina ActiveX.
3 Fare doppio clic sullicona COM+ Event Object.
NellEvent Object wizard, specificare il nome delloggetto evento, il nome
dellinterfaccia che definisce i gestori di evento e (facoltativamente) una breve
descrizione degli eventi.
Subscriber
Event Store
COM+ Catalog
COM+ Events
COM+ Application
Subscription
Event
Interface
Event
Interface
COM+ Application
Event Object
Publisher
Event Class
TCOMAdminCatalog or Component Services tool
Manages
Generate
event
Instantiates Delivers
event
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-25
G e n e r a z i o n e d i e v e n t i i n a m b i e n t e C O M +
Alluscita, il wizard crea un progetto contenente una libreria di tipi che definisce
loggetto evento e la sua interfaccia. Utilizzare il Type Library editor per definire i
metodi di quellinterfaccia. Questi metodi sono i gestori di evento che i client
implementano per rispondere agli eventi.
Il progetto delloggetto evento include il file di progetto, la unit _ATL per importare
le classi del modello ATL, e la unit _TLB per definire le informazioni della libreria di
tipi. Non include una unit di implementazione, comunque, in quanto gli oggetti
evento di COM+ non hanno implementazione. Limplementazione dellinterfaccia
a carico del client. Quando loggetto server chiama un oggetto evento di COM+,
COM+ intercetta la chiamata e linvia ai client registrati.Poich gli oggetti evento di
COM+ non richiedono loggetto implementazione, tutto ci che si deve fare dopo
avere definito linterfaccia delloggetto nel Type Library editor compilare il
progetto e installarlo in COM+.
COM+ impone alcune restrizioni sulle interfacce degli oggetti evento. Linterfaccia
che si definisce nel Type Library editor per loggetto evento deve rispettare le
seguenti regole:
Linterfaccia delloggetto evento deve derivare da IDispatch.
Tutti i nomi di metodo devono essere unici in tutte le interfacce delloggetto
evento.
Tutti i metodi sullinterfaccia delloggetto evento devono restituire un valore
HRESULT.
Il modificatore per tutti i parametri dei metodi deve essere [in].
Uso di COM+ Event Subscription object wizard
possibile creare il componente subscriber utilizzando C++Builder COM+
Subscription Object wizard. Per attivare il wizard:
1 Scegliere il comando File|New | Other.
2 Selezionare la pagina ActiveX.
3 Fare doppio clic sullicona COM+ Subscription Object.
Nella finestra di dialogo del wizard, immettere il nome della classe che implementer
linterfaccia dellevento. Scegliere dalla casella combinata il modello di threading.
Nel campo Interface, possibile immettere il nome dellinterfaccia dellevento,
oppure possibile fare clic sul pulsante Browse per attivare una lista di tutte le classi
evento attualmente installate nel Catalog di COM+. Anche la finestra di dialogo
COM+ Event Interface Selection contiene un pulsante Browse. possibile utilizzare
questo pulsante per cercare e selezionare una libreria di tipi che contenga linterfaccia
dellevento. Quando si seleziona una classe evento esistente (o si immette la libreria),
il wizard dar la possibilit di implementare automaticamente linterfaccia
supportata da quella classe evento. Se si seleziona la casella di controllo Implement
Existing Interface, il wizard creer automaticamente tutti i metodi nellinterfaccia.
possibile decidere di fare implementare al wizard le interfacce ereditate selezionando
la casella di controllo Implement Ancestor Interfaces. Tre interfacce dellantenato non
44-26 G u i d a a l l a p r o g r a mma z i o n e
G e n e r a z i o n e d i e v e n t i i n a m b i e n t e C O M +
vengono mai implementate dal wizard: IUnknown, IDispatch e IAppServer. Per
completare il wizard, immettere una breve descrizione del componente subscriber
dellevento e fare clic su OK.
Attivazione di eventi utilizzando un oggetto evento di COM+
Per generare un evento, un publisher crea per prima cosa unistanza della classe
evento, con i soliti meccanismi COM (per esempio CoCreateInstance). bene ricordare
che la classe evento contiene la propria implementazione dellinterfaccia dellevento,
e pertanto la generazione di un evento non altro che la semplice chiamata del
metodo appropriato dellinterfaccia.
A questo punto subentra il sistema a eventi di COM+. La chiamata al metodo di un
evento fa s che il sistema cerchi tutti i subscriber nel Catalog di COM+ e invii loro
notifica dellevento. Dal lato del subscriber, levento non sembra essere niente di pi
di una chiamata al metodo dellevento.
Quando un publisher genera un evento, i subscriber ne vengono informati in modo
sincrono, uno alla volta. Non v alcun modo per specificare lordine di notifica, n si
pu contare sul fatto che lordine sia lo stesso ogni volta che viene generato un
evento. Quando una classe evento installata nel Catalog di COM+, lamministratore
pu selezionare lopzione FireInParallel per richiedere che levento venga notificato
utilizzando pi thread. Ci non garantisce la consegna simultanea; semplicemente
una richiesta al sistema di consentire che ci possa avvenire.
Il valore restituito al publisher unaggregazione di tutti i codici restituiti da ogni
subscriber. Il publisher non ha alcun modo diretto per scoprire quale subscriber non
andato a buon fine. Per fare ci, un publisher deve implementare un filtro di
publisher. Per ulteriori informazioni su questo argomento, consultare la
documentazione MSDN di Microsoft. La tabella seguente riassume i codici derivanti
dalla scelta di varie combinazioni:
Tabella 44.4 Codici di ritorno dei publisher di evento
Codice restituito Significato
S_OK Tutti i subscriber sono andati a buon fine.
EVENT_S_SOME_SUBSCRIBERS_FAILED Non stato possibile chiamare qualche
subscriber, oppure alcuni hanno restituito un
codice di malfunzionamento (notare che questa
non una condizione di errore).
EVENT_E_ALL_SUBSCRIBERS_FAILED Non stato possibile chiamare alcun subscriber
oppure tutti i subscriber hanno restituito un
codice di malfunzionamento.
EVENT_S_NOSUBSCRIBERS Nel Catalog di COM+ non c alcuna
subscription (notare che questa non una
condizione di errore).
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-27
P a s s a g g i o d i r i f e r i m e n t i a o g g e t t i
Passaggio di riferimenti a oggetti
_
Le informazioni sul passaggio di riferimenti a oggetti sono valide solo per MTS, non
per COM+. Questo meccanismo necessario in ambiente MTS perch necessario
garantire che tutti i puntatori agli oggetti che sono in esecuzione in ambiente MTS
vengano indirizzati attraverso gli interceptor. Poich gli interceptor sono incorporati
in COM+, non necessario passare i riferimenti a oggetti.
In ambiente MTS, possibile passare riferimenti a oggetti (da usare, per esempio,
come callback), solo nei seguenti modi:
Tramite il ritorno da uninterfaccia di creazione delloggetto, come, per esempio,
CoCreateInstance (o un suo equivalente), ITransactionContext::CreateInstance o
IObjectContext::CreateInstance.
Tramite una chiamata a QueryInterface.
Tramite un metodo che ha chiamato SafeRef per ottenere il riferimento oggetto.
Un riferimento a oggetto ottenuto in uno dei modi sopra riportati viene definito
riferimento sicuro. I metodi chiamati usando riferimenti sicuri saranno eseguiti con
assoluta sicurezza allinterno del contesto corretto.
Lambiente di esecuzione di MTS vuole che le chiamate utilizzino riferimenti sicuri,
in modo da gestire le opzioni di contesto e consentire agli oggetti transazionali di
avere una durata indipendente dai riferimenti del client. I riferimenti sicuri non sono
necessari in ambiente COM+.
Uso del metodo SafeRef
Un oggetto pu usare una funzione SafeRef in modo da ottenere un riferimento sicuro
a se stesso che consenta di oltrepassare il contesto. Questa funzione disponibile
come metodo delloggetto TMtsDll; essa controlla se il server in esecuzione in
ambiente MTS o COM+ e restituisce, in base a ci, il puntatore opportuno.
SafeRef accetta come input
Un riferimento allID (RIID) dellinterfaccia che lattuale oggetto vuole passare ad
un altro oggetto o client.
AUn riferimento allinterfaccia IUnknown delloggetto corrente.
SafeRef restituisce un puntatore allinterfaccia specificata nel parametro RIID che
rende certo il passaggio al di l del contesto delloggetto attivo. Questo puntatore
restituisce NULL se loggetto richiede un riferimento sicuro su un oggetto diverso da
se stesso, o se linterfaccia richiesta nel parametro RIID non viene implementata.
Quando un oggetto MTS vuole passare un riferimento a se stesso per un client o per
un altro oggetto (da usare, per esempio, come callback), prima chiamer sempre
SafeRef e dopo passer il riferimento restituito da questa chiamata. Un oggetto non
passer mai un puntatore self, o un riferimento a se stesso ottenuto tramite una
chiamata interna a QueryInterface, ad un client o a qualsiasi altro oggetto. Una volta
che un tale riferimento stato passato fuori dal contesto delloggetto, non pi un
riferimento valido.
44-28 G u i d a a l l a p r o g r a mma z i o n e
D e b u g e c o l l a u d o d i o g g e t t i t r a n s a z i o n a l i
La chiamata a SafeRef su un riferimento che gi sicuro restituisce il riferimento
stesso non modificato, tranne che il numero di riferimento sullinterfaccia non viene
incrementato.
Quando un client chiama QueryInterface su un riferimento sicuro, il riferimento
restituito al client un riferimento sicuro.
Un oggetto che ottiene un riferimento sicuro deve rilasciare tale riferimento quando
non gli occorre pi.
Per informazioni dettagliate su SafeRef, consultare largomento SafeRef nella
documentazione Microsoft.
Callback
Gli oggetti possono effettuare il callback ai client e agli altri oggetti transazionali. Per
esempio, possibile avere un oggetto che crei un altro oggetto. La creazione di un
oggetto pu passare un riferimento di se stesso alloggetto creato; tale oggetto pu
usare poi questo riferimento per chiamare loggetto creante.
Se si sceglie di usare i callback, si devono tenere presenti le seguenti restrizioni:
Una chiamata di ritorno al client base o ad un altro package richiede la sicurezza a
livello di accesso sul client. Inoltre, il client deve essere un server DCOM.
I firewall intermedi potrebbero bloccare le chiamate di ritorno al client.
Il lavoro fatto sul callback viene eseguito nellambiente delloggetto da chiamare.
Pu far parte della stessa transazione, di una transazione diversa o di nessuna
transazione.
In ambiente MTS, loggetto che crea deve chiamare SafeRef e passare il riferimento
restituito alloggetto creato in modo da effettuare una chiamata di ritorno a se
stesso.
Debug e collaudo di oggetti transazionali
possibile effettuare il debug degli oggetti transazionali locali e remoti. Durante il
debug di oggetti transazionali, pu essere opportuno disattivare il timeout delle
transazioni.
Il timeout della transazione imposta per quanto tempo (in secondi) pu rimanere
attiva una transazione. Le transazioni che sono ancora attive dopo il timeout
vengono abbandonate automaticamente dal sistema. Per impostazione predefinita, il
valore del timeout di 60 secondi. possibile disattivare il timeout delle transazioni
specificando un valore 0, il che utile durante il debug.
Per informazioni sul debug remoto, consultare largomento Remote Debugging nella
Guida in linea.
Quando si effettua il collaudo di un oggetto transazionale che si intente eseguire in
ambiente MTS, pu essere opportuno verificare prima loggetto asternamente
allambiente MTS per semplificare lambiente di verifica.
C r e a z i o n e d i o g g e t t i MT S o C O M+ 44-29
I n s t a l l a z i o n e d i o g g e t t i t r a n s a z i o n a l i
Durante lo sviluppo di un server, non si pu effettuare di nuovo il build del server
mentre ancora in memoria, in quanto si riceverebbe un errore del compilatore del
tipo Cannot write to DLL while executable is loaded. Per evitare ci, si possono
impostare le propriet del package MTS o dellapplicazione COM+ in modo da
disattivare il server quando in stato di attesa.
Per disattivare il server quando in stato di attesa:
1 In MTS Explorer o in COM+ Component Manager, fare clic destro sul package
MTS o sullapplicazione COM+ in cui installato loggetto transazionale e
scegliere il comando Properties.
2 Selezionare la pagina Advanced.
Advanced determina se il processo del server associato ad un package viene
eseguito sempre o se viene disattivato dopo un certo lasso di tempo.
3 Cambiare il valore di timeout su 0, il che disattiva il server quando non ha pi un
client a cui fornire un servizio.
4 Fare clic su OK per salvare limpostazione.
Installazione di oggetti transazionali
Le applicazioni MTS sono costituite da un gruppo di oggetti MTS in-process che
vengono eseguiti in ununica istanza delleseguibile MTS (EXE). Un gruppo di
oggetti COM che vengono eseguiti tutti nello stesso processo viene chiamato
package. Una singola macchina pu eseguire molti package differenti, dove ciascun
package in esecuzione allinterno di un EXE MTS distinto.
In ambiente COM+, si opera con un gruppo analogo detto applicazione COM+. In
unapplicazione COM+ gli oggetti non devono essere necessariamente interni al
processo e non esiste un ambiente di esecuzione separato.
possibile raggruppare i componenti dellapplicazione in un singolo package MTS o
in unapplicazione COM+ da gestire allinterno di un unico processo. Pu essere
opportuno distribuire i componenti in pi package MTS o applicazioni COM+ in
modo da suddividere lapplicazione in pi processi o macchine.
Per installare oggetti transazionali in un package o in unapplicazione COM+:
1 Se il sistema supporta COM+, scegliere lopzione Run|Install COM+ objects. Se il
sistema non supporta COM+ ma sul sistema installato MTS, scegliere lopzione
Run|Install MTS objects. Se il sistema supporta n MTS n COM+, non si vedr
alcuna opzione di menu per installare gli oggetti transazionali.
2 Nella finestra di dialogo Install Object, selezionare gli oggetti da installare.
3 Se si stanno installando oggetti MTS, fare clic sul pulsante Package per ottenere un
elenco dei package MTS nel sistema. Se si stanno installando oggetti COM+, fare
clic sul pulsante Application. Indicare il package MTS o lapplicazione COM+ in
cui si stanno installando gli oggetti. possibile scegliere lopzione Into New
Package o Into New Application per creare un nuovo package MTS o
unapplicazione COM+ in cui installare loggetto. possibile anche scegliere Into
44-30 G u i d a a l l a p r o g r a mma z i o n e
A m m i n i s t r a z i o n e d i o g g e t t i t r a n s a z i o n a l i
Existing Package o Into Existing Application per installare loggetto in un package
MTS o in unapplicazione COM+ esistente fra quelli elencati.
4 Scegliere OK per aggiornare il catalogo, rendendo cos gli oggetti disponibili in
fase di esecuzione.
I package MTS possono contenere componenti di pi DLL, e i componenti di una
singola DLL possono essere installati in package differenti. Tuttavia, un singolo
componente non pu essere distribuito in pi package.
Analogamente, le applicazioni COM+ possono contenere componenti inclusi in pi
eseguibili, e componenti differenti di un singolo eseguibile possono essere installati
in applicazioni COM+ differenti.
_
possibile anche installare loggetto transazionale utilizzando COM+ Component
Manager o MTS Explorer. Durante linstallazione delloggetto con uno di questi
strumenti, accertarsi di applicare le impostazioni per loggetto che appaiono sulla
pagina COM+ del Type Library editor. Queste impostazioni non vengono applicate
automaticamente quando non si effettua linstallazione dallIDE.
Amministrazione di oggetti transazionali
Una volta installati degli oggetti transazionali, possibile amministrare questi
oggetti di runtime usando MTS Explorer (se sono installati in un package MTS) o
COM+ Component Manager (se sono installati in unapplicazione COM+). I due
strumenti sono identici, tranne per il fatto che MTS Explorer opera nellambiente di
esecuzione di MTS e COM+ Component Manager opera su oggetti COM+.
COM+ Component Manager e MTS Explorer posseggono uninterfaccia utente
grafica per la gestione e la distribuzione di oggetti transazionali. Utilizzando uno di
questi strumenti possibile
Configurare oggetti transazionali, package MTS o applicazioni COM+, e ruoli
Visualizzare le propriet dei componenti in un package o in unapplicazione
COM+ e visualizzare i package MTS o le applicazioni COM+ installati su un
computer
Controllare e gestire le transazioni per gli oggetti che comprendono transazioni
Spostare i package MTS o le applicazioni COM+ da un computer allaltro
Rendere un oggetto transazionale remoto disponibile per un client locale
Per informazioni dettagliate su questi strumenti, consultare lappropriato manuale
Administrators Guide di Microsoft.
C r e a z i o n e d i c o mp o n e n t i c u s t o m
P a r t e
V
ParteVCreazione di componenti custom
I capitoli inclusi nella sezione Creazione di componenti custom presentano i
concetti e le tecniche necessarie per progettare e implementare componenti custom in
C++Builder.
I n t r o d u z i o n e a l l a c r e a z i o n e d i c o mp o n e n t i 45-1
C a p i t o l o
45
Capitolo45Introduzione alla creazione di
componenti
Questo capitolo offre una panoramica sulla progettazione di componenti e sulla
procedura per la scrittura di componenti per applicazioni C++Builder. Presuppone
che si abbia familiarit con C++Builder e con i suoi componenti standard.
Librerie di classi
Componenti e classi
Creazione di componenti
Cosa mettere in un componente
Creazione di un nuovo componente
Verifica di componenti non installati
Collaudo di componenti installati
Installazione di un componente sulla Component palette
Per informazioni sullinstallazione di nuovi componenti, consultare Installazione di
package di componenti a pagina 15-6.
Librerie di classi
I componenti di C++Builder fanno tutti parte di due gerarchie di classi note come
Visual Component Library (VCL) e Component Library for Cross Platform (CLX). La
Figura 45.1 mostra la relazione delle classi selezionate che compongono la VCL. La
gerarchia della CLX simile a quella della VCL ma i controlli Windows sono
chiamati widget (quindi TWinControl chiamato TwidgetControl, ad esempio) ed
esistono altre differenze. Per maggiori informazioni sulla gerarchia delle classi e delle
relazioni di ereditariet che intercorrono tra le classi, consultare il Chapter 46,
Programmazione object-oriented per gli scrittori di componenti. Per una
panoramica delle differenze tra la CLX e la VCL, consultare CLX e VCL a
pagina 14-5 per dettagli sui componenti consultare la Guida di riferimento in linea
della CLX.
45-2 G u i d a a l l a p r o g r a mma z i o n e
C o m p o n e n t i e c l a s s i
La classe TComponent lantenato comune di ogni componente nella VCL e nalla
CLX. TComponent fornisce le propriet e gli eventi minimi necessari a un componente
per funzionare in C++Builder. I vari settori della libreria forniscono altre capacit pi
specifiche.
Figura 45.1 La gerarchia di classi della Visual Component Library
Quando si crea un componente, esso viene aggiunto alla VCL o alla CLX, derivando
una nuova classe da uno dei tipi di classe gi esistenti nella gerarchia.
Componenti e classi
Dal momento che i componenti sono classi, lo scrittore di componenti lavora con gli
oggetti a un livello differente da quello dello sviluppatore di applicazioni. La
creazione di nuovi componenti richiede che si derivino nuove classi.
In sintesi, esistono due differenze principali tra la creazione di componenti e il loro
utilizzo nelle applicazioni. Nella creazione di componenti:
Si ha accesso a parti della classe inaccessibili a chi sviluppa applicazioni.
Si aggiungono nuove parti al componente (ad esempio, le propriet).
Date queste differenze, chi scrive componenti deve prestare attenzione a un maggior
numero di convenzioni e pensare attentamente a come i componenti da lui sviluppati
verranno utilizzati da chi scrive applicazioni.
Creazione di componenti
Qualsiasi elemento di programma che si intende gestire in fase di progetto pu
diventare un componente. Creare un componente significa derivare una nuova classe
da una esistente. Si pu derivare un nuovo componente in molti modi:
TCustomControl
TApplication
TObject
TPersistent
TComponent
TControl
TGraphicControl TWinControl
TScrollingWinControl
TCustomForm
TForm
TActiveForm
Exception TStream TComObject
TCollection TStrings TGraphic TGraphicObject
TDataSet TMenu TCommonDialog TField
Most visual controls
inherit from
TWinControl.
I n t r o d u z i o n e a l l a c r e a z i o n e d i c o mp o n e n t i 45-3
C r e a z i o n e d i c o m p o n e n t i
Modifica di controlli esistenti
Creazione di controlli con finestra
Creazione di controlli grafici
Derivazioni di sottoclassi da controlli Windows
Creazione di componenti non visuali
La Tabella 45.1 riepiloga i vari tipi di componenti e le classi che si possono usare
come punto di partenza per ciascuna di queste tecniche.
Si possono anche derivare classi che non sono componenti e che non possono essere
gestite su una scheda, come TRegIniFile e TFont.
Modifica di controlli esistenti
Il modo pi semplice per creare un componente consiste nel personalizzarne uno
esistente. Si pu derivare un nuovo componente da un qualsiasi altro fornito con
C++Builder.
Alcuni controlli, come le caselle di riepilogo e le griglie, presentano diverse varianti
di una stessa impostazione di base. In questi casi, la VCL e la CLX includono una
classe astratta (il cui nome contiene la parola Custom, ad esempio TCustomGrid) da
cui derivare versioni personalizzate.
Ad esempio, si potrebbe creare una casella di riepilogo speciale, priva di alcune
propriet della classe standard TListBox. Non possibile rimuovere (nascondere) una
propriet ereditata da una classe antenato, quindi occorre derivare il componente da
un oggetto di livello superiore rispetto a TListBox nella gerarchia. Anzich partire
necessariamente dalla classe astratta TWinControl (o da TWidgetControl nella CLX) e
reinventare tutte le funzioni della casella di riepilogo, la VCL mette a disposizione
TCustomListBox, che implementa le propriet della casella di riepilogo ma non le
pubblica. Quando si deriva un componente da una classe astratta come
TCustomListBox, si rendono pubbliche solo le propriet che si vogliono rendere
disponibili nel componente, lasciando protetto tutto il resto.
Il Capitolo 47, Creazione di propriet, spiega come rendere pubbliche le propriet
ereditate. Il Capitolo 53, Modifica di un componente esistente, e il Capitolo 55,
Tabella 45.1 Punti di partenza per la creazione di componenti
Per raggiungere questo risultato Cominciare con questo tipo
Modifica di un componente esistente Qualsiasi componente esistente, come TButton o TListBox,
oppure un tipo astratto di componente, come
TCustomListBox
Creazione di un controllo con
finestra (o basato su widget in CLX)
TWinControl (TWidgetControl in CLX)
Creazione di un controllo grafico TGraphicControl
Creazione di una sottoclasse da un
controllo
Qualsiasi controllo Windows (VCL) o basato su widget
(CLX)
Creazione di un componente non
visuale
TComponent
45-4 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i c o m p o n e n t i
Personalizzazione di una griglia, mostrano alcuni esempi di come modificare i
controlli esistenti.
Creazione di controlli con finestra
I controlli con finestra nella VCL e nella CLX sono oggetti che appaiono in esecuzione
e con cui lutente pu interagire. Ogni controllo con finestra ha un handle di finestra,
accessibile tramite la propriet Handle, che consente al sistema operativo di
identificare il controllo e di operare su di esso. Se si utilizzano controlli VCL, lhandle
consente al controllo di ricevere il fuoco di input e pu essere passato alle funzioni
API di Windows. In CLX, questi controlli sono controlli basati su widget. Ogni
controllo basato su widget ha un handle, accessibile tramite la propriet Handle, che
identifica il widget sottostante.
Tutti i controlli con finestra discendono dalla classe TWinControl (TWidgetControl in
CLX). Fra questi vi sono numerosi controlli con finestra standard, quali pulsanti,
caselle di riepilogo e caselle di testo. Bench sia possibile derivare direttamente da
TWinControl (da TWidgetControl in CLX), un controllo originale (un controllo che non
in relazione con nessun altro controllo esistente), C++Builder fornisce
appositamente per questo scopo il componente TCustomControl. TCustomControl un
controllo con finestra specializzato che semplifica il disegno di complesse immagini
visuali.
Il Capitolo 55, Personalizzazione di una griglia, presenta un esempio di creazione
di un controllo con finestra.
Creazione di controlli grafici
Se non necessario che il controllo riceva il fuoco di input, possibile trasformarlo in
un controllo grafico. I controlli grafici sono analoghi ai controlli per finestra, ma non
hanno gli handle di finestra, e pertanto consumano meno risorse di sistema.
Componenti come TLabel, che non ricevono il fuoco di input, sono controlli grafici.
Anche se questi controlli non possono ricevere il fuoco, possibile progettarli in
modo che rispondano ai messaggi del mouse.
C++Builder supporta la creazione di controlli personalizzati grazie al componente
TGraphicControl. TGraphicControl una classe astratta derivata da TControl. Anche se
possibile derivare i controlli direttamente da TControl, meglio iniziare da
TGraphicControl, il quale fornisce un canvas su cui disegnare e, in Windows, in
grado di gestire i messaggi WM_PAINT; tutto ci che occorre fare ridefinire il
metodo Paint.
Il Capitolo 54, Creazione di un controllo grafico, contiene un esempio di creazione
di un controllo grafico.
Derivazioni di sottoclassi da controlli Windows
Nella programmazione tradizionale in Windows i controlli personalizzati vengono
creati definendo una nuova classe window e registrandola con Windows. La classe
I n t r o d u z i o n e a l l a c r e a z i o n e d i c o mp o n e n t i 45-5
C o s a m e t t e r e i n u n c o m p o n e n t e
window (simile agli oggetti o alle classi nella programmazione orientata agli oggetti)
contiene informazioni condivise tra istanze dello stesso tipo di controllo; possibile
basare una nuova classe window su una esistente; questa operazione viene detta
derivazione di sottoclassi (subclassing). Si inserisce quindi il controllo in una DLL
(Dynamic Link Library), in modo analogo a quanto si fa per i controlli standard di
Windows, e gli si fornisce uninterfaccia.
C++Builder consente di creare un contenitore di componenti per qualsiasi classe
window esistente. Pertanto se si desidera usare nelle applicazioni C++Builder una
libreria esistente di controlli personalizzati, possibile creare componenti di
C++Builder che si comportano come i propri controlli, e derivare i nuovi controlli
esattamente come si farebbe con qualsiasi altro componente.
Per esempi delle tecniche usate nei controlli Windows di derivazione delle classi,
vedere i componenti nel file header StdCtls che rappresentano i controlli Windows
standard, come TEdit. Per esempi della CLX, vedere QStdCtls.
Creazione di componenti non visuali
I componenti non visuali sono utilizzati come interfacce per elementi come database
(TDataSet o TSQLConnection) e clock di sistema (TTimer), e come segnaposti per le
finestre di dialogo (TCommonDialog nella VCL o TDialog nella CLX e i relativi
discendenti). probabile che quasi tutti i componenti che si scrivono siano controlli
visuali. I componenti non visuali possono essere derivati direttamente da
TComponent, la classe base astratta di tutti i componenti.
Cosa mettere in un componente
Per far s che i propri componenti siano parti affidabili dellambiente C++Builder,
necessario seguire determinate convenzioni durante la loro progettazione. Questa
sezione affronta i seguenti argomenti:
Rimozione delle dipendenze
Impostazione di propriet, metodi ed eventi
Incapsulamento della grafica
Registrazione di componenti
Rimozione delle dipendenze
Una qualit che rende i componenti utilizzabili la totale assenza nel codice di
restrizioni su ci che possono fare. Per caratteristica intrinseca, i componenti sono
incorporati allinterno delle applicazioni in combinazioni, ordini e contesti svariati. Si
dovrebbero progettare componenti che funzionino in qualsiasi situazione, senza
alcun prerequisito.
Un esempio eccellente di rimozione delle dipendenze la propriet Handle di
TWinControl. Chi ha gi scritto applicazioni Windows sa che uno degli aspetti pi
difficili e suscettibili di errori nellesecuzione di un programma di garantirsi,
45-6 G u i d a a l l a p r o g r a mma z i o n e
C o s a m e t t e r e i n u n c o m p o n e n t e
chiamando la funzione API CreateWindow, da un tentativo di accesso a una finestra o
a un controllo finch questi non vengono creati. I controlli per finestra di C++Builder
evitano allutente questa preoccupazione assicurando la disponibilit di un handle di
finestra valido in caso di necessit. Il controllo pu verificare se la finestra stata
creata utilizzando una propriet che rappresenta lhandle della finestra; se lhandle
non valido, il controllo crea una finestra e restituisce lhandle. In questo modo, ogni
volta che il codice di unapplicazione accede alla propriet Handle, si ha la sicurezza
di ottenere un handle valido.
Eliminando operazioni di base come la creazione di finestre, i componenti di
C++Builder consentono agli sviluppatori di concentrarsi su ci che vogliono
realmente fare. Non c alcun bisogno di verificare se lhandle esiste o di creare la
finestra, prima di passare un handle di finestra a una funzione API. Lo sviluppatore
di applicazioni pu dare per scontato il normale funzionamento, invece di continuare
a verificare tutte le cose che possono provocare di errori.
Per quanto la creazione di componenti liberi da dipendenze richieda molto tempo, di
solito tempo ben speso. Non solo risparmia agli sviluppatori di applicazioni
compiti ripetitivi e faticosi, ma riduce la quantit di documentazione e le incombenze
del supporto.
Impostazione di propriet, metodi ed eventi
Altre allimmagine visibile che pu essere gestita in Form designer, gli attributi pi
ovvi di un componente sono le propriet, gli eventi e i metodi. A ciascuno di questi
argomenti dedicato un capitolo; la spiegazione che segue mette in evidenza alcune
motivazioni che ne giustificano lutilizzo.
Propriet
Le propriet danno allo sviluppatore di applicazioni limpressione di impostare o di
leggere il valore di una variabile, mentre consentono allo scrittore di componenti di
nascondere la struttura dati associata o di implementare particolari elaborazioni
quando si accede al valore.
Ci sono molti vantaggi nellutilizzo delle propriet:
Le propriet sono disponibili in fase di progetto. Chi sviluppa applicazioni pu
impostare o modificare i valori iniziali delle propriet senza dover scrivere una
riga di programma.
Le propriet sono in grado di controllare i valori o i formati non appena vengono
assegnati dallo sviluppatore di applicazioni. La convalida dellinput in fase di
progettazione consente di prevenire errori.
Il componente pu creare su richiesta valori appropriati. Lerrore di
programmazione forse pi frequente quello di fare riferimento a una variabile
non inizializzata. Rappresentando i dati con una propriet, possibile garantire
che un valore sia sempre disponibile a richiesta.
I n t r o d u z i o n e a l l a c r e a z i o n e d i c o mp o n e n t i 45-7
C o s a m e t t e r e i n u n c o m p o n e n t e
Le propriet consentono di nascondere i dati con uninterfaccia semplice e
coerente. possibile modificare la struttura delle informazioni di una propriet
senza rendere percepibile il cambiamento a chi sviluppa applicazioni.
Il Capitolo 47, Creazione di propriet, spiega come aggiungere propriet ai
componenti.
Eventi
Un evento una particolare propriet che chiama del codice in risposta ad un input o
ad altra attivit in fase di esecuzione. Gli eventi offrono agli sviluppatori di
applicazioni un modo per collegare blocchi specifici di codice a occorrenze specifiche
in fase di esecuzione, come le azioni e la pressione dei tasti del mouse. Il codice che
viene eseguito al verificarsi di un evento detto gestore di evento.
Gli eventi consentono a chi sviluppa applicazioni di specificare le risposte per i
diversi tipi di input, senza dover definire nuovi componenti.
Il Chapter 48, Creazione di eventi, spiega come implementare gli eventi standard e
come definirne di nuovi.
Metodi
I metodi di una classe sono funzioni che operano su una classe piuttosto che su
specifiche istanze della classe. Per esempio, ogni metodo costruttore di un
componente un metodo della classe. I metodi dei componenti sono funzioni che
operano sulle stesse istanze dei componenti. Chi sviluppa applicazioni usa i metodi
per ordinare al componente di compiere unazione specifica o di restituire un valore
non contenuto in alcuna propriet.
Poich richiedono lesecuzione di codice, i metodi possono essere chiamati soltanto
in fase di esecuzione. I metodi risultano utili per svariati motivi:
I metodi incapsulano le funzionalit di un componente nello stesso oggetto in cui
risiedono i dati.
I metodi possono nascondere procedure complesse con uninterfaccia semplice e
coerente. Lo sviluppatore di applicazioni pu chiamare un metodo AlignControls
di un componente senza sapere come funziona o quali differenze presenta rispetto
al metodo AlignControls di un altro componente.
I metodi consentono di aggiornare diverse propriet con una sola chiamata.
Il Capitolo 49, Creazione di metodi, spiega come aggiungere metodi ai
componenti.
Incapsulamento della grafica
C++Builder semplifica la gestione della grafica in Windows poich incapsula i vari
strumenti grafici in un canvas. Il canvas rappresenta la superficie di disegno di una
finestra o di un controllo e contiene altre classi, come una penna, un pennello o un
font. Un canvas analogo a un contesto di dispositivo di Windows, ma effettua
automaticamente la maggior parte della manutenzione.
45-8 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n n u o v o c o m p o n e n t e
Se si gi scritta unapplicazione grafica per Windows, si ha familiarit con i requisiti
imposti dallinterfaccia GDI (Graphics Device Interface) di Windows. Per esempio, la
GDI limita il numero di contesti disponibili per i dispositivi e richiede che gli oggetti
grafici vengano ripristinati al loro stato iniziale prima di distruggerli.
C++Builder evita tutte queste preoccupazioni. Per disegnare su una scheda o su altro
componente, si accede alla propriet Canvas del componente. Se si desidera
personalizzare una penna o un pennello, se ne impostano il colore o lo stile. Al
termine, C++Builder si sbarazza delle risorse. C++Builder inoltre mette in cache le
risorse per evitare di ricrearle nel caso lapplicazione utilizzi spesso lo stesso tipo di
risorse.
sempre possibile accedere liberamente alla GDI di Windows, ma non si pu non
constatare che, se si utilizza il canvas incluso nei componenti di C++Builder, spesso il
codice pi semplice e viene eseguito pi velocemente. Le caratteristiche grafiche
sono spiegate in dettaglio nel Capitolo 50, Uso della grafica nei componenti.
Lincapsulamento della grafica della CLX funziona diversamente. Un canvas invece
un painter. Per disegnare su una scheda o su altro componente, si accede alla
propriet Canvas del componente. Canvas una propriet ed anche un oggetto di
nome TCanvas. TCanvas funge da wrapper per un oggetto Qt painter a cui possibile
accedere attraverso la propriet Handle. possibile utilizzare lo handle per accedere a
funzioni a basso livello delle libreria grafiche di Qt.
Se si desidera personalizzare una penna o un pennello, se ne impostano il colore o lo
stile. Al termine, C++Builder si sbarazza delle risorse. CLX inoltre memorizza nella
cache le risorse.
possibile utilizzare il canvas incorporato nei componenti CLX derivandolo da essi.
Il funzionamento delle immagini grafiche dipende dal canvas delloggetto da cui il
componente deriva.
Registrazione di componenti
Prima di installare i propri componenti nellIDE di C++Builder, necessario
registrarli. La registrazione comunica a C++Builder dove collocare il componente
sulla Component palette. anche possibile personalizzare il modo in cui C++Builder
registra i componenti nel file di scheda. Per maggiori informazioni sulla registrazione
di un componente, consultare il Capitolo 52, Come rendere disponibili i componenti
in fase di progetto.
Creazione di un nuovo componente
Per creare un nuovo componente si pu procedere in due modi:
Creazione di un componente con Component wizard
Creazione manuale di un componente
possibile usare uno di questi due metodi per creare un componente minimamente
funzionale, pronto per essere installato nella Component palette. Dopo
I n t r o d u z i o n e a l l a c r e a z i o n e d i c o mp o n e n t i 45-9
C r e a z i o n e d i u n n u o v o c o m p o n e n t e
linstallazione, si pu aggiungere il nuovo componente ad una scheda e collaudarlo
sia in fase di progetto sia in fase di esecuzione. In seguito sar possibile aggiungere
altre caratteristiche al componente, aggiornare la Component palette e continuare il
collaudo.
Ci sono diverse operazioni fondamentali da eseguire ogni qualvolta si crea un nuovo
componente. Questi aspetti vengono descritti di seguito; gli altri esempi riportati in
questo documento presuppongono una sufficiente padronanza degli argomenti
trattati.
1 Creare una unit per il nuovo componente.
2 Derivare il componente da un altro tipo di componente esistente.
3 Aggiungere propriet, metodi e eventi.
4 Registrare il componente con C++Builder.
5 Creare un file di Guida per il componente e le relative propriet, metodi ed eventi.
_
La creazione di un file di guida per fornire istruzioni agli utenti sulluso del
componente facoltativa.
6 Creare un package (una particolare libreria a collegamento dinamico) in modo che
sia possibile installare il componente nellIDE di C++Builder.
Al termine, il componente completo include i seguenti file:
Un file package (.BPL) o package collection (.PCE)
Una libreria (.LIB) per il package
Un file .BPI (Borland Import Library) per il package
Un file unit compilato (.OBJ)
Un file risorse compilato (.RES) per la mappa della palette
Un file di guida (.HLP)
anche possibile creare una bitmap per rappresentare il nuovo componente. Vedere
Creazione di una bitmap per un componente a pagina 45-15.
I rimanenti capitoli della Parte V illustrano i diversi aspetti della costruzione dei
componenti e forniscono numerosi esempi completi di scrittura di differenti tipi di
componenti.
Creazione di un componente con Component wizard
Component wizard semplifica le fasi iniziali della creazione di un componente.
Quando si utilizza Component wizard, necessario specificare solo quanto segue:
La classe da cui il componente derivato.
Il nome della classe del nuovo componente.
La pagina della Component palette in cui si desidera che appaia.
nome della unit in cui il componente verr creato.
Il percorso di ricerca per trovare la unit.
Il nome del package in cui si desidera collocare il componente.
Component wizard esegue le stesse operazioni che si compiono creando un
componente in modo manuale:
45-10 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n n u o v o c o m p o n e n t e
Creazione di una unit (un file .CPP e il file header associato).
Derivazione del componente.
Dichiarazione di un nuovo costruttore.
Registrazione del componente.
Component wizard non consente di aggiungere componenti a una unit esistente
(costituita da un file .CPP e dal file header associato). Se si vogliono aggiungere
nuovi componenti alla unit, occorre farlo manualmente.
1 Per avviare Component wizard, scegliere uno di questi metodi:
Scegliere Component|New Component.
Scegliere File|New|Other e fare doppio clic su Component.
Figura 45.2 Component wizard
Compilare i campi nel Component wizard:
2 Specificare nel campo Ancestor Type la classe da cui si sta derivando il nuovo
componente.
_
Nella lista a discesa, molti componenti sono elencati due volte con diversi nomi di
unit, con uno per la VCL e uno per la CLX. Le unit specifiche della CLX iniziano
con Q (come QGraphics invece di Graphics). Accertartarsi di effettuare la
derivazione dal componente corretto.
3 Specificare nel campo Class Name il nome della classe del nuovo componente.
4 Specificare nel campo Palette Page la pagina della Component palette in cui
installare il nuovo componente.
5 Nel campo Unit file name, specificare il nome della unit in cui si vuole dichiarare
la classe del componente.
6 Se la unit non si trova nel percorso di ricerca, modificare il percorso di ricerca nel
campo Search Path.
7 Per collocare il componente in un nuovo package o in uno gi esistente, fare clic su
Component|Install e usare la finestra di dialogo visualizzata per specificare un
package.
j
Se si deriva un componente da una classe VCL o CLX il cui nome inizia con
custom (come TCustomControl), bene evitare di collocarlo su una scheda finch
non sono stati ridefiniti tutti i metodi astratti nel componente originale.
I n t r o d u z i o n e a l l a c r e a z i o n e d i c o mp o n e n t i 45-11
C r e a z i o n e d i u n n u o v o c o m p o n e n t e
C++Builder non pu creare oggetti istanza di una classe che ha propriet o metodi
astratti.
8 Dopo aver completato i campi del Component wizard, scegliere OK. C++Builder
crea una nuova unit formata da un file .cpp e dal relativo file header associato.
Il file .cpp viene visualizzato nel Code editor. Il file contiene un costruttore per il
componente e la funzione Register che registra il componente, dicendo a C++Builder
quale componente aggiungere alla libreria di componenti e su quale pagina della
Component palette dovrebbe essere visualizzato. Il file contiene inoltre unistruzione
include che specifica il file header che stato creato. Ad esempio:
-c.c c>
-,i.i .s,
-c.c '.c..,c'
-,i.i ,ic.ics.i_,
aev .c..,c.,
__?aatcaII .c..,c.c..,c.,c .c
.,c.c
aaeeapace .c.c.,c
Nel caso di applicazioni CLX, nomi e ubicazioni di alcuni file sono differenti. Ad
esempio, ccs,,> in CLX diventa cxcs,,>.
Per aprire il file header nel Code editor, collocare il cursore sul nome del file header,
fare clic destro sul pulsante del mouse in modo da visualizzare il menu contestuale e
scegliere nel menu il comando Open File at Cursor.
Il file header contiene la nuova dichiarazione, composta da una dichiarazione di un
costruttore e da parecchie istruzioni #include per supportare la nuova classe. Ad
esempio:
-..c. .c..,c-
-.c.c .c..,c-
-c.c .ss,,>
-c.c s,,>
45-12 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n n u o v o c o m p o n e n t e
-c.c isscs,,>
-c.c .s,,>
ptIvate
ptetectei
pabIIc
__?aatcaII .c..,c.,c .c,
__pabIIaaei
,
-c..
Prima di continuare, salvare il file .cpp assegnandogli un nome significativo.
Creazione manuale di un componente
Il modo pi semplice per creare un nuovo componente usare il Component wizard.
La stessa procedura pu, comunque, essere eseguita anche manualmente.
Per creare un componente in modo manuale, si devono effettuare le seguenti
operazioni:
1 Creazione di un unit file
2 Derivazione del componente
3 Dichiarazione di un nuovo costruttore
4 Registrazione del componente
Creazione di un unit file
Una unit di C++Builder formata da una combinazione di un file .CPP e di un file .H
che vengono compilati in un file .OBJ. C++Builder utilizza le unit per svariati scopi.
Ogni scheda ha la propria unit e anche la maggior parte dei componenti (o gruppi
logici di componenti) ha la propria unit.
Quando si crea un componente, occorre creare una nuova unit per il componente o
aggiungere il nuovo componente ad una unit esistente.
1 Per creare una unit per un componente, scegliere uno dei metodi seguenti:
Scegliere il comando File|New|Unit.
Scegliere il comando File|New|Other in modo da visualizzare la finestra di
dialogo New Items, selezionare Unit e scegliere OK.
C++Builder crea un file .CPP e un file header e visualizza il file .CPP nel Code
editor. Salvare il file con un nome significativo.
2 Per aprire il file header, collocare nel Code editor il cursore sul nome del file
header, fare clic destro e scegliere nel menu contestuale il comando Open File at
Cursor.
3 Per aprire una unit esistente, selezionare File|Open e scegliere il codice sorgente
della unit a cui si desidera aggiungere il componente.
I n t r o d u z i o n e a l l a c r e a z i o n e d i c o mp o n e n t i 45-13
C r e a z i o n e d i u n n u o v o c o m p o n e n t e
_
Quando un componente viene aggiunto a una unit preesistente, bene accertarsi
che questa contenga il codice per i componenti. Per esempio, laggiunta del codice
per un componente ad una unit che contiene una scheda provoca errori nella
Component palette.
4 Una volta selezionata per il componente una unit nuova o preesistente, possibile
derivare la classe del componente.
Derivazione del componente
Ogni componente una classe derivata da TComponent, da uno dei suoi discendenti
pi specializzati (come TControl o TGraphicControl) o da una classe di componente
esistente. Il paragrafoCreazione di componenti a pagina 45-2 descrive da quale
classe derivare i diversi tipi di componenti.
La derivazione di nuove classi viene illustrata in dettaglio nella sezione Definizione
di nuove classi a pagina 46-1.
Per derivare una classe di componente, aggiungere una dichiarazione di classe al file
header.
Una semplice classe di componenti un componente non visuale derivato
direttamente da TComponent.
Per creare una semplice classe di componenti, aggiungere la seguente dichiarazione
di classe al file header:
ciss .~~ .c..,c ,cc .,c
,
La macro PACKAGE viene espansa in unistruzione che consente di esportare e di
importare le classi. Si dovrebbero inoltre aggiungere tutte le istruzioni include
necessarie per specificare i file .HPP richiesti dal nuovo componente. Di seguito sono
elencate le pi comuni istruzioni include usate di solito:
-c.c c.ss,,>
-c.c cs,,>
-c.c cisscs,,>
-c.c c.s,,>
Finora il nuovo componente non fa nulla di diverso da TComponent. stato solo
creato un framework in cui costruire il nuovo componente.
Dichiarazione di un nuovo costruttore
Ogni nuovo componente deve avere un costruttore che ridefinisca il costruttore della
classe da cui stato derivato. Quando si scrive il costruttore del nuovo componente,
si deve sempre chiamare il costruttore ereditato.
Allinterno della dichiarazione della classe, dichiarare un costruttore virtuale nella
sezione public della classe. Per maggiori informazioni sulla sezione public,
consultare Controllo dellaccesso a pagina 46-4. Ad esempio:
ciss .~~ .c..,c ,cc .,c
,cc
45-14 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n n u o v o c o m p o n e n t e
i __.isci .c..,c.,c ~.c,
,
Implementare il costruttore nel file .CPP:
__.isci .c..,c.c..,c.,c ~.c .,c~.c
Allinterno del costruttore, va aggiunto il codice che si vuole far eseguire al momento
della creazione del componente.
Registrazione del componente
La registrazione un semplice procedimento che indica a C++Builder quali
componenti aggiungere alla libreria di componenti e su quale pagina della
Component palette dovranno apparire. Per una trattazione dettagliata del processo
di registrazione, consultare il Capitolo 52, Come rendere disponibili i componenti in
fase di progetto.
Per registrare un componente:
1 Aggiungere al file .CPP della unit una funzione di nome Register, collocandola
allinterno di un namespace. Il namespace il nome del file in cui incluso il
componente, a cui viene sottratto lestensione, da scrivere tutto in lettere
minuscole ad eccezione della prima lettera.
Ad esempio, il codice seguente esiste allinterno di un namespace Newcomp, dove
Newcomp il nome del file .CPP:
i.cs,icc .c.c.,
-..c. cs.-
-.c.c cs.-
-c.c cisscs,,>
-c.c cs,,>
-c.c c..s,,>
-c.c c.s,,>
-c.c '.c.'
ciss . ,cc .
cxc . .,
-c..
Listruzione #include che include il file NEWCTRL.H parte dallassunto che il
componente risieda nella directory del progetto corrente o in una directory elencata
nel percorso dei file include del progetto.
Questo il file .CPP della unit della scheda:
-c.c cc>
-,i.i .s,
-c.c 'cs.'
-c.c '.c.'
-,i.i ,ic.ics.i_,
-,i.i cscc '...'
. .,
c c. .c..,
__.isci ...,c .c
..c
.c. c. .c.s,
I n t r o d u z i o n e a l l a c r e a z i o n e d i c o mp o n e n t i 45-19
C o l l a u d o d i c o m p o n e n t i i n s t a l l a t i
.c.>.ic s,
.c.>c. .,
i.cs,icc .c.c
,cc
i __.isci .i.,c.i,c.,c .c,
,
Non dimenticare di includere la macro PACKAGE (definita in Sysmac.h) che
consente di importare ed esportare le classi.
Una dichiarazione completa di componente include propriet, membri dati e
dichiarazioni dei metodi prima della parentesi graffa finale, ma anche una
dichiarazione vuota valida e rappresenta un punto di partenza per aggiungere le
caratteristiche del componente.
Antenati, discendenti e gerarchie della classe
Chi sviluppa applicazioni parte dallassunto che ogni controllo abbia propriet di
nome Top e Left che determinano la posizione del controllo sulla scheda. Non gli
interessa che tutti i controlli ereditino queste propriet da un antenato comune, nella
fattispecie TControl. Nel creare un componente, tuttavia, occorre sapere da quale
46-4 G u i d a a l l a p r o g r a mma z i o n e
C o n t r o l l o d e l l a c c e s s o
classe derivarlo affinch erediti le caratteristiche adatte. Ed bene sapere tutto ci
che il controllo eredita, per sfruttare tutte le caratteristiche ereditate senza doverle
impostare di nuovo.
La classe da cui si deriva un componente detta antenato immediato. Ogni
componente eredita dal suo antenato immediato, dallantenato dellantenato e cos
via. Tutte delle classi da cui un componente eredita sono dette essere i suoi antenati;
il componente un discendente dei suoi antenati.
Tutte assieme, le relazioni antenato-discendente in unapplicazione costituiscono una
gerarchia di classi. Ogni generazione nella gerarchia contiene molte pi cose rispetto
ai propri antenati, dal momento che ogni classe eredita tutto ci che hanno gli
antenati e aggiunge nuove propriet e metodi o ridefinisce quelli esistenti.
Se non si specifica un antenato immediato, C++Builder deriva il componente
dallantenato predefinito, TObject. TObject lantenato di tutte le classi della
gerarchia delloggetto.
La regola generale per scegliere loggetto da cui derivare un altro oggetto semplice:
si deve selezionare loggetto che contenga quanto pi possibile di ci che si vuole
includere nel nuovo oggetto, ma che non includa alcunch di ci che non si vuole nel
nuovo oggetto. sempre possibile aggiungere alloggetto nuove cose, ma non
possibile toglierne.
Controllo dellaccesso
There Esistono cinque livelli di controllo di accesso-detto anche visibilit-su propriet,
metodi e membri dati. La visibilit determinano quale codice pu accedere a quali
parti della classe. Specificando la visibilit, si definisce linterfaccia al componente.
La Tabella 46.1 mostra i livelli di visibilit, dal pi restrittivo al pi accessibile:
Tabella 46.1 Livelli di visibilit allinterno di un oggetto
Visibilit Significato Utilizzato per
private Accessibile solo nella classe in cui
definito.
Occultamento dei dettagli implementativi.
protected Accessibile solo nella classe in cui
definito e nei suoi discendenti.
Definizione dellinterfaccia per lo scrittore
di componenti.
public Accessibile a tutto il codice. Definizione dellinterfaccia di esecuzione.
__automated Accessibile a tutto il codice. Le
informazioni di tipo automation
vengono generate.
Solo OLE Automation.
__published Accessibile a tutto il codice e
dallObject Inspector. Memorizzata
in un file scheda.
Definizione dellinterfaccia di
progettazione.
P r o g r a mma z i o n e o b j e c t - o r i e n t e d p e r g l i s c r i t t o r i d i c o mp o n e n t i 46-5
C o n t r o l l o d e l l a c c e s s o
Occultamento dei dettagli implementativi
La dichiarazione di una parte di una classe come private, rende quella parte
invisibile al codice esterno a meno che le funzioni non siano dichiarate friends della
classe. Le parti private di una classe sono utili soprattutto per nascondere i dettagli
implementativi agli utenti della classe. Poich gli utenti della classe non possono
accedere alle parti private, possibile cambiare limplementazione interna della
classe senza alcuna influenza sul codice dellutente.
Se non si specifica alcun controllo di accesso su un membro dati, su un metodo o su
una propriet, tale parte risulta private.
Di seguito riportato un esempio, suddiviso in due parti, che illustra come il fatto di
dichiarare private un membro dati impedisca agli utenti di accedere alle
informazioni.
La prima parte una unit di una scheda costituita da un file header e da un file .CPP
che, nel gestore di evento OnCreate della scheda, assegna un valore a un membro dati
privato. Poich il gestore di evento viene dichiarato allinterno della classe
TSecretForm, la unit viene compilata senza errori.
-..c. -.cL.-
-.c.c -.cL.-
-c.c c.ss,,>
-c.c cs,,>
-c.c cisscs,,>
-c.c c.s,,>
-c..
Il file .CPP il seguente:
-c.c c>
-,i.i .s,
-c.c '.cL.'
-,i.i ,ic.ics.i_,
-,i.i cscc '...'
.ccc. .ccc.,
__.isci .ccc..ccc..,c .c
..c
46-6 G u i d a a l l a p r o g r a mma z i o n e
C o n t r o l l o d e l l a c c e s s o
-c.c c.ss,,>
-c.c cs,,>
-c.c cisscs,,>
-c.c c.s,,>
-c..
Il file .CPP riportato di seguito. Poich il gestore di evento OnCreate tenta di
assegnare un valore al membro dati private della scheda SecretForm, la compilazione
non va a buon fine e viene visualizzato il messaggio di errore
.ccc..ccc.c s icccsscc.
-c.c c>
-,i.i .s,
-c.c 'cs-.c'
-c.c '.cL.'
-,i.i ,ic.ics.i_,
-,i.i cscc '...'
cs. cs.,
__.isci cs.cs..,c .c
..c
Anche se un programma che usa la unit HideInfo pu usare classi di tipo TSecretForm,
quello stesso programma non pu accedere al membro dati FSecretCode di nessuna di
quelle classi.
Nelle applicazioni CLX i nomi e le ubicazioni di alcuni file header sono differenti. Ad
esempio, ccs,,> is cxcs,,> in CLX.
Definizione dellinterfaccia per lo scrittore di componenti
La dichiarazione di una parte di una classe come protected rende quella parte visibile
solamente alla stessa classe e ai suoi discendenti.
Si possono utilizzare le dichiarazioni protected per definire linterfaccia dello scrittore
di componenti alla classe. Le unit dellapplicazione non hanno accesso alle parti
protette, ma ce lhanno le classi derivate. Ci significa che chi scrive componenti pu
modificare il modo in cui opera una classe senza renderne visibili i dettagli a chi
sviluppa applicazioni.
_
Un errore comune quello di provare ad accedere ai metodi protetti dallinterno di
un gestore di evento. Di solito i gestori di evento sono metodi della scheda, e non del
componente che riceve levento. Di conseguenza essi non hanno accesso ai metodi
protetti del componente (a meno che il componente non sia dichiarato nella stessa
unit della scheda).
Definizione dellinterfaccia di esecuzione
Se una parte di una classe viene dichiarata public, quella parte diventa visibile a
ciascuna riga di codice che ha accesso alla classe.
Le parti pubbliche sono disponibile in esecuzione a tutto il codice, e pertanto le parti
pubbliche di una classe definiscono la sua interfaccia di esecuzione. Linterfaccia di
esecuzione utile quegli elementi non significativi o inadatti in fase di progettazione,
come le propriet dipendenti da dati immessi in esecuzione o che sono a sola lettura.
Devono essere resi pubblici anche i metodi che possono essere chiamati da chi
sviluppa applicazioni.
Di seguito riportato un esempio che mostra due propriet a sola lettura dichiarate
come parte dellinterfaccia di esecuzione di un componente:
ciss .~~ .i.,c.,c ,cc .,c
,ic
c.,css, .,c.ci .cis ic ,ic
cc.,icc,
,cc
c c.,css - .,
,ic
c.,cic,
__,csc.
__,,c c.,cic ci.c.,cic, .cc.,cic,
,
Dispatch dei metodi
Dispatch il termine usato per descrivere in che modo lapplicazione determina quali
sono i metodi della classe che devono essere chiamati quando incontra una chiamata
a un metodo della classe. Quando si scrive del codice che chiama un metodo della
classe, la chiamata simile ad una qualsiasi altra chiamata a funzione. Le classi,
tuttavia, hanno due modi differenti di eseguire il dispatch dei metodi.
I due tipi di dispatch dei metodi si differenziano a seconda che siano per
Metodi regolari (non virtuali)
Metodi virtuali
P r o g r a mma z i o n e o b j e c t - o r i e n t e d p e r g l i s c r i t t o r i d i c o mp o n e n t i 46-9
D i s p a t c h d e i m e t o d i
Metodi regolari
I metodi di classe sono regolari (o non virtuali) a meno che non vengano dichiarati
esplicitamente come virtuali, oppure a patto che essi ridefiniscano un metodo
virtuale presente in una classe base. Il compilatore in grado di determinare
lindirizzo esatto di un membro di una classe regolare in fase di compilazione.
Questa funzionalit nota come binding in compilazione.
Un metodo regolare di una classe base viene ereditato dalle classi derivate.
Nellesempio seguente, un oggetto di tipo Derived pu chiamare il metodo Regular()
come se fosse un proprio metodo. La dichiarazione di un metodo in una classe
derivata con lo stesso nome e gli stessi parametri di metodo regolare nella classe
antenato sostituisce il metodo dellantenato. Nellesempio seguente, quando si
chiama il metodo d->AnotherRegular(), esso viene smistato al metodo sostitutivo di
AnotherRegular() della classe Derived.
ciss isc
,cc
. ci,
. ~cci,
i . i,
,
ciss cc. ,cc isc
,cc
. ~cci, c,iccs isc~cci
. i, c.cs isci
,
. cc
cc. .,
. c. cc.,
.>ci, i ci is .cc i .c.cc . cc.
c si.c is ci .>iscci
.>~cci, i c c.c.c. ~cci,
c c,icc.c . isc~cci
.ccc .,
. c.isc c
c>i,
c>~cci,
Metodi virtuali
A differenza dei metodi regolari, che vengono collegati in fase di compilazione, i
metodi virtuali vengono collegati in esecuzione. Il meccanismo virtuale di C++
46-10 G u i d a a l l a p r o g r a mma z i o n e
M e m b r i a s t r a t t i d i c l a s s i
consente di chiamare un metodo in base al tipo della classe che si sta utilizzando per
chiamare il metodo.
Nellesempio precedente, se si chiamasse la funzione FunctionTwo() con un puntatore
a un oggetto di Derived, verrebbe chiamata la funzione Derived::Virtual(). Il
meccanismo virtuale ispeziona dinamicamente in esecuzione il tipo della classe
delloggetto che le viene passato e la smista al metodo opportuno. Ma la chiamata
alla funzione regolare b->AnotherRegular() chiamer sempre Base::AnotherRegular() in
quanto lindirizzo di AnotherRegular() stato determinato in fase di compilazione.
Per dichiarare un nuovo metodo virtuale, anteporre alla dichiarazione del metodo la
parola chiave virtual.
Quando il compilatore incontra la parola chiave virtual, crea un elemento nella
tabella dei metodi virtuali della classe (VMT). La VMT conserva gli indirizzi di tutti i
metodi virtuali presenti in una classe. Questa tabella di consultazione viene utilizzata
in fase esecuzione per determinare che b->Virtual deve chiamare Derived::Virtual()
invece di Base::Virtual().
Quando si deriva una nuova classe da una classe preesistente, la nuova classe riceve
una propria VMT, che comprende gli elementi della VMT dellantenato a cui
vengono aggiunti tutti i metodi virtuali dichiarati nella nuova classe. Inoltre, la classe
derivata pu ridefinire tutti i metodi virtuali ereditati.
Ridefinizione dei metodi
Ridefinire i metodi significa estendere o perfezionare un metodo di un antenato,
invece che sostituirlo. Per ridefinire un metodo in una classe discendente, dichiarare
di nuovo il metodo nella classe derivata, assicurandosi che il numero e il tipo degli
argomenti siano gli stessi.
Il codice successivo mostra la dichiarazione di due semplici componenti. Il primo
dichiara due metodi, ciascuno con un differente tipo di dispatch. Laltro, derivato dal
primo, sostituisce il metodo non virtuale e ridefinisce il metodo virtuale.
ciss .~~ s.,c ,cc .,c
,cc
. .c, ci .c.
i . is, i .c.
,
ciss .~~ .cc..,c ,cc s.,c
,cc
. .c, .ccics c. .c. '.' s.,c.c
. is, c.cs i s.,cis s.,c
,
Membri astratti di classi
Quando un metodo dichiarato come abstract in una classe antenato, occorre
renderlo evidente (dichiarandolo o implementandolo di nuovo) in qualsiasi
P r o g r a mma z i o n e o b j e c t - o r i e n t e d p e r g l i s c r i t t o r i d i c o mp o n e n t i 46-11
C l a s s i e p u n t a t o r i
componente discendente prima di poter utilizzare nelle applicazioni il nuovo
componente. C++Builder non in grado di creare istanze di una classe che contiene
membri astratti. Per maggiori informazioni sul modo di rendere evidenti le parti
ereditate delle classi, consultare il Capitolo 47, Creazione di propriet, and
Capitolo 49, Creazione di metodi.
Classi e puntatori
Ogni classe (e perci ogni componente) in realt un puntatore. Il fatto che la classe
sia un puntatore diventa importante quando una classe viene passata come
parametro. Come regola generale, si dovrebbero passare le classi per valore invece
che per riferimento. Il motivo che le classi sono gi dei puntatori, e come tali sono
riferimenti; passando una classe per riferimento equivale a passare un riferimento a
un riferimento.
46-12 G u i d a a l l a p r o g r a mma z i o n e
C l a s s i e p u n t a t o r i
C r e a z i o n e d i p r o p r i e t 47-1
C a p i t o l o
47
Capitolo47Creazione di propriet
Le parti pi evidenti dei componenti sono le propriet. Chi sviluppa applicazioni
pu visualizzarle e manipolarle in fase di progettazione e avere unimmediata
risposta di come il componente reagisce nel modulo di impostazione schede. Le
propriet ben progettate agevolano limpiego del componente da parte di altri e ne
assicurano una pi facile manutenzione.
Per fare il miglior uso possibile delle propriet dei componenti necessario
analizzare alcuni aspetti:
Perch creare le propriet
Tipi di propriet
Pubblicazione di propriet ereditate
Definizione delle propriet
Creazione di propriet array
Registrazione e caricamento delle propriet
Perch creare le propriet
Dal punto di vista dello sviluppatore di applicazioni, le propriet appaiono come
variabili. Gli sviluppatori possono impostarle o leggerne i valori come se fossero
membri dati. (Lunica cosa che non si pu fare con una propriet, ma solo con una
variabile, passarla per riferimento a un metodo sotto forma di argomento.)
Le propriet sono molto pi potenti dei semplici membri dati perch
Gli sviluppatori di applicazioni possono impostare le propriet durante la
progettazione. Mentre i metodi sono disponibili solo in fase di esecuzione, le
propriet consentono invece allo sviluppatore di personalizzare i componenti
prima di eseguire lapplicazione. Le propriet possono essere mostrate nellObject
Inspector, che semplifica il lavoro del programmatore: invece di gestire svariati
parametri per costruire un oggetto, si lascer a C++Builder il compito di leggerne i
47-2 G u i d a a l l a p r o g r a mma z i o n e
T i p i d i p r o p r i e t
valori dallObject Inspector. LObject Inspector convalida inoltre le assegnazioni
delle propriet non appena vengono eseguite.
Le propriet possono mascherare dettagli di implementazione. Ad esempio, i dati
memorizzati internamente in formato crittografato possono apparire non
crittografati come valori di una propriet; anche se il valore un semplice numero,
il componente pu cercare il valore in un database o eseguire calcoli complessi per
determinarlo. Le propriet consentono di aggiungere effetti complessi ad
assegnazioni a prima vista semplici; ci che appare unassegnazione a un membro
dati pu essere invece una chiamata a un metodo che implica unelaborazione
complessa.
Le propriet possono essere virtuali. Quindi, ci che a uno sviluppatore di
applicazioni appare come una propriet singola pu essere invece implementato
in modo diverso in componenti differenti.
Un semplice esempio la propriet Top di tutti i controlli.Lassegnazione di un
nuovo valore a Top non solo modifica un valore memorizzato, ma riposiziona ed
aggiorna il controllo. E gli effetti dellimpostazione di una propriet non sono
necessariamente limitati a un singolo componente. Per esempio, limpostazione a
true della propriet Down di uno SpeedButton provoca limpostazione a false di tutti
gli altri pulsanti appartenenti allo stesso gruppo.
Tipi di propriet
Una propriet pu essere di un qualunque tipo. Tipi diversi sono visualizzati in
modo differente nellObject Inspector, che, in fase di progetto, convalida le
assegnazioni di propriet non appena vengono create.
Tabella 47.1 Come appaiono le propriet nellObject Inspector
Tipo di propriet Trattamento dell Object Inspector
Semplice Le propriet numeriche, di tipo carattere e stringa appaiono nellObject
Inspector rispettivamente come numeri, caratteri e stringhe. Lutente pu
scrivere e modificare direttamente il valore della propriet.
Enumerato Le propriet dei tipi enumerati (compreso Boolean) appaiono come stringhe di
testo modificabili. Lutente pu far scorrere tutti i possibili valori facendo
doppio clic nella colonna del valore. Appare anche un elenco a discesa che
mostra tutti i valori possibili del tipo enumerato.
Set Le propriet dei tipi set appaiono nellObject Inspector come un insieme.
Espandendo linsieme con un doppio clic del mouse, lutente pu trattare ogni
elemento del set come un valore booleano: true se lelemento incluso nel set,
false se non lo ).
Oggetto Le propriet che sono a loro volta classi spesso dispongono di propri editor,
specificati nella procedura di registrazione del componente. Tuttavia, se la
classe che fa capo a una propriet contiene a sua volta la propriet Published,
lObject Inspector permette allutente di espandere lelenco (con un doppio
clic) per includere quelle propriet e di modificarle individualmente. Le
propriet delloggetto devono discendere da TPersistent.
C r e a z i o n e d i p r o p r i e t 47-3
P u b b l i c a z i o n e d i p r o p r i e t e r e d i t a t e
Pubblicazione di propriet ereditate
Tutti i componenti ereditano propriet dalle proprie classi antenate. Quando si
deriva un componente da uno esistente, il nuovo componente eredita tutte le
propriet del suo antenato immediato. Se si deriva il componente da una classe
astratta, la maggior parte delle propriet ereditate sono protected (protette) o public
(pubbliche) ma non sono published (rese pubbliche.
Per rendere disponibile in fase di progettazione nellObject Inspector una propriet
protetta o pubblica bisogna ridichiararla come published. Ridichiarare significa
aggiungere una dichiarazione per la propriet ereditata alla dichiarazione della
classe discendente.
Se si deriva un componente VCL da TWinControl, per esempio, esso eredita anche la
propriet DockSite protetta. Ridichiarando invece DockSite nel nuovo componente
possibile cambiare il livello di protezione e trasformarlo in public o published.
Il codice che segue mostra come ridichiarare DockSite in modo published rendendolo
disponibile durante lo sviluppo.
ciss .~~ .i.,c.,c ,cc
__,csc.
__,,c c..c,
,
Nel ridichiarare una propriet si specifica solo il nome della propriet, non il tipo e le
altre informazioni descritte nel paragrafo successivo Definizione delle propriet. Si
possono anche dichiarare nuovi valori predefiniti e specificare se memorizzare la
propriet.
La ridichiarazione pu diminuire la protezione di una propriet, ma non aumentarla.
Pertanto, possibile rendere pubblica una propriet protetta, ma non consentito
nascondere una propriet pubblica ridichiarandola come protetta.
Definizione delle propriet
Questa sezione illustra come dichiarare nuove propriet e spiega alcune convenzioni
seguite per i componenti standard. Gli argomenti trattati sono i seguenti:
Interface Le propriet che sono interfacce possono essere visualizzate nellObject
Inspector purch il valore sia uninterfaccia che implementata da un
componente (un discendente di TComponent). Le propriet interfaccia hanno
spesso i propri editor di propriet.
Array Le propriet array devono avere i propri editor; l Object Inspector non ha il
supporto interno per la modifica delle propriet array. possibile specificare
un editor di propriet quando si registra il componente.
Tabella 47.1 Come appaiono le propriet nellObject Inspector (continua) (continua)
Tipo di propriet Trattamento dell Object Inspector
47-4 G u i d a a l l a p r o g r a mma z i o n e
D e f i n i z i o n e d e l l e p r o p r i e t
Dichiarazione della propriet
Memorizzazione interna dei dati
Accesso diretto
Access methods
Valori predefiniti delle propriet
Dichiarazione della propriet
AUna propriet dichiarata nella dichiarazione della classe del componente. Per
dichiarare una propriet, occorre specificare tre cose:
Il nome della propriet.
Il tipo della propriet.
I metodi usati per leggere e scrivere il valore della propriet. Se non viene
dichiarato il metodo di scrittura, la propriet a sola lettura.
Le propriet dichiarate in una sezione __published della dichiarazione della classe
del componente sono modificabili in fase di progetto con Object Inspector. Il valore
di una propriet resa pubblica viene salvato assieme al componente nel file della
scheda. Le propriet dichiarate in una sezione public sono disponibili in fase di
esecuzione e possono essere lette o impostate da programma.
Di seguito riportata una tipica dichiarazione di propriet di nome Count.
ciss .~~ .,c ,cc .,c
,ic
, .ii .c.cc . sic
__.isci c, ci. .c.
. __.isci .c ~ , .c .c.
,cc
__,,c ci.c, .c.c, ,,c .ccii
,
Memorizzazione interna dei dati
Non vi sono restrizioni su come memorizzare il dato di una propriet. In generale,
comunque, i componenti di C++Builder seguono queste convenzioni:
I dati delle propriet vengono memorizzati allinterno dei membri dati della
classe.
I membri dati utilizzati per memorizzare i dati della propriet sono privati e
dovrebbero essere accessibili soltanto dallinterno del componente stesso. I
componenti derivati dovrebbero utilizzare la propriet ereditata: non hanno
bisogno di accedere direttamente allarea di memorizzazione interna dei dati della
propriet.
C r e a z i o n e d i p r o p r i e t 47-5
D e f i n i z i o n e d e l l e p r o p r i e t
I nomi degli identificatori di questi membri dati iniziano con la lettera F seguita
dal nome della propriet. Per esempio, i dati della propriet Width definita in
TControl sono memorizzati in un membro dati di nome FWidth.
Il principio che alla base di queste convenzioni che solo i metodi di
implementazione di una propriet dovrebbero avere accesso ai dati cui essa si
riferisce. Se un metodo o unaltra propriet ha bisogno di cambiare quel dato,
dovrebbe farlo utilizzando la propriet e non accedendo direttamente ai dati
memorizzati. Ci garantisce che limplementazione di una propriet pu cambiare
senza invalidare i componenti derivati.
Accesso diretto
Laccesso diretto la maniera pi semplice per rendere disponibili i dati delle
propriet. Ci significa che le sezioni read e write della dichiarazione della propriet
specificano che lassegnazione o la lettura del valore della propriet accedono
direttamente al membro dati di memorizzazione interna senza chiamare un metodo
di accesso. Laccesso diretto utile se si vuole rendere disponibile una propriet
nellObject Inspector ma si vuole evitare che le modifiche al valore provochino
unelaborazione immediata.
abbastanza comune avere accesso diretto per la sezione read di una dichiarazione
di propriet ma usare un metodo di accesso per la sezione write. Ci fa s che lo stato
del componente venga aggiornato quando il valore della propriet cambia.
La dichiarazione di un tipo componente riportata di seguito mostra una propriet
che utilizza laccesso diretto sia per la parte read sia per la parte write.
ciss .~~ .i.,c.,c ,cc .,c
,ic
__.isci cicc.c L.cx, c L.cx ,ii.cc
. __.isci .cicc.c L.cx, ic,
,cc
__,,c i ci.cicc.c, .c.cicc.c, .cx, .c.i,
__,,c . ci.cicc.c, .c.cicc.c, .cx., .c.i,
__,,c ci ci.cicc.c, .c.cicc.c, .cx, .c.i,
,
Poich ogni elemento della data (giorno, mese e anno) un intero e poich
limpostazione di ciascuno di essi richiede la codifica della data, il codice evita la
duplicazione condividendo i metodi di lettura e scrittura di tutte e tre le propriet.
Occorre quindi solo un metodo per leggere un elemento della data e un altro metodo
per scriverlo.
Di seguito riportato il metodo di lettura per ottenere un elemento della data:
__.isci .i.,cic.icicc.c L.cx
Questo il metodo di scrittura usato per impostare lopportuno elemento della data:
. __.isci .i.,cic.i.cicc.c L.cx, ic
C r e a z i o n e d i p r o p r i e t 47-7
D e f i n i z i o n e d e l l e p r o p r i e t
Il metodo read
Il metodo read per una propriet una funzione che non richiede parametri (tranne
nei casi citati di seguito) e restituisce un valore dello stesso tipo della propriet. Per
convenzione il nome della funzione Get seguito dal nome della propriet. Per
esempio, il metodo read relativo a una propriet di nome Count sar GetCount. Il
metodo read manipola i dati memorizzati internamente in modo da produrre il
valore della propriet con il tipo appropriato.
Le uniche eccezioni alla regola che impone lassenza di parametri sono le propriet
array e quelle che utilizzano specificatori di indice (vedere il paragrafo Creazione di
propriet array a pagina 47-8), in quanto entrambe passano i propri valori di indice
come parametri. (Per creare un singolo metodo read condiviso da pi propriet,
usare gli specificatori di indice.)
ISe non si dichiara un metodo read, la propriet a sola scrittura. Le propriet a sola
scrittura sono utilizzate raramente.
Il metodo write
Il metodo write per una propriet una funzione membro che richiede un solo
parametro dello stesso tipo della propriet (tranne nei casi citati di seguito). Il
parametro pu essere passato per riferimento o per valore e pu avere un nome
qualsiasi. Per convenzione, il nome del metodo write Set seguito dal nome della
propriet. Ad esempio, il metodo write di una propriet chiamata Count sar
SetCount. Il valore passato nel parametro diventa il nuovo valore della propriet; il
metodo write deve compiere tutte le operazioni necessarie per collocare il dato
appropriato nellarea di memorizzazione interna della propriet.
Le uniche eccezioni alla regola del singolo parametro sono le propriet array e quelle
che utilizzano specificatori di indice, in quanto passano i propri valori di indice come
secondo parametro. (Per creare un singolo metodo write condiviso da pi propriet,
usare gli specificatori di indice.)
Se non si dichiara un metodo write, la propriet a sola lettura.
I metodi write di solito verificano se un nuovo valore differisce dal valore attuale
prima di modificare la propriet. Per esempio, di seguito riportato un semplice
metodo write per una propriet di tipo intero di nome Count che memorizza il suo
valore attuale in un membro dati di nome FCount.
. __.isci ..,c.c ic
. ic
ic,
,.ic,
,ic
c Lsc,
,cc
i __.isci .i.,c.,c .,c .c ,
__,csc.
__,,c c Lsc ci.Lsc, .cLsc, .c.ic,
,
__.isci .i.,c.,c.i.,c.,c .,c .c
.,c .c
Lsc c,
,ic
.sc.~s. __.isci c..cc..c L.cx,
,cc
__,,c .sc.~s. ..cc..c, L.cx ci.c..cc..c,
,
Questo il metodo GetNumberSize nel file .CPP:
.sc.~s. __.isci c..,cc..cc..c L.cx
.sc.~s. cs,
s.c L.cx
cisc
cs '.c',
cci.,
cisc
cs '.c..',
cci.,
cisc
cs 'ic',
cci.,
.c.i cs '.. s.c',
c cs,
47-10 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i p r o p r i e t p e r i s o t t o c o m p o n e n t i
Creazione di propriet per i sottocomponenti
Per impostazione predefinita, quando il valore di una propriet un altro
componente, si assegna un valore a quella propriet aggiungendo alla scheda o al
modulo dati unistanza dellaltro componente e quindi assegnando quel componente
come valore della propriet. Tuttavia, anche possibile che il componente crei la
propria istanza delloggetto che implementa il valore della propriet. Un tale
componente dedicato viene detto sottocomponente.
Tutti gli oggetto persistenti (tutti i discendenti di TPersistent) possono essere
sottocomponenti. A differenza dei singoli componenti che, talvolta, possono essere
assegnati come valore di una propriet, le propriet pubblicate dei sottocomponenti
vengono salvate con il componente che li crea. Affinch ci sia vero, comunque,
devono essere soddisfatte le seguenti condizioni:
LOwner del sottocomponente deve essere il componente che lo crea e lo utilizza
come valore di una propriet pubblicata. Nel caso di sottocomponenti che
discendono da TComponent, possibile fare ci impostando la propriet Owner del
sottocomponente. Per altri sottocomponenti, necessario ridefinire il metodo
GetOwner delloggetto persistente in modo che restituisca il componente che sta
creando.
Se il sottocomponente un discendente di TComponent, deve indicare di essere un
sottocomponente chiamando il metodo SetSubComponent. Di solito, questa
chiamata viene effettuata o dal possessore al momento della creazione del
sottocomponente oppure dal costruttore del sottocomponente.
Di solito, le propriet i cui valori sono sottocomponenti sono a sola lettura. Se si
permette di modificare una propriet il cui valore un sottocomponente, il setter
della propriet deve liberare il sottocomponente nel momento in cui al valore della
propriet viene assegnato un altro componente. Inoltre, il componente spesso crea
una nuova istanza del proprio sottocomponente quando la propriet viene impostata
a NULL. In caso contrario, se la propriet fosse stata modificata in un altro
componente, il sottocomponente non potrebbe essere mai ripristinato in fase di
progettazione. Il seguente esempio illustra un setter di propriet per una propriet il
cui valore un TTimer:
veIi __?aatcaII c..,c.c.c.,xs.c ic
I? ic .c
I? ic
I? .c .c>.c taIa
ieIete .c,
.c ic,
.c>cc..citaIa,
eIae . ic
I? .c .c>.c taIa
C r e a z i o n e d i p r o p r i e t 47-11
R e g i s t r a z i o n e e c a r i c a m e n t o d e l l e p r o p r i e t
.c aev xs.ctaIa,
.c.c.c.,cttae,
.c>cc..citaIa,
Si noti che il setter della propriet visto in precedenza ha effettuato una chiamata al
metodo FreeNotification del componente che stato impostato come valore della
propriet. Questa chiamata garantisce che il componente che stato assegnato come
valore della propriet invii una notifica nel caso debba essere distrutto. La notifica
viene inviata chiamando il metodo Notification. Questa chiamata viene gestita
ridefinendo il metodo Notification nel seguente modo:
veIi __?aatcaII c..,c..ciisscs.,c ~.,c,
isscs,ci ,ci
,cc
i __.isci ..isi.,c ~.c,
__,csc.
__,,c ~ .c.ii.,
,
Il costruttore del componente TMyStatusBar nel file .CPP il seguente:
__.isci ..isi..isi .,c ~.c
.ic~.c
~ i.,
ptetectei
beeI __?aatcaII .cL,
pabIIc
__pabIIaaei
__ptepett, Iat L.,i sc.ttae, i.is sc.
__ptepett, Iat .,i sc.?aIae, cc sc.
__ptepett, Iat ..c.cs sc..cL, sic .c,c.s .c ic
,
47-14 G u i d a a l l a p r o g r a mma z i o n e
R e g i s t r a z i o n e e c a r i c a m e n t o d e l l e p r o p r i e t
Inizializzazione dopo il caricamento
Un componente, dopo aver letto tutti i valori delle sue propriet dalla sua descrizione
registrata, richiama un metodo virtuale chiamato Loaded, che esegue tutte le
inizializzazioni richieste. La chiamata di Loaded avviene prima che compaiano la
scheda e i suoi controlli, cos che non c da preoccuparsi del fatto che
linizializzazione possa provocare sfarfallio sullo schermo.
Per inizializzare un componente dopo che ha caricato i valori delle sue propriet,
occorre ridefinire il metodo Loaded.
_
La prima cosa da fare in un metodo Loaded chiamare il metodo ereditato Loaded. Ci
assicura che tutte le propriet ereditate verranno inizializzate correttamente prima
che sia inizializzato il componente.
Registrazione e caricamento di propriet non pubbliche
Per impostazione predefinita, sole le propriet pubbliche vengono caricate e salvate
con un componente. Tuttavia, possibile caricare e salvare anche propriet non
pubbliche. Questa possibilit consente di avere propriet persistenti che non
appaiono nellObject Inspector. Ci consente anche ai componenti di memorizzare e
caricare valori di propriet che C++Builder non in grado di leggere o di scrivere
perch il valore della propriet troppo complesso. Per esempio, loggetto TStrings
non pu appoggiarsi al comportamento automatico di C++Builder per memorizzare
e caricare le stringhe che esso rappresenta e deve utilizzare il meccanismo spiegato di
seguito.
possibile salvare le propriet non pubbliche aggiungendo del codice che spiega a
C++Builder come caricare e salvare il valore delle propriet.
Per scrivere il codice necessario a caricare e salvare le propriet, seguire le istruzioni
seguenti:
1 Creare dei metodi per memorizzare e caricare il valore della propriet.
2 Ridefinire il metodo DefineProperties, passando quei metodi un oggetto filer.
Creazione di metodi per memorizzare e caricare i valori delle propriet
Per memorizzare e caricare le propriet non pubbliche, per prima cosa si deve creare
un metodo per memorizzare il valore della propriet e un altro metodo per caricarlo.
Esistono due possibilit:
Creare un metodo di tipo TWriterProc per memorizzare il valore della propriet e
un metodo di tipo TReaderProc per caricare il valore della propriet. Questo
approccio consente di sfruttare le capacit intrinseche di C++Builder di
salvataggio e caricamento di tipi semplici. Se il valore della propriet costituito
da tipi che C++Builder in grado di salvare e caricare, utilizzare questo metodo.
Creare due metodi di tipo TStreamProc, uno per memorizzare e uno per caricare il
valore della propriet. TStreamProc richiede come un argomento uno stream, ed
C r e a z i o n e d i p r o p r i e t 47-15
R e g i s t r a z i o n e e c a r i c a m e n t o d e l l e p r o p r i e t
possibile utilizzare i metodi dello stream per scrivere e leggere i valori della
propriet.
Per esempio, si immagini una propriet che rappresenta un componente creato in
fase di esecuzione. C++Builder sa come scrivere questo valore, ma non in grado di
farlo automaticamente perch il componente non stato creato da Form Designer.
Poich il sistema di stream gi in grado di caricare e salvare componenti, possibile
utilizzare il primo metodo.I metodi seguenti caricano e memorizzano il componente
creato dinamicamente che rappresenta il valore di una propriet di nome
MyCompProperty:
. __.isci .i.,c.,ci..,.,cci.c ci.c
. ci.c>ci.ci
..,.,c ci.c>ci..,c.,
. __.isci .i.,c.,c.c.,.,cc c
. ..,.,c
c>ccic,
c>c.,c..,.,c,
csc
c>cci.isc,
. .i.,c.,c c>~ccs>..,.,c .
cic ..,.,c .,
csc . ..,.,c .
.i.,c.,c c>~ccs>..,.,c>.i.c
..,.,c>.i.c
cic c,
csc cic .isc,
,ic
..c c.,
,ccc.
__,,c ..c c. ci.c., .cc.,
C r e a z i o n e d i e v e n t i 48-3
C o s u n e v e n t o
,
Per saperne di pi su TNotifyEvent e sugli altri tipi di evento, vedere la prossima
sezione I tipi degli eventi sono tipi closure.
valore dellevento anche durante lesecuzione. Il vantaggio principale della gestione
degli eventi come propriet, comunque, che lutente del componente pu assegnare
allevento un gestore durante lo sviluppo usando Object Inspector.
I tipi degli eventi sono tipi closure
Poich un evento un puntatore a un gestore di eventi, il tipo della propriet
dellevento deve essere un closure. Analogamente, il codice usato per gestire levento
deve essere il metodo di una classe, di tipo appropriato.
Per essere compatibile con un evento di un certo tipo, il metodo di gestione evento
deve avere lo stesso numero e tipo di parametri, nello stesso ordine e passati nello
stesso modo.
C++Builder definisce i closure per tutti i suoi eventi standard. Quando il
programmatore crea i propri eventi, pu utilizzare un closure esistente, se
appropriato, o definirne uno proprio.
Il tipo restituito dai gestori di evento void
Il tipo restituito dai gestori di evento pu essere solo di tipo void. Anche se i gestori
possono restituire solo tipi void, sempre possibile ottenere dal codice utente delle
informazioni di ritorno passando gli argomenti per riferimento. Se si adotta questo
metodo, occorre accertarsi di assegnare allargomento un valore consentito prima di
effettuare la chiamata, in modo che non sia necessario che il codice dellutente
modifichi il valore.
Un esempio del passaggio degli argomenti per riferimento a un gestore di evento
levento legato alla pressione dei tasti, di tipo TKeyPressEvent. TKeyPressEvent
definisce due argomenti, il primo indicante loggetto che ha generato levento, e
laltro indicante il tasto premuto:
,c.c. . __.isci __csc c.csscccc .c.c, i c,
Normalmente, il parametro Key contiene il carattere premuto dallutente. In
determinate circostanze, tuttavia, lutente del componente potrebbe decidere di
cambiare il carattere. Un esempio potrebbe essere quello di forzare tutti i caratteri in
maiuscolo in un controllo per lediting. In questo caso lutente potrebbe definire il
seguente gestore per la pressione dei tasti:
. __.isci ..c.cssccc .c.c, i c
c ,iscc,
Comunque, per rispondere a speciali combinazioni di tasti (come quelle con il tasto
Alt), necessario rispondere al messaggio WM_GETDLGCODE o
CM_WANTSPECIALKEYS da Windows. Per informazioni sulla scrittura dei gestori
di messaggi vedere il Capitolo 51, Gestione dei messaggi e delle notifiche di
sistema.
Visibilit degli eventi
Le dichiarazioni degli eventi standard in TControl e TWinControl (TWidgetControl
nella CLX) sono protette, come lo sono i metodi ad essi corrispondenti. Se si sta
ereditando da una di queste classi astratte e si vogliono rendere accessibili i relativi
eventi in esecuzione o in progettazione, occorre ridichiarare gli eventi come public o
published.
La ridichiarazione di una propriet senza specificarne limplementazione mantiene
invariati i metodi dimplementazione, ma modifica il livello di protezione. quindi
possibile prendere un evento definito in TControl ma che non stato reso visibile, e
renderlo tale dichiarandolo public o published.
Ad esempio, per creare un componente che rende visibile levento OnClick in fase di
progetto, si potrebbe aggiungere quanto segue alla dichiarazione della classe del
componente.
ciss .~~ . ,cc s.
OnClick OnDragDrop OnEndDrag OnMouseMove
OnDblClick OnDragOver OnMouseDown OnMouseUp
OnEnter OnKeyDown OnKeyPress
OnKeyUp OnExit
48-6 G u i d a a l l a p r o g r a mma z i o n e
D e f i n i z i o n e d i e v e n t i p e r s o n a l i z z a t i
__,csc.
__,,c c., .i.cs c. iiicc c ccc Ls,cc
,
Modifica della gestione standard degli eventi
IVolendo modificare il modo in cui il componente risponde a determinati tipi di
evento, si potrebbe essere tentati di scrivere una certa sequenza di istruzioni e
assegnarla allevento. Come sviluppatori di applicazioni, esattamente quello si
farebbe. Ma quando si crea un componente, occorre mantenere levento disponibile
per gli sviluppatori che utilizzeranno il componente.
Questo il motivo dei metodi di implementazione protetti, associati a ognuno degli
eventi standard. Ridefinendo il metodo di implementazione, possibile cambiare la
gestione interna dellevento; e chiamando il metodo ereditato, possibile conservare
la gestione standard, incluso levento per il codice dello sviluppatore di applicazioni.
Lordine in cui si chiamano i metodi importante. Come regola, occorre chiamare
prima il metodo ereditato, consentendo che lesecuzione del gestore di evento
previsto dallo sviluppatore dellapplicazione avvenga prima della propria
personalizzazione (e, in alcuni casi, impedendo che avvenga). Possono comunque
verificarsi casi in cui si vuole che il proprio codice venga eseguito prima di chiamare
il metodo ereditato. Per esempio, se il codice ereditato in qualche modo dipendente
dallo stato del componente e il proprio codice modifica lo stato, occorrerebbe
effettuare le modifiche e poi consentire al codice dellutente di rispondere ad esse.
Si supponga che si stia scrivendo un componente e si voglia modificare il modo con
cui risponde al clic del mouse. Invece di assegnare un gestore allevento OnClick
come farebbe uno sviluppatore di applicazioni, si pu sostituire il metodo Click
protetto:
. __.isci .c.
,ccc.
. __.isci .i.cc,
,cc
i __.isci icic~ci,
,
Quello che segue il codice, incluso nel file .CPP, che implementa i metodi:
. __.isci .i.,c.,c.i.cc
-c -c - ,
. . - ,
__.isci .i.,c.,cicic~ci
c . -c,
U s o d e l l a g r a f i c a n e i c o mp o n e n t i 50-1
C a p i t o l o
50
Capitolo50Uso della grafica nei componenti
Windows dispone di una potente interfaccia GDI (graphics device interface) per
disegnare grafici indipendenti dal dispositivo. La GDI richiede al programmatore
ulteriori requisiti, come ad esempio la gestione delle risorse grafiche. C++Builder si
fa carico di tutte le fastidiose incombenze necessarie alla GDI, permettendo di
concentrarsi sul lavoro produttivo invece di andare alla ricerca di handle persi o di
risorse non rilasciate.
Le funzioni GDI, come qualsiasi parte delle API di Windows, possono essere
chiamate direttamente dallapplicazione C++Builder. Molto probabilmente, per, si
noter che pi rapido e semplice usare lincapsulamento delle funzioni grafiche di
C++Builder.
Le funzioni GDI sono specifiche per Windows e non sono utilizzabili in ambiente
CLX o per applicazioni multipiattaforma. Tuttavia, i componenti CLX utilizzano una
libreria Qt.
Gli argomenti trattati in questa sezione includono:
Introduzione alla grafica
Utilizzo del canvas
Operazioni con le immagini
Le bitmap fuori schermo
Risposta alle modifiche
Introduzione alla grafica
C++Builder incapsula la GDI di Windows (QT di CLX) in vari modi. Laspetto pi
significativo per lo sviluppatore di componenti il modo in cui il componente mostra
la propria immagine sullo schermo. Quando viene chiamata direttamente una
funzione GDI, necessario avere un handle per un contesto di dispositivo, allinterno
del quale vengono selezionati gli strumenti di disegno come la penna, il pennello e il
50-2 G u i d a a l l a p r o g r a mma z i o n e
I n t r o d u z i o n e a l l a g r a f i c a
font. Una volta terminata la realizzazione dellimmagine, il programmatore deve
personalmente riportare il device context allo stato originario e poi rilasciarlo.
Anzich obbligare ad operare sulla grafica a livelli particolareggiati, C++Builder
fornisce uninterfaccia semplice ma molto completa: la propriet Canvas di un
componente. Il canvas garantisce di avere sempre disponibile un device context
valido, che viene rilasciato non appena si finito di usarlo. Analogamente, il canvas
ha una serie di propriet specifiche che rappresentano la penna, il pennello e il font
correnti.
Poich il canvas gestisce automaticamente tutte queste risorse, lo sviluppatore di
componenti non deve preoccuparsi di creare, selezionare e rilasciare direttamente
cose come gli handle di penna. sufficiente ordinare al canvas di utilizzare un certo
tipo di penna e il canvas si occuper del resto.
Uno dei benefici della gestione delle risorse grafiche da parte di C++Builder sta nel
fatto che C++Builder pu mettere le risorse nella cache, velocizzando notevolmente
le operazioni ripetitive. Per esempio, se si sta creando unapplicazione che
ripetutamente genera, utilizza e rilascia un particolare tipo di penna, non necessario
ripetere tutte queste operazioni ogni volta allinterno di un ciclo. C++Builder, infatti,
salva le risorse grafiche allinterno della cache; in questo modo non deve ricreare lo
strumento, ma si limita a riutilizzarne uno esistente.
Un esempio di quanto detto pu essere una applicazione che ha dozzine di schede
aperte, con centinaia di controlli. Ognuno di questi controlli pu avere una o pi
propriet TFont. Anche se ci pu generare centinaia o migliaia di istanze di oggetti
TFont, la maggior parte delle applicazioni tende ad utilizzare solo due o tre handle di
font grazie alla cache per i font.
Di seguito sono riportati due esempi che illustrano quanto sia semplice la codifica
della grafica con C++Builder. Il primo esempio usa le funzioni GDI standard per
disegnare unellisse gialla tracciata su sfondo blu nella finestra, secondo una tecnica
adottata con altri strumenti di sviluppo. Il secondo usa un canvas per disegnare la
stessa ellisse in unapplicazione scritta con C++Builder.
Questo il codice ObjectWindows:
veIi ....i .i, c cisc, cc cc
iis>.c> cc,
iis>s> cc.,
iis>,sc, ., , ,
L.ic>.cc>i..c'c...sicic.,',
Loggetto picture riconosce lestensione .bmp come estensione standard per i file
bitmap, pertanto crea il proprio grafico come TBitmap e quindi chiama il metodo
LoadFromFile del grafico. Poich il grafico una bitmap, carica limmagine dal file
sotto forma di bitmap.
Gestione delle tavolozze
Nel caso di componenti della VCL e della CLX, quando lesecuzione del programma
avviene su dispositivi basati su tavolozza (tipicamente, in modalit video a 256
colori), C++Builder controlla automaticamente la realizzazione della tavolozza di
supporto. Cio se si ha un controllo che ha una tavolozza, si possono utilizzare i due
metodi ereditati da TControl per controllare come Windows utilizza la tavolozza.
Il supporto delle tavolozza per i controlli presenta due aspetti:
Specifica di una tavolozza per un controllo
Risposta alle modifiche della tavolozza
Molti controlli non hanno bisogno di una tavolozza, ma i controlli che contengono
immagini grafiche molto colorate (come un controllo image) possono aver bisogno
di interagire con Windows e con il driver dello schermo per assicurare un aspetto
appropriato. Windows fa riferimento a questo processo definendolo realizing delle
tavolozze.
Il realizing delle tavolozze il processo che garantisce che la finestra frontale utilizzi
la tavolozza completa, mentre quelle di sfondo ne utilizzino il massimo possibile,
mappando poi gli altri colori a quelli pi simili disponibili nella tavolozza effettiva.
Quando le finestre vengono spostate luna di fronte allaltra, Windows esegue
nuovamente il realizing.
_
Anche C++Builder non fornisce un supporto specifico per creare o gestire le
tavolozze, se non nel caso delle bitmap. Se si dispone di un handle di tavolozza,
comunque, i controlli C++Builder sono in grado di gestirlo.
Specifica di una tavolozza per un controllo
Per specificare la tavolozza per un controllo della VCL e della CLX, ridefinire il
metodo GetPalette del controllo affinch restituisca lhandle della tavolozza.
Quando la tavolozza di un controllo viene specificata esplicitamente, avvengono due
cose:
Lapplicazione viene informata che la tavolozza del controllo deve essere
sottoposta al processo di realizing.
La tavolozza da usare nel realizing viene esplicitata.
50-6 G u i d a a l l a p r o g r a mma z i o n e
L e b i t m a p f u o r i s c h e r m o
Risposta alle modifiche della tavolozza
Se un controllo della VCL e della CLX specifica una tavolozza ridefinendo GetPalette,
C++Builder si occupa automaticamente di rispondere ai messaggi di Windows
relativi alla tavolozza. Il metodo che gestisce i messaggi relativi alle tavolozza
PaletteChanged.
Lo scopo primario di PaletteChanged determinare se il realizing della tavolozza del
controllo deve avvenire in foreground o in background. Windows gestisce il realizing
delle tavolozza facendo in modo che la finestra frontale abbia una tavolozza di
foreground e che le altre finestre dispongano di tavolozze di background.
C++Builder migliora questo trattamento poich provvede al realizing delle tavolozze
dei controlli che si trovano allinterno di una stessa finestra secondo la sequenza di
accesso tramite il tasto TAB. Lunico caso in cui potrebbe essere necessario ridefinire
questo comportamento predefinito quando si desidera che un controllo, che non il
primo nella sequenza, abbia la tavolozza di foreground.
Le bitmap fuori schermo
Durante il disegno di immagini grafiche complesse, una comune tecnica nella
programmazione grafica consiste nel creare una bitmap esternamente allo schermo,
di tracciare limmagine sulla bitmap e di copiare infine limmagine completa dalla
bitmap alla destinazione finale sullo schermo. Lutilizzo di questa tecnica riduce lo
sfarfallio che sarebbe altrimenti causato dalle ripetute operazioni di disegno
direttamente sullo schermo.
La classe bitmap di C++Builder, usata per rappresenta immagini bitmap in risorse e
file, pu operare anchessa come unimmagine fuori schermo.
I due aspetti principali relativi alle operazioni con bitmap fuori schermo sono:
Creazione e gestione di bitmap fuori schermo.
Copia di immagini bitmap.
Creazione e gestione di bitmap fuori schermo
Quando si crea unimmagine grafica complessa, consigliabile non disegnarla
direttamente sul canvas che appare sullo schermo. Anzich disegnare sul canvas
della scheda o del controllo, si pu costruire un oggetto bitmap, disegnare sul canvas
delloggetto, e infine copiare limmagine cos completata nel canvas sullo schermo.
Luso pi comune di una bitmap fuori schermo avviene nel metodo Paint di un
controllo grafico.
Per un esempio di come disegnare unimmagine complessa su una bitmap fuori
schermo, esaminare il codice sorgente del controllo Gauge presente nella pagina
Samples della Component palette. Il controllo gauge traccia le varie forme e il testo
su una bitmap fuori schermo prima di copiarle sullo schermo. Il codice sorgente del
controllo reperibile nel file Cgauges.cpp presente nella subdirectory Examples\
Controls\Source.
U s o d e l l a g r a f i c a n e i c o mp o n e n t i 50-7
R i s p o s t a a l l e m o d i f i c h e
Copia di immagini bitmap
C++Builder consente di usare quattro modi differenti per copiare le immagini da un
canvas allaltro. A seconda delleffetto che si vuole ottenere, occorre chiamare un
metodo differente.
La Tabella 50.2 riassume i metodi per la copia di immagini negli oggetti canvas.
Risposta alle modifiche
Tutti gli oggetti grafici, incluso i canvas e i relativi oggetti posseduti (penne, pennelli,
e font), possiedono eventi predefiniti per rispondere alle modifiche delloggetto.
Usando questi eventi, si pu fare in modo che i componenti (o le applicazioni che li
usano) rispondano alle modifiche ridisegnando le proprie immagini.
Rispondere alle modifiche negli oggetti grafici particolarmente importante se li si
rende pubblici come parte dellinterfaccia di progettazione dei componenti. Lunico
modo per assicurarsi che laspetto del componente in fase di progetto coincida con le
propriet impostate nell Object Inspector quello di rispondere alle modifiche degli
oggetti.
Per rispondere ai cambiamenti in un oggetto grafico, assegnare un metodo allevento
OnChange della classe.
Il componente shape rende pubbliche le propriet che rappresentano la penna e il
pennello usati per disegnarne il contorno. Il costruttore del componente assegna un
metodo allevento OnChange di ciascuno di essi, facendo in modo che il componente
si ridisegni automaticamente a video nel caso vengano modificati la penna o il
pennello. Sebbene il componente shape sia scritto in Object Pascal, quella che segue
la traduzione in linguaggio C++ del componente shape con un nuovo nome,
TMyShape.
Questa la dichiarazione della classe nel file header:
ciss .~~ ..i,c ,cc i,c
,ic
,ccc.
,cc
i __.isci ..i,c.,c .c,
__,csc.
Tabella 50.2 Metodi per la copia di immagini
Per creare questo effetto Chiamare questo metodo
Copiare un intero grafico. Draw
Copiare e ridimensionare un grafico. StretchDraw
Copiare parte di un canvas. CopyRect
Copiare una bitmap con operazioni raster. BrushCopy (VCL)
Copiare un grafico pi volte affiancandolo
fino a riempire unarea.
TiledDraw(CLX)
50-8 G u i d a a l l a p r o g r a mma z i o n e
R i s p o s t a a l l e m o d i f i c h e
.c .c,
s s,
. __.isci .cic.ccc .c.c,
,
Questo il codice nel file .CPP:
__.isci ..i,c..i,c.,c .c
i,c.c
. ,
-c ,
.c c. .c,
.c>ic .cic.,
s c. s,
s>ic .cic.,
Li.ic,
G e s t i o n e d e i me s s a g g i e d e l l e n o t i f i c h e d i s i s t e ma 51-1
C a p i t o l o
51
Capitolo51Gestione dei messaggi e delle
notifiche di sistema
I componenti spesso devono rispondere alle notifiche dal sistema operativo
sottostante. Il sistema operativo informa lapplicazione di accadimenti, come ad
esempio, ci che fa lutente con il mouse e con la tastiera. Anche alcuni controlli
generano delle notifiche, come i risultati delle azioni dellutente quale, ad esempio, la
selezione di un elemento in una casella di riepilogo. La VCL e la CLX gestiscono gi
la maggior parte delle comuni notifiche. comunque possibile che vi sia la necessit
di scrivere un codice proprio per gestire tali notificazioni.
Nella VCL, le notifiche arrivano sotto forma di messages. Questi messaggi possono
provenire da una qualsiasi sorgente, inclusi Windows, i componenti della VCL e i
componenti che sono statidefiniti. Vi sono tre aspetti da considerare quando si opera
con i messaggi:
Il sistema di gestione dei messaggi
Modifica della gestione dei messaggi
Creazione di nuovi gestori di messaggio
In CLX, le notifiche arrivano sotto forma di segnali e di eventi di sistema invece che
sotto forma di messaggi di Windows. Per i dettagli su come operare con le notifiche
di sistema nella CLX, vedere Risposta alle notifiche di sistema utilizzando la CLX a
pagina 51-11.
Il sistema di gestione dei messaggi
Tutte le classi della VCL dispongono di un meccanismo incorporato per la gestione
dei messaggi, cosiddetti metodi di gestione dei messaggi o gestori dei messaggi.
Lidea fondamentale nella gestione dei messaggi che le classi ricevono messaggi di
qualche tipo e li distribuiscono, chiamando un determinato metodo appartenente a
51-2 G u i d a a l l a p r o g r a mma z i o n e
I l s i s t e m a d i g e s t i o n e d e i m e s s a g g i
un gruppo, a seconda del messaggio ricevuto.Se non esiste nessun metodo specifico
per un determinato messaggio, viene richiamato un gestore predefinito.
Lo schema che segue mostra come funziona il meccanismo di smistamento dei
messaggi:
La Visual Component Library definisce un sistema di smistamento dei messaggi che
trasforma tutti i messaggi di Windows (compresi quelli definiti dallutente), diretti a
una classe particolare, in chiamate a metodi. Non sar mai necessario modificare il
meccanismo di smistamento dei messaggi. Tutto ci che occorre fare creare metodi
per gestire i messaggi. Per maggiori informazioni consultare la sezione
Dichiarazione di un nuovo metodo di gestione messaggi a pagina 51-8.
Cosa contiene un messaggio di Windows?
Un messaggio di Windows pu essere immaginato come una struttura di dati che
contiene diversi membri dati utili. Il pi importante di questi rappresentato da un
valore di tipo integer che identifica il messaggio. Windows definisce molti messaggi,
e il file MESSAGES.HPP ne dichiara tutti gli identificatori.
I programmatori Windows sono soliti lavorare con le definizioni di Windows che
identificano un messaggio, come, ad esempio, WM_COMMAND o WM_PAINT. Un
programma Windows tradizionale contiene una procedura di finestra che serve
come callback per i messaggi generati dal sistema. In questa procedura di finestra
esiste solitamente unistruzione switch piuttosto corposa con varie istruzioni case,
una per ciascun messaggio che questa finestra in grado di gestire.
A questa procedura per finestra vengono passate ulteriori informazioni utili
mediante due parametri, wParam e lParam, per word parameter e long parameter.
Spesso, ogni parametro contiene pi di una porzione di informazione ed necessario
estrarre la porzione rilevante mediante le macro di Windows, quali LOWORD e
HIWORD. Per esempio, chiamando HIWORD( lParam ) si ricava la word alta di
questo parametro.
Originariamente, i programmatori Windows erano costretti a ricordare o a cercare
nelle API di Windows quali informazioni erano contenute in ogni parametro.
Windows ha recentemente implementato i message crackers per semplificare la
sintassi relativa alla gestione dei messaggi Windows e dei parametri associati. Con i
message crackers, anzich utilizzare una vasta istruzione switch che analizza tutte le
informazioni contenute nei parametri, si pu semplicemente associare al messaggio
una funzione di gestione. Se si include WINDOWSX.H in un programma Windows
standard, risulta disponibile la macro HANDLE_MSG e si pu scrivere un codice
come questo:
. .c.-i.c -. .., L. c, .., c,ci, L. .is
. ...c -. .., L. .cssic, .~~. ..ii., .~~. .ii.
Event MainWndProc WndProc Dispatch Handler
G e s t i o n e d e i me s s a g g i e d e l l e n o t i f i c h e d i s i s t e ma 51-3
I l s i s t e m a d i g e s t i o n e d e i m e s s a g g i
s.c .cssic
Luso di questo stile di frantumazione dei messaggi rende pi palese il fatto che i
messaggi vengono smistati a particolari gestori. Inoltre, si possono dare nomi
significativi alla lista dei parametri per le proprie funzioni di gestione. In questo
modo pi facile comprendere una funzione che accetta un parametro chiamato
nVirtKey, il quale rappresenta il valore di wParam in un messaggio WM_KEYDOWN.
Smistamento dei messaggi
Quando unapplicazione crea una finestra, essa registra nel kernel di Windows una
procedura di finestra. La procedura di finestra la routine che gestisce i messaggi per
la finestra. Tradizionalmente, nella procedura di finestra c unistruzione switch
piuttosto corposa che contiene gli elementi di ciascun messaggio che dovr essere
gestito dalla finestra. bene ricordare che il termine finestra, in questa accezione,
pu far riferimento a qualsiasi cosa presente sullo schermo: ogni finestra, ogni
controllo e cos via. Ogni volta che si crea un nuovo tipo di finestra, necessario
creare una procedura di finestra completa.
La VCL semplifica lo smistamento dei messaggi in vari modi:
Ciascun componente eredita un sistema completo per lo smistamento dei
messaggi.
Il sistema di smistamento ha una gestione standard. Il programmatore deve
definire solo gli handle per i messaggi ai quali va data una risposta particolare.
possibile modificare una piccola parte della gestione dei messaggi e affidarsi ai
metodi ereditati per la maggior parte dellelaborazione.
Il maggior vantaggio di questo sistema di smistamento messaggi risiede nella
possibilit di inviare in tutta sicurezza qualsiasi messaggio a qualsiasi componente in
qualsiasi momento. Se il componente non ha un gestore per quel messaggio, la
gestione predefinita che se ne occupa, di solito ignorando il messaggio.
Il flusso dei messaggi
La VCL registra un metodo di nome MainWndProc come procedura per finestra per
ciascun tipo di componente presente in unapplicazione. MainWndProc contiene un
blocco per la gestione delle eccezioni, che passa la struttura del messaggio da
Windows a un metodo virtuale di nome WndProc e che gestisce qualunque eccezione
chiamando il metodo HandleException della classe applicazione.
MainWndProc un metodo non virtuale che non contiene alcuna gestione per nessun
particolare messaggio. Le personalizzazioni avvengono in WndProc, dal momento
che ogni tipo di componente pu ridefinire il metodo per soddisfare le proprie
particolari necessit.
51-4 G u i d a a l l a p r o g r a mma z i o n e
M o d i f i c a d e l l a g e s t i o n e d e i m e s s a g g i
I metodi WndProc controllano tutte le condizioni particolari che possono influenzare
lelaborazione catturando i messaggi non desiderati. Per esempio, mentre vengono
trascinati, i componenti ignorano gli eventi di tastiera, pertanto il metodo WndProc di
TWinControl lascia passare gli eventi di tastiera solo se il componente non viene
trascinato. Infine, WndProc chiama Dispatch, un metodo non virtuale ereditato da
TObject, che stabilisce quale metodo chiamare per gestire il messaggio.
Dispatch utilizza il membro dati Msg della struttura del messaggio per stabilire come
smistare un particolare messaggio. Se il componente definisce un gestore per quel
particolare messaggio, Dispatch chiama il metodo. Se il componente non definisce un
gestore per quel messaggio, Dispatch chiama DefaultHandler.
Modifica della gestione dei messaggi
Prima di cambiare la gestione dei messaggi dei propri componenti, accertarsi che
questo sia veramente ci che si desidera. La VCL traduce la maggior parte dei
messaggi Windows in eventi che possono essere gestiti sia da chi scrive componenti
sia da chi li utilizza. Invece di cambiare il comportamento della gestione dei
messaggi, pi probabile che occorra modificare il comportamento della gestione
dellevento.
Per cambiare la gestione dei messaggi nei componenti della VCL, si ridefinisce il
metodo che gestisce il messaggio. In determinate circostanze, si pu anche impedire
che un componente gestisca un messaggio, intercettando il messaggio stesso.
Ridefinizione del metodo di gestione
Per cambiare il modo in cui un componente gestisce un particolare messaggio, si
deve ridefinire il metodo che lo gestisce. Se il componente non gestisce gi quel
particolare messaggio, diventa necessario dichiarare un nuovo metodo per la
gestione.
Per ridefinire il metodo di gestione di un messaggio,
1 Dichiarare nella parte protetta della dichiarazione del componente un nuovo
metodo nel proprio componente con lo stesso nome del metodo che si vuole
ridefinire.
Correlare il metodo al messaggio che esso ridefinisce utilizzando tre macro.
Le macro assumono questa forma:
L._...~_.~.
...~_-~.,ii.cc, ,ii.cc., ,ii.cc
._...~_.~.
Parameter1 lindice del messaggio definito da Windows, parameter2 il tipo di
struttura del messaggio, e parameter3 il nome del metodo del messaggio.
possibile inserire un numero qualunque di macro MESSAGE_HANDLER tra le
macro BEGIN_MESSAGE_MAP e END_MESSAGE_MAP.
G e s t i o n e d e i me s s a g g i e d e l l e n o t i f i c h e d i s i s t e ma 51-5
M o d i f i c a d e l l a g e s t i o n e d e i m e s s a g g i
Per esempio, per ridefinire la gestione del componente del messaggio WM_PAINT, si
deve ridichiarare il metodo WMPaint, e con le tre macro si deve correlare il metodo al
messaggio WM_PAINT:
ciss .~~ ..,c ,cc .,c
,ccc.
. __.isci ..i..i .cssic,
L._...~_.~.
...~_-~.._.~L., ..i, ..i
._...~_.~..,c
,
Uso dei parametri del messagio
Una volta allinterno del metodo di gestione dei messaggi, il componente ha accesso
a tutti i parametri della struttura dei messaggi. Poich il parametro passato al gestore
di messaggi un puntatore, il gestore, se necessario, pu modificare il valore dei
parametri. Lunico parametro che cambia frequentemente il valore di ritorno del
messaggio: il valore restituito dalla chiamata a SendMessage che invia il messaggio.
Poich nel metodo di gestione dei messaggi il tipo del parametro Message varia in
funzione del messaggio gestito, per informazioni sui nomi e sul significato dei singoli
parametri necessario fare riferimento alla documentazione relativa ai messaggi di
Windows. Se per qualsiasi ragione fosse necessario fare riferimento ai parametri del
messaggio usando la vecchia denominazione (WParam, LParam e cos via), possibile
effettuare la conversione di tipo da Message al tipo generico TMessage, che utilizza
quei nomi di parametri.
Intercettazione dei messaggi
In alcune circostanze potrebbe risultare preferibile che i componenti ignorino i
messaggi. Vale a dire, si potrebbe impedire che il componente smisti il messaggio al
proprio gestore. Per intercettare il messaggio, occorre ridefinire il metodo virtuale
WndProc .
Per i componenti della VCL, il metodo WndProc analizza i messaggi prima di passarli
al metodo Dispatch, il quale, a sua volta, determina quale metodo usare per gestire il
messaggio. Se si ridefinisce WndProc, il componente ha la possibilit di filtrare i
messaggi prima di smistarli. La ridefinizione di WndProc di un controllo derivato da
TWinControl assomiglia allesempio seguente:
. __.isci ...c.cssic .cssic
51-6 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i n u o v i g e s t o r i d i m e s s a g g i o
Il componente TControl definisce lintera serie di messaggi relativi al mouse e li filtra
se un utente esegue operazioni di drag and drop con i controlli. Ridefinendo
WndProc, questo compito viene facilitato in due modi:
possibile filtrare gruppi di messaggi anzich specificare i gestori per ciascuno di
essi.
possibile impedire completamente che il messaggio venga smistato, in modo che
i gestori non siano mai chiamati.
Qui di seguito viene riportata una parte del metodo WndProc per TControl cos come
stata implementata nella VCL in Object Pascal:
pteceiate ..cvat .cssic .cssic,
beIa
,ccc.
. __.isci .ic.cssic .cssic,
L._...~_.~.
...~_-~.._-~., .cssic, .ic
._...~_.~.
,
. __.isci ..ic.cssic .cssic
.cssic.ii., sc c .. ,ii.cc
.ic.cssic, ci c cc. .cssic i.c
Invio di messaggi
Di solito, unapplicazione manda un messaggio per inviare notifiche di modifiche
allo stato o per trasmettere informazioni. Il componente pu trasmettere messaggi a
tutti i controlli in una scheda, inviare messaggi a un particolare controllo (o
allapplicazione stessa) o anche inviare messaggi a se stesso.
G e s t i o n e d e i me s s a g g i e d e l l e n o t i f i c h e d i s i s t e ma 51-9
C r e a z i o n e d i n u o v i g e s t o r i d i m e s s a g g i o
Esistono vari modi per inviare un messaggio Windows. Il metodo utilizzato dipende
dal tipo di messaggio inviato. I seguenti argomenti descrivono i diversi modi per
inviare messaggi Windows.
Trasmissione di un messaggio a tutti i controlli in una scheda
Quando il componente modifica delle impostazioni globali che influiscono su tutti i
controlli in una scheda o in altro contenitore, si potrebbe volere inviare un messaggio
a quei controlli in modo che essi si possano aggiornare adeguatamente. Non tutti i
controlli potrebbero avere bisogno di rispondere alla notifica, ma trasmettendo il
messaggio, possibile informare tutti i controlli che sanno come rispondere e
permettere agli altri controlli di ignorare il messaggio.
Per trasmettere un messaggio a tutti i controlli in un altro controllo, utilizzare il
metodo Broadcast. Prima di trasmettere un messaggio, si riempie una struttura di
messaggio con le informazioni che si desidera comunicare. (Per informazioni sulle
strutture dei messaggi, vedere Dichiarazione di un tipo di struttura di messaggio a
pagina 51-7).
.cssic .s,
.s.s ._......~,
.s.ii. ,
.s.ii. IattaIa,
.scs ,
Quindi, passare questa struttura di messaggio al genitore di tutti i controlli a cui si
desidera inviare la notifica. Questi pu essere un qualsiasi controllo
nellapplicazione. Ad esempio, pu essere il genitore del controllo che si sta
scrivendo:
.ic>i.cis.s,
Pu essere la scheda che contiene il controllo:
c.ic.taIa>i.cis.s,
Pu essere la scheda attiva:
.ccc>~cc.>i.cis.s,
Possono anche essere tutte le schede nellapplicazione:
?et Iat , .ccc>., --
.ccc>.s,>i.cis.s,
Chiamata diretta del gestore del messaggio di un controllo
Talvolta c solo un singolo controllo che deve rispondere al messaggio. Se si conosce
il controllo che dovrebbe ricevere il messaggio, il modo pi semplice e diretto per
inviare il messaggio consiste nel chiamare il metodo Perform del controllo.
Vi sono due motivi principali per cui si chiama il metodo Perform di un controllo:
Si desidera innescare la stessa risposta che il controllo d ad un messaggio
standard Windows (o ad un altro). Ad esempio, quando un controllo griglia riceve
un messaggio di pressione tasti, crea un controllo inline di edit e quindi invia il
messaggio di pressione tasti al controllo di edit.
51-10 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i n u o v i g e s t o r i d i m e s s a g g i o
Il controllo a cui si desidera inviare la notifica potrebbe essere noto, ma si potrebbe
non sapere che tipo di controllo . Poich non si conosce il tipo del controllo di
destinazione, non si pu utilizzare nessuno dei suoi metodi specializzati, ma
poich tutti i controlli hanno la capacit di gestire i messaggi sempre possibile
inviare un messaggio. Se il controllo ha un gestore di messaggio per il messaggio
che viene inviato, risponder adeguatamente. Altrimenti, ignorer il messaggio
inviato e restituir 0.
Per chiamare il metodo Perform, non necessario creare una struttura di messaggio.
necessario solo passare come parametri lidentificativo del messaggio, WParam e
LParam. Perform restituisce il risultato del messaggio.
Invio di un messaggio utilizzando la coda dei messaggi Windows
In unapplicazione multithread non sufficiente chiamare il metodo Perform perch il
controllo di destinazione in un thread diverso da quello che in esecuzione.
Tuttavia, utilizzando la coda dei messaggi Windows, possibile comunicare in tutta
sicurezza con altri thread. La gestione dei messaggi si verifica sempre nel thread VCL
principale, ma possibile mandare un messaggio mediante la coda dei messaggi
Windows da un qualsiasi thread nellapplicazione. Una chiamata a SendMessage
sincrona. Cio, SendMessage non ritorna finch il controllo di destinazione non ha
gestito il messaggio, anche se in un altro thread.
Utilizzare la chiamata API Windows, SendMessage, per inviare un messaggio a un
controllo utilizzando la coda dei messaggi Windows. SendMessage accetta gli stessi
parametri del metodo Perform, salvo la necessit di identificare il controllo di
destinazione passando il suo handle Window. Cos, invece di scrivere
.scs ic>.c..._....~, , ,
si dovrebbe scrivere
.scs .c..cssicic>-i.c, ....~, , ,
Per maggiori informazioni sulla funzione di SendMessage, consultare la
documentazione MSDN di Microsoft. Per ulteriori informazioni sulla scrittura di pi
thread che possono essere contemporaneamente in esecuzione, vedere
Coordinamento dei thread on pagina 11-7.
Invio di un messaggio che non viene eseguito immediatamente
A volte si potrebbe volere inviare un messaggio ma non si sa se sia sicuro che il
destinatario del messaggio lo esegua immediatamente. Ad esempio, se il codice che
invia un messaggio viene chiamato da un gestore di evento sul controllo di
destinazione, si potrebbe volere essere certi che lesecuzione del gestore di evento sia
terminata prima che il controllo esegua il messaggio. possibile gestire questa
situazione a patto che non sia necessario conoscere il risultato del messaggio.
Utilizzare la chiamata API Windows, PostMessage, per inviare un messaggio a un
controllo e al contempo consentirgli di attendere di aver terminato di gestire tutti gli
altri messaggi prima di gestire il vostro. PostMessage accetta esattamente gli stessi
parametri di SendMessage.
G e s t i o n e d e i me s s a g g i e d e l l e n o t i f i c h e d i s i s t e ma 51-11
R i s p o s t a a l l e n o t i f i c h e d i s i s t e m a u t i l i z z a n d o l a C L X
Per maggiori informazioni sulla funzione di PostMessage, consultare la
documentazione MSDN di Microsoft.
Risposta alle notifiche di sistema utilizzando la CLX
Quando si utilizza Windows, il sistema operativo invia le notifiche direttamente
allapplicazione e ai controlli che essa contiene utilizzando messaggi Windows.
Questo approccio, tuttavia, non appropriato per la CLX, in quanto la CLX una
libreria multipiattaforma e i messaggi Windows non sono utilizzati in Linux. Per
rispondere alle notifiche di sistema CLX utilizza invece una modalit indipendente
dalla piattaforma
In CLX, la modalit analoga ai messaggi Windows un sistema di segnali
provenienti dallo strato del widget sottostante. Mentre nella VCL i messaggi
Windows possono avere origine o dal sistema operativo o dai controlli Windows
nativi che la VCL avvolge, lo strato del widget utilizzato dalla CLX fa a una
distinzione fra questi due. Se la notifica ha origine da un widget, detta un segnale.
Se la notifica ha origine dal sistema operativo, detta evento di sistema. Lo strato del
widget comunica ai componenti CLX gli eventi di sistema come segnali di tipo evento.
Risposta ai segnali
Lo strato del widget sottostante emette una gamma di segnali, ognuno dei quali
rappresenta un tipo diverso di notifica. Questi segnali includono oltre agli eventi di
sistema (il segnale di evento) anche le notifiche specifiche del widget che le ha
generate. Ad esempio, tutti i widget quando vengono liberati generano un segnale
destroyed, i widget trackbar generano un segnale valueChanged, i controlli header
generano un segnale sectionClicked, e cos via.
Ogni componente CLX risponde ai segnali provenienti dal proprio widget
sottostante assegnando un metodo come gestore del segnale. Ci viene fatto
utilizzando un oggetto hook speciale, associato al widget sottostante. Loggetto hook
un oggetto leggero che in realt solo una raccolta di puntatori a metodo, ognuno
dei quali specifico per un particolare segnale. Quando un metodo del componente
CLX stato assegnato alloggetto hook come gestore di un segnale specifico, ogni
volta che il widget genera il segnale specifico, viene chiamato il metodo sul
componente CLX. Questo comportamento illustrato nella Figura 51.1.
Figura 51.1 Instradamento del segnale
QWidget
QHook (Widget)
TWidgetControl
Method
Event
Filter
51-12 G u i d a a l l a p r o g r a mma z i o n e
R i s p o s t a a l l e n o t i f i c h e d i s i s t e m a u t i l i z z a n d o l a C L X
_
I metodi di ogni oggetto hook sono dichiarati nella unit Qt. Controllare il file qt.hpp
per vedere i metodi disponibili per un determinato oggetto hook. I metodi sono
semplificati in routine globali con nomi che riflettono loggetto hook a cui essi
appartengono. Ad esempio, tutti i metodi sulloggetto hook associato al widget
applicazione (QApplication) iniziano QApplication_hook. Questa semplificazione
necessaria in modo che loggetto CLX di Object Pascal possa accedere ai metodi
delloggetto hook di C++.
Assegnazione dei gestori di segnale custom
Molti controlli CLX assegnano gi metodi per gestire segnali dal widget sottostante.
Di solito, questi metodi sono privati e non virtuali. Pertanto, se si desidera scrivere
un proprio metodo per rispondere a un segnale, necessario assegnare il metodo
alloggetto hook associato al widget. Per fare ci, si deve ridefinire il metodo
HookEvents.
_
Se il segnale a cui si desidera rispondere una notifica di un evento di sistema, non si
deve utilizzare una ridefinizione del metodo HookEvents. Per i dettagli su come
rispondere agli eventi di sistema, vedere Risposta a eventi di sistema nel prosieguo
del capitolo.
Nella ridefinizione del metodo HookEvents, dichiarare una variabile di tipo TMethod.
Quindi, per ogni metodo che si desidera assegnare come gestore di segnale
alloggetto hook, fare quanto segue:
1 Inizializzare la variabile del tipo TMethod per rappresentare un gestore di metodo
per il segnale.
2 Assegnare questa variabile alloggetto hook. possibile accedere alloggetto hook
utilizzando la propriet Hooks che il componente eredita da THandleComponent o
TWidgetControl.
Nella ridefinizione, chiamare sempre il metodo ereditato HookEvents in modo da
connettere anche i gestori di segnale assegnati dalle classi di base.
Il codice seguente una traduzione del metodo HookEvents di TTrackBar. Illustra
come ridefinire il metodo HookEvents per aggiungere dei gestori custom di segnale.
vIttaaI veIi __?aatcaII ic.i-.csveIi
.c. .c.,
i.c .c. c,csc i i.c . c _..c icic. si
icic.-. s i .c. . ic.i i cs,.s c si
_..c_icic._c.c. icic.-.,
~ss .c. c . ccc .c i ci cis -.s c
,c . . ccc isscic. . c .c ..c
_..c_._._icic.i,aaeIc_caat _..c_.->-.s, .c.,
c,ci c ,ccss . c s.c.c. cc
_..c_s.c.c._c.c. icic.-.,
_..c_._._icic.i,aaeIc_caat _..c_.->-.s, .c.,
i c cc. .c. s i cc. si i.cs ic .c. ,
.c-.cs,
G e s t i o n e d e i me s s a g g i e d e l l e n o t i f i c h e d i s i s t e ma 51-13
R i s p o s t a a l l e n o t i f i c h e d i s i s t e m a u t i l i z z a n d o l a C L X
Risposta a eventi di sistema
Quando lo strato del widget riceve una notifica di evento dal sistema operativo,
genera uno speciale oggetto evento (QEvent o uno dei suoi discendenti) per
rappresentare levento. Loggetto evento contiene informazioni a sola lettura
sullevento che si verificato. Il tipo delloggetto evento indica il tipo di evento che si
verificato.
Lo strato del widget notifica al componente CLX gli eventi di sistema utilizzando uno
speciale segnale di tipo evento. Esso passa loggetto QEvent al gestore di segnale
dellevento. Lelaborazione del segnale di evento un po pi complicata rispetto
allelaborazione di altri segnali in quanto arriva prima alloggetto applicazione. Ci
significa che unapplicazione ha due opportunit per rispondere a un evento di
sistema: una volta a livello dellapplicazione (TApplication) e una volta a livello del
singolo componente (il discendente TWidgetControl o THandleComponent). Tutte
queste classi (TApplication, TWidgetControl e THandleComponent) assegnano gi dallo
strato del widget un gestore di segnale per il segnale evento. Cio, tutti gli eventi di
sistema vengono indirizzati automaticamente al metodo EventFilter, che ha un ruolo
simile al metodo WndProc dei controlli VCL. La gestione degli eventi di sistema
illustrata nella Figura 51.2.
Figura 51.2 Instradamento dellevento di sistema
EventFilter gestisce la maggior parte delle notifiche di sistema comunemente
utilizzate, traducendole negli eventi che sono introdotti dalle classi di base del
componente. Cos, ad esempio, il metodo EventFilter di TWidgetControl risponde agli
eventi del mouse (QMouseEvent) generando gli eventi OnMouseDown, OnMouseMove
e OnMouseUp, agli eventi di tastiera (QKeyEvent) generando gli eventi OnKeyDown,
OnKeyPress, OnKeyString e OnKeyUp, e cos via.
Eventi comunemente utilizzati
Il metodo EventFilter di TWidgetControl gestisce molte delle comuni notifiche di
sistema chiamando i metodi protetti introdotti in TControl o in TWidgetControl. La
maggior parte di questi metodi virtuale, in modo che sia possibile ridefinirli
durante la scrittura di componenti e implementare le risposte agli eventi di sistema.
QApplication
QHook (App)
TApplication
QEvent EventFilter()
Default Processing
QWidget
QHook (Widget)
TWidgetControl
EventFilter()
Default Processing
?
?
Operating
system
(XWindows,
MSWindows)
51-14 G u i d a a l l a p r o g r a mma z i o n e
R i s p o s t a a l l e n o t i f i c h e d i s i s t e m a u t i l i z z a n d o l a C L X
Quando si ridefiniscono questi metodi, non necessario preoccuparsi di operare con
loggetto evento o (nella maggior parte dei casi) con un qualunque altro oggetto
presente nello strato del widget sottostante.
Quando si desidera che il componente CLX risponda alle notifiche di sistema, bene
per prima cosa controllare se esiste gi un metodo protetto in grado di rispondere
alla notifica. possibile controllare la documentazione di TControl o di
TWidgetControl (e qualsiasi altra classe base da cui si deriva il componente) per
vedere se esiste un metodo protetto che risponda allevento a cui si interessati. La
Tabella 51.1 elenca i metodi protetti pi comunemente utilizzati da TControl e da
TWidgetControl che possibile utilizzare.
Nella ridefinizione, chiamare il metodo ereditato in modo che qualsiasi processo
predefinito possa ancora rispondere ai segnali.
_
Oltre ai metodi che rispondono agli eventi di sistema, i controlli includono molti
metodi simili che hanno origine con TControl o TWidgetControl per notificare al
controllo i diversi eventi. Bench questi non rispondano a eventi di sistema, essi
svolgono gli stessi compiti di molti messaggi Windows che vengono inviati ai
controlli VCL. La Tabella 51.1 elenca alcuni di questi metodi.
Tabella 51.1 Metodi protetti di TWidgetControl per la risposta ad eventi di sistema
Metodo Descrizione
BeginAutoDrag Chiamato quando lutente fa clic sul tasto sinistro del mouse se il controllo
ha un DragMode impostato a dmAutomatic.
Click Chiamato quando lutente rilascia il tasto del mouse sul controllo.
DblClick Chiamato quando lutente fa doppio clic con il mouse sul controllo.
DoMouseWheel Chiamato quando lutente gira la rotella del mouse.
DragOver Chiamato quando lutente trascina il cursore del mouse sul controllo.
KeyDown Chiamato quando lutente preme un tasto mentre il controllo ha il fuoco.
KeyPress Chiamato dopo KeyDown se KeyDown non gestisce la pressione del tasto.
KeyString Chiamato quando lutente preme un tasto nel caso in cui il sistema utilizzi
un sistema di caratteri multibyte.
KeyUp Chiamato quando lutente rilascia un tasto mentre il controllo ha il fuoco.
MouseDown Chiamato quando lutente fa clic sul tasto del mouse sul controllo.
MouseMove Chiamato quando lutente sposta il cursore del mouse sul controllo.
MouseUp Chiamato quando lutente rilascia il tasto del mouse sul controllo.
PaintRequest Chiamato quando il sistema deve ridisegnare il controllo.
WidgetDestroyed Chiamato quando si distrugge un widget che alla base di un controllo.
Tabella 51.2 Metodi protetti di TWidgetControl per la risposta ad eventi dai controlli
Metodo Descrizione
BoundsChanged Chiamato quando il controllo viene ridimensionato.
ColorChanged Chiamato quando viene modificato il colore del controllo.
CursorChanged Chiamato quando si modifica la forma del cursore. Il cursore del mouse
assume questa forma quando su questo widget.
G e s t i o n e d e i me s s a g g i e d e l l e n o t i f i c h e d i s i s t e ma 51-15
R i s p o s t a a l l e n o t i f i c h e d i s i s t e m a u t i l i z z a n d o l a C L X
Ridefinizione del metodo EventFilter
Se si desidera rispondere a una notifica di evento e non c alcun metodo protetto per
quellevento che possibile ridefinire, possibile ridefinire lo stesso metodo
EventFilter. Nella ridefinizione, controllare il tipo del parametro Event del metodo
EventFilter ed eseguire la propria particolare elaborazione quando rappresenta il tipo
di notifica a cui si desidera rispondere. possibile evitare unulteriore elaborazione
della notifica dellevento facendo in modo che il metodo EventFilter restituisca true.
_
Vedere la documentazione Qt della TrollTech per i dettagli sui vari tipi di oggetti
QEvent.
Il codice seguente una traduzione del metodo EventFilter di TCustomControl. Illustra
come ottenere il tipo di evento dalloggetto QEvent quando si ridefinisce EventFilter.
Notare che, bench non sia visibile nellesempio, una volta che si identificato il tipo
di evento, possibile convertire il tipo delloggetto QEvent in un appropriato
discendente specializzato di QEvent (come QMouseEvent).
vIttaaI beeI __?aatcaII s.cc__ccc- .c.c, __c-
c
beeI ci .ccc.c.c, c,
avItca _c_,cc
caae _c,c_cs.c
caae _c,c_csL
caae _c,c_cs
,.ic.is.,
tetata ci,
Generazione di eventi Qt
Analogamente al modo in cui un controllo VCL pu definire e inviare messaggi
Windows custom, possibile fare in modo che il controllo CLX definisca e generi
eventi Qt di sistema. Il primo passo consiste nel definire un ID univoco per levento
EnabledChanged Chiamato quando unapplicazione modifica lo stato enabled di una finestra
o di un controllo.
FontChanged Chiamato quando si modifica la raccolta di risorse dei font.
PaletteChanged Chiamato quando cambia la tavolozza del widget.
ShowHintChanged Chiamato quando si visualizzano o si nascondono i suggerimenti di un
controllo.
StyleChanged Chiamato quando vengono cambiati gli stili GUI della finestra o del
controllo.
TabStopChanged Chiamato quando si modifica la sequenza di tabulazione sulla scheda.
TextChanged Chiamato quando il testo del controllo viene modificato.
VisibleChanged Chiamato quando si nasconde o visualizza un controllo.
Tabella 51.2 Metodi protetti di TWidgetControl per la risposta ad eventi dai controlli (continua)
Metodo Descrizione
51-16 G u i d a a l l a p r o g r a mma z i o n e
R i s p o s t a a l l e n o t i f i c h e d i s i s t e m a u t i l i z z a n d o l a C L X
(simile al modo in cui necessario definire un ID di messaggio quando si definisce
un messaggio Windows custom):
atatIc ceaat .c_L Iat _.c,c_xsc - ,
Nel codice in cui si desidera generare levento, si utilizza la funzione
QCustomEvent_create (dichiarata in Qt.hpp) per creare un oggetto evento con il nuovo
ID di evento. Un secondo parametro facoltativo permette di fornire alloggetto
evento un valore che un puntatore alle informazioni che si vogliono associare
allevento:
_s.c- .c _s.c_ccic.c_L, s,
Una volta che si creato loggetto evento, possibile registrarlo chiamando il metodo
QApplication_postEvent:
_~,,ci_,sc~,,ci>-i.c, .c,
Affinch qualsiasi componente risponda a questa notifica, necessario solo
ridefinirne il metodo EventFilter, controllando un tipo di evento MyEvent_ID. Il
metodo EventFilter pu acquisire i dati forniti al costruttore chiamando il metodo
QCustomEvent_data, dichiarato in Qt.hpp.
C o me r e n d e r e d i s p o n i b i l i i c o mp o n e n t i i n f a s e d i p r o g e t t o 52-1
C a p i t o l o
52
Capitolo52Come rendere disponibili i
componenti in fase di progetto
Questo capitolo descrive le operazioni necessarie per rendere disponibili nellIDE i
componenti creati. Rendere disponibile i propri componenti in fase di progetto
unoperazione che richiede diverse fasi:
Registrazione di componenti
Aggiunta di bitmap alla tavolozza
Preparazione di un file di Guida per il componente
Aggiunta di editor di propriet
Aggiunta di editor di componenti
Compilazione dei componenti in package
Non tutte queste operazioni valgono per tutti i componenti. Per esempio, se non si
definiscono nuovi eventi o propriet, non occorre predisporre una specifica Guida
alluso. Le uniche operazioni sempre necessarie sono la registrazione e la
compilazione.
Una volta che i propri componenti sono stati registrati e compilati in package, essi
possono essere distribuiti ad altri sviluppatori e installati nellIDE. Per maggiori
informazioni sullinstallazione dei packages nellIDE, consultare il paragrafo
Installazione di package di componenti a pagina 15-6.
Registrazione di componenti
La registrazione si fonda sulle unit e pertanto, se si creano molti componenti in una
singola unit, possibile registrarli tutti in una volta.
Per registrare un componente, aggiungere una funzione Register nel file .CPP della
unit. Allinterno della funzione Register si registrano i componenti e si determina
dove installarli nella Component palette.
52-2 G u i d a a l l a p r o g r a mma z i o n e
R e g i s t r a z i o n e d i c o m p o n e n t i
_
Se si crea un componente scegliendo Component|New Component nellIDE, il
codice necessario per la sua registrazione viene aggiunto automaticamente.
I passi per registrare manualmente un componente sono:
Dichiarazione della funzione Register
Scrittura della funzione Register
Dichiarazione della funzione Register
La registrazione comporta la scrittura nel file .CPP della unit di ununica funzione, il
cui nome deve essere Register. La funzione Register deve esistere allinterno di un
namespace. Il namespace il nome del file in cui contenuto il componente con tutte
le lettere in minuscolo eccetto la prima.
Il codice seguente mostra come viene implementata la funzione Register allinterno di
un namespace. Il namespace viene chiamato Newcomp, mentre il file viene chiamato
Newcomp.CPP:
aaeeapace .c.c.,
Nellesempio vengono dichiarati due array, classes1 e classes2. Nella prima chiamata
a RegisterComponents larray classes1 ha 2 voci, per cui il terzo argomento lindice
della seconda voce, che 1. Nella seconda chiamata a RegisterComponents larray
classes2 ha un elemento, per cui il terzo argomento 0.
Aggiunta di bitmap alla tavolozza
Ogni componente ha bisogno di una bitmap per rappresentare il componente nella
Component palette. Se non si specifica una propria bitmap, C++Builder ne utilizza
una predefinita.
Poich le tavolozze sono necessarie soltanto in fase di progetto, non occorre
compilarle nella unit di compilazione del componente. Devono essere fornite come
una file risorsa di Windows con lo stesso nome del file .CPP, ma con estensione .DCR
(acronimo di Dynamic Component Resource). Questo file risorsa pu essere creato
utilizzando leditor Image in C++Builder. Ogni bitmap deve essere di 24 pixel
quadrati.
Per ogni componente che si vuole installare, occorre indicare un file bitmap della
tavolozza, allinterno del quale si deve fornire una bitmap per ogni componente che
si registra. Limmagine bitmap ha lo stesso nome della classe del componente. bene
tenere il file bitmap della tavolozza nella stessa directory in cui si trova il file
compilato, in modo che C++Builder possa trovare le bitmap quando installa i
componenti nella Component palette.
Ad esempio, se si vuole creare un componente di nome TMyControl, occorre creare
un file risorsa .DCR o .RES contenga una bitmap di nome TMYCONTROL. I nomi dei
file risorsa possono essere scritti in lettere maiuscole o minuscole, ma per
convenzione, sono generalmente in maiuscolo.
Preparazione di un file di Guida per il componente
Se si seleziona un componente standard su una scheda, o una propriet o un evento
nellObject Inspector, premendo il tasto F1 si richiama la Guida relativa a quel
determinato elemento. Creando opportuni file di Guida, si pu fornire agli
sviluppatori lo stesso tipo di documentazione per i propri componenti.
C o me r e n d e r e d i s p o n i b i l i i c o mp o n e n t i i n f a s e d i p r o g e t t o 52-5
P r e p a r a z i o n e d i u n f i l e d i G u i d a p e r i l c o m p o n e n t e
possibile fornire un piccolo file di guida che descriva i propri componenti. In
questo modo il proprio file diviene parte della Guida utente del sistema C++Builder.
Per informazioni su come comporre un file di Guida da utilizzare con i componenti,
consultare la sezione Creazione del file di Guida a pagina 52-5.
Creazione del file di Guida
Per creare i file risorsa per la Guida di Windows (in formato rtf), si pu utilizzare
qualunque strumento. C++Builder include Microsoft Help Workshop che compila i
file della Guida e mette a disposizione una Guida in linea dedicata a chi scrive tali
file. Nella Guida in linea di Help Workshop si possono trovare informazioni
complete sulla creazione di file di Guida.
La creazione di file di Guida per i componenti costituita da tre fasi:
Creazione delle voci
Come rendere sensibile al contesto la guida del componente Aggiunta di file di
Guida al componente
Creazione delle voci
Per fare in modo che la Guida del proprio componente si integri completamente con
la Guida del resto dei componenti nella libreria, osservare le seguenti convenzioni:
1 Ogni componente deve avere un argomento della guida.
Largomento del componente deve mostrare in quale unit il componente
dichiarato e fornirne una breve descrizione. Esso deve essere collegato ad una
finestra secondaria che descrive la posizione del componente nella gerarchia degli
oggetti e ne elenca tutte le propriet, gli eventi, e i metodi. Gli sviluppatori di
applicazioni accedono a questo argomento selezionando il componente in una
scheda e premendo F1. Per un esempio di un argomento del componente, collocare
un componente in una scheda e premere F1.
Largomento del componente deve avere una nota a pi di pagina di tipo # con un
valore univoco per identificare largomento. La nota a pi di pagina di tipo # serve
al sistema della Guida per identificare in modo univoco ogni argomento.
Largomento del componente deve avere una nota a pi di pagina di tipo K per la
ricerca delle parole chiave nellIndice del sistema della Guida, che includa il nome
della classe del componente. Per esempio, la nota a pi di pagina per la parola
chiave relativa al componente TMemo TMemo.
Deve anche avere una nota a pi di pagina di tipo $ che fornisce il titolo
allargomento. Il titolo appare nella finestra di dialogo Topics Found, nella finestra
di dialogo Bookmark e nella finestra History.
2 Ogni componente deve includere i seguenti argomenti secondari per lo
spostamento:
Una gerarchia di argomenti con collegamenti a ogni antenato del componente
nella gerarchia dei componenti.
52-6 G u i d a a l l a p r o g r a mma z i o n e
P r e p a r a z i o n e d i u n f i l e d i G u i d a p e r i l c o m p o n e n t e
Un elenco di tutte le propriet disponibili nel componente, con collegamenti
alle voci che descrivono quelle propriet.
Un elenco di tutti gli eventi disponibili nel componente, con collegamenti alle
voci che descrivono quegli eventi.
Un elenco di tutti i metodi disponibili nel componente, con collegamenti alle
voci che descrivono quei metodi.
Utilizzando Alinks, possibile effettuare collegamenti alle classi, alle propriet, ai
metodi o agli eventi degli oggetti nella Guida del sistema C++Builder. Quando si
effettua un collegamento ad un oggetto classe, Alink utilizza il nome di classe
delloggetto, seguito da un trattino di sottolineatura e dalla stringa object. Per
esempio, per effettuare il collegamento alloggetto TCustomPanel, usare il seguente
codice:
~s..ic_ccc,
Quando si effettua il collegamento ad una propriet, ad un metodo o ad un evento,
fare precedere il nome della propriet, del metodo o dellevento dal nome
delloggetto che lo implementa e da un trattino di sottolineatura. Per esempio, per
collegarsi alla propriet Text, che viene implementato da TControl, utilizzare il
seguente codice:
~_cx,
Per vedere un esempio di argomento secondario di spostamento, visualizzare la
Guida per un qualsiasi componente e fare clic sui collegamenti con etichetta
gerarchia, propriet, metodi o eventi.
3 Ogni propriet, metodo ed evento dichiarato allinterno del componente deve
avere un proprio argomento.
Ogni argomento di una propriet, evento o metodo deve mostrare la dichiarazione
dellelemento e descriverne luso. Gli sviluppatori di applicazioni possono
consultare questi argomenti evidenziando lelemento nellObject Inspector e
premendo il tasto F1 oppure posizionando il cursore nel Code editor sul nome
dellelemento e premendo il tasto F1. Per vedere un esempio di un argomento di
Guida relativa alle propriet, selezionare un qualsiasi elemento nellObject
Inspector e premere F1.
Gli argomenti propriet, evento e metodo devono includere una nota a pi di
pagina di tipo K che elenca il nome della propriet, del metodo o dellevento e il
suo nome in combinazione con il nome del componente. Pertanto, la propriet
Text di TControl ha la seguente nota a pi di pagina di tipo K:
cx,,,cx,cx,
Gli argomenti propriet, evento e metodo devono anche includere una nota a pi
di pagina di tipo $ che indica il titolo dellargomento, come TControl::Text.
Tutti questi argomenti devono avere un ID di argomento univoco, inserito come una
nota a pi di pagina di tipo #.
Come rendere sensibile al contesto la guida del componente
Ogni componente, propriet, metodo ed evento deve avere una nota a pi di pagina
di tipo A. La nota a pi di pagina A viene utilizzata per visualizzare largomento
C o me r e n d e r e d i s p o n i b i l i i c o mp o n e n t i i n f a s e d i p r o g e t t o 52-7
A g g i u n t a d i e d i t o r d i p r o p r i e t
quando lutente seleziona un componente e preme F1, o quando una propriet o un
evento viene selezionato nellObject Inspector e lutente preme F1. La nota a pi di
pagina di tipo A deve rispettare alcune convenzioni per il nome:
Se largomento della Guida riguarda un componente, la nota a pi di pagina di tipo A
costituita da due voci separate da un punto e virgola e utilizza questa sintassi:
.,ciss_ccc,.,ciss
dove ComponentClass il nome della classe del componente.
Se largomento della Guida riguarda una propriet o un evento, la nota a pi di
pagina di tipo A costituita da tre voci separate da un punto e virgola e utilizza
questa sintassi:
.,ciss_c.c,c.c_,c,c.c
dove ComponentClass il nome della classe del componente, Element il nome della
propriet, del metodo o dellevento, e Type Property, Method o Event
Per esempio, per una propriet di nome BackgroundColor di un componente
denominato TMyGrid, la nota a pi di pagina di tipo A
.._ic..,ic.._.,c,ic..
Aggiunta di file di Guida al componente
Per aggiungere il proprio file di Guida a C++Builder, utilizzare il programma di
utilit OpenHelp (chiamato oh.exe) presente nella directory bin o cui si pu accedere
dallIDE tramite il comando Help|Customize.
Ulteriori informazioni sulluso di OpenHelp sono presenti nel file OpenHelp.hlp,
oltre a informazioni su come aggiungere altri file di Guida personali al sistema di
Guida.
Aggiunta di editor di propriet
LObject Inspector fornisce funzioni predefinite di editing per tutti i tipi di propriet.
possibile, comunque, indicare un editor alternativo per propriet specifiche
scrivendo e registrando editor di propriet. Si possono registrare editor di propriet
validi soltanto per le propriet dei componenti che si scrivono, ma si possono creare
anche editor che si applicano a tutte le propriet di un certo tipo.
Al livello pi semplice un editor di propriet pu funzionare in uno dei seguenti
metodi o in entrambi: visualizzando e permettendo allutente di modificare il valore
attuale come una stringa di testo, e visualizzando una finestra di dialogo che
permette altri tipi di modifiche. In funzione della propriet che deve essere editata,
pu risultare utile fornire uno o entrambi i tipi.
La scrittura di una propriet editor richiede queste cinque operazioni:
1 Derivazione di una classe editor di propriet
2 Modifica della propriet come testo
3 Modifica globale della propriet
4 Specifica degli attributi delleditor
52-8 G u i d a a l l a p r o g r a mma z i o n e
A g g i u n t a d i e d i t o r d i p r o p r i e t
5 Registrazione delleditor di propriet
Derivazione di una classe editor di propriet
Sia la CLX che la VCL definiscono diversi tipi di editor di propriet, i quali
discendono tutti da TPropertyEditor. Quando si crea un editor di propriet, la classe
editor di propriet utilizzata pu discendere direttamente da TPropertyEditor o
indirettamente tramite una delle classi editor di propriet descritte nella Tabella 52.1.
Le classi nella unit DesignEditors possono essere utilizzate sia per applicazioni VCL
sia per applicazioni CLX. Alcune classi editor di propriet, tuttavia, forniscono
finestre di dialogo specializzate e sono pertanto specializzate o per la VCL o per la
CLX. Queste sono reperibili rispettivamente nelle unit VCLEditors e CLXEditors.
_
La cosa assolutamente necessaria per un editor di propriet che discenda da
TBasePropertyEditor e che supporti linterfaccia IProperty. TPropertyEditor, comunque,
offre unimplementazione predefinita dellinterfaccia IProperty.
La lista nella Tabella 52.1 non completa. Le unit VCLEditors e CLXEditors
definiscono anche alcuni editor di propriet specializzati, utilizzati da propriet
particolari come il nome del componente. Gli editor di propriet elencati sono quelli
pi utilizzati per le propriet definite dallutente.
Tabella 52.1 Tipi di editor di propriet predefiniti
Tipo Propriet su cui opera
TOrdinalProperty Tutti gli editor di propriet di tipo ordinale (cio, propriet di tipo
integer, carattere ed enumerato) discendenti da TOrdinalProperty.
TIntegerProperty Tutti i tipi integer compresi quelli predefiniti e i sottointervalli definiti
dallutente.
TCharProperty Il tipo Char e tutti gli eventuali sottointervalli, come A..Z.
TEnumProperty Tutti i tipi enumerati.
TFloatProperty Tutti i numeri in virgola mobile.
TStringProperty AnsiStrings.
TSetElementProperty I singoli elementi dei set, mostrati come valori booleani
TSetProperty Tutti i set. I set non sono modificabili direttamente ma possono essere
espansi in un elenco di propriet elementi set.
TClassProperty Classi. Mostra il nome della classe e permette di espanderlo per mostrare
le propriet rese pubbliche della classe.
TMethodProperty Puntatori ai metodi, in modo particolare gli eventi.
TComponentProperty Componenti nella stessa scheda. Non modifica le propriet del
componente ma pu puntare a un componente specifico di tipo
compatibile.
TColorProperty I colori dei componenti. Mostra le costanti colore se disponibili, in caso
contrario mostra un valore esadecimale. Un elenco a discesa contiene le
costanti colore. Un doppio clic apre una finestra di dialogo di selezione
del colore.
C o me r e n d e r e d i s p o n i b i l i i c o mp o n e n t i i n f a s e d i p r o g e t t o 52-9
A g g i u n t a d i e d i t o r d i p r o p r i e t
Il seguente esempio mostra la dichiarazione di un semplice editor di propriet di
nome TMyPropertyEditor:
cIaaa .~~ ..,c. pabIIc .,c.
pabIIc
vIttaaI beeI __?aatcaII ~iveIi,
vIttaaI .sc.~s. __?aatcaII cicveIi,
vIttaaI veIi __?aatcaII .cicceaat .sc.~s. ic,
__?aatcaII vIttaaI -..,c.veIi
__?aatcaII ..,c.veIi s..,c.
,
Modifica della propriet come testo
Tutte le propriet hanno bisogno di fornire una rappresentazione stringa dei loro
valori da visualizzare nellObject Inspector. Molte propriet consentono, inoltre,
allutente di immettere un nuovo valore per la propriet. Le classi editor di propriet
forniscono metodi virtuali che si possono ridefinire per effettuare la conversione tra
la rappresentazione testuale e il valore effettivo.
I metodi che vengono ridefiniti si chiamano GetValue e SetValue. Leditor di propriet
eredita anche una serie di metodi utilizzati per assegnare e leggere varie specie di
valori, come illustrato nella Tabella 52.2.
Quando si ridefinisce un metodo GetValue, si chiama uno dei metodi Get; quando si
ridefinisce un metodo SetValue, si chiama uno dei metodi Set.
Visualizzazione del valore della propriet
Il metodo GetValue delleditor di propriet restituisce una stringa che rappresenta il
valore attuale della propriet. LObject Inspector utilizza questa stringa nella colonna
valore della propriet. GetValue restituisce come valore predefinito unknown.
TFontNameProperty Nomi di font. Lelenco a discesa mostra tutti i font correntemente
installati.
TFontProperty I font. Permette lespansione delle singole propriet font oltre a consentire
laccesso alla finestra di dialogo dei font.
Tabella 52.2 Metodi per leggere e scrivere i valori delle propriet
Tipo della propriet Metodo Get Metodo Set
Numero in virgola mobile GetFloatValue SetFloatValue
Closure (evento) GetMethodValue SetMethodValue
Tipo ordinale GetOrdValue SetOrdValue
Stringa GetStrValue SetStrValue
Tabella 52.1 Tipi di editor di propriet predefiniti
Tipo Propriet su cui opera
52-10 G u i d a a l l a p r o g r a mma z i o n e
A g g i u n t a d i e d i t o r d i p r o p r i e t
Per fornire alla propriet una rappresentazione stringa, ridefinire il metodo GetValue
delleditor di propriet.
Se la propriet non un valore stringa, GetValue deve convertire il valore in una
rappresentazione stringa.
Impostazione del valore della propriet
Il metodo SetValue delleditor di propriet prende una stringa scritta dallutente nell
Object Inspector, la converte nel tipo appropriato e imposta il valore della propriet.
Se la stringa non rappresenta un valore corretto per la propriet, SetValue deve
generare uneccezione e non deve utilizzare il valore improprio.
Per leggere i valori delle propriet, ridefinire il metodo SetValue delleditor di
propriet.
SetValue deve convertire la stringa e convalidare il valore prima di chiamare uno dei
metodi Set.
Modifica globale della propriet
Si pu fornire opzionalmente una finestra di dialogo nella quale lutente pu editare
in modo visuale una propriet. Limpiego pi comune degli editor di propriet
riguarda le propriet che sono di per s delle classi. Un esempio la propriet Font,
per la quale lutente pu aprire una finestra di dialogo font per scegliere
contemporaneamente tutti gli attributi di font.
Per fornire una finestra di dialogo per la modifica globale delle propriet, ridefinire il
metodo Edit della classe delleditor di propriet.
I metodi Edit usano gli stessi metodi Get e Set utilizzati nella scrittura dei metodi
GetValue e SetValue. Infatti, un metodo Edit chiama sia un metodo Get sia un metodo
Set. Poich leditor specifico del tipo, generalmente non c bisogno di convertire i
valori delle propriet in stringhe. Leditor generalmente tratta con il valore cos come
lo rileva.
Quando lutente fa clic sul pulsante ... vicino alle propriet o fa doppio clic sulla
colonna valore, lObject Inspector chiama il metodo Edit delleditor di propriet.
Durante la nuova implementazione del metodo Edit, seguire questi passi:
1 Costruire leditor che si sta utilizzando per la propriet.
2 Leggere il valore attuale e assegnarlo alla propriet usando un metodo Get.
3 Quando lutente seleziona un nuovo valore, assegnare quel valore alla propriet
usando un metodo Set.
4 Distruggere leditor.
C o me r e n d e r e d i s p o n i b i l i i c o mp o n e n t i i n f a s e d i p r o g e t t o 52-11
A g g i u n t a d i e d i t o r d i p r o p r i e t
Specifica degli attributi delleditor
Leditor di propriet deve fornire tutte quelle informazioni che l Object Inspector
pu utilizzare per stabilire quali strumenti mostrare a video. Per esempio, lObject
Inspector deve sapere se la propriet contiene delle sottopropriet o pu mostrare
una lista dei valori possibili.
Per specificare gli attributi delleditor, si deve ridefinire il metodo GetAttributes
delleditor di propriet.
GetAttributes un metodo che restituisce un insieme di valori di tipo
TPropertyAttributes che possono includere uno o tutti i seguenti valori:
Le propriet Color sono pi versatili di molte altre propriet perch consentono agli
utenti di selezionarle in vari modi allinterno dellObject Inspector: scrivendone il
nome, selezionandole da una lista o usando un editor personalizzato. Il metodo
Tabella 52.3 Flag attributi di un editor di propriet
Flag
Metodo
correlato Significato del flag, se incluso
paValueList GetValues Leditor pu restituire un elenco di valori
enumerati.
paSubProperties GetProperties La propriet ha sottopropriet che possibile
visualizzare.
paDialog Edit Leditor pu visualizzare una finestra di dialogo
per modificare lintera propriet.
paMultiSelect N/D La propriet dovrebbe essere visualizzata quando
lutente seleziona pi di un componente.
paAutoUpdate SetValue Aggiornare il componente dopo ogni modifica
invece di aspettare la conferma del valore.
paSortList N/D LObject Inspector dovrebbe ordinare lelenco dei
valori.
paReadOnly N/D Lutente non pu modificare il valore della
propriet.
paRevertable N/D Attiva la voce di menu Revert to Inherited del menu
contestuale dellObject Inspector. Lelemento di
menu dice alleditor della propriet di scartare il
valore corrente della propriet e di ritornare ai
valori impostati in precedenza o a quelli predefiniti.
paFullWidthName N/D Il valore non necessario che sia visualizzato.
LObject Inspector utilizza invece per il nome della
propriet la sua larghezza completa.
paVolatileSubProperties GetProperties LObject Inspector riaggiorna i valori di tutte le
sottopropriet ogni volta che il valore della
propriet viene modificato.
paReference GetComponent
Value
Il valore un riferimento a qualcosaltro. Se
utilizzato insieme a paSubProperties loggetto
referenziato dovrebbe essere visualizzato come
sottopropriet di questa propriet.
52-12 G u i d a a l l a p r o g r a mma z i o n e
A g g i u n t a d i e d i t o r d i p r o p r i e t
GetAttributes di TColorProperty, pertanto, contiene diversi attributi nel valore
restituito:
vIttaaI __.isci .,c~ccs .,cc~ccs
tetata .,
avItca L.cx
caae c s , bteak,
caae c i, bteak,
_
bene assicurarsi che il proprio metodo GetVerb restituisca un valore per ogni
possibile indice indicato da GetVerbCount.
Implementazione dei comandi
Quando si seleziona un comando fornito da GetVerb nella funzione di impostazione,
viene chiamato il metodo ExecuteVerb. Per ogni comando fornito nel metodo GetVerb,
implementare unazione nel metodo ExecuteVerb. Utilizzando la propriet Component
delleditor, si pu accedere al componente da modificare.
Ad esempio, il seguente metodo ExecuteVerb implementa i comandi per il metodo
GetVerb dellesempio precedente.
veIi __?aatcaII ..xcccccIat L.cx
52-18 G u i d a a l l a p r o g r a mma z i o n e
A g g i u n t a d i e d i t o r d i c o m p o n e n t i
avItca L.cx
caae
.i ..,ccii aev .i,
..,ccii>xccc,
..,c .,c>s.,c ..,ccii>cic,
ieIete ..,ccii,
bteak,
caae
i, ci c i .c.
bteak,
i , aev i.,
,>xccc,
..,c .,c> ,>,
ieIete ,,
_
Se si vuole visualizzare il Code editor per un gestore di eventi quando si fa doppio
clic sul componente, utilizzare TDefaultEditor come classe basse per il proprio editor
del componente al posto di TComponentEditor. Quindi, invece di ridefinire il metodo
Edit, ridefinire in sua vece il metodo protetto TDefaultEditor::EditProperty.
EditProperty effettua un scansione dei gestori di eventi del componente, e attiva il
primo che trova. Questo processo pu essere modificato facendo s che venga cercato
uno specifico gestore di eventi. Per esempio:
veIi __?aatcaII ....,c.,c. .,c.,
beeI c, beeI cc.
. .,c.>iss.i.cLs.c..,c
C o me r e n d e r e d i s p o n i b i l i i c o mp o n e n t i i n f a s e d i p r o g e t t o 52-19
A g g i u n t a d i e d i t o r d i c o m p o n e n t i
.,iccx.,c.>c.i.c, .,ccic
c.i...,c.,c., c, cc.,
~.i,
Iat ~ii,
-.~ ~.icc,
L.ic .,c>.cc>.ic,ci..i~.i, ~ii, ~.icc,
,ci. ,, ,ci., . cci c c,ci.
,,>.c~s-i.c~.i, ~ii,
52-20 G u i d a a l l a p r o g r a mma z i o n e
C o m p i l a z i o n e d e i c o m p o n e n t i i n p a c k a g e
veIi __?aatcaII .~~ csc
-c.c sss,,>
-c.c cs,,>
-c.c cisscs,,>
-c.c ..s,,>
-c.c ..s,,>
,ic
,ccc.
,cc
__,csc.
,
-c..
Il file .CPP associato sar pi o meno come questo:
-c.c c>
-,i.i .s,
-c.c 'c.c.'
-,i.i ,ic.ics.i_,
sic c . i.cc.c..c.
c. c..c..,
__.isci c..c.c..c..,c .c
.c..c
i.cs,icc c.c.
Nelle applicazioni CLX i nomi e le ubicazioni di alcuni file header sono differenti. Ad
esempio, ccs,,> cxcs,,> in CLX.
Mo d i f i c a d i u n c o mp o n e n t e e s i s t e n t e 53-3
M o d i f i c a d e l l a c l a s s e d e l c o m p o n e n t e
_
In questo esempio si presuppone che non si utilizzi il Component wizard per creare
questo componente, ma che si proceda manualmente. Se si usa il Component wizard,
verr aggiunto automaticamente un costruttore a TYellowMemo.
Modifica della classe del componente
Una volta creata una nuova classe di componente, possibile modificarla
praticamente in qualsiasi modo. In questo caso, si modificher solamente il valore
iniziale di una propriet del componente memo. Ci comporta due piccole modifiche
alla classe del componente:
Ridefinizione del costruttore.
Specifica del nuovo valore predefinito di una propriet.
il costruttore che, di fatto, imposta il valore della propriet. Il valore predefinito
impostato dice a C++Builder quali valori memorizzare nel file scheda (.dfm per la
VCL e .xfm per la CLX). C++Builder memorizza solamente i valori che differiscono
da quelli predefiniti, quindi importante compiere entrambe queste operazioni.
Ridefinizione del costruttore
Quando un componente viene collocato su una scheda in fase di progetto, o quando
unapplicazione costruisce un componente durante lesecuzione, il costruttore del
componente imposta i valori delle relative propriet. Quando un componente viene
caricato da un file scheda, lapplicazione imposta tutte le propriet modificate in fase
di progetto.
_
Quando si ridefinisce un costruttore, il nuovo costruttore deve chiamare il costruttore
ereditato prima di fare qualsiasi altra cosa. Per ulteriori informazioni consultare il
paragrafo Ridefinizione dei metodi a pagina 46-10.
In questo esempio, il nuovo componente necessita della ridefinizione del costruttore
ereditato da TMemo per impostare la propriet Color a clYellow. A questo scopo,
aggiunge la dichiarazione di ridefinizione del costruttore alla dichiarazione della
classe, quindi scrive il nuovo costruttore nel file .CPP:
ciss .~~ c..c. ,cc .c.
,cc
i __.isci c..c..,c .c, c csc .ccii
__,csc.
__,,c ,
,
__.isci c..c.c..c..,c .c
.c..c c csc .,c.ci .s
cis c csc . .c.
cc., cs c c.,c c.
53-4 G u i d a a l l a p r o g r a mma z i o n e
M o d i f i c a d e l l a c l a s s e d e l c o m p o n e n t e
_
Se per creare il componente si utilizzato il Component wizard, sufficiente soltanto
aggiungere cc., al costruttore esistente.
A questo punto possibile installare il nuovo componente nella Component palette e
aggiungerlo alla scheda. La propriet Color predefinita ora clYellow.
Specifica del nuovo valore predefinito di una propriet
Quando C++Builder memorizza la descrizione di una scheda in un file scheda,
memorizza solo i valori delle propriet che differiscono da quelli predefiniti. La
memorizzazione dei soli valori che differiscono da quelli predefiniti aiuta a
mantenere piccoli i file di scheda e rende pi rapido il caricamento della scheda. Se si
crea una propriet o si modifica il valore predefinito, pu essere utile aggiornare la
dichiarazione della propriet per includere il nuovo valore predefinito. I file di
scheda, il caricamento e i valori predefiniti sono spiegati pi dettagliatamente nel
Capitolo 52, Come rendere disponibili i componenti in fase di progetto.
Per modificare il valore predefinito di una propriet:
1 Ridichiarare il nome della propriet.
2 Porre un segno uguale (=) dopo il nome della propriet.
3 Scrivere la parola chiave default, un altro segno uguale e il valore predefinito,
racchiudendo il tutto fra parentesi graffe.
Si noti che non necessario dichiarare di nuovo lintera propriet, ma solo il nome e il
valore predefinito.
Per il componente memo yellow, si deve dichiarare di nuovo la propriet Color in una
sezione __published della dichiarazione della classe, con un valore predefinito pari a
clYellow:
ciss .~~ c..c. ,cc .c.
,cc
i __.isci c..c..,c .c,
__,csc.
__,,c .c.icc.,
,
Ecco di nuovo TYellowMemo, ma questa volta ha unaltra propriet published,
WordWrap, con un valore predefinito impostato a false:
ciss .~~ c..c. ,cc .c.
,cc
i __.isci c..c..,c .c,
__,csc.
__,,c .c.icc.,
__,,c .i, .c.i.isc,
,
Mo d i f i c a d i u n c o mp o n e n t e e s i s t e n t e 53-5
M o d i f i c a d e l l a c l a s s e d e l c o m p o n e n t e
La specifica del valore predefinito della propriet non influenza minimamente il
funzionamento del componente. Occorre ancora impostare esplicitamente il valore
predefinito del costruttore del componente. La differenza sta nel funzionamento
interno dellapplicazione. Per TYellowMemo, C++Builder non scriver pi WordWrap
nel file scheda se false, perch gli stato comunicato che il costruttore imposter
automaticamente quel valore. Ecco il codice del costruttore:
__.isci c..c.c..c..,c ~.c .c.~.c
cc.,
.i, .isc,
53-6 G u i d a a l l a p r o g r a mma z i o n e
M o d i f i c a d e l l a c l a s s e d e l c o m p o n e n t e
C r e a z i o n e d i u n c o n t r o l l o g r a f i c o 54-1
C a p i t o l o
54
Capitolo54Creazione di un controllo grafico
Un controllo grafico un tipo di componente semplice. Poich un controllo
esclusivamente grafico non riceve mai il fuoco, non possiede n richiede un handle di
finestra. Gli utenti possono comunque gestire il controllo col mouse, ma non c una
interfaccia di tastiera.
Il componente grafico presentato in questo capitolo TShape, il componente shape
che appare nella pagina Additional della Component palette. Anche se il
componente che viene creato identico al componente shape standard, necessario
chiamarlo in modo diverso per evitare duplicati di identificatori. In questo capitolo al
componente viene assegnato il nome TSampleShape e vengono illustrati tutti i passi
necessari alla sua creazione:
Creazione e registrazione del componente
Pubblicazione delle propriet ereditate
Aggiunta di funzionalit grafiche
Creazione e registrazione del componente
La creazione di qualunque componente inizia nello stesso modo: si deriva una classe
di componente, si salvano i file .CPP e .H del componente, si registra il componente,
lo si compila e lo si installa nella Component palette. Questo processo viene descritto
nella sezione Creazione di un nuovo componente a pagina 45-8.
_
In questo esempio si presuppone che non si utilizzi Component wizard, ma che si
crei il componente manualmente.
Per questo esempio, seguire la procedura generale di creazione di un componente,
con queste specifiche:
1 Derivare un nuovo tipo di componente chiamato TSampleShape, discendente da
TGraphicControl.
54-2 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e e r e g i s t r a z i o n e d e l c o m p o n e n t e
2 Chiamare il file header del componente SHAPES.H e il file .CPP associato
SHAPES.CPP.
3 Registrare TSampleShape nella pagina Samples (o in unaltra pagina della CLX)
della Component palette.
Il file header risultante sar simile al seguente:
-..c. .i,cs-
-.c.c .i,cs-
-c.c sss,,>
-c.c cs,,>
-c.c cisscs,,>
-c.c ..s,,>
,ic
,ccc.
,cc
__,csc.
,
-c..
Il file .CPP sar pi o meno come questo:
-c.c c>
-,i.i .s,
-c.c '.i,cs'
-,i.i ,ic.ics.i_,
sic c . i.cc..i.,c.i,c
c. .i.,c.i,c.,
__.isci .i.,c.i,ci,c.,c .c
i,c.c
i.cs,icc .i,cs
Nelle applicazioni CLX i nomi e le ubicazioni di alcuni file header sono differenti. Ad
esempio, <vcl\controls.hpp> <clx\qcontrols.hpp> in CLX.
Pubblicazione delle propriet ereditate
Una volta derivato un tipo di componente, si pu decidere quali propriet ed eventi,
dichiarati nelle sezioni protette della classe antenato, si vogliono rendere disponibili
nel nuovo componente. TGraphicControl pubblica gi tutte le propriet che
consentono al componente di funzionare come un controllo, per cui, lunica cosa che
occorre rendere pubblica la capacit di rispondere agli eventi del mouse e di gestire
le operazioni drag-and-drop.
Il modo per rendere pubbliche le propriet e gli eventi ereditati spiegato nel
paragrafo Pubblicazione di propriet ereditate a pagina 47-3 e Visibilit degli
eventi a pagina 48-5. Entrambi i processi includono la ridichiarazione del nome
delle propriet nella sezione published della dichiarazione della classe.
Per il controllo shape possibile rendere pubblici i tre eventi del mouse, le due
propriet e i tre eventi relativi alle operazioni di drag-and-drop:
ciss .~~ .i.,c.i,c ,cc i,c
,ic
__,csc.
__,,c is ,
__,,c i..c ,
__,,c i, ,
__,,c ic ,
__,,c .i ,
__,,c .sc. ,
__,,c .sc.c ,
__,,c .sc, ,
,
Il controllo shape dellesempio rende disponibili agli utenti le interazioni del mouse e
il drag-and-drop.
Aggiunta di funzionalit grafiche
Una volta dichiarato il componente grafico e resa pubblica ogni propriet ereditata
che si vuole rendere disponibile, possibile aggiungere alcune funzionalit grafiche
che distinguano il componente. Durante la creazione di un controllo grafico, vengono
compiute due operazioni:
1 Determinazione di cosa disegnare.
2 Disegno dellimmagine del componente.
54-4 G u i d a a l l a p r o g r a mma z i o n e
A g g i u n t a d i f u n z i o n a l i t g r a f i c h e
Inoltre, al nostro controllo shape di esempio verranno aggiunte alcune propriet che
permetteranno agli sviluppatori di applicazioni di personalizzare il controllo
modificandone laspetto durante lo sviluppo.
Determinazione di cosa disegnare
Un controllo grafico pu modificare il proprio aspetto per riflettere una condizione
dinamica, incluso linput dellutente. Un controllo grafico che non varia mai non
sarebbe probabilmente neanche un componente. Se si vuole unimmagine statica,
invece di usare un controllo, la si pu importare.
In generale, laspetto di un controllo grafico dipende da alcune combinazioni delle
propriet. Il controllo Gauge, per esempio, ha propriet che ne determinano forma e
orientamento oltre a determinare se mostrare levolversi di un processo
numericamente e/o graficamente. Similmente, il controllo shape ha propriet che
determinano quale tipo di figura deve tracciare.
Per attribuire al controllo una propriet che determini la figura da disegnare,
aggiungere un propriet di nome Shape.Ci richiede
1 Dichiarzione del tipo della propriet.
2 Dichiarazione della propriet.
3 Scrittura del metodo di implementazione.
La creazione di propriet illustrata pi dettagliatamente nel Capitolo 47,
Creazione di propriet.
Dichiarzione del tipo della propriet
Quando si dichiara la propriet di un tipo definito dallutente, prima della classe che
include la propriet si deve dichiarare il tipo. La categoria pi comune dei tipi di
propriet definiti dallutente quello enumerato.
Aggiungere la seguente definizione di tipo prima della dichiarazione della classe del
controllo shape.
c. .i.,c.i,c,c ssccic, ss.ic, ss.cc, ss..ic, ss,sc,
sscc ,
ciss .~~ .i.,c.i,c ,cc i,c s s ici. cc
possibile ora utilizzare questo tipo per dichiarare una nuova propriet allinterno
della classe.
Dichiarazione della propriet
Quando si dichiara una propriet, solitamente necessario dichiarare un membro
dati privato per registrare i dati delle propriet, quindi specificare i metodi di lettura
e/o scrittura del valore della propriet. Spesso non necessario utilizzare un metodo
per leggere il valore, ma sufficiente puntare ai dati registrati.
Per il controllo shape bisogna dichiarare un membro dati che contenga la figura
attiva, quindi dichiarare una propriet che legga e scriva tale membro dati
richiamando un metodo.
C r e a z i o n e d i u n c o n t r o l l o g r a f i c o 54-5
A g g i u n t a d i f u n z i o n a l i t g r a f i c h e
Aggiungere la seguente dichiarazione a TSampleShape:
ciss .~~ .i.,c.i,c ,cc i,c
,ic
.i.,c.i,c,c .i,c,
. __.isci .c.i,c.i.,c.i,c,c ic,
__,csc.
__,,c .i.,c.i,c,c .i,c ci..i,c, .c.c.i,c, .c.i,
,
Ora tutto ci che rimane da fare aggiungere limplementazione di SetShape.
Scrittura del metodo di implementazione
Quando la parte read o write della definizione della propriet usa un metodo invece
di accedere direttamente ai dati memorizzati della propriet, occorre implementare il
metodo.
Aggiungere limplementazione del metodo SetShape al file SHAPES.CPP:
. __.isci .i.,c.i,c.c.i,c.i.,c.i,c,c ic
. .i,c ic c . s s i cic
.i,c ic, sc c c. ic
Li.ic, .cc i c,i . c c. si,c
,cc
i __.isci .i.,c.i,c.,c .c,
,
54-6 G u i d a a l l a p r o g r a mma z i o n e
A g g i u n t a d i f u n z i o n a l i t g r a f i c h e
Se si iniziata la creazione del componente mediante il wizard Component, questa
operazione gi stata eseguita automaticamente.
1 Ridichiarare le propriet Height e Width con i loro nuovi valori predefiniti:
ciss .~~ .i.,c.i,c ,cc i,c
__,csc.
__,,c -c,
__,,c .,
. ,
-c ,
,
Dichiarazione delle propriet di accesso
possibile garantire laccesso agli oggetti posseduti di un componente dichiarando
le propriet del tipo degli oggetti.Questo d modo agli sviluppatori di accedere agli
oggetti in fase di progetto o durante lesecuzione. Solitamente, la parte read della
propriet referenzia solo il membro dati, ma la parte write chiama un metodo che
consente al componente di reagire alle modifiche nelloggetto posseduto.
Aggiungere al controllo shape le propriet che forniscono laccesso ai membri dati
penna e pennello. Si dichiareranno anche i metodi per reagire alle modifiche
apportate alla penna o al pennello.
ciss .~~ .i.,c.i,c ,cc i,c
,ic
.c .c,
s s,
. __.isci .css ic,
. __.isci .c.c.c ic,
__,csc.
__,,c s s ci.s, .c.cs, .c.i,
__,,c .c .c ci..c, .c.c.c, .c.i,
,
Quindi, scrivere i metodi SetBrush e SetPen nel file .CPP:
. __.isci .i.,c.i,c.cs s ic
s>~ssic,
. __.isci .i.,c.i,c.c.c .c ic
.c>~ssic,
. ,
-c ,
s c. s, csc c ,c
.c c. .c, csc c cs
,
3 Scrivere il nuovo distruttore nel file .CPP:
__.isci .i.,c.i,c-.i.,c.i,c
,cc
. __.isci .cic.ccc .c,
,
Assegnare il metodo StyleChanged agli eventi OnChange delle classi penna e pennello
nel costruttore TSampleShape nel file SHAPES.CPP:
__.isci .i.,c.i,c.i.,c.i,c.,c .c i,c.c
C r e a z i o n e d i u n c o n t r o l l o g r a f i c o 54-9
A g g i u n t a d i f u n z i o n a l i t g r a f i c h e
. ,
-c ,
s c. s,
s>ic .cic.,
.c c. .c,
.c>ic .cic.,
,ccc.
i . __.isci .i,
,
Quindi, scrivere il metodo nel file. CPP:
. __.isci .i.,c.i,c.i
.,,,-,.,
iis>.c .c, c, c c.,cs ,c
iis>s s, c, c c.,cs cs
., sc c c.,c ..
54-10 G u i d a a l l a p r o g r a mma z i o n e
A g g i u n t a d i f u n z i o n a l i t g r a f i c h e
--c, sc c c.,c c
., sic s.ics . cccssics
. -
.,
csc
.-,
s.c.i,c
Paint viene chiamato ogni volta che il controllo ha bisogno di aggiornare la sua
immagine. I controlli vengono disegnati quando essi appaiono per la prima volta o
quando scompare una finestra di fronte ad loro. anche possibile forzare la
rigenerazione dellimmagine chiamando Invalidate, come fa il metodo StyleChanged.
Perfezionamento del disegno della figura
Il controllo shape standard fa una cosa in pi rispetto al controllo shape di esempio:
gestisce non solo i quadrati e i cerchi, ma anche i rettangoli e le ellissi. Per fare ci,
occorre scrivere del codice che in grado di individuare il lato pi corto e di centrare
limmagine.
Qui di seguito viene riportato il metodo Paint perfezionato che corregge i quadrati e
le ellissi:
. __.isci .i.,c.i,c.i.
.,,,-,.,
iis>.c .c, c, c c.,cs ,c
iis>s s, c, c c.,cs cs
., sc c c.,c ..
--c, sc c c.,c c
., sic s.ics . cccssics
. -
.,
csc
.-,
s.c.i,c i.s c, .. i. ,s
C r e a z i o n e d i u n c o n t r o l l o g r a f i c o 54-11
A g g i u n t a d i f u n z i o n a l i t g r a f i c h e
cisc ssccic
cisc ss.cc
cisc ss,sc
., s ,c. . csc si,cs
cci.,
cisc ss.ic
cisc ss..ic
cisc sscc
. .., ccc csc .i
-.., i. cci
cci.,
.c.i
cci.,
s.c.i,c
54-12 G u i d a a l l a p r o g r a mma z i o n e
A g g i u n t a d i f u n z i o n a l i t g r a f i c h e
P e r s o n a l i z z a z i o n e d i u n a g r i g l i a 55-1
C a p i t o l o
55
Capitolo55Personalizzazione di una griglia
C++Builder dotato di componenti astratti utilizzabili come basi per i componenti
personalizzati. I pi importanti sono le griglie e le liste. In questo capitolo possibile
vedere come si crea un piccolo calendario mensile partendo dalla griglia base
TCustomGrid.
La creazione del calendario richiede le seguenti operazioni:
Creazione e registrazione del componente
Come rendere pubbliche le propriet ereditate
Cambiamento dei valori iniziali
Ridimensionamento delle celle
Riempimento delle celle
Scorrimento di mesi e anni
Scorrimento dei giorni
-c.c csss,,>
-c.c ccs,,>
-c.c ccisscs,,>
-c.c c..s,,>
-c.c c.s,,>
,ic
,ccc.
,cc
__,csc.
,
-c..
Il file CALSAMP.CPP sar simile al seguente:
-c.c cc>
-,i.i .s,
-c.c 'i.i.,'
-,i.i ,ic.ics.i_,
c c. .i.,cic.i.,
i.cs,icc isi.,
_
Se per creare il componente si utilizzato il Component wizard componente, il file
header conterr anche la dichiarazione di un nuovo costruttore e il file
CALSAMP.CPP conterr le istruzioni iniziali di un costruttore. Se non c nessun
costruttore, possibile aggiungerlo in seguito.
P e r s o n a l i z z a z i o n e d i u n a g r i g l i a 55-3
C o m e r e n d e r e p u b b l i c h e l e p r o p r i e t e r e d i t a t e
Nelle applicazioni CLX, i nomi e le ubicazioni di alcuni file header sono differenti.
Ad esempio, ccs,,> diventa cxcs,,> in CLX.
Come rendere pubbliche le propriet ereditate
Il componente griglia astratto, TCustomGrid, provvisto di un grande numero di
propriet dichiarate protected. possibile scegliere quali di queste propriet rendere
disponibili per lutente del controllo calendario.
Per rendere disponibili agli utenti le propriet protette ereditate dal componente,
necessario dichiararle nella sezione _published della dichiarazione del componente.
Per il controllo calendario bisogna rendere pubbliche le seguenti propriet ed eventi:
ciss .~~ .i.,cic.i ,cc s..
__,csc.
__,,c ~ , ,cs ,,ccs
__,,c .c.c ,
__,,c ,
__,,c ,
__,,c .c. ,
__,,c .ic ,
__,,c .ic ,
__,,c c. , ,cs ccs
__,,c cc. ,
__,,c i, ,
__,,c ic ,
__,,c .i ,
__,,c c. ,
__,,c c.css ,
__,,c c, ,
,
Ci sono numerose altre propriet che possono anche essere rese pubbliche, ma che
non vengono utilizzate nel calendario, come Options che abilita lutente a scegliere il
tipo di linea da utilizzare nella griglia del disegno.
Se si installa il componente calendario modificato nella Component palette e si
utilizza in unapplicazione, nel calendario si troveranno molte propriet ed eventi
disponibili, tutti completamente funzionali. A questo punto possibile aggiungere
nuove possibilit al proprio progetto.
Cambiamento dei valori iniziali
Un calendario essenzialmente una griglia con un numero definito di righe e di
colonne e inoltre non tutte le righe contengono sempre dei dati. Per questo motivo
non sono state rese pubbliche le propriet ColCount e RowCount, dal momento che
molto improbabile che gli utenti del calendario vogliano visualizzare pi di sette
55-4 G u i d a a l l a p r o g r a mma z i o n e
R i d i m e n s i o n a m e n t o d e l l e c e l l e
giorni alla settimana. Si deve anche fissare il valore iniziale di queste propriet, in
modo da avere sempre sette giorni alla settimana.
Per modificare i valori iniziali delle propriet del componente, ridefinire il
costruttore per impostare i valori desiderati.
Occorre ricordarsi di aggiungere il costruttore nella parte public della dichiarazione
della classe del componente e di scrivere il nuovo costruttore nel file header:
ciss .~~ .i.,cic.i ,cc s..
,ccc.
i . __.isci i.c ~, ~., cs ..scc cc,
.i..ic ~.ic,
,cc
__.isci .i.,cic.i.,c .c, c i..c. csc
,
Nel file CALSAMP.CPP scrivere il codice del costruttore:
__.isci .i.,cic.i.i.,cic.i.,c .c s...c
,
. ,
xc.s ,
xc..s ,
.cis ss.c,
,s ,s >> ic.ccc i.cs.cccc.,
_
Si pu notare che alla dichiarazione della classe stato anche aggiunto un metodo
DrawCell, e che nel file .CPP stato iniziato il metodo DrawCell. Ci non
assolutamente necessario ora, ma se si cercasse di collaudare TSampleCalendar prima
di ridefinire DrawCell, si incapperebbe in un errore legato alla funzione pure virtual.
Ci dovuto al fatto che TCustomGrid una classe astratta.La ridefinizione di
DrawCell viene discussa pi avanti, nella sezione Riempimento delle celle.
Il calendario ora ha sette colonne e sette righe, di cui la riga superiore fissa o senza
funzionalit di scorrimento.
Ridimensionamento delle celle
,ccc.
. __.isci ...c...c .cssic,
L._...~_.~.
...~_-~.._.L., ...c, ...c
._...~_.~.s..
,
Ecco il codice per il metodo nel file CALSAMP.CPP:
. __.isci .i.,cic.i...c...c .cssic
,ccc.
. __.isci .sic..,
,
Ecco il codice per il metodo nel file CALSAMP.CPP :
. __.isci .i.,cic.i.sic..
. ccx,
c.,i,
. ~. ccx .i.i.cs,~ - ,
csc
ccx '',
c.,i i..~, ~., i.. s .c.c. ic
. c.,i ccx L.c.,i,
,ic
ic.c ic,
,
2 Inizializzare nel costruttore la data del membro dati:
__.isci .i.,cic.i.i.,cic.i.,c .c s...c
ic iccic,
3 Dichiarare una propriet di runtime per permettere laccesso alla data codificata:
ciss .~~ .i.,cic.i ,cc s..
,cc
__,,c ic.c ic.iic ci.ic, .c.cic.iic, .c.i,
,
necessario un metodo per limpostazione della data, poich tale operazione deve
anche aggiornare limmagine a video del controllo. Dichiarare SetCalendarDate in
TSampleCalendar:
ciss .~~ .i.,cic.i ,cc s..
,ic
. __.isci .cic.iicic.c ic,
,
Questo il metodo SetCalendar:
. __.isci .i.,cic.i.cic.iicic.c ic
ic ic, .c c c. .ic ic
c.cs, ,.ic c sccc .ic
55-8 G u i d a a l l a p r o g r a mma z i o n e
R i e m p i m e n t o d e l l e c e l l e
Accesso a giorno, mese e anno
Una data codificata numericamente adatta per le applicazioni, ma pi comodo
lavorare con giorni, mesi e anni. possibile preparare accessi alternativi a questi
elementi codificati creando delle propriet.
Poich ogni elemento della data (giorno, mese, anno) un intero e poich
limpostazione di ognuno richiede la ricodifica della data, possibile evitare la
duplicazione del codice ogni volta, condividendo il metodo per tutte e tre le
propriet. possibile scrivere due metodi, uno per leggere un elemento e uno per
scriverlo, e utilizzare questi metodi per acquisire e impostare le tre propriet.
Per poter accedere a giorno, mese e anno durante lo sviluppo, bisogna passare per le
seguenti fasi:
1 Dichiarare le tre propriet, assegnando a ognuna un numero di indice univoco:
ciss .~~ .i.,cic.i ,cc s..
,cc
__,,c i ci.cicc.c, .c.cicc.c, .cx,
.c.i,
__,,c . ci.cicc.c, .c.cicc.c, .cx.,
.c.i,
__,,c ci ci.cicc.c, .c.cicc.c, .cx,
.c.i,
,
2 Dichiarare e scrivere il metodo di implementazione, impostando i diversi elementi
per ogni valore dellindice:
ciss .~~ .i.,cic.i ,cc s..
,ic
__.isci cicc.c L.cx, c c L.cx ,ii.cc
. __.isci .cicc.c L.cx, ic,
,
Ecco i metodi GetDateElement e SetDateElement:
__.isci .i.,cic.icicc.c L.cx
c cs,
Ora possibile impostare giorno, mese e anno del calendario in fase di progetto
utilizzando lObject Inspector oppure in fase di esecuzione tramite programma.
Naturalmente non stato ancora aggiunto il codice per disegnare le date nelle celle,
ma ora disponibile la data desiderata.
Generazione dei numeri dei giorni
Linserimento dei numeri nel calendario implica diverse considerazioni. Il numero di
giorni in un mese dipende da quale mese si considera e bisogna ricordarsi degli anni
bisestili. Inoltre, il primo giorno del mese cade in giorni della settimana differenti, a
seconda del mese e dellanno. Se lanno bisestile, utilizzare la funzione IsLeapYear.
Per ottenere il numero dei giorni di un mese, usare larray MonthDays nel file header
SysUtils.
Quando sono note le informazioni sugli anni bisestili e sul numero di giorni in ogni
mese, possibile calcolare dove inserire la singola data sulla griglia. Il calcolo
basato sul giorno della settimana con cui comincia il mese.
Poich per ogni cella da riempire sar necessario conoscere il numero di scostamento
del mese, il metodo migliore quello di calcolarne il valore ogni volta che vengono
cambiati il mese o lanno, e quindi fare riferimento ogni volta a tale valore.
possibile registrare il valore in un membro dati della classe, quindi aggiornare tale
membro dati ogni volta che cambia la data.
Per inserire i giorni nelle celle appropriate:
1 Aggiungere un membro dati per loffset del mese alla classe e un metodo che
aggiorni il valore del membro dati:
ciss .~~ .i.,cic.i ,cc s..
,ic
...sc, sic . c ..sc
,ccc.
i . __.isci ,.icic.i.,
,
55-10 G u i d a a l l a p r o g r a mma z i o n e
R i e m p i m e n t o d e l l e c e l l e
. __.isci .i.,cic.i,.icic.i.
,.icic.i,
. __.isci .i.,cic.i.cic.iicic.c ic
cs ...sc - ~ - ~. , cicic .i . s cc
. cs cs > .is,Lsci,cici,.
cs , c . i.
c cs,
P e r s o n a l i z z a z i o n e d i u n a g r i g l i a 55-11
S c o r r i m e n t o d i m e s i e a n n i
. ccx,
c.,i,
. ~. s s c ci.c .
ccx .i.i.cs,~ - , s sc c .i i.c
csc
c.cs, s s ici. cc
ic.iic Lc.ic.iic, ,
. __.isci .i.,cic.i.c.
ic.iic Lc.ic.iic, ,
. __.isci .i.,cic.i.cxci
ic.iic Lc.ic.iic, .,
. __.isci .i.,cic.i.cci
ic.iic Lc.ic.iic, .,
,ic
..c ic,
,ccc.
i . __.isci ic,
__,csc.
__,,c ..c ic ci.ic, .cic,
.ic . ics,
55-14 G u i d a a l l a p r o g r a mma z i o n e
S c o r r i m e n t o d e i g i o r n i
ic ic,
,.icic.i,
ic, s s c c. sic.c
Se ora lutente fa clic su una cella vuota o tenta di muoversi su una cella vuota con le
frecce, il calendario lascia selezionata la cella corrente.
C r e a z i o n e d i u n c o n t r o l l o d i a c c e s s o a i d a t i 56-1
C a p i t o l o
56
Capitolo56Creazione di un controllo di accesso
ai dati
Quando si lavora con connessioni database, spesso conveniente avere controlli
associati ai dati. Ovvero, lapplicazione pu stabilire un collegamento tra il controllo
e una parte del database. C++Builder include etichette, caselle di testo, caselle di
riepilogo, caselle combinate, controlli di consultazione e griglie associati ai dati.
anche possibile creare propri controlli associati ai dati. Per ulteriori informazioni sui
controlli data-aware, consultare il Capitolo 19, Uso dei controlli dati.
Esistono diversi livelli di associazione ai dati. Il pi semplice un controllo per
accedere a dati in sola lettura, o data browsing, utilizzato per controllare lo stato
attuale di un database. Pi complesso il controllo relativo a dati che si possono
anche modificare, o data editing, dove lutente pu scrivere i valori da riportare nel
database gestendo il controllo. Inoltre, si noti che il livello di interfaccia con un
database pu variare: nel caso pi semplice si ha un collegamento con un singolo
campo, in casi pi complessi si sviluppa un controllo che ha accesso a pi record.
Per prima cosa il capitolo illustra il caso pi semplice, cio la creazione di un
controllo a sola lettura che si collega a un singolo campo in un dataset. Il controllo
specifico da utilizzare TSampleCalendar, creato nel Capitolo 55, Personalizzazione
di una griglia. anche possibile utilizzare il controllo calendario standard,
TCalendar, presente nella pagina Samples della Component palette.
Quindi il capitolo continua con una spiegazione di come trasformare il nuovo
controllo per la consultazione dei dati in un controllo per lediting dei dati.
Creazione di un controllo per lesame dei dati
La creazione di un controllo calendario associato ai dati, sia che sia un controllo a sola
lettura o uno nel quale lutente pu modificare i dati associati del dataset, coinvolge
le seguenti operazioni:
56-2 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n c o n t r o l l o p e r l e s a m e d e i d a t i
Creazione e registrazione del componente
Aggiunta di un datalink
Risposta alle modifiche dei dati
Creazione e registrazione del componente
La creazione di qualsiasi componente inizia sempre nello stesso modo: si deriva la
classe di un componente, si salvano il file .CPP e .H del componente, lo si registra, lo
si compila e lo si installa nella Component palette. Questo processo viene descritto
nella sezione Creazione di un nuovo componente a pagina 45-8.
Per questo esempio seguire la procedura generale per la creazione di un componente,
con le seguenti specifiche:
Derivare una nuova classe del componente di nome TDBCalendar, discendente da
TSampleCalendar. Capitolo 55, Personalizzazione di una griglia, mostra come
creare il componente TSampleCalendar.
Assegnare come nome DBCAL.H al file haeder e DBCAL.CPP al file .CPP.
Registrare TDBCalendar nella pagina Samples (o in unaltra pagina della CLX)
della Component palette.
Nelle applicazioni CLX i nomi e le ubicazioni di alcuni file header sono differenti. Ad
esempio, <vcl\controls.hpp> <clx\qcontrols.hpp> in CLX.
Il file header risultante apparir pi o meno come il seguente:
-..c. i-
-.c.c i-
-c.c csss,,>
-c.c ccs,,>
-c.c ccisscs,,>
-c.c c..s,,>
-c.c c.s,,> c.c c .s ci.c
-c.c cisi., c.c c ci.c i .ccics .i.,cic.i
,ic
,ccc.
,cc
__,csc.
,
-c..
Il file .CPP risulter simile a questo:
-,i.i . isi., . .i.,cic.i
-c.c cc>
-,i.i .s,
-c.c 'i'
C r e a z i o n e d i u n c o n t r o l l o d i a c c e s s o a i d a t i 56-3
C r e a z i o n e d i u n c o n t r o l l o p e r l e s a m e d e i d a t i
-,i.i ,ic.ics.i_,
c c. ic.i.,
i.cs,icc cci
_
Se si utilizzato il wizard Component per iniziare la creazione del componente
TDBCalendar, il file header conterr il costruttore gi dichiarato e il file .CPP avr la
definizione del costruttore.
Ora possibile trasformare il nuovo componente in un visualizzatore di dati.
Costruzione del controllo a sola lettura
Dal momento che questo calendario sar a sola lettura, ha senso definire il controllo
stesso come a sola lettura, in modo che gli utenti non possano effettuarvi
cambiamenti e ritrovarli nei dati del database.
Definire un calendario a sola lettura implica:
Aggiunta della propriet ReadOnly.
Permettere gli aggiornamenti necessari.
,ic
c ci., .c. . ci sic
,ccc.
,cc
56-4 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n c o n t r o l l o p e r l e s a m e d e i d a t i
i __.isci ic.i.,c .c,
__,csc.
__,,c ci. ci.ci., .cci., .c.ic,
,
2 Scrivere il costruttore nel file DBCAL.CPP:
i __.isci ic.iic.i.,c .c
.i.,cic.i.c
,ic
c ,.i, ,ic .i . ci sc
,ccc.
i c __.isci .cccc ~, ~.,
,cc
i . __.isci ,.icic.i,
,
c __.isci ic.i.cccc ~, ~.
. __.isci ic.i,.icic.i
,.ic, sc .i i. ,.ics
.i.,cic.i,.icic.i, ,.ic is si
cic
,.i .isc,
.,
,ic
56-6 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n c o n t r o l l o p e r l e s a m e d e i d a t i
c.ii. ii.,
,
Prima di compilare lapplicazione, necessario includere i file DB.HPP e
DBTABLES.HPP nel file DBCAL.H:
-c.c ,,>
-c.c iccs,,>
Dichiarzione delle propriet di accesso
Ogni controllo data-aware ha una propriet DataSource che specifica quale classe
datasource nellapplicazione fornisce i dati al controllo. Inoltre, un controllo che
accede ad un singolo campo ha bisogno della propriet DataField per specificare quel
campo nella sorgente dati.
A differenza di quanto visto nellesempio relativo alle classi possedute riportato nel
Capitolo 54, Creazione di un controllo grafico, le propriet di accesso trattate
nellesempio non consentono di accedere alle classi possedute, ma alle propriet
corrispondenti nella classe posseduta. In pratica, bisogna costruire propriet che
abilitano il controllo e il relativo collegamenti a condividere la stessa sorgente dati e
lo stesso campo.
Dichiarare le propriet DataSource e DataField e i rispettivi metodi di
implementazione, quindi scrivere i metodi come metodi pass-through per arrivare
alle propriet corrispondenti della classe datalink:
Un esempio di dichiarazione delle propriet di accesso
ciss .~~ ic.i ,cc .i.,cic.i
,ic
,
~s. __.isci ic.iciic.
c ii.>c..i.c,
c ii.>ii.cc,
C r e a z i o n e d i u n c o n t r o l l o d i a c c e s s o a i d a t i 56-7
C r e a z i o n e d i u n c o n t r o l l o p e r l e s a m e d e i d a t i
. __.isci ic.i.ciic.~s. ic
ii.>c..i.c ic,
. __.isci ic.i.cii.ccii.cc ic
.ic .
ic>cc..cis,
ii.>ii.cc ic,
Ora che sono stati stabiliti i collegamenti tra il calendario e il relativo datalink, c il
passo pi importante. necessario costruire una classe datalink quando il controllo
calendario viene generato e distruggere il datalink prima della distruzione del
calendario.
Inizializzazione del datalink
Un controllo associato ai dati deve poter accedere al proprio datalink finch esiste e
quindi deve costruire loggetto datalink allinterno del proprio costruttore e
distruggerlo prima di essere a sua volta distrutto.
Ridefinire il costruttore e il distruttore del calendario:
ciss .~~ ic.i ,cc .i.,cic.i
,cc
i __.isci ic.i.,c .c,
__.isci -ic.i,
,
__.isci ic.iic.i.,c .c .i.,cic.i.c
ci. c,
ii. c. c.ii.,
ii.> s,
__.isci ic.i-ic.i
ii.> .,
ii.>,.icii .,
.ccc ii.,
,ic
. __.isci iiicccc .c.c,
,
. __.isci ic.iiiic ccc .c.c
ci. c,
ii. c. c.ii., csc c .ii. ccc
ii.> s,
ii.>iiic iiic, iic c i.c
__.isci ic.i-ic.i
ii.> .,
ii.>,.icii .,
ii.>iiic ., .cic c i.c cc.c
.ccc ii., .cs c .ii. ccc
,ccc.
i . __.isci .sc..sc , ...ic .., .,
,
,
Scrivere il metodo MouseDown nel file .CPP:
. __.isci ic.i.sc..sc , ...ic .., .,
,ccc.
i . __.isci c.sc. s c, ...ic ..,
,
2 Scrivere il metodo KeyDown nel file .CPP:
C r e a z i o n e d i u n c o n t r o l l o d i a c c e s s o a i d a t i 56-11
C r e a z i o n e d i u n c o n t r o l l o p e r l e d i t i n g d e i d a t i
. __.isci ic.ic.sc. s c, ...ic ..
cc .c., .ccic cc ,c
.csc. s,,> .c.c,
.c.c .c.c _. _. _ iss i .cs sc
_L- _. _-. _.L _..,
. ci. . c s ci.
.c.cisc i. .c s c sc
ii.>. i. .c. s c. ..c
csc
,ic
56-12 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n c o n t r o l l o p e r l e d i t i n g d e i d a t i
. __.isci ,.iciiccc .c.c,
,
2 Scrivere il metodo UpdateData nel file .CPP:
. __.isci ic.i,.icii ccc .c.c
,ccc.
i . __.isci ic,
,
2 Scrivere il metodo Change, chiamando il metodo Modified che informa il dataset
che i dati sono stati modificati, quindi chiamare il metodo Change ereditato:
. __.isci ic.iic
. ii. .
ii.>...c., ci c ...c. .c.
.i.,cic.iic, ci c cc. ic .c.
C r e a z i o n e d i u n c o n t r o l l o d i a c c e s s o a i d a t i 56-13
C r e a z i o n e d i u n c o n t r o l l o p e r l e d i t i n g d e i d a t i
Aggiornamento del dataset
Finora, una modifica allinterno del controllo data-aware ha modificato valori nella
classe datalink del campo. Il passo finale della creazione di un controllo modifica dati
quello di aggiornare il dataset col nuovo valore. Laggiornamento dovrebbe essere
effettuato quando chi ha modificato il valore nel controllo associato ai dati esce dal
controllo facendo clic esternamente al controllo o premendo il tasto Tab. Questo
processo funziona in modo diverso nella VCL e nella CLX.
Nella VCL sono definiti vari ID per il controllo dei messaggi relativi alle operazioni
sui controlli. Per esempio, il messaggio CM_EXIT viene trasmesso al controllo
quando lutente ne esce. Si possono scrivere gestori di messaggi che rispondono al
messaggio. In questo caso, quando lutente esce dal controllo, il metodo CMExit, il
gestore del messaggio CM_EXIT, risponde aggiornando il record nel dataset coi
valori modificati nella classe campo datalink. Per maggiori informazioni sui gestori
di messaggio, consultare il Capitolo 51, Gestione dei messaggi e delle notifiche di
sistema.
Per aggiornare il dataset allinterno di un gestore messaggi:
1 Aggiungere il gestore messaggio al componente TDBCalendar:
ciss .~~ ic.i ,cc .i.,cic.i
,ic
. __.isci .x...ii.s .cssic,
L._...~_.~.
...~_-~.._.L, ...ii.s, .x
._...~_.~.
,
2 Scrivere il codice nel file .CPP in modo che somigli al seguente:
. __.isci ic.i.x...ii.s .cssic
cic
Nella CLX, TWidgetControl ha un metodo protetto DoExit che viene chiamato quando
il fuoco viene spostato via dal controllo. Questo metodo chiama il gestore di evento
dellevento OnExit. possibile ridefinire questo metodo per aggiornare il record nel
dataset prima di generare il gestore di evento OnExit.
Per aggiornare il dataset quando lutente si sposta dal controllo, fare quanto segue:
1 Aggiungere la direttiva override al metodo DoExit del componente TDBCalendar:
56-14 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i u n c o n t r o l l o p e r l e d i t i n g d e i d a t i
ciss .~~ ic.i ,cc .i.,cic.i
,ic
.~.L . __.isci x.,
,
2 Scrivere il codice nel file .CPP in modo che somigli al seguente:
. __.isci ic.ix.
cic
T r a s f o r ma z i o n e d i u n a f i n e s t r a d i d i a l o g o i n u n c o mp o n e n t e 57-1
C a p i t o l o
57
Capitolo57Trasformazione di una finestra di
dialogo in un componente
A volte potrebbe risultare utile trasformare una finestra di dialogo usata di frequente
in un componente da aggiungere alla Component palette. I componenti finestra di
dialogo funzioneranno esattamente come i componenti standard delle finestre di
dialogo comuni. Lo scopo quello di creare un semplice componente che possa
essere aggiunto a un progetto e per il quale sia possibile impostarne le propriet in
fase di progettazione.
La trasformazione di una finestra di dialogo in un componente richiede le seguenti
operazioni:
1 Definizione dellinterfaccia del componente.
2 Creazione e registrazione del componente
3 Creazione dellinterfaccia del componente
4 Verifica del componente
Il componente wrapper di C++Builder associato alla finestra di dialogo, crea ed
esegue la finestra di dialogo durante lesecuzione, passando i dati specificati
dallutente. Il componente finestra di dialogo risulta pertanto riutilizzabile e
Personalizzazione.
Questo capitolo descrive come creare un componente contenitore (wrapper) che
contiene la finestra About Box fornita nellObject Repository di C++Builder.
_
Copiare i file ABOUT.H, ABOUT.CPP e ABOUT.DFM nella directory di lavoro.
Aggiungere ABOUT.CPP al progetto in modo da creare un file ABOUT.OBJ quando
si costruisce il componente contenitore.
Non ci sono considerazioni speciali da fare per la progettazione di una finestra di
dialogo che deve essere inglobata in un componente. Quasi tutte le schede possono
operare come una finestra di dialogo in questo contesto.
57-2 G u i d a a l l a p r o g r a mma z i o n e
D e f i n i z i o n e d e l l i n t e r f a c c i a d e l c o m p o n e n t e .
Definizione dellinterfaccia del componente.
Prima di creare il componente per la finestra di dialogo, occorre decidere come
svilupparlo in modo da poterlo utilizzare. possibile creare uninterfaccia tra la
finestra di dialogo e le applicazioni che la utilizzano.
Per esempio, si osservino le propriet dei componenti di una comune finestra di
dialogo. possibile notare che consentono agli sviluppatori di impostare lo stato
iniziale della finestra di dialogo, come il titolo e limpostazione iniziale dei controlli,
e, una volta chiusa la finestra di dialogo, di rileggere tutte le informazioni necessarie.
Non ci sono interazioni dirette con i singoli controlli nella finestra di dialogo, ma solo
con le propriet nel componente contenitore.
Linterfaccia deve inoltre contenere informazioni sufficienti affinch la scheda della
finestra di dialogo possa apparire nella modalit specificata dallo sviluppatore e
restituisca ogni informazione richiesta dallapplicazione. Si pu pensare alle
propriet incapsulate nel componente contenitore come a dati persistenti per una
finestra di dialogo transiente.
La finestra About non deve restituire alcuna informazione, cos le propriet del
contenitore devono contenere solo le informazioni necessarie per visualizzare
correttamente la finestra. Poich ci sono quattro campi separati nella finestra About
che possono essere modificati dalle applicazioni, si forniranno, per questi, quattro
propriet di tipo stringa.
Creazione e registrazione del componente
La creazione di qualsiasi componente inizia sempre nello stesso modo: si deriva la
classe di un componente, si salvano il file .CPP e .H del componente, lo si registra, lo
si compila e lo si installa nella component palette. Questo processo viene descritto
nella sezione Creazione di un nuovo componente a pagina 45-8.
Per questo esempio necessario seguire la procedura generale per la creazione di un
componente, con le seguenti specifiche:
Derivare un nuovo tipo di componente chiamato TAboutBoxDlg, discendente da
TComponent.
Chiamare i file unit del componente ABOUTDLG.H e ABBOUTDLG.CPP.
Registrare TAboutBoxDlg nella pagina Sample della Component palette.
Il file .HPP risultante dovrebbe essere simile al seguente:
-..c. ~c-
-.c.c ~c-
-c.c csss,,>
-c.c ccs,,>
-c.c ccisscs,,>
-c.c c..s,,>
T r a s f o r ma z i o n e d i u n a f i n e s t r a d i d i a l o g o i n u n c o mp o n e n t e 57-3
C r e a z i o n e d e l l i n t e r f a c c i a d e l c o m p o n e n t e
ciss .~~ ~cx ,cc .,c
,ic
,ccc.
,cc
__,csc.
,
-c..
Il file .CPP della unit sar simile al seguente:
-c.c cc>
-,i.i .s,
-c.c '~c'
-,i.i ,ic.ics.i_,
c c. ~cx.,
i.cs,icc ~c
_
Se stato utilizzato il wizard Component per inizializzare questo componente, a
TAboutDlg verr aggiunto anche un costruttore.
Nelle applicazioni CLX i nomi e le ubicazioni di alcuni file header sono differenti. Ad
esempio, <vcl\controls.hpp> <clx\qcontrols.hpp> in CLX.
In questa fase il nuovo componente ha solamente le capacit intrinseche ed ereditate
da TComponent. il pi semplice componente non visuale. Nella sezione successiva si
creer linterfaccia tra il componente e la finestra di dialogo.
Creazione dellinterfaccia del componente
Queste sono le operazioni da svolgere per creare linterfaccia del componente:
1 Inclusione dei file unit della scheda.
2 Aggiunta delle propriet di interfaccia.
3 Aggiunta del metodo Execute.
57-4 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d e l l i n t e r f a c c i a d e l c o m p o n e n t e
Inclusione dei file unit della scheda
Per inizializzare il proprio componente wrapper e visualizzare la finestra di dialogo
inclusa, necessario aggiungere i file della scheda al progetto.
Includere ABOUT.H e il collegamento ad ABOUT.OBJ nel file header del
componente:
-c.c '~c'
-,i.i . '~cc'
Il file header della scheda dichiara sempre unistanza della classe della scheda. Nel
caso della finestra About, la classe della scheda TAboutBox e il file ABOUT.H
include quanto segue:
cxc ~cx ~cx,
Aggiunta delle propriet di interfaccia
Prima di procedere, bisogna decidere quali sono le propriet necessarie al contenitore
affinch gli sviluppatori possano utilizzare la finestra di dialogo come componente
nelle applicazioni. Per ottenere ci, si possono aggiungere le dichiarazioni per queste
propriet nella dichiarazione del componente.
Le propriet nei componenti contenitore sono qualcosa di pi semplice delle
propriet che si potrebbero creare scrivendo un semplice componente. Ricordarsi
che, in questo caso, si stanno creando alcuni dati persistenti che il contenitore pu
passare alla finestra di dialogo e ricevere da essa. Inserendo questi dati sotto forma di
propriet, si consente agli sviluppatori di impostare i dati in fase di progetto, in
modo che il contenitore li possa passare alla finestra di dialogo in fase di esecuzione.
La dichiarazione di una propriet di interfaccia richiede due aggiunte alla
dichiarazione della classe del componente:
Un membro dati privato, cio la variabile che il contenitore usa per registrare il
valore della propriet
La dichiarazione published stessa della propriet, che specifica il nome della
propriet e indica quale membro dati utilizzare per la registrazione.
Le propriet di interfaccia di questo tipo non necessitano di metodi di accesso.
Utilizzano un accesso diretto ai propri dati registrati. Per convenzione, il membro
dati che contiene il valore di propriet ha lo stesso nome della propriet, ma
preceduto dalla lettera F. Il membro dati e la propriet devono essere dello stesso
tipo.
Per esempio, per dichiarare una propriet di interfaccia di tipo integer di nome Year,
dichiararla come segue:
ciss .~~ i,,c ,cc .,c
,ic
ci, .ii .c.cc . c ci,,c .ii
,ccc.
T r a s f o r ma z i o n e d i u n a f i n e s t r a d i d i a l o g o i n u n c o mp o n e n t e 57-5
C r e a z i o n e d e l l i n t e r f a c c i a d e l c o m p o n e n t e
,cc
__,csc.
__,,c ci ci.ci, .cci, ,,c .icc. . sic
,
Per la finestra About servono quattro propriet di tipo string, rispettivamente per il
nome del prodotto, linformazione sulla versione, linformazione sul copyright e un
eventuale commento. Il file ABOUTDLG.H apparir ora in questo modo:
ciss .~~ ~cx ,cc .,c
,ic
ci,
. ..c.i.c, cs, ,, ..cs,
,ccc.
,cc
__,csc.
__,,c ci ci.ci, .cci,
__,,c . ..c.i.c ci...c.i.c, .c..c.i.c,
__,,c . cs ci.cs, .ccs,
__,,c . , ci.,, .c,,
__,,c . ..cs ci...cs, .c..cs,
,
Quando si installa il componente nella component Palette e lo si colloca su una
scheda, sar possibile impostarne le propriet, e questi valori saranno
automaticamente inseriti nella scheda. Il contenitore potr quindi utilizzare questi
valori quando esegue la finestra di dialogo inglobata.
Aggiunta del metodo Execute
La parte finale del componente interfaccia un metodo per aprire la finestra di
dialogo e restituire un risultato quando viene chiusa. Come con i componenti
finestra di dialogo comune, possibile utilizzare una funzione booleana di nome
Execute che restituisce true se lutente fa clic su OK, oppure false se lutente annulla
la finestra di dialogo.
La dichiarazione del metodo Execute sempre simile alla seguente:
ciss .~~ .i,,c ,cc .,c
,cc
c __.isci xccc,
,
Limplementazione minima di Execute deve costruire la finestra di dialogo, mostrarla
come una finestra di dialogo modale e restituire true o false, a seconda del valore
restituito da ShowModal.
Questo il metodo Execute per una finestra di dialogo di tipo TMyDialogBox:
c __.isci .i,,cxccc
57-6 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d e l l i n t e r f a c c i a d e l c o m p o n e n t e
ix c. .ix~,,ci, csc c ..
c cs,
cic
ix>cc, .s,sc . ..
cic
~cx>cc, .s,sc . ~c cx
c cs L, c.,ic cs L i. c ci ic
Aggiungere alla parte public della classe TAboutDlg nel file header ABOUTDLG.H la
dichiarazione per il metodo Execute:
ciss .~~ ~c ,cc .,c
T r a s f o r ma z i o n e d i u n a f i n e s t r a d i d i a l o g o i n u n c o mp o n e n t e 57-7
V e r i f i c a d e l c o m p o n e n t e
,cc
i c __.isci xccc,
,
Verifica del componente
Una volta installato il componente della finestra di dialogo, lo si pu usare come si fa
con le comuni finestre di dialogo, mettendone uno su una scheda ed eseguendo la
scheda. Un modo rapido per verificare la finestra di dialogo About quello di
aggiungere un pulsante a una scheda che mandi in esecuzione la finestra di dialogo
quando lutente fa clic sul pulsante.
Ad esempio, se si creato una finestra di dialogo About, la si trasformata in un
componente e la si aggiunta alla Component palette, possibile collaudarla nel
seguente modo:
1 Creare un nuovo progetto.
2 Collocare un componente About sulla scheda principale.
3 Inserire un pulsante nella scheda.
4 Fare doppio clic sul pulsante per scrivere il gestore di evento clic.
5 Inserire la seguente linea di codice:
~cx>xccc,
6 Eseguire lapplicazione.
Quando appare la scheda principale, fare clic sul pulsante. Apparir la finestra About
con licona predefinita del progetto e il nome Project1. Scegliere OK per chiudere la
finestra di dialogo.
Si pu collaudare ulteriormente il componente impostando le varie propriet del
componente About ed eseguendo nuovamente lapplicazione.
57-8 G u i d a a l l a p r o g r a mma z i o n e
V e r i f i c a d e l c o m p o n e n t e
E s t e n s i o n e d e l l I D E 58-1
C a p i t o l o
58
Capitolo58Estensione dellIDE
possibile estendere e personalizzare l IDE con voci di menu, pulsanti della barra
strumenti, wizard dinamici per la creazione di schede e altro, utilizzando le API di
Open Tools (spesso abbreviato in API Tools). Le API Tools sono un insieme di pi di
100 interfacce (classi astratte) che interagiscono con e controllano lIDE , compresi il
menu principale, le barre strumenti, lelenco delle azioni principali e delle immagini,
i buffer delleditor interno dei sorgenti, le macro e i collegamenti di tastiera, le schede
e i relativi componenti nelleditor delle schede, il debugger e il processo in fase di
debug, il completamento del codice, la vista dei messaggi e la lista To-Do.
Utilizzare le API Tools significa semplicemente scrivere classi che implementano
alcune interfacce e chiamare i servizi forniti da altre interfacce. Il codice delle API
Tools deve essere compilato e caricato nellIDE in fase di progettazione come un
package di progettazione oppure in una DLL. Quindi, scrivere unestensione delle
API Tools pi o meno come scrivere un editor di propriet o di un componente.
Prima di affrontare questo capitolo, assicurarsi di avere familiarit con le nozioni di
base per operare con i package (Capitolo 15, Uso di package e di componenti) e per
registrare componenti (Capitolo 52, Come rendere disponibili i componenti in fase
di progetto). Sarebbe anche bene leggere il Capitolo 13, Supporto del linguaggio
C++ per la VCL e la CLX, soprattutto la sezione Eredit e interfacce a pagina 13-2
per informazioni sulle interfacce in stile Delphi.
Questo capitolo tratta i seguenti argomenti:
Panoramica sugli strumenti API
Scrittura di una classe wizard
Ottenimento dei servizi delle API Tools
Operazioni con file ed editor
Creazione di schede e di progetti
Notifica a un wizard di eventi dellIDE
Installazione della DLL di un wizard
58-2 G u i d a a l l a p r o g r a mma z i o n e
P a n o r a m i c a s u g l i s t r u m e n t i A P I
Panoramica sugli strumenti API
Tutte le dichiarazioni delle API Tools risiedono in un singolo file header,
ToolsAPI.hpp; il namespace Toolsapi. Di solito, per utilizzare le API Tools, si usa il
package designide: cio necessario costruire gli add-in delle API Tools come un
package di progettazione o come una DLL che utilizza package di esecuzione. Per
informazioni sui problemi realtivi ai package e alle librerie, vedere Installazione del
package del wizard a pagina 58-7 and Installazione della DLL di un wizard a
pagina 58-23.
Linterfaccia principale per la scrittura di unestensione delle API Tools
IOTAWizard, ed per questo che la maggior parte degli add-in dellIDE sono detti
wizard. La maggior parte dei wizard di C++Builder e di Delphi sono intercambiabili.
possibile scrivere e compilare un wizard in Delphi e utilizzarlo in seguito in
C++Builder, e viceversa. Linteroperabilit funziona al meglio con lo stesso numero
di versione, ma anche possibile scrivere wizard da utilizzare in future versioni di
entrambi i prodotti. Per ulteriori informazioni sulla compatibilit con future versioni,
vedere Utilizzo di una DLL senza package di esecuzione a pagina 58-24.
Per utilizzare le API Tools, vengono scritte le classi dei wizard che implementano
una o pi interfacce definite nella unit ToolsAPI. Si ricordi dal Capitolo 13 che
C++Builder rappresenta uninterfaccia Object Pascal come una classe astratta. Per
implementare linterfaccia, necessario ridefinire le funzioni membro della classe
astratta e i suoi antenati e implementare la funzione QueryInterface per riconoscere
linterfaccia GUID.
Un wizard utilizza i servizi forniti dalle API Tools. Ogni servizio costituito da
uninterfaccia che presenta un insieme di funzioni connesse. Limplementazione
dellinterfaccia nascosta allinterno dellIDE. Le API Tools pubblicano solo
linterfaccia, che pu essere utilizzata per scrivere i wizard senza occuparsi
dellimplementazione delle interfacce. I vari servizi permettono laccesso alleditor
dei sorgenti, al designer delle schede, al debugger e cos via. La sezione Ottenimento
dei servizi delle API Tools a pagina 58-8 esamina questo argomento in modo
approfondito.
Il servizio e le altre interfacce rientrano in due categorie di base. possibile
distinguerle grazie al prefisso utilizzato per il nome del tipo:
NTA (native tools API) garantisce laccesso diretto agli oggetti effettivi IDE, come
loggetto TMainMenu dellIDE. Quando vengono utilizzate queste interfacce, il
wizard deve usare i package di Borland, il che significa anche che il wizard
legato a una versione specifica dellIDE. Il wizard pu risiedere in un package di
progettazione o in una DLL che utilizza i package di esecuzione.
OTA (open tools API) non richiedere package e accede allIDE solo attraverso le
interfacce. In teoria, si potrebbe scrivere un wizard in qualsiasi linguaggio che
supporta le interfacce in stile COM, a condizione che sia possibile operare anche
con la convenzione di chiamata __fastcall di Borland e con i tipi Object Pascal
come AnsiString. Le interfacce OTA non garantiscono il completo accesso allIDE,
ma quasi tutte le funzionalit delle API Tools sono disponibili attraverso le
E s t e n s i o n e d e l l I D E 58-3
S c r i t t u r a d i u n a c l a s s e w i z a r d
interfacce OTA. Se un wizard utilizza solo le interfacce OTA, possibile scrivere
una DLL che non dipenda da una versione specifica dellIDE.
Le API Tools hanno due tipi di interfacce: un tipo che deve essere implementato dal
programmatore e un tipo che viene implementato dallIDE. La maggior parte delle
interfacce appartiene a questultima categoria: le interfacce definiscono la capacit
dellIDE ma nascondono l implementazione corrente. I tipi di interfacce che devono
essere implementate ricadono in tre categorie: wizard, notifier e creator:
Come gi stato menzionato in questa sezione, una classe wizard implementa
linterfaccia IOTAWizard e le eventuali interfacce derivate.
Un notifier un altro tipo di interfaccia delle API Tools. LIDE utilizza il notifier
per richiamare il wizard quando accade qualcosa di interessante. Il
programmatore scrive una classe che implementa linterfaccia notifier e registra il
notifier con le API Tools e lIDE esegue una call back alloggetto notifier quando
lutente apre un file, modifica il codice sorgente, modifica una scheda, avvia una
sessione di debug, e cos via. I notifier vengono trattati in Notifica a un wizard di
eventi dellIDE a pagina 58-19.
Un creator un altro tipo di interfaccia che necessario implementare. Le API
Tools utilizzano un creator per creare nuove unit, progetti o altri file o per aprire i
file esistenti. La sezione Creazione di schede e di progetti a pagina 58-14 tratta
questi argomenti in modo pi approfondito.
Altre importanti interfacce sono i moduli e gli editor. Uninterfaccia di modulo
rappresenta una unit aperta, che ha uno o pi file. Uninterfaccia di editor
rappresenta un file aperto. Diversi tipi di interfacce editor consentono laccesso a
diversi aspetti dellIDE: leditor dei sorgente ai file sorgente, il Form designer ai file
scheda e le risorse di progetto ai file di risorse. La sezione Operazioni con file ed
editor a pagina 58-13 tratta questi argomenti in modo approfondito.
Le seguenti sezioni descrivono le fasi per la scrittura di un wizard. Fare riferimento ai
file della guida in linea per i dettagli completi di ogni interfaccia.
Scrittura di una classe wizard
Ci sono quattro tipi di wizard, che si differenziano per le interfacce implementate
dalla classe wizard. La Tabella 58.1 descrive i quattro tipi di wizard.
I quattro tipi di wizard si differenziano solo per il modo in cui il wizard viene
richiamato dallutente:
Tabella 58.1 I quattro tipi di wizard
Interfaccia Descrizione
IOTAFormWizard Di solito crea una nuova unit, scheda o altro file
IOTAMenuWizard Viene automaticamente aggiunto al menu della guida
IOTAProjectWizard Di solito crea una nuova applicazione o un altro progetto
IOTAWizard Wizard eterogeneo che non rientrano in altre categorie
58-4 G u i d a a l l a p r o g r a mma z i o n e
S c r i t t u r a d i u n a c l a s s e w i z a r d
Un menu wizard viene aggiunto al menu Help dellIDE. Quando lutente sceglie la
voce di menu, lIDE chiama la funzione Execute() del wizard. I wizard normali
offrono una maggiore flessibilit, perci i menu wizard vengono di solito utilizzati
solo per prototipi e per eseguire il debug.
I wizard di scheda e i wizard di progetto vengono chiamati wizard repository
perch risiedono nellObject Repository. Lutente chiama questi wizard dalla
finestra di dialogo New Items. Lutente pu anche vedere i wizard nellObject
Repository (scegliendo la voce di menu Tools| Repository). Lutente pu
selezionare la casella di controllo New Form di un wizard di scheda, la quale
comunica allIDE di chiamare il wizard di scheda quando lutente sceglie la voce
di menu File|New Form. Lutente pu inoltre selezionare la casella di controllo
Main Form. La casella di controllo dice allIDE di impiegare il wizard delle schede
come scheda predefinita per una nuova applicazione. Lutente pu controllare la
casella di controllo New Project per un wizard di progetto. Quando lutente
sceglie File|New Application, lIDE chiama il wizard di progetto selezionato.
Il quarto tipo di wizard viene utilizzato in situazioni che non rientrano nelle altre
categorie. Un normale wizard non fa niente automaticamente o da solo. Al
contario, necessario definire il modo in cui il wizard viene richiamato.
Le API Tools non impongono nessuna restrizione al wizard, come richiedere un
wizard di progetto per creare un progetto. possibile scrivere semplicemente un
wizard di progetto per creare una scheda e un wizard di schede per creare un
progetto (se qualcosa che si desidera realmente fare).
Implementazione delle interfacce wizard
Ogni classe wizard deve implementare almeno IOTAWizard, che richiede di
implementare anche i suoi antenati: IOTANotifier e IInterface. I wizard delle schede e
dei progetti devono implementare tutte le loro interfacce antenato, cio,
IOTARepositoryWizard, IOTAWizard, IOTANotifier e IInterface.
Limplementazione di IInterface deve seguire le normali regole delle interfacce Object
Pascal, che sono le stesse di quelle delle interfacce COM. Vale a dire, QueryInterface
esegue conversioni di tipo e AddRef e Release gestiscono il conteggio dei riferimenti. Si
potrebbe volere utilizzare una classe base comune per semplificare la scrittura del
wizard e delle classi notifier.
Ad esempio, Delphi ha la classe TNotifierObject, che implementa IOTANotifier con
corpi di funzione vuoti. possibile scrivere una classe simile in C++, come verr
mostrato in seguito.
cIaaa .~~ ..cccc pabIIc L~..c
pabIIc
__?aatcaII ..cccc c._c
vIttaaI __?aatcaII -..cccc,
veIi __?aatcaII ~.c.ic,
veIi __?aatcaII c.c.ic,
veIi __?aatcaII csc.,
veIi __?aatcaII ...c.,
ptetectei
E s t e n s i o n e d e l l I D E 58-5
S c r i t t u r a d i u n a c l a s s e w i z a r d
LLc.icc
vIttaaI -. __aticaII _cLc.iccceaat L, veIi,
vIttaaI . __aticaII ~..c.,
vIttaaI . __aticaII ccisc,
ptIvate
Iea c._c,
,
Limplementazione dellinterfaccia IInterface immediata:
. __aticaII ..cccc~..c.
tetata Lcc.c.Lcc.cc._c,
. __aticaII ..ccccccisc
. cs Lcc.c.ccc.cc._c,
I? c._c
ieIete taIa ,
tetata cs,
I? . __aaIie?LLc.icc
c atatIc_caat LLc.icc>taIa,
atatIc_caat LLc.icc>c>~..c.,
tetata ._,
I? . __aaIie?L~..c
c atatIc_caat L~..c>taIa,
atatIc_caat L~..c>c>~..c.,
tetata ._,
tetata _.L.~,
I? . __aaIie?L~.c.i.
c atatIc_caat L~.c.i.>taIa,
atatIc_caat L~.c.i.>c>~..c.,
tetata ._,
I? . __aaIie?L~.i.
c atatIc_caat L~.i.>taIa,
atatIc_caat L~.i.>c>~..c.,
tetata ._,
tetata cc._cLc.icc., c,
Poich AfterSave, BeforeSave, e cos via, hanno nella classe base corpi di funzione
vuoti, nella classe derivata possibile lasciarli come corpi di funzione vuoti ed
evitare la chiamata non necessaria a inherited::AfterSave ().
Semplificazione dellimplementazione delle interfacce
Poich le interfacce Object Pascal sono simili alle interfacce COM, possibile
utilizzare wizard COM come aiuto per la scrittura della classe wizard. Tuttavia,
COM richiedono molto pi lavoro rispetto a quello richiesto dalle semplici interfacce
Object Pascal. Con un uso giudizioso di classi base e con qualche operazione di taglia
e incolla, risulter probabilmente pi semplice non utilizzare i wizard COM, ma
continuare ad utilizzare semplici implementazioni. Ad esempio, possibile rendere
pi semplice limplementazione di QueryInterface definendo una semplice macro:
E s t e n s i o n e d e l l I D E 58-7
S c r i t t u r a d i u n a c l a s s e w i z a r d
-ie?Iae __L.~, ., c
I? . __aaIie?
c atatIc_caat >taIa,
atatIc_caat >c>~..c.,
tetata ._,
Utilizzare questa macro come segue:
-. __aticaII ..i._cLc.iccceaat L ., veIi c
__L.~L~.c.i., ., c,
__L.~L~.i., ., c,
tetata cc._cLc.icc., c,
possibile registrare anche editor di propriet, componenti, e cos via, come parti
dello stesso package.
bene ricordare che un package di progettazione parte dellapplicazione principale
di C++Builder, quindi qualsiasi nome di scheda deve essere univoco per l intera
applicazione e per tutti gli altri package di progettazione. Questo lo svantaggio
maggiore nellutilizzo di package: non si possono conoscere i nomi che altri
programmatori potrebbero attribuire alle loro schede.
Durante lo sviluppo, installare il package del wizard nel modo in cui si installerebbe
qualsiasi altro package di progettazione: fare clic sul pulsante Install nel Package
manager. LIDE compiler e collegher il package e cercher di caricarlo. LIDE
mostra una finestra di dialogo che informa se loperazione andata a buon fine.
58-8 G u i d a a l l a p r o g r a mma z i o n e
O t t e n i m e n t o d e i s e r v i z i d e l l e A P I T o o l s
Ottenimento dei servizi delle API Tools
Per fare qualcosa di utile, un wizard deve accedere allIDE: ai suoi editor, alle sue
finestre, al suo menu e cos via. Questo il ruolo delle interfacce di servizio. Le API
Tools includono molti servizi, come i servizi delle azioni per eseguire le azioni dei
file, i servizi delleditor per accedere alleditor del codice sorgente, i servizi del
debugger per accedere al debugger, e cos via. La Tabella 58.2 riassume tutte le
interfacce di servizio.
Per utilizzare uninterfaccia di servizio, convertire la variabile BorlandIDEServices nel
servizio richiesto utilizzando la funzione membro Supports. Ad esempio,
veIi sc_.cs.c_.ccbeeI .cc
_._L~cci.iscs .i,
I? i.L.cccs>.,,s.i
.i>cic .cc,
.cLc. c. scccs>.i.c>Lc.s>Lc.s,,
I? .,iccxc.>.i.c, 'c.s.c'
.c_c. aev .cLc.,
.c_c.>~c ic,
c.>Lsc, .c_c.,
__?aatcaII ..i.-..i.
_._L.~.cccs scccs,
i.L.cccs>.,,sscccs,
cc. i c cis, i. c.c i cs i sc
s ic
c.c_icic, scccs>i,ss.i,
c.c_icic, scccs>i,scs.,i,
c.c_icic, scccs>i,s.i.i.i,
c.c_icic, scccs>i,scci,
c.c_icic, scccs>i,sc.i,
c.c_icic, scccs>i,sLcci,
ieIete .c_c.,
ieIete ic,
_._L~..c.cccs sc,
i.L.cccs>.,,ssc,
?et Iat , sc>..c, --
_._L~..c ..c sc>..cs,,
_._L~.cc, ,,
I? ..c>.,,s,
tetata ,,
58-14 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i s c h e d e e d i p r o g e t t i
tetata ,
Le interfacce degli editor danno accesso al loro stato interno. possibile esaminare il
codice sorgente o i componenti che lutente sta modificando, apportare modifiche al
codice sorgente, ai componenti o alle propriet, modificare la selezione nelleditor
sorgente e delleditor delle schede ed eseguire quasi tutte le azioni delleditor che
possono essere eseguite dallutente.
Un wizard pu accedere a tutti i componenti della scheda utilizzando uninterfaccia
delleditor della scheda. Ogni componente (tra cui la scheda principale o il modulo
dati) ha uninterfaccia associata IOTAComponent. Un wizard pu esaminare o
cambiare la maggior parte delle propriet dei componente. Se necessario avere
controllo assoluto sul componente, possibile convertire linterfaccia
IOTAComponent in INTAComponent. Linterfaccia nativa del componente consente al
wizard di accedere direttamente al puntatore INTAComponent. Questo potrebbe
essere importante se fosse necessario leggere o modificare una propriet di tipo
classe, come TFont, il che possibile solo tramite interfacce in stile NTA.
Creazione di schede e di progetti
C++Builder dispone gi di molti wizard per schede e progetti, ed possibile
scriverne di propri. LObject Repository permette di creare modelli statici che
possono essere utilizzati in un progetto, ma un wizard molto pi potente perch
dinamico. Il wizard pu interagire con lutente e creare vari tipi di file a seconda delle
risposte dellutente. Questa sezione descrive come scrivere un wizard per scheda o
per progetto.
E s t e n s i o n e d e l l I D E 58-15
C r e a z i o n e d i s c h e d e e d i p r o g e t t i
Creazione dei moduli
Di solito un wizard per scheda o per progetto crea uno o pi file nuovi. Tuttavia al
posto di file reali, sarebbe meglio creare moduli senza nome e non salvati. Quando
lutente li salva, lIDE richiede allutente un nome per il file. Un wizard utilizza un
oggetto creator per creare tali moduli.
Una classe creator implementa uninterfaccia creator, la quale eredita da
IOTACreator. Il wizard passa un oggetto creator al metodo CreateModule del servizio
del modulo e lIDE richiama loggetto creator per ottenere i parametri di cui ha
bisogno per creare il modulo.
Ad esempio, un wizard per scheda che crea una nuova scheda implementa di solito
GetExisting() per restituire false e GetUnnamed() per restituire true. Ci crea un
modulo che non ha nome (in modo che lutente debba scegliere un nome prima che il
file possa essere salvato) e non si appoggia ad alcun file esistente (in modo che
lutente debba salvare il file anche se non viene apportato nessun cambiamento).
Altri metodi del creator comunicano allIDE il tipo di file che viene creato (per
esempio, progetto, unit o scheda), forniscono il contenuto del file o restituiscono il
nome della scheda, il nome dellantenato e altre importanti informazioni. Ulteriori
callback consentono a un wizard di aggiungere moduli a un progetto appena creato o
aggiungono componenti a una scheda appena creata.
Per creare un nuovo file, come viene spesso richiesto in un wizard per scheda o per
progetto, di solito necessario fornirne i contenuti. Per fare ci, scrivere una nuova
classe che implementa linterfaccia IOTAFile. Se il wizard in grado di farlo con i
contenuti predefiniti del file, possibile restituire un puntatore 0 da qualsiasi
funzione che restituisce IOTAFile.
Ad esempio, si supponga che lazienda per cui si lavora abbia un blocco di commento
standard che deve apparire allinizio di ogni file sorgente. Si potrebbe fare ci
utilizzando un modello statico nellObject Repository, ma potrebbe essere necessario
aggiornare manualmente il blocco di commento per riportare lautore e la data di
creazione. Invece, possibile utilizzare un creator per riempire in modo dinamico il
blocco di commento al momento della creazione del file.
Il primo passo consiste nello scrivere un wizard che crea nuove unit e nuove schede.
La maggior parte delle funzioni del creator restituiscono zero, stringhe vuote o altri
valori predefiniti, i quali comunicano alle API Tools di creare una nuova unit o una
nuova scheda con il comportamento predefinito. Ridefinire GetCreatorType per
comunicare alle API Tools se devono creare una unit oppure una scheda. Per creare
una unit, restituire la macro sUnit. Per creare una scheda, restituire sForm. Per
semplificare il codice, utilizzare una singola classe che accetti come argomento del
costruttore il tipo creator. Salvare il tipo creator in un membro dati, in modo da
permettere a GetCreatorType di restituirne il valore. Ridefinire NewImplSource e
NewIntfSource per restituire i contenuti del file desiderati.
cIaaa .~~ ci pabIIc L~..cci
pabIIc
__?aatcaII ciceaat ~s. cci_,c
c._c, cci_,ccci_,c
vIttaaI __?aatcaII -ci,
58-16 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i s c h e d e e d i p r o g e t t i
L~..cci
vIttaaI ~s. __?aatcaII c~ccs.i.c,
vIttaaI ~s. __?aatcaII cL.,c.i.c,
vIttaaI ~s. __?aatcaII cL.c.i.c,
vIttaaI ~s. __?aatcaII c..i.c,
vIttaaI beeI __?aatcaII c.i.,
vIttaaI beeI __?aatcaII c...,
vIttaaI beeI __?aatcaII c...cc,
vIttaaI _._L~c __?aatcaII .c..c
ceaat ~s. .L.c, ceaat ~s. ~ccsL.c,
vIttaaI _._L~c __?aatcaII .c.L.,.cc
ceaat ~s. ..cL.c, ceaat ~s. .L.c,
ceaat ~s. ~ccsL.c,
vIttaaI _._L~c __?aatcaII .c.L..cc
ceaat ~s. ..cL.c, ceaat ~s. .L.c,
ceaat ~s. ~ccsL.c,
vIttaaI veIi __?aatcaII .cic.
ceaat _._L~.. ..,
L~ci
vIttaaI ~s. __?aatcaII cci,c,
vIttaaI beeI __?aatcaII cxs,
vIttaaI ~s. __?aatcaII cc.sc.,
vIttaaI _._L~..c __?aatcaII c.c,
vIttaaI beeI __?aatcaII ci.c.,
ptetectei
LLc.icc
vIttaaI -. __aticaII _cLc.iccceaat L, veIi,
vIttaaI . __aticaII ~..c.,
vIttaaI . __aticaII ccisc,
ptIvate
Iea c._c,
ceaat ~s. cci_,c,
,
La maggior parte dei membri di Creator restituiscono zero o stringhe vuote. I metodi
booleani restituiscono true, tranne GetExisting, che restituisce false. Il metodo pi
interessante GetOwner, che restituisce un puntatore al modulo del progetto
corrente, oppure 0 se non esiste alcun progetto. Non esiste un modo semplice per
scoprire il progetto corrente o il gruppo di progetti corrente. GetOwner deve
esaminare in sequenza invece tutti i moduli aperti. Se viene trovato un gruppo di
progetti, deve essere lunico gruppo di progetti aperto, in modo che GetOwner
restituisca il suo progetto corrente. Altrimenti, la funzione restituisce il primo
modulo di progetto che trova, oppure 0 se non aperto alcun progetto.
_._L~..c __?aatcaII cic.c
c c cc ,cc
_._L~.cc cs ,
_._L~..c.cccs sc Iatet?ace_caat L~..c.cccs>i.L.cccs,
?et Iat , sc>..c, --
beIa
_._L~..c ..c sc>..cs,,
E s t e n s i o n e d e l l I D E 58-17
C r e a z i o n e d i s c h e d e e d i p r o g e t t i
_._L~.cc ,cc,
_._L~.cc, ,,
I? ..c>.,,s,cc
c.c.cc c .s ,cc ..c
I? cs
cs ,cc,
eIae I? ..c>.,,s,
. c ,cc ,, s c s icc ,cc
cs ,>~cc.cc,
bteak,
tetata cs,
tetata scc,
tetata ,
possibile conservare il testo del contenuto del file in una risorsa per renderne pi
semplice la modifica, ma per maggiore semplicit, questo esempio scrive
58-18 G u i d a a l l a p r o g r a mma z i o n e
C r e a z i o n e d i s c h e d e e d i p r o g e t t i
direttamente il codice sorgente nel wizard. Supponendo che ci sia una scheda,
lesempio seguente genera il codice sorgente. possibile aggiungere con facilit il
caso pi semplice di una unit normale. Controllare FormIdent e se vuoto, creare una
unit normale; altrimenti creare una unit di scheda. Lo scheletro di base del codice lo
stesso dellimpostazione predefinita dellIDE (con laggiunta iniziale dei commenti,
naturalmente), ma possibile modificarlo nel modo desiderato.
_._L~c __?aatcaII ci.c.L.,.cc
ceaat ~s. ..cL.c,
ceaat ~s. .L.c,
ceaat ~s. ~ccsL.c
Si noti che il codice sorgente contiene stringhe con formato %m e %y. Questi sono
concettualmente simili a printf o ai controlli Format, ma vengono espansi dalla
funzione di espansione del wizard. Pi precisamente, %m viene espanso
nellidentificativo del modulo o della unit, %f nel nome della scheda e %a nel nome
dellantenato. Si noti come il nome della schada vengo utilizzato per il nome del tipo
della scheda con laggiunta di una T maiuscola. Alcuni specificatori di formato
aggiuntivi semplificano la generazione del blocco di commento: %d per la data, %u
per lutente e %y per lanno. (La scrittura della funzione di espansione
indipendente dalle API Tools ed proposto come un esercizio per il lettore.)
NewIntfSource simile a NewImplSource, ma genera il file dellinterfaccia (.h).
Il passo finale consiste nella creazione di due wizard per scheda: uno utilizza sUnit
come tipo di creator e laltro utilizza sForm. Con ulteriore vantaggio per lutente,
possibile utilizzare INTAServices per aggiungere una voce di menu al menu File|
E s t e n s i o n e d e l l I D E 58-19
N o t i f i c a a u n w i z a r d d i e v e n t i d e l l I D E
New al fine di richiamare ciascun wizard. Il gestore di evento OnClick della voce di
menu pu chiamare la funzione Execute del wizard.
Alcuni wizard possono avere la necessit di attivare o disattivare le voci di menu, a
seconda di ci che sta avvenendo nellIDE. Ad esempio, un wizard che controlla un
progetto in un sistema di controllo del codice sorgente dovrebbe disattivare la sua
voce di menu Check In se nellIDE non aperto alcun file. possibile aggiungere
questa funzione al wizard utilizzando i notificatori, come viene spiegato nella
sezione successiva.
Notifica a un wizard di eventi dellIDE
Un aspetto importante della scrittura di un wizard con un comportamento corretto
consiste nel fare in modo che il wizard risponda agli eventi dellIDE. In particolare,
qualsiasi wizard che tenga traccia delle interfacce dei moduli deve essere in grado di
rilevare quando lutente chiude il modulo, in modo che il wizard possa rilasciare
linterfaccia. Per fare ci, il wizard necessita di un notificatore, il che significa che
necessario scrivere una classe notifier.
Tutte le classi notifier implementano una o pi interfacce notifier. Le interfacce
notifier definiscono i metodi delle callback; il wizard registra un oggetto notifier con
le API Tools e lIDE richiama il notificatore quando accade qualcosa di importante.
Ogni interfaccia notifier eredita da IOTANotifier, bench non tutti i suoi metodi
vengano utilizzati per un particolare notificatore. LaTabella 58.3 elenca tutte le
interfacce notifier e fornisce una breve descrizione per ognuna di esse.
Tabella 58.3 Le interfacce notifier
Interfaccia Descrizione
IOTANotifier Classe base astrattaper tutti i notificatori
IOTABreakpointNotifier Per innescare o sostituire un breakpoint nel debugger
IOTADebuggerNotifier Per eseguire un programma nel debugger o per aggiungere o
cancellare breakpoint
IOTAEditLineNotifier Per tracciare gli spostamenti delle righe nelleditor dei sorgenti
IOTAEditorNotifier Per modificare o salvare un file sorgente o cambiare i file nelleditor
IOTAFormNotifier Per salvare una scheda oppure modificare la scheda o qualsiasi suo
componente (o modulo dati)
IOTAIDENotifier Per caricare progetti, per installare package e per altri eventi globali
dellIDE
IOTAMessageNotifier Per aggiungere o rimuovere pagine (gruppi di messaggio) nella vista
dei messaggi
IOTAModuleNotifier Per modificare, salvare o rinominare un modulo
IOTAProcessModNotifier Per caricare un modulo di processo nel debugger
IOTAProcessNotifier Per creare o distruggere thread e processi nel debugger
IOTAThreadNotifier Per modificare lo stato di un thread nel debugger
IOTAToolsFilterNotifier Per richiamare un filtro strumenti
58-20 G u i d a a l l a p r o g r a mma z i o n e
N o t i f i c a a u n w i z a r d d i e v e n t i d e l l I D E
Per vedere come utilizzare i notificatori, si consideri lesempio precedente. Mediante
i creator di modulo, lesempio crea un wizard che aggiunge un commento ad ogni
file sorgente. Il commento include il nome iniziale della unit, ma lutente salva quasi
sempre il file con un nome diverso. In questo caso, sarebbe bello se il wizard
aggiornasse il commento in modo da farlo corrispondere al vero nome del file.
Per fare ci, necessario un notificatore di modulo. Il wizard salva linterfaccia del
modulo che CreateModule restituisce e la utilizza per registrare un notificatore di
modulo. Il notificatore di modulo riceve la notifica quando lutente modifica il file
oppure lo salva, ma questi eventi non sono importanti per questo wizard, e pertanto
AfterSave e le relative funzioni hanno corpi vuoti. La funzione importante
ModuleRenamed, che lIDE chiama quando lutente salva il file con un nuovo nome. La
dichiarazione per la classe notifier del modulo la seguente:
cIaaa ..c..c pabIIc ..cccc, pabIIc L~..c..c
csc s .c
.cx ..c>~....cs,
E s t e n s i o n e d e l l I D E 58-21
N o t i f i c a a u n w i z a r d d i e v e n t i d e l l I D E
c.c.cc c ..cs . i.c
i.c iccxxicc.i.c..c>c.i.c, '',
__?aatcaII ..c..c-..c..c
58-22 G u i d a a l l a p r o g r a mma z i o n e
N o t i f i c a a u n w i z a r d d i e v e n t i d e l l I D E
Cosa accade se lutente inserisce degli altri commenti prima del nome del modulo? In
questo caso, necessario utilizzare un notificatore edit line per tenere traccia del
numero di riga in cui si trova si trova il nome del modulo. Per fare ci, utilizzare le
interfacce IOTAEditLineNotifier e IOTAEditLineTracker, descritte nella guida in linea.
bene essere prudenti durante la scrittura dei notificatori. necessario assicurarsi
che nessun notificatore sopravviva al suo wizard. Ad esempio, se lutente utilizzasse
il wizard per creare una nuova unit e quindi scaricasse il wizard, ci sarebbe ancora un
notificatore collegato alla unit. I risultati sarebbero imprevedibili, ma molto
probabilmente, lIDE si bloccherebbe. Quindi, il wizard deve tenere traccia di tutti i
suoi notificatori e deve annullare la registrazione di ogni notificatore prima che il
wizard venga distrutto. Daltra parte, se lutente per prima cosa chiudesse il file, il
notificatore di modulo riceverebbe una notifica Destroyed, il che significa che il
notificatore deve annullare la propria registrazione e rilasciare tutti i riferimenti al
modulo. Il notificatore si deve rimuovere anche dallelenco principale dei notificatori
del wizard.
Di seguito viene riportata la versione finale della funzione Execute del wizard. Questa
funzione crea il nuovo modulo, utilizza linterfaccia del modulo e crea un notificatore
di modulo, quindi lo salva in un elenco di interfacce (TInterfaceList).
veIi __?aatcaII c.i.xccc
_._L~..c.cccs sc,
i.L.cccs>.,,ssc,
_._L~..c ..c sc>cic..caev cicci_,c,
_._L~..c..c .c aev ..c..c..c,
s>~...c,
Il distruttore del wizard itera passa in esame lelenco delle interfacce e annulla la
registrazione di ogni notificatore nellelenco. Il permettere semplicemente allelenco
delle interfacce di rilasciare le interfacce elencate non sufficiente poich anche lIDE
conserva le stesse interfacce. necessario comunicare allIDE di rilasciare le
interfacce notifier per poter liberare gli oggetti notifier. In questo caso, il distruttore
inganna i notificatori facendo credere loro che i rispettivi moduli siano stati distrutti.
In una situazione pi complicata, si trarrebbe maggior vantaggio nello scrivere una
funzione Unregister separata per la classe notifier.
__?aatcaII c.i.-c.i.
csc i c .cs c s
?et Iat s>, > ,
_._L~..c .c,
s>Lc.s,>.,,s.c,
.cc. c isscic. ccc is ccc .csc.
i cccs c .c cci sc. ,
.c>csc.,
s>ccc,
ieIete s,
ieIete c.,
E s t e n s i o n e d e l l I D E 58-23
I n s t a l l a z i o n e d e l l a D L L d i u n w i z a r d
Il resto del wizard gestisce i dettagli di routine della registrazione del wizard,
installando voci di menu e cose simili. La sezione successiva propone ulteriori
dettagli sulla registrazione di un wizard illustrando come eseguire loperazione con
una DLL invece che con un package.
Installazione della DLL di un wizard
possibile installare un wizard anche con una DLL. Assicurarsi che il wizard utilizzi
la RTL dinamica e i package di esecuzione. Aggiungere il package designide
allelenco dei package di esecuzione in Project Options. La DLL deve esportare una
funzione di inizializzazione il cui nome INITWIZARD0001. Quando lIDE carica la
DLL, cerca il nome di esportazione speciale e chiama quella funzione. Per esportare
la funzione possibile utilizzare un file di definizione del modulo oppure utilizzare
una dichiarazione __declspec(dllexport). In questo caso, necessario anche evitare di
modificare il nome; dichiarare poi la funzione come extern C.
La funzione deve essere di tipo TWizardInitProc. Essa accetta come uno degli
argomenti un puntatore a una funzione di registrazione. Essa chiama questa
funzione per registrare ogni oggetto wizard, nello stesso modo in cui un wizard di
package chiama RegisterPackageWizard. La funzione di inizializzazione dovrebbe
restituire true nel caso loperazione sia andata a buon fine oppure false in caso
contrario. Il seguente esempio mostra come scrivere la funzione di inizializzazione.
exteta '' beeI __aticaII __iecIapec .cx, L.LL.~
ceaat _._Li.L.cccs,
.i.csc.c csc.c,
.i.c.ic.c
csc.caev ..i.,
csc.caev .c.i.,
tetata ttae ,
ciL.cccs sc,
caev c.i.s,
caev c.i.s.,
tetata ttae,
_._L~.cccs sc,
ciL.cccs>.,,ssc,
tetata sc>c~cccsc,c,
cs,scc''' '
`>
icc c.c''>
>
>.i.c>
>i,i>
>c>
`
.cic i c cc.s c i.i,c i. .c c .c. ics
i c c. .ci~.i,ccc.s
. , ci., c.c.cx
`>
>
.>.>` ccx~.i,c_.i.cs,icx `>.>.>
.>.>` ccx~.i,c_i,is,icx `>.>.>
.>.>` ccx~.i,c_cs,icx `>.>.>
>
`
G u i d a d i r i f e r i me n t o a g l i s c r i p t l a t o s e r v e r d i We b S n a p B-25
E s e m p i J S c r i p t
`>
icc>
Esempio 10
Vedere anche: propriet LinkToPage e AsFieldValue del tipo AdapterAction
(page B-4), propriet InputName e DisplayText del tipo AdapterField (page B-7),
propriet HiddenFields e HiddenRecordFields del tipo Adapter (page B-2)
Questo esempio genera una scheda HTML per modificare i campi delladapter e
inoltra le azioni delladapter.
`
c.c s.c iiccs . c i.i,c, .c.s, i. ics
~.i,c..csicc~.i,c
~.i,c_.i.c~.i,c.i.c
~.i,c_i,i~.i,ci,i
~.i,c_c~.i,cc
~.i,c_~,,~.i,c~,,
~.i,c_c.cs.~.i,cc.cs.
. c i.i,c . ..c css c ..c s ici. sc L. c ..c s ici.
sc s s ,cic cccisc i i.i,c ic sc c ..c cxi.,c, i sc
. ic .. , c i.i,c Lsc ..c
. ~.i,c..c''
~.i,c..c'.'
`>
.. i.c'~.i,c.' .c.',s'>
s ..c .c. .c.cs c ic i s cxccc. .c c .. s sc.c. >
, ,c'..c' i.c'__ic'>
`
c ..c .c.s .c.c. c c i.i,c
. ~.i,c-..cc.s
~.i,c-..cc.scc.scs,sc
`>
` . ~.i,c-..ccc.c.s
~.i,c-..ccc.c.scc.scs,sc
`>
icc>
>
.>
icc>
>
B-26 B o o k n a me g o e s h e r e
E s e m p i J S c r i p t
c , .c.s c. c .c.s . c i.i,c >
.>.i.c.>
. >, ,c'cx' s.c'.1' i.c'`~.i,c_.i.cL,.i.c`>' ic'
` ~.i,c_.i.c.cx `>' >.>
>
>
.>i,i.>
. >, ,c'cx' s.c'.1' i.c'`~.i,c_i,iL,.i.c`>'
ic'` ~.i,c_i,i.cx `>' >.>
>
>
.>c.>
. >, ,c'cx' s.c'.1' i.c'`~.i,c_cL,.i.c`>'
ic'` ~.i,c_c.cx `>' >.>
>
icc>
.>
>
>
.>
icc>
c sc. cs cxccc ics sc ..ic s s
,ic s cccic. i.c cxcc i ic >
>
.>, ,c'sc.' ic'~,,'
cc. '~.i,c.__icic
`~.i,c_~,,..ic.ic.i.c~sc.ic`>'>.>
.>, ,c'sc.' ic'c.cs'
cc. '~.i,c.__icic
`~.i,c_c.cs...ic.ic.i.c~sc.ic`>'> .>
>
icc>
.>
>
icc>
..>
Esempio 11
Vedere anche: propriet Array e AsHREF del tipo AdapterAction (page B-4)
Questo esempio mostra le azioni delladapter per supportare limpaginazione. Le
azioni PrevPage, GotoPage e NextPage vengono mostrate come collegamenti
ipertestuali. Lazione GotoPage ha un array di comandi. I comandi vengono
enumerati in modo da generare un collegamento ipertestuale per passare ad ogni
singola pagina.
`
c.c iiccs . c i.i,c i. ics
~.i,c ..csccii..c_c~.i,c
G u i d a d i r i f e r i me n t o a g l i s c r i p t l a t o s e r v e r d i We b S n a p B-27
E s e m p i J S c r i p t
.c.ic ~.i,c.c.ic
.ic ~.i,c.ic
.cx.ic ~.i,c.cx.ic
`>
ccic i icc i .s,is ,c.s cc.cc ,ics >
icc cc,i..''>
>
.>
`
.c,ic .s,is '' sc i ic i . c c..i. s cicc.
. .c.icicc.
`>
i c.'`.c.ic..ic.ic.i.c~s-`>'>i>
`
csc
`>
i>i>
` `>
`
.ic is i s . c..i.s , c s
sc i ic i . c c..i. s cicc.
. .ic~i
i c c. .ci.ic~i
. , ci., c.c.cx
`>
.>
` . .icicc.
`>
i c.'`.ic..ic.ic.i.c~s-`>'>
`.ics,iicc`>i>
`
csc
`>
i>`.ics,iicc`>i>
`
`>
.>
`
`>
.>
`
.cx.ic .s,is '>>' sc i ic i . c c..i. s cicc.
. .cx.icicc.
`>
B-28 B o o k n a me g o e s h e r e
E s e m p i J S c r i p t
i c.'`.cx.ic..ic.ic.i.c~s-`>'>>>i>
`
csc
`>
i>>>i>
` `>
.>
icc>
Esempio 12
Vedere anche: propriet Image del tipo AdapterField (page B-7)
Lesempio 12 mostra limmagine di un campo delladapter.
`
ccic iiccs . c i.i,c i. .c.
~.i,c..csccii..cii.c~.i,c
i,c~.i,ci,c
`>
s,i c i.i,c .c. is i .ic >
. sc'`i,cL.ic i,cL.ic~s- `>'
i'`i,cs,icx`>'>
Esempio 13
Vedere anche: propriet Values e ValuesList del tipo AdapterField (page B-7)
Questo esempio scrive un campo delladapter con elementi HTML <select> e
<option>.
`
c i ccc i .c.cs -. sccc ,s . i i.i,c .c.
c cc. ccc is c .. cc.cs
cx s ci c ,> cc.cs
c c .cc . ,> cc.cs
.,c s ci c cc .,c
sc s ic is i icc . c sccc> cc.c
sc is ..s
c.c,s.
cs,sccsccc s.c' - cc - ' i.c' - .L,.i.c - ' -
c.,c - > - ccx - sccc>
.c .c,s.
i s
i
i
G u i d a d i r i f e r i me n t o a g l i s c r i p t l a t o s e r v e r d i We b S n a p B-29
E s e m p i J S c r i p t
i c
. .icss
i c c. .ci.icsscc.s
. , ci., c.c.cx
s- ,
.icssic,
i scccc.
. .ics
scccc. .Lsi
csc
scccc. .ics-isic
. scccc.
s - scccc.
.icssic.i.c,
.
. s - ic' - - '
s - > - - ,>
c--
c.cs
c. ccc,
cx s
c c
.,c .ics .,c
c ,
`>
`
ccic -. sccc ,s . i i.i,c .c.
.c c.ccc,s.
c.c,s.
`>
sccc s.c'`cc`>' i.c'`.L,.i.c`>' `c.,c`> >
`ccx`>
sccc>
`
`>
Esempio 14
Vedere anche: propriet Values e ValuesList del tipo AdapterField (page B-7)
B-30 B o o k n a me g o e s h e r e
E s e m p i J S c r i p t
Questo esempio scrive un campo delladapter come gruppo di elementi
<input type=checkbox>.
`
c i ccc i .c.cs -. ccc. cxcs . i i.i,c .c.
c cc. ccc is c .. cc.cs
cx s ci c , ,cccc.cx> cc.cs
c c .cc . ,> cc.cs
.c cc.x,.,cs,i
i s
i
i
i c,
i ..L,.i.c
. .icss
s- , ,c'ccc.cx'
. .Lsic s- ccc.c.
s - ic'c' - i.c' - . - '
. i s- - i
s - >,>
c
csc
s - icc>>
i c c. .ci.icsscc.s
. , ci., c.c.cx
. c ` cs c s - >>
s- .>, ,c'ccc.cx'
.icssic,
i ccc.c.
. .ics
ccc.c. .Lsi
csc
ccc.c. .ics-isic
. ccc.c.
s- ccc.c.
.icssic.i.c,
.
s - ic' - - ' - i.c' - . - '
. i s- - i
s - > - - ,>.>
c--
G u i d a d i r i f e r i me n t o a g l i s c r i p t l a t o s e r v e r d i We b S n a p B-31
E s e m p i J S c r i p t
c.cs
s - >icc>
c. ccc,
cx s
c c
c ,
`>
`
c i i.i,c .c. is i ccc. cx ,
.c ccc.x,., cs, i
ccc.x,., cs, i
cs,sccccx,
`>
Esempio 15
Vedere anche: propriet Values e ValuesList del tipo AdapterField (page B-7), tipo
AdapterFieldValues (page B-10)
Questo esempio scrive un campo delladapter come elenco di valori a sola lettura
utilizzando gli elementi <ul> e <li>.
`
c i ccc i .c.cs -. s ics . i i.i,c .c.
c cc. ccc is c .. cc.cs
cx s ci c > cc.cs
c c .cc . cc.cs
.c sics.
i s
i
i
i c,
c. ccc,
. .ics
i c c. .ci.icscc.s
B-32 B o o k n a me g o e s h e r e
E s e m p i J S c r i p t
. , ci., c.c.cx
s- >
s - .icsicc.s,icx,
s - >
c--
c.cs
cx s
c c
c ,
`>
`
c i i.i,c .c. is i s . ci. ics
.c csics.
csics.
`>
>`ccx`>>
`
`>
Esempio 16
Vedere anche: Tipo AdapterFieldValuesList (page B-11), propriet Values e ValuesList
del tipo AdapterField (page B-7)
Questo esempio scrive un campo delladapter come un gruppo di elementi
< input type=radio>.
`
c i ccc i .c.cs -. i. cs . i i.i,c .c.
c cc. ccc is c .. cc.cs
cx s ci c , ,ci.> cc.cs
c c .cc . cc.cs
.c i.,.,cs,i
i s
i
i
i c,
G u i d a d i r i f e r i me n t o a g l i s c r i p t l a t o s e r v e r d i We b S n a p B-33
E s e m p i J S c r i p t
i ..L,.i.c
. .icss
s- , ,c'i.'
. .Lsic s- ccc.c.
s - ic'c' - i.c' - . - '
. i s- - i
s - >,>
c
csc
s - icc>>
i c c. .ci.icsscc.s
. , ci., c.c.cx
. c ` cs c s - >>
s- .>, ,c'i.'
.icssic,
i ccc.c.
. .ics
ccc.c. .Lsi
csc
ccc.c. .ics-isic
. ccc.c.
s- ccc.c.
.icssic.i.c,
.
s - ic' - - ' - i.c' - . - '
. i s- - i
s - > - - ,>.>
c--
c.cs
s - >icc>
c. ccc,
cx s
c c
c ,
`>
`
c i i.i,c .c. is i i. c ,
.c ci.,., cs, i
ci.,., cs, i
cs,sccccx,
`>
B-34 B o o k n a me g o e s h e r e
E s e m p i J S c r i p t
Esempio 17
Vedere anche: AdapterField types DisplayStyle, ViewMode, and InputStyle properties
(page B-7)
Questo esempio genera del codice HTML per un campo delladapter in base ai valori
delle propriet InputStyle, DisplayStyle e ViewMode.
`
.c cc..
..c .c...c
. ..c L,
.c .L,.c
. .c .ccc.,c .c .ccc
c.ccc,s.
csc . .c cc.x
ccc.x,., .,
csc . .c i.
ci.,., .,
csc . .c cx~ci
`>
cxici .i, i.c'`.L,.i.c`>'>` ..cx `>cxici>
`
csc . .c .iss..L,
`>
, ,c',iss..' i.c'`.L,.i.c`>'>
`
csc . .c c
`>
, ,c'.c' i.c'`.L,.i.c`>'>
`
csc
`>
, ,c',' i.c'`.L,.i.c`>' ic'` ..cx `>'>
`
csc
.c .s,i.c
. .c s
csics.
csc . .c L.ic
`>
G u i d a d i r i f e r i me n t o a g l i s c r i p t l a t o s e r v e r d i We b S n a p B-35
E s e m p i J S c r i p t
. sc'`.L.ic .L.ic~s- `>' i'`.s,icx`>'>
`
csc
cs,scc,> - .s,icx - ,>
`>
Esempio 18
Vedere anche: oggetto Page (page B-17), propriet Title delloggetto Application
(page B-15)
Questo esempio utilizza propriet delloggetto Application e delloggetto Page per
generare unintestazione di pagina.
.>
ci.>
c>
` .icc `>
c>
ci.>
c.>
>` ~,,cic `>>
.>` .icc `>.>
Esempio 19
Vedere anche: oggetto EndUser (page B-16)
Questo esempio utilizza le propriet delloggetto EndUser per visualizzare il nome, il
comando di login e il comando di logout di un utente.
` . .sc
. .scs,i.i.c
`>
>cc.c `.scs,i.i.c `>>
`
. .scicc.
`>
i c.'`.sc~s-`>'>i>
`
. .sc.icc.
`>
i c.'`.sc.~s-`>'>i>
`
`>
B-36 B o o k n a me g o e s h e r e
E s e m p i J S c r i p t
Esempio 20
Vedere anche: Tipo Module (page B-12)
Questo esempio elenca gli oggetti in un modulo in grado di gestire script .
`
c i -. icc s c i.c i. cissi.c . i sc,icc cccs i ..c
.c s..ccccs.
`>
,>,>
icc c.c''>
>
cs,i'.'>`..i.c_ - - .iss.i.c_`>>
>
`
i c c. .ci.cccs
. , ci., c.c.cx
`>
>
.>
` cc..i.c_ - - cc.iss.i.c_ `>
.>
>
`
`>
icc>
`
`>
Esempio 21
Vedere anche: propriet DisplayStyle e Enabled del tipo AdapterAction (page B-4)
Questo esempio genera del codice HTML per unazione delladapter in base alla
propriet DisplayStyle dellazione.
`
c -. . i i.i,c ic s c s,i.c ,,c
i ic
ci, ci, L. ci. c ics .s,i icc s sc.
.. i.c . c -. ..
, ,ic i.c i.c ic cxcc L. ci., c cc ,ic s sc.
.c i s .c .cs sc c ics ~i ,,c Ls s iss.c. i
c ic is i sc c..i.
.c c~ci, ci,, .., ,
G u i d a d i r i f e r i me n t o a g l i s c r i p t l a t o s e r v e r d i We b S n a p B-37
E s e m p i J S c r i p t
. ci,
ci, is,iicc
. ,
, .ic.i.c
.c is,i.c
. .c ~c
. iicc.
sc c c. ,,c Lsci., sc. c .. s i -. ..
.c.s ic ,i . c -. ccs
`>
i c.''cc.'`..`>__icic
`i..ic,~sc.ic`>,`..`>sc.,c .isc,'>
`ci,`>i>
`
csc
`>
i>`ci,`>i>
`
csc
`>
, ,c'sc.' ic'` ci,`>'
cc.'`..`>__icic`i..ic,~sc.ic`>'>
`
`>
Esempio 22
Vedere anche: propriet HiddenFields, HiddenRecordFields, e Mode del tipo Adapter
(page B-2)
Questo esempio genera una tabella HTML per aggiornare pi record di dettaglio.
`
Lc.s~.i,c..cs.Lc.s~.i,c
.cs~.i,c..cs..cs~.i,c
.c..cs~.i,c.c.
s..cs~.i,cs.
.c..cs~.i,c.c.
.cx..cs~.i,c.cx.
c.cs..cs~.i,cc.cs.
~,,.cs~.i,c~,,
Lc..Lc.s~.i,cLc..
.i.Lc.s~.i,c.i.
scLc.s~.i,csc
B-38 B o o k n a me g o e s h e r e
E s e m p i J S c r i p t
_Lc.s~.i,c_
`>
sc . i.i,cs ,.ic .,c .ci cc.s
c .cs i.i,c s isscic. . c .isc .iisc
c c.s i.i,c s isscic. . c .ci .iisc
ic . i . .s,is ics .. c c.s i.i,c c
c. .s,i i ,> cc.c . c. _ c i,, c
,.ics c _ ic cic .ci cc.>
s,i c .c .cc i. cs.c .cc ics >
.>.c. ` .c.s,icx `>.>
.>s. ` s.s,icx `>.>
`
. c c.s i.i,c c. ..c cccisc s .. ,.ics
c _ .c.
Lc.s~.i,c..c .
`>
.. i.c'~.i,c.' .c.',s'>
c.c i ..c .c. . sc.c. c ic i.c i. ,ii.ccs >
, ,c'..c' i.c'__ic'>
`
c ..c .c.s ci sic ..i ic c
.cs i.i,c i. c.s i.i,c
. .cs~.i,c-..cc.s
.cs~.i,c-..cc.scc.scs,sc
. Lc.s~.i,c-..cc.s
Lc.s~.i,c-..cc.scc.scs,sc
c ..c .c.s ci sic ..i ic c cc
cc. . c .cs i.i,c
. .cs~.i,c-..ccc.c.s
.cs~.i,c-..ccc.c.scc.scs,sc`>
icc c.c''>
>
>Lc..>
>.i.>
>sc>
>_>
>
`
i c c. .ciLc.s~.i,ccc.s
. , ci., c.c.cx
`>
>
.>`Lc..s,icx`>.>
.>`.i.s,icx`>.>
.>`scs,icx`>.>
.>, ,c'cx' i.c'`_L,.i.c`>' ic'` _.cx `>' >.>
G u i d a d i r i f e r i me n t o a g l i s c r i p t l a t o s e r v e r d i We b S n a p B-39
E s e m p i J S c r i p t
>
`
c ..c .c.s ci sic ..i ic cic cc. . c
c.s i.i,c s s cc.c. c c c.s i.i,c .c ,.i c _ .c.
. Lc.s~.i,c-..ccc.c.s
Lc.s~.i,c-..ccc.c.scc.scs,sc
`>
icc>
,>,>
icc>
.>, ,c'sc.' ic'.c .c'
cc.'~.i,c.__icic`.c...ic.ic.i.c~sc.ic`>'>.>
.>, ,c'sc.' ic'.cx .c'
cc.'~.i,c.__icic`.cx...ic.ic.i.c~sc.ic`>'>.>
.>, ,c'sc.' ic'c.cs'
cc.'~.i,c.__icic`c.cs...ic.ic.i.c~sc.ic`>'>
.>
.>, ,c'sc.' ic'~,,'
cc.'~.i,c.__icic`~,,..ic.ic.i.c~sc.ic`>'>
.>
icc>
..>
B-40 B o o k n a me g o e s h e r e
E s e m p i J S c r i p t
I n d i c e I-1
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
Simboli
... (puntini) pulsanti 19-23
Numeri
80x87, coprocessori A-3
A
a capo automatico 6-8
-a, opzione del compilatore A-6
abort, funzione A-11
Abort, procedura
prevenzione delle
modifiche 22-21
AbortOnKeyViol,
propriet 24-54
AbortOnProblem,
propriet 24-54
About, finestra 57-2
aggiunta a controlli
ActiveX 43-5
aggiunta di propriet 57-5
esecuzione 57-6
acceleratori 8-36
acceleratori di tastiera 9-6
Access, tabelle
transazioni locali 24-33
accesso
oggetti volatili A-6
regioni di memoria A-6
union A-5
accesso ai dati
componenti 7-16, 18-1
thread 11-5
meccanismi 7-16 7-17, 18-1
18-2, 22-2
multipiattaforma 17-7, 18-2
accordo di licenza 17-17
Acquire, metodo 11-8
action bands 8-20
Action client, definizione 8-18
action editor
aggiunta di azioni 33-5
cambio di azioni 33-6
Action List editor 8-20
Action Manager 8-20, 8-21, 8-23
definizione 8-19
Actions, propriet 33-5
Active Documents 38-11, 38-15
Vedi anche IoleDocumentSite,
interfaccia
active scripting 34-34
Active Server Objects 42-1
42-9
creazione 42-2 42-8
debug 42-8 42-9
registrazione 42-8
server in-process 42-7
server out-of-process 42-7
Active Server Objects,
wizard 42-2 42-3
Active Server Pages Vedere ASP
Active Template Library Vedere
ATL
Active, propriet
dataset 22-4
sessioni 24-18, 24-19
socket client 37-7
socket server 37-8
ActiveAggs, propriet 27-14
ActiveFlag, propriet 20-20,
20-21
ActiveForms 43-1, 43-6 43-7
applicazioni multi-tier 29-32
come applicazioni Web
database 29-32
creazione 43-2
e InternetExpress 29-31
wizard 43-6 43-7
ActiveX 38-14 38-15, 43-1
applicazioni Web 38-14,
43-1, 43-17 43-19
confronto con ASP 42-7
e InternetExpress 29-31
29-32
interfacce 38-21
ActiveX, controlli
.cab, file 43-19
17-5, 38-11, 38-14, 43-1 43-19
aggiunta di metodi 43-9
43-11
aggiunta di propriet 43-9
43-11
applicazioni Web 38-14,
43-1, 43-17 43-19
attivazione di eventi 43-11
concessione in licenza 43-5,
43-7 43-8
creazione 43-2, 43-4 43-7
da controlli VCL 43-4 43-7
data-aware 40-9 40-11,
43-8, 43-12 43-14
debug 43-17
distribuzione su Web 43-17
43-19
elementi 43-2 43-4
gestione di eventi 43-11
43-12
importazione 40-4 40-5
interfacce 43-8 43-14
librerie di tipi 38-18, 43-3
modello di threading 43-5
pagine di propriet 40-7,
43-3, 43-14 43-16
progettazione 43-4
propriet persistenti 43-14
registrazione 43-16 43-17
uso di tipi compatibili con
Automation 43-4, 43-8
wizard 43-4 43-6
wrapper di componenti 40-6,
40-7 40-8, 40-9 40-11
_OCX, unit 40-5
ActiveX, pagina (Component
palette) 5-8, 5-9, 40-5
ActnList, unit 8-31
adapter 34-2
adapter dispatcher 34-10, 34-37
adapter dispatcher,
richieste 34-38
adapter produttori di
pagine B-1
AdapterPageProducer 34-11
adattamento delle
tavolozze 50-5, 50-6
adattatori 34-5 34-6
adattatori, dispatcher 34-9
Add Fields, finestra di
dialogo 23-5
Add To Repository,
comando 7-26
Add, metodo
colonne persistenti 19-20
menu 8-44
stringhe 4-19
AddAlias, metodo 24-25
AddFieldDef, metodo 22-41
AddFontResource,
funzione 17-15
AddIndex, metodo 27-9
AddIndexDef, metodo 22-41
Indice
I-2 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
Additional, pagina (Component
palette) 5-7
AddObject, metodo 4-21
AddParam, metodo 22-55
AddPassword, metodo 24-22
AddRef, metodo 38-4
Address, propriet,
TSocketConnection 29-25
AddStandardAlias,
metodo 24-26
AddStrings, metodo 4-20
ADO 22-2, 25-1, 25-2
componenti 25-1 25-20
panoramica 25-1 25-2
datastore 25-2, 25-4
distributori di risorse 44-6
distribuzione 17-7
provider 25-3, 25-4
transazioni implicite 25-6
25-7
ADO, comandi 25-7, 25-17
25-20
annullamento 25-19
asincroni 25-19
esecuzione 25-18 25-19
iterazione 21-13
parametri 25-20
reperimento dati 25-19
25-20
specifica 25-18
ADO, connessioni 25-2 25-9
asincrone 25-5
connessione a datastore 25-2
25-7
esecuzione di comandi 25-6
eventi 25-7 25-9
time out 25-5 25-6
ADO, dataset 25-9 25-17
aggiornamenti batch 25-12
25-15
connessione 25-10
file dati 25-15 25-16
prelievo asincrono 25-11
25-12
ricerche basate su
indice 22-29
ADO, oggetti 25-1
oggetto Connection 25-4
25-5
RDS DataSpace 25-17
Recordset 25-9, 25-10 25-11
ADO, pagina (Component
palette) 5-8, 18-2, 25-1
ADT, campi 23-24, 23-24 23-26
campi persistenti 23-25
23-26
esplicitazione 19-24
visualizzazione 19-24, 23-24
23-25
ADTG, file 25-15
AfterApplyUpdates,
evento 27-34, 28-8
AfterCancel, evento 22-22
AfterClose, evento 22-4
AfterConnect, evento 21-3,
29-28
AfterConstruction 13-15
AfterDelete, evento 22-21
AfterDisconnect, evento 21-4,
29-28
AfterDispatch, evento 33-6, 33-9
AfterEdit, evento 22-18
AfterGetRecords, evento 28-8
AfterInsert, evento 22-19
AfterOpen, evento 22-4
AfterPost, evento 22-21
AfterScroll, evento 22-6
aggancio 6-4
AggFields, propriet 27-15
aggiornamenti batch 25-12
25-15
annullamento 25-15
applicazione 25-14
aggiornamenti in cache 27-17
27-26
ADO 25-12 25-15
annullamento 25-15
applicazione 25-14
BDE 24-33 24-50
aggiornamento dataset a
sola lettura 24-11
applicazione 24-11, 24-35
tabelle multiple 24-42,
24-46
gestione degli errori 24-39
24-41
dataset client 18-10 18-15,
27-17, 27-21 27-26
aggiornamento dataset a
sola lettura 24-11
applicazione 24-11, 27-22
27-23
tabelle multiple 24-42,
24-46
errori di
aggiornamento 27-25
27-26, 28-12
transazioni 21-7
oggetti update 27-20
panoramica 27-18 27-19
provider 28-8
relazioni master/
detail 27-20
aggiornamenti in cascata 28-6
aggiunta di record 22-20
Aggregates, propriet 27-12,
27-14
aggregati di
manutenzione 27-12 27-15
specifica 27-12 27-13
aggregazioni
COM 38-9 38-10
dataset client 27-12 27-15
aggregazioni di
manutenzione 18-16
campi di aggregazione 23-10
operatori di riepilogo 27-13
subtotali 27-13
valori 27-14
alias
BDE 24-3, 24-14, 24-25
24-27
cancellazione 24-27
creazione 24-25 24-26
local 24-26
specifica 24-14, 24-15
Type Library editor 39-10,
39-18
AliasName, propriet 24-14
Align, propriet 8-4
barre di stato 9-17
controlli di testo 6-7
pannelli 8-47
Alignment, propriet 9-7
barre di stato 9-17
campi 23-12
controlli memo data-
aware 19-9
controlli memo e rich
edit 9-3
griglie dati 19-22
griglie decisionali 20-13
intestazioni di colonna 19-23
allineamento A-3
campi di bit e A-6
membri della struttura A-6
word A-6
AllowAllUp, propriet 9-9
pulsanti di scelta rapida 8-48
pulsanti strumento 8-51
AllowDelete, propriet 19-31
AllowGrayed, propriet 9-9
AllowInsert, propriet 19-31
alTop, costante 8-47
I n d i c e I-3
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
ambiente di sistema operativo
stringhe, modifica
permanente A-11
ambienti A-11
animazione, controlli 9-20
anni bisestili 55-9
annidati, dichiaratori A-6
ANSI C
caratteri multibyte A-2
diagnostica A-1
diagnostici A-8
formati data e ora A-12
funzione main A-2
specifiche di
implementazione A-1
standard,
implementazione A-1
trattino,
interpretazione A-10
ANSI, set di caratteri 16-3
estesi A-2
AnsiString 52-8
Apache DLL 17-10
Apache server, DLL 32-7
creazione 33-1, 34-9
Apache, applicazioni 32-7
creazione 33-1, 34-9
debug 32-11
apartment, modello di
threading 41-8
API Tools 58-1 58-25
creator 58-3, 58-14 58-19
creazione di file 58-14
58-19
debug 58-11 58-12
editor 58-3, 58-13 58-14
moduli 58-3, 58-13 58-14
notificatori 58-3
servizi 58-2, 58-8 58-14
Append, metodo 22-19, 22-20
Insert e 22-19
AppendRecord, metodo 22-22
application adapter 34-10
application server 18-14, 29-1,
29-12 29-18
apertura di
connessioni 29-28
callback 29-18
identificazione 29-24
interfacce 29-17 29-18,
29-29
interruzione di
connessioni 29-28
moduli dati multipli 29-21
29-22
moduli dati remoti 7-25
registrazione 29-12, 29-22
29-23
scrittura 29-13
Application, variabile 8-2
applicazione socket
dispatcher 29-10
applicazioni
adattamento delle
tavolozze 50-5, 50-6
Apache 32-7, 33-1, 34-9
applicazioni client basate su
Web 29-31 29-43
bidirezionali 16-4
CGI, indipendenti 34-9
client/server 29-1
protocolli di rete 24-16
COM 7-20
CORBA 31-1 31-19
creazione 8-1
database 18-1
multipiattaforma 14-22
distribuzione 17-1
file 17-2
grafiche 45-8, 50-1
informazioni di stato 9-16
internationali 16-1
ISAPI 32-7, 33-1, 34-9
MDI 7-2
MTS 7-20
multipiattaforma 14-1
14-30
multi-thread 11-1
multi-tier 29-1 29-43
panoramica 29-3 29-4
NSAPI 32-7, 33-1, 34-9
porting in Linux 14-2 14-21
SDI 7-2
server Web 7-17
servizio 7-4
Web Broker 33-1 33-21
Web server 7-17, 34-8
Win-CGI indipendenti 34-9
applicazioni basate su file 18-9
18-10
dataset client 27-35 27-37
applicazioni client
architettura 29-4
COM 38-3, 38-10, 40-1
40-18
come applicazioni Web
server 29-31
creazione 29-23 29-30, 40-1
40-18
fornitura di query 28-6
interfacce 37-2
interfacce utente 29-1
leggere 29-2, 29-31
librerie di tipi 39-14, 40-2
40-7
multi-tier 29-2, 29-4
oggetti transazionali 44-2
protocolli di rete 24-16
socket e 37-1
Web Services 36-17 36-18
applicazioni database 7-16
basate su file 25-15 25-16
distribuite 7-17
distribuzione 17-6
XML e 30-1 30-11
applicazioni di servizio 7-4
7-9
codice di esempio 7-5, 7-7
debug 7-9
esempio 7-7
applicazioni distribuite
CORBA 31-1 31-19
applicazioni GDI 45-8, 50-1
applicazioni multi-thread
sessioni 24-13, 24-29 24-31
applicazioni multi-tier 29-1
29-43
applicazioni Web 29-31
29-43
creazione 29-32 29-33,
29-34 29-43
callback 29-18
componenti 29-2 29-3
creazione 29-12 29-30
licenze del server 29-3
vantaggi 29-2
applicazioni per console
VCL e 7-4
applicazioni remote
TCP/IP 37-1
applicazioni server
architettura 29-5
COM 38-5 38-9, 41-1
41-18
interfacce 37-2
multi-tier 29-5 29-12, 29-12
29-18
registrazione 29-22 29-23
servizi 37-1
Web Services 36-10 36-17
applicazioni single-tier 18-3
applicazioni three-tier Vedi
applicazioni multi-tier
applicazioni two-tier 18-3, 18-9,
18-13
I-4 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
applicazioni Web
ActiveX 43-17 43-19
client multi-tier 29-32
database 29-31 29-43
Apply, metodo 24-48
ApplyRange, metodo 22-36
ApplyUpdates, metodo 14-29,
24-34
BDE, dataset 24-37
dataset client 25-13, 27-7,
27-22, 27-22 27-23, 28-3
provider 27-22, 28-3, 28-8
TDatabase 24-36
TXMLTransformClient 30-10
AppNamespacePrefix,
variabile 36-3
AppServer, propriet 28-3,
29-17, 29-29
Appunti
azzeramento della
selezione 6-10
formati
aggiunta 52-19
oggetti grafici 10-3, 19-10
Arc, metodo 10-4
architettura
applicazioni basate su
BDE 24-1 24-2
applicazioni CORBA 31-1
31-4
applicazioni database 18-6
18-15, 24-1 24-2
client 29-4
server 29-5
multi-tier 29-4, 29-5
Web Broker, applicazioni
server 33-3
argomenti
fmod, funzione A-8
array 47-3, 47-8
come argomenti delle
funzioni 13-24
come propriet 13-24
come tipi restituiti 13-24
open 13-17
safe 39-13
tipi integer A-5
puntatori A-5
array of const 13-19
array, campi
esplicitazione 19-24
visualizzazione 19-24, 23-24
23-25
ARRAYSIZE, macro 13-18
as, operatore 13-23
AS_ApplyUpdates,
metodo 28-3
AS_ATTRIBUTE 36-7
AS_DataRequest, metodo 28-3
AS_Execute, metodo 28-3
AS_GetParams, metodo 28-3
AS_GetProviderNames,
metodo 28-3
AS_GetRecords, metodo 28-4
AS_RowRequest, metodo 28-4
ASCII, codice A-2
ASCII, tabelle 24-5
ascolto connessioni 37-3, 37-8
chiusura 37-8
ascolto di connessioni 37-9
ASP 38-14, 42-1 42-9
confronto con ActiveX 42-7
confronto con Web
Broker 42-1
generazione di pagine 42-3
HTML, documenti 42-1
limiti nelle prestazioni 42-1
linguaggio script 38-14, 42-3
progettazione UI 42-1
ASP, intrinsics 42-3 42-7
accesso 42-2 42-3
oggetto Application 42-4
oggetto Request 42-4 42-5
oggetto Response 42-5 42-6
oggetto Server 42-7
oggetto Session 42-6
assegnazione del nome a un
thread 11-13 11-15
assegnazione, operatori 13-7
assembler, codice 14-20
assert, funzione A-8
Assign Local Data,
comando 27-15
Assign, metodo
elenchi di stringhe 4-20
AssignedValues,
propriet 19-24
AssignValue, metodo 23-18
Associate, propriet 9-6
as-soon-as-possible,
disattivazione 29-7
ATL 38-23 38-25
file header 38-23
opzioni 41-9
traccia delle chiamate 41-9,
41-18
atomicit
transazioni 18-5, 44-11
attivit
oggetti transazionali 44-20
44-22
Attributes, propriet
parametri 22-48, 22-55
TADOConnection 25-6
attributi
editor di propriet 52-11
attributi dei campi
assegnazione 23-14
attributi di campo 23-14 23-15
in pacchetti dati 28-6
rimozione 23-15
attributi di transazione
impostazione 44-12
moduli dati
transazionali 29-16
attributo di attivazione
propriet condivise 44-7
audio, filmati 10-33
auto_ptr 12-6
AutoCalcFields, propriet 22-24
AutoComplete, propriet 29-8
auto-dispatch,
componenti 36-12
AutoDisplay, propriet 19-10,
19-11
AutoEdit, propriet 19-5
AutoHotKeys property 8-36
Automation
Active Server Objects 42-2
binding anticipato 38-19
binding differito 41-14
compatibilit dei tipi 39-12,
41-16 41-17
descrizioni dei tipi 38-13
interfacce 41-13 41-15
interfaccia IDispatch 41-14
ottimizzazione 38-19
Automation controller 40-1,
40-13 40-17, 41-14
creazione di oggetti 40-13
40-14
esempio 40-11 40-13
eventi 40-15 40-17
interfacce dispatch 40-14
40-15
interfacce duali 40-14
Automation server 38-11
Vedi anche COM, oggetti
accesso a oggetti 41-14
librerie di tipi 38-18
Automation, oggetti
Vedi anche COM, oggetti
wizard 41-4 41-9
I n d i c e I-5
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
wrapper di componenti 40-8
40-9
esempio 40-11 40-13
Automation, server 38-13
AutoPopup, propriet 8-53
AutoSelect, propriet 9-4
AutoSessionName,
propriet 24-31, 33-19
AutoSize, propriet 8-5, 9-3,
17-15, 19-9
.avi, clip 9-20, 10-31
.avi, file 10-34
.avi, filmati 10-34
azioni 8-25 8-32
aggiornamento 8-29
classi di azioni 8-29
client 8-19
definizione 8-18, 8-19
destinatario 8-20
esecuzione 8-27
predefinite 8-30
registrazione 8-31
azioni, elementi
dispatch 34-41
azioni, richieste 34-39
B
Background 8-22
backslash, caratteri (\)
file include A-7
bande di azioni
definizione 8-18
Bands, propriet 8-52, 9-10
barre di avanzamento 9-17
barre di scorrimento 9-5
finestre di testo 6-8
barre di separazione 9-7
barre di separazione
(menu) 8-36
barre di stato 9-16
internazionalizzazione 16-9
owner draw 6-12
barre strumenti 8-45, 9-9
aggiunta 8-49 8-51
aggiunta di pannelli
come 8-47 8-49
creazione 8-20
disattivazione di
pulsanti 8-50
inserimento di pulsanti 8-47
8-49, 8-50
liste di azioni 8-19
menu contestuali 8-52
occultamento 8-53
owner-draw 6-12
progettazione 8-45 8-53
pulsanti di scelta rapida 9-8
strumento predefinito di
disegno 8-48
trasparenti 8-50, 8-52
BaseCLX
classi di eccezioni 12-17
definizione 4-1, 14-6
Basic Object Adapter Vedere
BOA
batch, file
esecuzione A-12
Linux 14-14
BatchMove, metodo 24-8
BDE
distributori di risorse 44-6
BDE Administration,
utilit 24-15, 24-57
BDE, dataset 18-1, 22-2, 24-2
24-13
applicazione aggiornamenti
in cache 24-37
copia 24-52
database 24-3 24-4
operazioni batch 24-50
24-55
sessioni 24-3 24-4
supporto decisionale,
componenti e 20-5
supporto per database
locali 24-5 24-8
tipi 24-2
BDE, pagina (Component
palette) 5-8, 18-1
BeforeApplyUpdates,
evente 27-34, 28-8
BeforeCancel, evento 22-22
BeforeClose, evento 22-4
BeforeConnect, evento 21-3,
29-28
BeforeDelete, evento 22-21
BeforeDestruction,
metodo 13-15
BeforeDisconnect, evento 21-4,
29-28
BeforeDispatch, evento 33-5,
33-7
BeforeGetRecords, evento 28-8
BeforeInsert, evento 22-19
BeforeOpen, evento 22-4
BeforePost, evento 22-21
BeforeScroll, evento 22-6
BeforeUpdateRecord,
evento 24-34, 24-42, 27-24,
28-12
BEGIN_MESSAGE_MAP,
macro 51-4, 51-8
BeginAutoDrag, metodo 51-14
BeginDrag, metodo 6-1
BeginRead, metodo 11-9
BeginTrans, metodo 21-7
BeginWrite, metodo 11-9
bevel 9-20
Beveled 9-7
bidirezionali, applicazioni 16-4
metodi 16-7 16-8
propriet 16-6
bidirezionali, cursor 22-51
bilanciamento del carico 31-3
Bind, metodo
TAutoDriver 40-14
binding anticipato
Automation 38-19, 41-13
COM 38-18
binding di dati 43-12
binding differito 31-15
Automation 41-13, 41-14
binding dinamico 31-15
CORBA 31-4, 31-16
DII 31-4
binding statico
CORBA 31-14
bit, acmpi A-6
bit, campi
allineamento A-6
ordine di allocazione A-6
superamento dei limiti della
word A-6
bitmap 9-20, 10-19 10-20, 50-4
aggiunta a component 45-15
aggiunta ai componenti 52-4
aggiunta di scorribili 10-18
associazione a stringhe 6-13
barre strumenti 8-50
caricamento 50-5
controlli grafici e 54-4
disegno 10-19
disegno di superfici 50-4
distruzione 10-22
eventi draw-item 6-16
fuori schermo 50-6 50-7
impostazione dello stato
iniziale 10-18
internazionalizzazione 16-10
pennelli 10-10
propriet dei pennelli 10-8,
10-10
scorrimento 10-18
sostituzione 10-21
temporanee 10-18, 10-19
I-6 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
vuote 10-19
bitmap a scorrimento 10-18
bitmap fuori schermo 50-6
50-7
bitmap, oggetti 10-3
bitmap, pulsanti 9-8
bitmaps
associazione a stringhe 4-21
in frame 8-16
bitwise, operatori
integer con segno e A-5
BLOB 19-10
memorizzazione in
cache 24-4
BLOB, campi 19-3
acquisizione su
richiesta 28-6
ottenimento di valori 24-4
visualizzazione di
grafici 19-10
visualizzazione di
valori 19-10
blocchi esclusivi
tabelle 24-6
blocco di oggetti
annidamento di
chiamate 11-8
thread 11-8
blocco di terminazione 12-13
BlockMode, propriet 37-9,
37-10, 37-11
bmBlocking 37-11
BMPDlg, unit 10-22
bmThreadBlocking 37-9, 37-11
BOA 31-2, 31-5
BOA_init 31-8
conflitti di thread 31-12
inizializzazione 31-14
obj_is_ready, metodo 31-8
Bof, propriet 22-6, 22-7, 22-9
bookmark
supporto in base al tipo di
dataset 22-9
Bookmark, propriet 22-10
BookmarkValid, metodo 22-10
Boolean, campi 19-2
BorderWidth, propriet 9-14
bordi
pannelli 9-14
bordi, disegno 10-6
Borland Database Engine 7-16,
18-1, 22-2, 24-1
aggiornamenti in
cache 24-33 24-50
errori di
aggiornamento 24-39
alias 24-3, 24-14, 24-17, 24-25
24-27
cancellazione 24-27
creazione 24-25 24-26
disponibilit 24-26
query eterogenee 24-10
specifica 24-14, 24-15
apertura di connessioni a
database 24-20
applicazioni Web 17-10
chiamate alle API 24-1, 24-4
chiusura delle
connessioni 24-20
connessione a database 24-17
connessione predefinita,
propriet 24-19
dataset 24-2
distribuzione 17-8, 17-9,
17-17
driver 24-1, 24-14
gestione delle
connessioni 24-20 24-22
nomi di driver 24-14
ODBC, driver 24-17
operazioni batch 24-50
24-55
programmi di utilit 24-56
24-57
query eterogenee 24-9
24-10
recupero dei dati 22-50, 24-2,
24-10
requisiti di licenza 17-17
sessioni 24-17
tipi di tabelle 24-5
transazioni implicite 24-31
Borland, contatti 1-3
BorlandIDEServices,
variabile 58-8, 58-24
BoundsChanged, metodo 51-14
.bpi, file 15-2, 15-14
.bpk, file 15-2, 15-7, 15-8
.bpl, file 15-1, 15-14, 17-3
briefcase, modello 18-15
Broadcast, metodo 51-9
broker di dati 27-27, 29-1
brokering delle
connessioni 29-27
Brush, propriet 9-20, 10-4,
10-8, 50-3
BrushCopy, metodo 50-3, 50-7
buffer, file con A-9
business-to-business,
comunicazioni 35-1
ButtonAutoSize,
propriet 20-10
ButtonStyle, propriet
griglie dati 19-22, 19-23,
19-24
ByteType 4-23
C
C++ e Object Pascal
argomenti delle
funzioni 13-8, 13-20, 13-24
assegnazione 13-7
chiamata a metodi
virtuali 13-10, 13-15
copia di oggetti 13-6
costruttori 13-22
costruttori di copia 13-7
costruzione di oggetti 13-8
differenze 13-15, 13-20
distruzione di oggetti 13-13
inizializzazione delle
classi 13-12
parallelismi nel
linguaggio 13-17
parametri senza tipo 13-17
passaggio per
riferimento 13-17
riferimenti 13-6
RTTI 13-23
tipi bool 13-20
C++, gestione delle
eccezioni 12-1
C++, modello a oggetti 13-1
CacheBLOB, propriet 24-4
CachedUpdates,
propriet 14-29, 24-34
calendari 55-1 55-14
aggiunta di date 55-6 55-11
come renderli a sola
lettura 56-3 56-5
definizione di propriet ed
eventi 55-3, 55-8, 55-12
ridimensionamento 55-4
selezione del giorno
corrente 55-11
spostamento nei 55-11
55-14
callback
applicazioni multi-tier 29-18
limiti 29-11, 29-12
oggetti transazionali 44-28
calloc, funzione A-11
campi 23-1 23-29
I n d i c e I-7
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
a sola lettura 19-6
aggiornamento dei
valori 19-5
aggiunta a schede 10-27
10-29
assegnazione di valori 22-23
attivazione 23-17
cambio dei valori 19-6
colonne persistenti e 19-19
database 56-6, 56-7
elenco 21-14
formati predefiniti 23-16
inserimento dati 22-19, 23-15
limitazione della validit dei
dati 23-22 23-23
nascosti 28-5
opzioni reciprocamente
esclusive 19-2
propriet 23-1
record del messaggio 51-7
reperimento dati 23-18
tipi di dati astratti 23-24
23-29
valori nulli 22-22
valori predefiniti 23-22
visualizzazione di
valori 19-11, 23-18
campi array
campi persistenti 23-27
campi BLOB 19-2
campi booleani 19-14
campi calcolati 22-24, 23-6
assegnazione di valori 23-8
campi di consultazione
e 23-10
dataset client 27-11 27-12
definizione 23-7 23-9
campi chiave 22-34
multipli 22-33, 22-34
campi dati 23-6
definizione 23-7
campi del dataset 23-27 23-28
campi di aggregazione 23-6,
27-15
definizione 23-10 23-11
visualizzazione 23-11
campi di array 23-26 23-27
campi di classe
dichiarazione 54-6
campi di classi 54-4
campi di consultazione 19-13,
23-6
cache dei valori 23-10
definizione 23-9 23-10
fornitura di valori da
programma 23-10
in griglie dati 19-23
performance 23-10
specifica 19-23
campi di oggetti 23-24 23-29
tipi 23-24
campi di riferimento 23-28
23-29
campi dinamici 23-2 23-3
campi memo 19-2, 19-9 19-10
rich edit 19-10
campi nascosti 28-5
campi numerici
formattazione 23-16
campi ora
formattazione 23-16
campi persistenti 19-17, 23-3
23-17
ADT, campi 23-25 23-26
assegnazione dei nomi 23-6
campi array 23-27
campi del dataset 22-39
cancellazione 23-11
commutazione a
dinamici 23-4
creazione 23-4 23-5, 23-5
23-11
creazione tabelle 22-41
definizione 23-5 23-11
elenco 23-5
ordinamento 23-5
pacchetti dati e 28-5
propriet 23-11 23-16
tipi speciali 23-5, 23-6
campi stringa 9-18
dimensioni 23-6
campi, definizioni 22-40, 22-41
campo, oggetti
propriet
condivisione 23-14
CanBePooled, metodo 44-10
Cancel, metodo 22-19, 22-22,
25-19
Cancel, propriet 9-8
CancelBatch, metodo 14-29,
25-13, 25-15
cancellazioni in cascata 28-6
CancelRange, metodo 22-36
CancelUpdates, metodo 14-29,
24-34, 25-13, 27-7
CanModify, propriet
dataset 19-5, 22-17, 22-39
griglie dati 19-28
query 24-11
canvas 45-7, 50-3
aggiornamento dello
schermo 10-2
aggiunta di figure 10-11
10-12, 10-14
copia di immagini 50-7
disegno di linee 10-6, 10-10
10-11, 10-29 10-30
cambio dello spessore
della penna 10-6
gestori di evento 10-27
disegno e tracciamento 10-4
panoramica 10-1 10-4
propriet comuni,
metodi 10-4
strumenti di disegno
predefiniti 54-6
tavolozze 50-5 50-6
tracciamento e disegno 10-23
Canvas, propriet 9-20, 45-8
Caption, propriet
caselle di gruppo e gruppi di
opzioni 9-14
etichette 9-4
griglie decisionali 20-13
intestazioni di colonna 19-23
TForm 9-16
voci non valide 8-34
caratteri 47-2
multibyte A-2
newline A-9
null A-9
punto decimale A-7
wide A-4
caratteri estesi 16-3
caratteri ideografici 16-3
abbreviazioni 16-9
caselle combinate 9-12, 14-8,
19-2, 19-12
consultazione 19-23
data-aware 19-11 19-14
owner-draw 6-12
eventi measure-item 6-15
caselle combinate di
consultazione 19-2, 19-12
19-14
campi di consultazione 19-13
in griglie dati 19-23
riempimento 19-23
sorgenti dati
secondarie 19-13
caselle di controllo 9-9, 9-11
data-aware 19-14 19-15
TDBCheckBox 19-2
caselle di gruppo 9-14
I-8 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
caselle di riepilogo 9-11, 19-2,
19-12, 55-1
data-aware 19-11 19-14
memorizzazione di propriet
esempio 8-9
owner-draw 6-12
eventi draw-item 6-16
eventi measure-item 6-15
riempimento 19-11
rilascio di elementi 6-3
trascinamento di
elementi 6-2, 6-3
caselle di riepilogo di
consultazione 19-2, 19-12
19-14
campi di consultazione 19-13
sorgenti dati
secondarie 19-13
caselle grafiche 19-2
catch, istruzione 12-2, 12-3,
12-17
CComCoClass 38-24, 41-3, 41-4,
42-2
CComModule 38-24
CComObjectRootEx 38-24
38-25, 41-3, 41-4, 42-2
CellDrawState, funzione 20-13
celle (griglie) 9-18
CellRect, metodo 9-18
Cells, funzione 20-13
Cells, propriet 9-18
CellValueArray, funzione 20-13
centralizzazione di oggetti
moduli dati remoti 29-8
29-9
cerchi, disegni 54-10
CGI, applicazioni 32-6, 32-7
creazione 33-2, 34-9
Change, metodo 56-12
ChangeCount, propriet 14-29,
24-34, 27-6
ChangedTableName,
propriet 24-55
CHANGEINDEX 27-8
character
wide A-4
Chart Editing, finestra di
dialogo 20-16 20-19
Chart FX 17-5
CHECK, vincolo 28-13
Checked, propriet 9-9
CheckSynchronize routine 11-5
chiavi di licenza 43-7
chiavi parziali
impostazione degli
intervalli 22-34
ricerca 22-31
ChildName, propriet 29-30
Chord, metodo 10-4
ciclo del messaggio
thread 11-5
class factory
supporto ATL 38-24
classi 45-2, 45-3, 46-1, 47-2
accesso 46-4 46-8, 54-7
antenato 46-3 46-4
astratte 45-3
creazione 46-1
definizione 45-13, 46-2
derivazioe di nuove 46-2
derivazione di nuove 46-3
discendenti 46-3 46-4
editor di propriet
come 52-8
gerarchia 46-4
istanziazione 46-2, 48-2
limitazione dellaccesso 46-5
passaggio come
parametri 46-11
predefinite 46-4
propriet come 47-2
sezione private 46-5
sezione protected 46-7
sezione public 46-7
sezione published 46-8
supporto per Object
Pascal 13-16
classi antenato 46-3 46-4
predefinite 46-4
classi astratte 45-3
classi base
costruttori 13-11
classi creatore
CoClass 40-6, 40-13 40-14
classi derivate 46-3 46-4
classi in stile VCL 13-1
eredit 13-2
classi richiamabili
creazione 36-13
__classid, operatore 13-24
ClassInfo, metodo 13-23
ClassName, metodo 13-23
ClassNameIs, metodo 13-23
ClassParent, metodo 13-23
ClassType, metodo 13-23
Clear, metodo
campi 23-18
elenchi di stringhe 4-20, 4-21
ClearSelection, metodo 6-10
Click, metodo 51-14
ridefinizione 48-6, 55-13
client base 44-2
client leggeri, applicazioni 29-2,
29-31
client Vedere applicazioni client
client, applicazioni
CORBA 31-2, 31-14 31-17
client, socket
oggetti socket 37-6
client/server, applicazioni 7-16
Clipboard 6-8, 6-9, 19-10
controllo del contenuto 6-11
controllo delle
immagini 10-24
grafici e 10-22 10-24
Clipbrd, unit 6-9, 10-22
clock, funzione A-12
CloneCursor, metodo 27-16
Close, metodo
componenti
connessione 21-4
connessioni al
database 24-20
dataset 22-4
sessioni 24-19
CloseDatabase, metodo 24-20
CloseDataSets, metodo 21-13
closure 48-2, 48-8
__closure, parola chiave 13-25
CLSID 38-6, 38-17, 40-5
file package di licenza 43-8
CLX
costruzione di oggetti 14-13
definizione 3-1
e VCL 14-5 14-8
eventi di sistema 51-13
51-16
notifiche di sistema 51-11
51-16
segnali 51-11 51-12
unit 14-10 14-12
CLX applicazioni
distribuzione 17-6
CLX, applicazioni
applicazioni database 14-21
14-29
applicazioni Internet 14-30
creazione 14-1 14-2
panoramica 14-1
porting in Linux 14-2 14-21
clx60.bpl 17-6
CM_EXIT, messaggio 56-13
CMExit, metodo 56-13
CoClass
I n d i c e I-9
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
aggiornamento 39-15
assegnazione dei nomi 41-3,
41-5
controlli ActiveX 43-5
creazione 38-6, 39-14, 40-6,
40-13 40-14
dichiarazioni 40-5
Type Library editor 39-10,
39-16 39-17
wrapper di componenti 40-1,
40-3
limiti 40-2
CoClasses 38-6
CLSID 38-6
wrapper di componenti
_OCX, unit 40-2
Code editor 2-4
gestori di evento e 5-4
panoramica 2-4
visualizzazione 52-18
Code Insight
modelli 7-3
codice 49-4
modelli 7-3
porting in Linux 14-17
14-21
codice sorgente
apertura di librerie 10-16
editing 2-2
riutilizzo
visualizzazione
gestori di evento
specifici 5-4
COInit, flag 41-9
ColCount, propriet 19-31
collaudo dei server, Web
Application Debugger 34-9
collazione, sequenza A-2
collegamenti ai dati 56-5 56-7
inizializzazione 56-7
collegamento statico
COM 38-18
colonne 9-17
cancellazione 19-18
griglie decisionali 20-12
inclusione in tabelle
HTML 33-20
persistenti 19-17, 19-19
cancellazione 19-21
creazione 19-19 19-24
inserimento 19-20
riordinamento 19-21
propriet 19-19, 19-22
19-23
reimpostazione 19-24
stato predefinito 19-17, 19-24
colonne dinamiche 19-17
propriet 19-18
colonne persistenti 19-17, 19-19
cancellazione 19-18, 19-21
creazione 19-19 19-24
inserimento 19-20
riordinamento 19-21
Color, propriet 9-4, 9-20
griglie dati 19-22
griglie decisionali 20-13
intestazioni di colonna 19-23
penne 10-6
pennelli 10-8, 10-9
ColorChanged, metodo 51-14
colori
internazionalizzazione
e 16-10
penne 10-6
colori, griglie di 10-6
Cols, propriet 9-18
Columns editor
cancellazione di
colonne 19-21
creazione di colonne
persistenti 19-19
riordinamento delle
colonne 19-21
Columns, propriet 9-11, 19-20
griglie 19-17
gruppi di pulsanti di
opzione 9-14
ColWidths, propriet 6-15, 9-18
COM 7-20
aggregazione 38-9 38-10
applicazioni 38-3 38-10,
38-20
distribuite 7-20
binding anticipato 38-18
client 38-3, 38-10, 39-14, 40-1
40-18
contenitori 38-10, 40-1
controller 38-10, 40-1
CORBA e 31-1
definizione 38-1 38-2
estensioni 38-2, 38-10 38-13
panoramica 38-1 38-25
proxy 38-7, 38-8
specifiche 38-1
stub 38-8
wizard 38-20 38-25, 41-1
COM+ 7-20, 29-7, 38-11, 38-15,
44-1
Vedi anche oggetti
transazionali
applicazioni 44-7, 44-29
Component Manager 44-30
condivisione di oggetti 44-10
configurazione di
attivit 44-21 44-22
eventi 40-16 40-17, 44-22
44-26
MTS e 44-2
oggetti evento 44-24 44-25
oggetti subscriber di
eventi 44-25
oggetti transazionali 38-15
38-16
puntatori di interfaccia 38-5
server in-process 38-7
sincronizzazione delle
chiamate 44-21 44-22
transazioni 29-18
COM, distribuiti 38-7, 38-8
COM, interfacce 38-3 38-5,
41-3
aggiunta a librerie di
tipi 39-14
Automation 41-13 41-15
identificatori di
dispatch 41-14
implementazione 38-6, 38-25
informazioni di tipo 38-17
interfacce duali 41-13 41-14
IUnknown 38-4
marshaling 38-8 38-9
modifica 39-15 39-16, 41-9
41-12
ottimizzazione 38-19
propriet 39-9
puntatore ad interfaccia 38-5
COM, libreria 38-2
COM, oggetti 38-3, 38-5 38-9,
41-1 41-18
aggregazione 38-9 38-10
creazione 41-2 41-17
debug 41-9, 41-18
interfacce 38-3, 41-9 41-15
modelli di threading 41-5
41-9
progettazione 41-2
registrazione 41-17 41-18
wizard 41-3 41-4, 41-5
41-9
wrapper di componenti 40-1,
40-2, 40-3, 40-5, 40-7 40-13
COM, server 38-3, 38-5 38-9,
41-1 41-18
apertura di librerie 38-20
esterni al processo 38-7
I-10 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
interni al processo 38-7
istanziazione 41-9
modelli di threading 41-7,
41-9
progettazione 41-2
remoti 38-7
comandi, liste di azioni 8-20
COMCTL32.DLL 8-46
Command Text, editor 22-46
command, oggetti
iterazione 21-13
CommandCount,
propriet 21-13, 25-7
Commands, propriet 21-13,
25-7
CommandText, propriet 22-46,
25-16, 25-17, 25-18, 25-20, 26-6,
26-7, 26-8, 27-34
CommandTimeout,
propriet 25-5, 25-19
CommandType,
propriet 25-16, 25-17, 25-18,
26-6, 26-7, 26-8, 27-34
commenti
conformit ANSI A-2
Commit, metodo 21-8
CommitTrans, metodo 21-9
CommitUpdates, metodo 14-29,
24-34, 24-37
Common Object Request Broker
Architecture Vedere CORBA
communicazioni
standard
OMG 31-1
commutatori 8-48, 8-51
CompareBookMark,
metodo 22-10
compilatore, direttive
applicazioni Linux 14-18
compilazione del codice 2-4
Component Palette
aggiunta di
componenti 15-6, 52-1, 52-4
frame 8-15
Component palette 5-7
ActiveX, pagina 5-9, 40-5
Additional, pagina 5-7
ADO, pagina 5-8, 18-2, 25-1
BDE, pagina 5-8, 18-1
Data Access, pagina 5-7,
18-2, 29-2
Data Controls, pagina 18-16,
19-1, 19-2
DataSnap, pagina 5-8, 29-2,
29-5, 29-6
dbExpress page 5-8, 18-2,
26-2
Decision Cube, pagina 18-16,
20-1
Dialogs, pagina 5-8
elenco delle pagine 5-7
FastNet, pagina 5-8
Indy Clients, pagina 5-8
Indy Misc, pagina 5-9
Indy Servers, pagina 5-9
installazione di
componenti 45-20
InterBase, pagina 5-8, 18-2
Internet, pagina 5-8
InternetExpress, pagina 5-8
QReport, pagina 5-8
Samples, pagina 5-8, 5-9
Servers, pagina 5-8, 5-9
specifica della pagina 45-14
spostamento di
componenti 45-21
Standard, pagina 5-7
System, pagina 5-7
WebServices, pagina 29-2
Win 3.1, pagina 5-8
Win32, pagina 5-7
Component wizard 45-9
componente DBComboBox 19-2
componente
DBLookupComboBox 19-2
componenti 45-1, 46-1, 47-3
aggiunta a una unit
esistente 45-12
aggiunta alla Component
Palette 52-1
aggiunta alle unit 45-13
astratti 45-3
bitmap 45-15
bitmap della tavolozza 52-4
browse dei dati 56-1 56-8
cambio 53-1 53-5
classi derivate 45-3, 45-13,
54-3
collaudo 45-17, 45-19, 57-7
creazione 45-2, 45-9
custom 5-9
data-aware 56-1
dipendenze 45-5 45-6
doppio clic 52-16, 52-18
52-19
editing dei dati 56-8 56-13
guida in linea 52-4
inizializzazione 47-14, 54-7,
56-7
installazione 5-9, 15-6 15-7,
45-20, 52-20
interfacce 46-4, 46-7, 57-2
in esecuzione 46-7
in progettazione 46-8
menu contestuali 52-16,
52-17 52-18
non visuali 45-5, 45-13, 57-3
package 15-9, 52-20
personalizzazione 45-3, 47-1,
48-1
problemi in
installazione 52-20
raggruppamento 9-14 9-16
registrazione 45-14, 52-2
ridimensionamento 9-7
risposta agli eventi 48-6,
48-7, 48-8, 48-9, 56-8
spostamento 45-21
standard 5-7 5-9
componenti calendario 9-13
componenti connessione
database 18-8 18-9, 21-15,
24-3
accesso ai metadati 21-14
21-15
ADO 25-2 25-9
BDE 24-17
collegamento 24-14
24-15, 25-2 25-4, 26-3
26-6
dbExpress 26-2 26-6
esecuzione di comandi
SQL 21-11 21-12, 25-6
implicita 21-2
impliciti 24-3, 24-14,
24-20, 24-21, 25-3
in moduli dati
remoti 29-6
istruzioni per la
connessione 26-3
DataSnap 18-15, 29-3, 29-4
29-5, 29-23, 29-24 29-30
apertura di
connessioni 29-28
gestione delle
connessioni 29-27
interruzione di
connessioni 29-28
protocolli 29-9 29-12,
29-24
componenti custom 5-9
componenti database 7-16, 24-3,
24-17
I n d i c e I-11
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
applicazione aggiornamenti
in cache 24-36
identificazione dei
database 24-14 24-15
sessioni e 24-13 24-14,
24-21 24-22
temporanei 24-21
interruzione 24-21
componenti di auto-
dispatch 36-16
componenti menu 8-33
componenti non visuali 45-13
componenti per il supporto
decisionale
aggiunta 20-3 20-4
opzioni di progetto 20-9
componenti, wrapper 45-5, 57-2
controlli ActiveX 40-7 40-8,
40-9 40-11
inizializzazione 57-4
oggetti Automation 40-8
40-9
esempio 40-11 40-13
oggetti COM 40-1, 40-2, 40-3,
40-7 40-13
comporessione dati
TSocketConnection 29-26
ComputerName,
propriet 29-24, 29-25
comunicazioni 37-1
protocolli 24-16, 32-3, 37-2
UDP e TCP 31-3
standard 32-3
concessione in licenza
controlli ActiveX 43-5, 43-7
43-8
Internet Explorer 43-8
condivisione di oggetti 44-10
disattivazione 44-10
condivisione di risorse 44-6
44-9
condivisione di schede e finestre
di dialogo 7-25 7-28
ConfigMode, propriet 24-26
configurazione, file
Linux 14-15
conformit A-1
congruenza
transazioni 18-5, 44-11
Connected, propriet 21-3
componenti
connessione 21-4
ConnectEvents, metodo 40-15
Connection Editor 26-5 26-6
Connection Points,
mappa 41-11
Connection String Editor 25-4
Connection, propriet 25-3,
25-10
ConnectionBroker 27-27
ConnectionName,
propriet 26-4
ConnectionObject,
propriet 25-4
ConnectionString,
propriet 21-2, 21-5, 25-3,
25-10
ConnectionTimeout,
propriet 25-5
ConnectOptions, propriet 25-5
connessioni
apertura 29-28, 37-7
client 37-3
database 21-3 21-6
apertura 24-19, 24-20
asincrone 25-5
asssegnazione dei
nomi 26-4 26-6
centralizzazione 29-7
chiusura 24-20
gestione 24-20 24-22
limitazione 29-8
persistenti 24-19
protocolli di rete 24-16
temporanee 24-21
DCOM 29-10, 29-24
HTTP 29-9 29-11, 29-26
interruzione 29-28, 37-8
protocolli 29-9 29-12, 29-24
server di database 21-3,
24-16
SOAP 29-11, 29-26
TCP/IP 29-10 29-11, 29-25,
37-2 37-3
connessioni a database 21-3
21-6
centralizzazione 29-7
interruzione 21-4, 21-4
limitazione 29-8
mantenimento 21-3
persistenti 24-19
connessioni bloccanti 37-10,
37-11
gestione di eventi 37-9
connessioni client 37-2, 37-3
accettazione richieste 37-8
apertura 37-7
numeri di porta 37-5
connessioni con nome 26-4
26-6
aggiunta 26-5
cambio del nome 26-6
cancellazione 26-5
caricamento in
esecuzione 26-5
connessioni database
condivisione 44-6
connessioni di ascolto 37-2, 37-8
numeri di porta 37-5
connessioni non bloccanti 37-10
connessioni remote 37-2 37-3
apertura 37-8
invio/ricezione di
informazioni 37-10
connessioni server 37-2, 37-3
numeri di porta 37-5
connessioni socket 29-10
29-11, 29-25, 37-2 37-3
apertura 37-7, 37-8
chiusura 37-8
invio/ricezione di
informazioni 37-10
multiple 37-5
punti terminali 37-3, 37-6
tipi 37-2
Console Wizard 7-4
console, applicazioni 7-4
CGI 32-7
constanti
assegnazione di valori
sequenziali 10-13
CONSTRAINT, vincolo 28-14
ConstraintErrorMessage,
propriet 23-12, 23-23
Constraints, propriet 8-4, 27-8,
28-14
construttori
classe base 13-8
Contains, elenco (package) 15-7,
15-9, 15-11, 52-20
conteggio dei riferimenti
oggetti COM 38-4
Content, metodo
produttori di pagine 33-15
Content, propriet
oggetti risposta Web 33-13
ContentFromStream, metodo
produttori di pagine 33-15
ContentFromString, metodo
produttori di pagine 33-15
ContentStream, propriet
oggetti risposta Web 33-13
I-12 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
contesti di dispositivo 10-2,
45-7, 50-1
contesti di oggetti 44-4
contesti di oggetto 44-5
ASP 42-3
transazioni 44-11
contesto dati
applicazioni Web
Service 36-8
ContextHelp 7-36
contravariance 13-25
controlli
browse dei dati 56-1 56-8
cambio 45-3
come implemetazione di
controlli ActiveX 43-3
custom 45-5
data-aware 19-1 19-34
editing dei dati 56-8 56-13
forme 54-8
generazione di controlli
ActiveX 43-2, 43-4 43-7
grafici 50-4, 54-1 54-11
creazione 45-4, 54-3
disegno 54-3 54-5, 54-9
54-11
eventi 50-7
owner-draw 6-12, 6-15
dichiarazione 6-13
per finestra 45-4
raggruppamento 9-14 9-16
ricevimento del fuoco 45-4
ridimensionamento 50-7,
55-4
ritracciamento 54-8, 54-10,
55-4, 55-5
tavolozze e 50-5 50-6
visualizzazione dei dati 19-4,
23-19
controlli custom 45-5
librerie 45-5
controlli data-aware 19-1
19-34, 23-18, 56-1
a sola lettura 19-8
aggiornamento dati 19-7
associazione con
dataset 19-3 19-4
browse dei dati 56-1 56-8
creazione 56-1 56-14
disattivazione
ritracciamento 19-6, 22-8
distruzione 56-7
editing 19-5 19-6, 22-18
editing dei dati 56-8 56-13
funzioni comuni 19-2
griglie 19-16
inserimento dati 23-15
inserimento di record 22-20
liste 19-2 19-3
rappresentazione di
campi 19-8
risposta alle modifiche 56-7
visualizzazione dei dati 19-6
19-7
nelle griglie 19-17, 19-30
valori correnti 19-9
visualizzazione di
grafici 19-10
controlli di animazione 10-31
10-32
esempio 10-32
controlli di editing 6-7, 9-1 9-4,
19-2, 19-9
formati rich edit 19-10
multiriga 19-9
selezione del testo 6-9
controlli di input 9-5
controlli di testo 9-1 9-4
controlli di testo multiriga 19-9,
19-10
controlli elenco 9-10 9-13
controlli grafici 45-4, 50-4, 54-1
54-11
bitmap e 54-4
creazione 45-4, 54-3
disegno 54-3 54-5, 54-9
54-11
eventi 50-7
salvataggio delle risorse di
sistema 45-4
controlli preesistenti 45-5
controllo di versione 2-5
ControlType, propriet 20-9,
20-16
convalida dei dati
immessi 23-17
convenzioni per i nomi
membri dati 48-2
propriet 47-7
convenzioni per lassegnazione
dei nomi
eventi 48-8
propriet 47-7
convenzioni per lassegnazione
del nome
metodi 49-2
tipi di record dei
messaggi 51-7
convenzioni sui nomi
risorse 52-4
conversione di misure
classi 4-32 4-35
conversioni complesse 4-30
famiglie di conversione 4-28
creazione
dellesempio 4-29
registrazione 4-29
fattore di conversione 4-32
utilit 4-27 4-35
valuta 4-32
conversioni
integer A-5
puntatori a integer A-5
regole di
arrotondamento A-4
tipi di dati A-4
costanti wide
character A-4
integer A-5
interi A-4
virgola mobile A-4
valori di campo 23-17, 23-19
23-21
valori non rappresentati A-4
virgola mobile A-4
conversioni di ore 4-29
Convert, funzione 4-28, 4-30,
4-31, 4-35
convogliatori di eventi
definizione 40-15 40-16
convogliatori di evento 41-12
ConvUtils, unit 4-27
coolbar 8-45, 8-46, 9-10
aggiunta 8-51 8-52
configurazione 8-52
occultamento 8-53
progettazione 8-45 8-53
coordinate
posizione corrente di
disegno 10-26
copia
immagini bitmap 50-7
oggetti 13-6
copia, costruttori 13-7
coprocessori numericis
formati in virgola
mobile A-3
Copy (Object Repository) 7-27
CopyFile, funzione 4-10
CopyFrom
TStream 4-3
CopyMode, propriet 50-3
CopyRect, metodo 10-4, 50-3,
50-7
CopyToClipboard, metodo 6-10
I n d i c e I-13
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
controlli memo data-
aware 19-10
grafici 19-10
CORBA 31-1 31-19
accettazione di richieste del
client 31-6, 31-8
codice generato in
automatico 31-9
COM e 31-1
file IDL 31-5
implementazione di
oggetti 31-7, 31-10 31-13
istanziazione di oggetti 31-8
modello di delega 31-8 31-9
panoramica 31-1 31-4
standard 31-1 31-19
thread 31-12 31-13
VCL e 31-8, 31-14
verifica 31-17 31-19
CORBA Client, wizard 31-14
CORBA Object, wizard 31-7
31-8, 31-14
CORBA Server, wizard 31-5
CORBA, applicazioni
client 31-14 31-17
panoramica 31-1 31-4
server 31-4 31-14
uso della VCL 31-8
utilizzo della VCL 31-14
CORBA, oggetti
binding 31-16
definizione di interfacce 31-5
31-13
generici 31-16
costanti
assegnazione di nomi 10-13
carattere A-7
valori A-4
caratteri
wide A-4
character
wide A-4
puntatore null A-8
wide character A-4
costruttori 12-6, 12-16, 45-17,
47-13, 49-3, 56-7
applicazioni
multipiattaforma 14-13
C++ e Object Pascal 13-22
classe base 13-13
copia 13-7
dichiarazione 45-13
multipli 8-8
oggetti posseduti e 54-6, 54-7
ridefinizione 53-3
Count, propriet
elenchi di stringhe 4-19
TSessionList 24-30
CP32MT.lib, libreria RTL 12-19
cp32mti.lib, libreria di
importazione 12-19
.cpp, file 15-2, 15-14
Create Data Set, comando 22-41
Create Submenu, comando
(Menu designer) 8-37, 8-40
CREATE TABLE 21-12
Create Table, comando 22-41
CreateDataSet, metodo 22-41
CreateObject, metodo 42-3
CreateParam, metodo 27-30
CreateSharedPropertyGroup 44
-7
CreateSuspended,
parametro 11-12
CreateTable, metodo 22-41
CreateTransactionContextEx
esempio 44-15 44-16
creator 58-3, 58-14 58-19
creazione di package 15-11
15-14
creazione di un modulo Web
page 34-19
crittografia,
TSocketConnection 29-26
crosstab 20-2 20-3, 20-11
definizione 20-2
monodimensionali 20-3
multidimensionale 20-3
valori di riepilogo 20-3
crosstab
multidimensionale 20-3
crtl.dcu 17-7
cubi decisionali 20-7 20-9
aggiornamento 20-7
dimensioni
apertura/chiusura 20-10
paginate 20-21
drill down 20-5, 20-10, 20-12,
20-21
gestione della memoria 20-8
mappe decisionali 20-6, 20-7,
20-8, 20-20, 20-21
opzioni di progetto 20-9
pivot 20-5, 20-10
propriet 20-7
subtotali 20-5
visualizzazione dei
dati 20-10, 20-11
Currency, propriet
campi 23-12
cursor 22-5
bidirezionali 22-51
clonazione 27-16
collegamento 22-37, 26-12
sincronizzazione 22-43
spostamento 22-7, 22-30,
22-31
allultima riga 22-6, 22-8
alla prima riga 22-6, 22-9
con condizioni 22-11
unidirezionali 22-51
CursorChanged, metodo 51-14
CursorType, propriet 25-12,
25-13
CurValue, propriet 28-12
Custom, propriet 29-41
CustomConstraint,
propriet 23-12, 23-23, 27-8
CutToClipboard, metodo 6-10
controlli memo data-
aware 19-10
grafici 19-10
cw32mt.lib, libreria RTL 12-19
cw32mti.lib, libreria di
importazione 12-19
D
-D, opzione del linker 15-13
data
locale A-12
Data Access , pagina
(Component palette) 29-2
Data Access, pagina
(Component palette) 5-7, 18-2
Data Bindings editor 40-9
Data Controls, pagina
(Component palette) 5-7,
18-16, 19-1, 19-2
Data Definition
Language 21-11, 22-45, 24-9,
26-11
Data Dictionary 24-55 24-56,
29-3
vincoli 28-14
Data Manipulation
Language 21-11, 22-45, 24-9
data, campi
formattazione 23-16
data, formati A-12
Data, propriet 27-5, 27-15,
27-16, 27-37
data-aware, controlli 18-16
database 7-16, 18-1 18-6, 56-1
accesso 22-1
accesso non autorizzato 21-4
I-14 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
aggiunta di dati 22-23
alias e 24-14
applicazioni Web e 33-18
assegnazione dei nomi 24-14
basati su file 18-3
connessione 21-15
connessioni implicite 21-2
generazione di risposte
HTML 33-18 33-21
identificazione 24-14 24-15
login a 18-4, 21-4 21-6
propriet di accesso 56-6
56-7
relazionali 18-1
scelta 18-3
sicurezza 18-4
tipi 18-3
transazioni 18-5
Database Desktop 24-57
Database Explorer 24-15, 24-56
database locali 18-3
accesso 24-5
alias 24-26
assegnazione nuovo nome a
tabelle 24-8
supporto per BDE 24-5
24-8
database management
systems 29-1
database navigator 19-2, 19-31
19-34, 22-6
attivazione/disattivazione
dei pulsanti 19-32, 19-33
cancellazione dei dati 22-21
editing 22-18
pulsanti 19-32
suggerimenti 19-34
Database Properties
editor 24-15
visualizzazione dei
parametri di
connessione 24-15
database server 7-16, 21-3, 24-16
tipi 18-3
database, applicazioni 18-1
architettura 18-6 18-15
basate su file 18-9 18-10,
27-35 27-37
distribuite 7-17
multipiattaforma 14-22
multi-tier 29-3 29-4
porting 14-25
scalabilit 18-11
database, componenti
condivisi 24-17
database, driver
BDE 24-1, 24-3, 24-14
dbExpress 26-3 26-4
Database, parametro 26-4
DatabaseCount, propriet 24-22
DatabaseName, propriet 21-2,
24-3, 24-14
query eterogenee 24-10
Databases, propriet 24-22
DataChange, metodo 56-11
DataCLX
definizione 14-5
DataField, propriet 19-11, 56-6
caselle di riepilogo e
combinate di
consultazione 19-13
DataRequest, metodo 27-34,
28-3
dataset 18-7, 22-1 22-57
a sola lettura,
aggiornamento 24-11
aggiunta di record 22-19
22-20, 22-23
annullamento delle
modifiche 22-22
apertura 22-4
basati su ADO 25-9 25-17
basati su BDE 24-2 24-13
campi 22-1
cancellazione di record 22-20
22-21
categorie 22-24 22-26
chiusura 22-4 22-5
conferma dei record 22-22
senza
disconnessione 21-13
componenti decisionali
e 20-5 20-7
conferma dei record 22-21
22-22
contrassegno di record 22-9
22-11
creazione 22-40 22-42
cursor 22-5
custom 22-2
documenti HTML 33-21
editing 22-18 22-19
filtraggio di record 22-13
22-16
iterazione 21-13
modalit 22-3 22-4
modifica dei dati 22-17
22-23
navigazione 19-31, 22-5
22-9, 22-17
non indicizzati 22-23
procedure registrate 22-25,
22-52 22-57
provider e 28-2
query 22-25, 22-43 22-52
ricerca 22-11 22-13
chiavi parziali 22-31
estensione della
ricerca 22-31
su pi colonne 22-11,
22-12
usando indici 22-12,
22-13, 22-29 22-31
riga corrente 22-5
stati 22-3 22-4
tabelle 22-24, 22-26 22-43
unidirezionali 26-1 26-20
dataset client 27-1 27-38, 29-3
aggiornamento dei
record 27-33
aggiornamento record 27-21
27-26
aggregazione di dati 27-12
27-15
annullamento delle
modifiche 27-6
applicazione degli
aggiornamenti 27-22
27-23
applicazioni basate su
file 27-35 27-37
campi calcolati 27-11 27-12
cancellazione di indici 27-10
caricamento di file 27-36
combinazione dei dati 27-15
combinazione delle
modifiche 27-36
commutazione di
indici 27-10
con dataset sorgente
interno 27-23
con dataset
unidirezionali 26-11
condivisione di dati 27-16
connecting to other
dataset 27-26 27-34
connessione ad altri
dataset 18-10 18-15
copia di dati 27-15 27-16
creazione di tabelle 27-35
27-36
distribuzione 17-7
editing 27-5
filtraggio dei record 27-2
27-5
I n d i c e I-15
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
fornitura di query 27-34
27-35
indici 27-8 27-11
aggiunta 27-9
limitazione dei record 27-31
parametri 27-29 27-31
provider e 27-26 27-34
raggruppamento di
dati 27-10 27-11
ricerche basate su
indice 22-29
risoluzione degli errori di
aggiornamento 27-22
risoluzione errori di
aggiornamento 27-25
27-26
salvataggio delle
modifiche 27-7
salvataggio di file 27-37
specifica dei provider 27-27
27-28
spostamenti nei 27-2
tipi 27-19 27-20
vincoli 27-7 27-8, 27-32
27-33
disattivazione 27-32
dataset decisionale 20-5 20-7
dataset di destinazione,
definizione 24-50
dataset non indicizzati 22-20
dataset sorgente,
definizione 24-50
dataset unidirezionali 26-1
26-20
collegamento 26-6 26-8
connessione ai server 26-2
esecuzione di comandi 26-9
26-11
limitazioni 26-1
modifica dei dati 26-11
prelievo dei metadati 26-13
26-18
prelievo di dati 26-8 26-9
preparazione 26-9
tipi 26-2
dataset, campi
persistenti 22-39
visualizzazione 19-26
dataset, produttori di
pagine 33-19
conversione dei valori di
campo 33-19
DataSet, propriet
griglie dati 19-18
provider 28-2
dataset, provider 18-12
DataSetCount, propriet 21-13
DataSetField, propriet 22-39
DataSets, propriet 21-13
DataSnap, pagina (Component
palette) 5-8, 29-2, 29-5, 29-6
DataSource, propriet
caselle di riepilogo e
combinate di
consultazione 19-13
controlli ActiveX 40-9
controlli data-aware 56-6
database navigator 19-34
griglie dati 19-18
query 22-49
datastore 25-2
DataType, propriet
parametri 22-47, 22-48,
22-54, 22-55
date
componenti calendario 9-13
impostazione A-7
inserimento 9-13
internazionalizzazione 16-10
__DATE__, macro
disponibilit A-7
DateTimePicker,
componente 9-13
dati
a sola visualizzazione 19-8
accesso 56-1
analisi 18-16, 20-2
diagrammazione 18-16
formati,
internazionalizzazione 16-
10
inserimento 22-19
modifica 22-17 22-23
report 18-17
sincronizzazione delle
schede 19-4
stampa 18-17
valori predefiniti 19-11,
23-22
visualizzazione 23-18, 23-19
disattivazione
ritracciamento 19-6
nelle griglie 19-17, 19-30
valori correnti 19-9
dati immessi, convalida 23-17
dati, filtri
campi vuoti 22-15
definizione 22-14 22-16
operatori 22-15
uso di segnalibri 25-11
dati, moduli
Web 34-2
dati, vincoli Vedi vincoli
Day, propriet 55-6
DB/2, driver
distribuzione 17-10
dBASE, tabelle 24-5
assegnazione nuovo
nome 24-8
DatabaseName 24-3
indici 24-7
protezione con
password 24-22 24-24
transazioni locali 24-33
DBChart, componente 18-16
DBCheckBox, componente 19-2,
19-14 19-15
DBComboBox,
componente 19-11 19-12
DBConnection, propriet 27-18
DBCtrlGrid, componente 19-3,
19-30 19-31
propriet 19-31
DBEdit, componente 19-2, 19-9
dbExpress 17-7, 18-2, 26-1 26-2
applicazioni
multipiattaforma 14-21
14-28
componenti 26-1 26-20
debug 26-18 26-20
distribuzione 26-1
driver 26-3 26-4
metadati 26-12 26-18
dbExpress, applicazioni 17-11
dbExpress, pagina (Component
palette) 5-8, 18-2, 26-2
dbGo 25-1
DBGrid, componente 19-2,
19-16 19-30
eventi 19-29
propriet 19-22
DBGridColumns,
componente 19-17
DBImage, componente 19-2,
19-10 19-11
DblClick, metodo 51-14
DBListBox, componente 19-2,
19-11 19-12
DBLogDlg, unit 21-4
DBLookupComboBox,
componente 19-12 19-14
DBLookupListBox,
componente 19-2, 19-12
19-14
I-16 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
DBMemo, componente 19-2,
19-9 19-10
DBMS 29-1
DBNavigator,
componente 19-2, 19-31
19-34
DBRadioGroup,
componente 19-2, 19-15
DBRichEdit, componente 19-3,
19-10
DBSession, propriet 24-3, 24-4
DBText, componente 19-2, 19-8
19-9
dbxconnections.ini 26-4, 26-5
26-6
dbxdrivers.ini 26-3 26-4
DCOM 38-7, 38-8
applicazioni
InternetExpress 29-35
applicazioni multi-tier 29-10
connessione allapplication
server 27-28, 29-24
distribuzione di
applicazioni 7-20
DCOM connessioni 29-10, 29-24
DCOMCnfg.exe 29-36
.dcr, file 52-4
bitmap 45-15
DDL 21-11, 22-45, 22-51, 24-9,
26-11
debug
Active Server Objects 42-8
42-9
applicazioni
dbExpress 26-18 26-20
applicazioni di servizio 7-9
applicazioni Web server 32-9
32-12, 33-2
codice 2-5
controlli ActiveX 43-17
CORBA 31-17 31-19
oggetti COM 41-9, 41-18
oggetti transazionali 44-28
44-29
Web server,
applicazioni 34-9
wizard 58-11 58-12
debugger integrato 2-5
decimale, punti A-7
Decision Cube Editor 20-7
20-9
Cube Capacity 20-20
Dimension Settings 20-8
Memory Control 20-8
Decision Cube, pagina
(Component palette) 18-16,
20-1
Decision Query editor 20-6
__declspec 13-3
__declspec(delphirtti) 36-2
__declspec, parola chiave 7-12,
13-29
DECnet, protocollo
(Digital) 37-1
default
parola chiave 47-8
Default, casella di controllo 7-3
Default, propriet
elementi di azione 33-7
DEFAULT_ORDER, indice 27-8
DefaultColWidth,
propriet 9-18
DefaultDatabase, propriet 25-4
DefaultDrawing,
propriet 6-13, 19-29
DefaultExpression,
propriet 23-22, 27-8
DefaultHandler, metodo 51-4
DefaultPage, propriet 34-42
DefaultRowHeight,
propriet 9-18
definizioni di indici
copia 22-41
definizioni di tipo
Type Library editor 39-10
39-11
delega 48-1
Delete Table, comando 22-42
Delete Templates, comando
(Menu designer) 8-40, 8-42
Delete Templates, finestra di
dialogo 8-42
Delete, comando (Menu
designer) 8-40
DELETE, istruzioni 24-42,
24-45, 28-10
Delete, metodo 22-20
elenchi di stringhe 4-20, 4-21
DeleteAlias, metodo 24-27
DeleteFile, funzione 4-7
DeleteFontResource,
funzione 17-15
DeleteIndex, metodo 27-10
DeleteRecords, metodo 22-43
DeleteSQL, propriet 24-42
DeleteTable, metodo 22-42
delphiclass, argomento 13-29
DelphiInterface, classe 13-3,
13-4, 13-21, 58-8
delphireturn, argomento 13-29,
13-30
Delta, propriet 27-5, 27-21
DEPLOY 17-16
DEPLOY, documento 17-9,
17-16
dereferenziati, puntatori 13-7
derivazione di classe per
controlli Windows 45-4
dettagli annidati 22-38 22-39
dettaglio, tabelle annidate 29-20
dettaglio, tabelle,
annidate 23-27 23-28
device, interattivi A-2
DeviceType, propriet 10-33
.dfm, file 14-2, 16-10, 47-11
generazione 16-13
Dialogs, pagina (Component
palette) 5-8
dichiaratori
annidamento A-6
numero di A-6
dichiarazioni
classi 46-11, 54-6
interfacce 13-2
private 46-5
protected 46-7
public 46-7
published 46-8
gestori di evento 48-5, 48-8,
55-13
gestori di messaggi 51-5,
51-6, 51-8
metodi 10-16, 46-10, 49-4
public 49-3
propriet 47-3, 47-3 47-7,
47-8, 47-13, 48-8, 54-4
tipi definiti
dallutente 54-4
tipi dei nuovi
componenti 46-3
dichiarazioni di tipo
propriet 54-4
tipi enumerati 10-13, 10-14
DII 31-15, 31-16
Interface Repository 31-13
DimensionMap, propriet 20-6,
20-7
Dimensions, propriet 20-13
Direction, propriet
parametri 22-48, 22-55
directory
e Linux 14-16
file include A-7
directory, servizio 31-3
I n d i c e I-17
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
direttive
#ifdef 14-18
#ifndef 14-19
$LIBPREFIX,
compilatore 7-11
$LIBSUFFIX,
compilatore 7-11
$LIBVERSION,
compilatore 7-11
compilazione
condizionale 14-18
Linux 14-19
protected 48-5
published 47-3, 57-4
direttive al compilatore
librerie 7-11
package 15-12
diritti di accesso
WebSnap 34-31 34-33
DirtyRead 21-10
DisableCommit, metodo 44-14
DisableConstraints,
metodo 27-32
DisableControls, metodo 19-6
DisabledImages, propriet 8-50
dischi CDaudio 10-34
DisconnectEvents,
metodo 40-16
dispatch actions 34-10
dispatch, interfacce 41-13, 41-14
41-15
chiamata a metodi 40-14
40-15
compatibilit dei tipi 41-16
identificatori 41-14
librerie di tipi 39-10
Dispatch, metodo 51-4, 51-5
dispatcher 33-2, 33-4 33-6,
34-37, 34-42
applicazioni basate su
DLL 33-3
gestione delle richieste 33-9
oggetti auto-dispatch 33-5
selezione di elementi di
azione 33-6, 33-7
dispID 38-18, 40-15, 41-14
collegamento a 41-15
dispinterface 41-13, 41-14
41-15
binding dinamico 39-10
librerie di tipi 39-10
DisplayFormat, propriet 19-29,
23-12, 23-16
DisplayLabel, propriet 19-19,
23-12
DisplayWidth, propriet 19-18,
23-12
dispositivi di supporto 10-33
distribuite, applicazioni
database 7-17
MTS e COM+ 7-20
distribuiti, oggetti
CORBA Vedere CORBA,
oggetti
distributori di risorse 44-6
ADO 44-6
BDE 44-6
distribuzione
applicazioni 17-1
applicazioni CLX 17-6
applicazioni database 17-6
applicazioni generiche 17-1
applicazioni MIDAS 17-10
applicazioni Web 17-10
Borland Database
Engine 17-9
controlli ActiveX 17-5
dbExpress 26-1
estensioni dellIDE 58-7,
58-23 58-25
file DLL 17-6
file package 17-3
SQL Links 17-9
distribuzione di applicazioni
package 15-14
distruttori 12-6, 49-3, 56-7
implicazioni nella
VCL 13-13, 13-14 13-15
oggetti posseduti e 54-6, 54-7
divisione
segno del resto A-5
Dizionario dati 23-14 23-15
DLL 7-13
creazione 7-10, 7-12
distribuzione 17-10
incorporazione in
HTML 33-15
installazione 17-6
internazionalizzazione 16-11
, 16-13
link 7-15
Linux Vedere .so, file
MTS 44-2
package 15-1, 15-2, 15-12
server COM 38-7
modelli di threading 41-7
server HTTP 32-6, 32-7
dllexport 7-12, 7-13
DllGetClassObject 44-3
dllimport 7-11
DllRegisterServer 44-3
DML 21-11, 22-45, 22-51, 24-9
.dmt, file 8-41, 8-42
Document Literal, stile 36-1
DocumentElement,
propriet 35-4
DoExit, metodo 56-13
DOM 35-2, 35-2 35-3
implementazioni 35-2
utilizzo 35-4
dominio, errori A-8
DoMouseWheel, metodo 51-14
doppio clic
componenti 52-16
risposta a 52-18 52-19
Down, propriet 9-8
pulsanti di scelta rapida 8-48
.dpl, file 15-2
drag-and-dock 6-4 6-7
drag-and-drop 6-1 6-4
DLL 6-4
eventi 54-3
ottenimento di informazioni
di stato 6-4
personalizzazione 6-4
puntatore del mouse 6-4
DragMode, propriet 6-1
griglie 19-21
DragOver, metodo 51-14
Draw, metodo 10-4, 50-3, 50-7
DrawShape 10-16
drill-down, schede 19-16
drintf, unit 24-56
DriverName, propriet 24-14,
26-3
DropConnections,
metodo 24-14, 24-21
DropDownCount,
propriet 9-12, 19-12
DropDownMenu,
propriet 8-52
DropDownRows, propriet
caselle combinate di
consultazione 19-14
griglie dati 19-22, 19-23
durabilit
distributori di risorse 44-6
transazioni 18-5, 44-11
dynamic array, tipi 36-4
dynamic invocation interface
Vedere DII
dynamic, argomento 13-30
E
EBX, registro 14-9, 14-21
I-18 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
eccezioni 49-2, 51-3
costruttori 13-14
definizione 12-1
formato bit 12-12
generazione 4-2
Linux 14-15
rigenerazione 4-2
threads 11-7
eccezioni non gestite 12-6
eccezioni strutturate 12-7
eccezioni, basate su C,
gestione 12-7
eccezioni, gestione
funzioni helper 12-7
Edit, metodo 22-18, 52-10, 52-11
EditFormat, propriet 19-29,
23-12, 23-16
editing del codice 2-2, 2-4
EditKey, metodo 22-29, 22-31
EditMask, propriet 23-15
campi 23-12
editor
API Tools 58-3, 58-13 58-14
editor di componenti 52-16
52-20
predefiniti 52-16
registrazione 52-19
editor di propriet 5-3, 47-2,
52-7 52-13
attributi 52-11
come classi derivate 52-8
finestre di dialogo
come 52-10
registrazione 52-12 52-13
EditRangeEnd, metodo 22-35,
22-36
EditRangeStart, metodo 22-35
effetto elastico, esempio 10-24
10-30
elaborazione di dati
distribuiti 29-2
elaborazione multiprocessore
thread 11-1
elementi di azione 33-3, 33-4,
33-6 33-9
aggiunta 33-5
attivazione e
disattivazione 33-7
avvertenze in modifica 33-3
concatenamento 33-9
gestori di evento 33-4
predefiniti 33-5, 33-7
produttori di pagine e 33-16
risposta a richieste 33-8
selezione 33-6, 33-7
elementi grafici
aggiunta a HTML 33-15
associazione a stringhe 4-21
autonomi 50-3
cancellazione 10-23
caricamento 10-20, 50-4, 50-5
complessi 50-6
contenitori 50-4
copia 10-23
disegno di linee 10-6, 10-10
10-11, 10-29 10-30
cambio dello spessore
della penna 10-6
disegno e tracciamento 10-4
esempio di effetto
elastico 10-24 10-30
formati dei file 10-3
funzioni, chiamata 50-1
in frame 8-16
incollaggio 10-24
internazionalizzazione 16-10
metodi 50-3, 50-4
copia di immagini 50-7
tavolozze 50-5
panoramica sulla
programmazione 10-1
10-4
registrazione 50-4
ridimensionamento 10-21,
19-10, 50-7
ridisegno delle
immagini 50-7
salvataggio 10-21, 50-4
sostituzione 10-21
strumenti di disegno 50-7,
54-6
cambio 54-8
visualizzazione 9-19
elementi grafici indipendenti
dal dispositivo 50-1
elementi Web 29-39
propriet 29-40 29-41
elenchi
uso in thread 11-5
elenchi a discesa 19-23
elenchi di azioni 5-5, 8-19, 8-21,
8-25 8-53
elenchi di file
rilascio di elementi 6-3
trascinamento di
elementi 6-2, 6-3
elenchi di ricerca (sistemi di
Guida) 52-5
elenchi di stringhe 4-16 4-21
a breve termine 4-17
a lungo periodo 4-18
aggiunta a 4-19
cancellazione di
stringhe 4-20
caricamento da file 4-16
controlli owner-draw 6-13
6-14
copia 4-20
creazione 4-17 4-18
iterazione tra 4-19
oggetti associati 4-20 4-21
ordinamento 4-20
posizione in 4-19
ricerca di stringhe 4-19
salvataggio su file 4-16
sottostringhe 4-19
spostamento di stringhe 4-20
Ellipse, metodo 10-5, 10-12, 50-3
ellissi
disegno 10-11, 54-10
Embed, marcatore HTML
(<EMBED>) 33-15
EmptyDataSet, metodo 22-43,
27-29
EmptyTable, metodo 22-43
EnableCommit, metodo 44-14
EnableConstraints,
metodo 27-32
EnableControls, metodo 19-6
Enabled, propriet
controlli data-aware 19-7
elementi di azione 33-7
menu 6-10, 8-44
sorgenti dati 19-4, 19-6
EnabledChanged, metodo 51-15
end user adapter 34-10, 34-27
END_MESSAGE_MAP,
macro 51-4, 51-8
EndRead, metodo 11-9
EndWrite, metodo 11-9
enumerati, tipi
Web Services 36-6
enumerazioni A-6
EOF, contrassegno 4-4
Eof, propriet 22-6, 22-7, 22-8
era, clock, funzione A-12
EReadError 4-2
eredit
limitazioni 13-2
multipla 13-2
eredit da classi 3-4 3-5
ereditate
propriet 54-3, 55-3
pubblicazione 47-3
ereditati
I n d i c e I-19
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
eventi 48-5
metodi 48-6
ERemotableException 36-15
errori
dominio A-8
socket 37-8
underflow range A-8
errori di aggiornamento
messaggi di risposta 29-38
risoluzione 27-22, 27-25
27-26, 28-9, 28-12
eseguibili, file
in Linux 14-15
esercizio
WebSnap 34-12 34-24
estensioni del linguaggio 13-29
estensioni delle parole
chiave 13-24
estesi, set di caratteri A-2
etichette 9-4, 16-10, 19-2, 45-4
colonne 19-19
Euro, conversioni 4-32, 4-35
EventFilter, metodo
eventi di sistema 51-15
eventi 5-3 5-6, 45-7, 48-1
48-10
a livello di applicazione 8-2
accesso 48-5
ADO, connessioni 25-7
25-9
assegnazione dei nomi 48-8
associazione a gestori 5-5
attesa di 11-10
attivazione 43-11
broker XML 29-38
COM 41-11, 41-12
COM+ 40-16 40-17, 44-22
44-26
condivisi 5-5
controller Automation 40-12,
40-15 40-17
controlli ActiveX 43-11
43-12
controlli data-aware
attivazione 19-7
controlli grafici 50-7
definizione di nuovi 48-6
48-10
ereditati 48-5
gestione dei messaggi 51-4,
51-7
griglie dati 19-29 19-30
implementazione 48-2, 48-4
interfacce 41-11
login 21-5
mouse 10-25 10-27
verifica di 10-27
oggetti Automation 41-5
oggetti campo 23-16 23-17
oggetti COM 41-4, 41-11
41-12
predefiniti 5-4
preparazione della
guida 52-4
risposta a 48-6, 48-7, 48-8,
48-9, 56-8
segnalazione 11-10
sistema 3-3
sorgenti dati 19-4 19-5
standard 48-4
timeout 11-11
tipi 3-3
utente 3-3
VCL, wrapper di
componenti 40-3
eventi clic 10-26, 48-1, 48-8
eventi del mouse 54-3
eventi di notifica 48-7
eventi di sistema
personalizzazione 51-15
eventi di tastiera
internazionalizzazione 16-9
EWriteError 4-2
__except, parola chiave 12-7,
12-8
Exception
definizione 3-5
__except, parola chiave 12-11
Exception, classe 12-17
Exclusive, propriet 24-6
ExecProc, metodo 22-56, 26-11
ExecSQL, metodo 22-50, 22-51,
26-10
oggetti update 24-48
Execute, metodo
comandi ADO 25-18 25-19,
25-20
componenti
connessione 21-11
dataset client 27-30, 28-3
finestr di dialogo 8-17, 57-5
provider 28-3
TBatchMove 24-54
thread 11-4
ExecuteOptions,
propriet 25-11
ExecuteTarget, metodo 8-31
EXISTINGARRAY,
macro 13-18, 13-20
exit, funziones A-11
Expandable, propriet 19-26
Expanded, propriet
colonne 19-25, 19-26
griglie dati 19-22
Expression, propriet 27-13
ExprText, propriet 23-11
F
fabbriche di classi 38-6
facoltativi, parametri 27-16
factory 34-5
FastNet, pagina (Component
palette) 5-8
Fetch Params, comando 27-29
FetchAll, metodo 14-29, 24-34
FetchBlobs, metodo 27-29, 28-4
FetchDetails, metodo 27-29,
28-4
fetch-on-demand 27-29
FetchOnDemand,
propriet 27-29
FetchParams, metodo 27-29,
28-3
fgetpos, funzione A-10
field datalink, classe 56-11
Field Link designer 22-37
FieldAddress, metodo 13-23
FieldByName, metodo 22-33,
23-21
FieldCount, propriet
campi persistenti 19-19
FieldDefs, propriet 22-41
FieldKind, propriet 23-12
FieldName, propriet 23-6,
23-12, 29-40
campi persistenti 19-19
griglie dati 19-22, 19-23
griglie decisionali 20-13
Fields editor 7-24, 23-3
applicazione degli attributi
di campo 23-15
barra del titolo 23-4
cancellazione di campi
persistenti 23-11
creazione di campi
persistenti 23-4 23-5, 23-5
23-11
definizione dei set di
attributi 23-14
liste di campi 23-5
pulsanti di navigazione 23-4
rimozione del set di
attributi 23-15
riordinamento delle
colonne 19-21
I-20 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
Fields, propriet 23-21
FieldValues, propriet 23-21
figure 9-20, 10-11 10-12, 10-14
disegno 10-11, 10-14
riempimento 10-8, 10-9
riempimento con
bitmap 10-10
tracciamento di
contorni 10-6
figure geometriche
disegno 54-10
file 4-4 4-13
aggiunta A-9
apertura
abort, funzione A-11
ripetuta A-9
buffer A-9
cambio del nome 4-9
cancellazione 4-7
con lunghezza zero A-9
copia 4-10
dimensioni 4-4
grafici 10-20 10-22, 50-4
handle 4-5, 4-7
invio attraverso il Web 33-13
modalit 4-7
operazioni con 4-4 4-13
posizione 4-4
ricerca 4-4, 4-8
risorse 8-45
routine
API di Windows 4-5
della libreria runtime 4-7
routine di data-ora 4-9
routine di data-ora 4-9
temporanei A-11
trattamento 4-7 4-10
troncamento durante la
scrittura A-9
file bitmap per la palette 52-4
file di licenza dei package 43-8
file di trasformazione 30-1
30-6
nodi definiti dallutente 30-5,
30-7 30-8
TXMLTransform 30-7
TXMLTransformClient 30-9
TXMLTransformProvider 30
-8
file eseguibili
internazionalizzazione 16-11
, 16-13
server COM 38-7
file indice 24-7
file indice non di
produzione 24-7
file scheda 3-8, 16-13
file sorgente
modifica 2-2
file sorgenti A-7
condivisione (Linux) 14-14
package 15-2
FileAge, funzione 4-9
FileExists, funzione 4-8
FileGetDate, funzione 4-9
FileName, propriet
dataset client 18-10, 27-36,
27-37
files
scheda 14-2
FileSetDate, funzione 4-9
FillRect, metodo 10-5, 50-3
Filter, propriet 22-14, 22-14
22-15
Filtered, propriet 22-13
FilterGroup, propriet 25-12,
25-14
FilterOnBookmarks,
metodo 25-11
FilterOptions, propriet 22-16
filtri 22-13 22-16
attivazione/
disattivazione 22-13
campi vuoti 22-15
confronto di stringhe 22-16
dataset client 27-3 27-5
con parametri 27-31
definizione 22-14 22-16
e intervalli 22-32
gestione delle eccezioni 12-9
impostazione in
esecuzione 22-16
operatori 22-15
opzioni per campi di
testo 22-16
query e 22-13
sensibilit maiuscole/
minuscole 22-16
uso di segnalibri 25-11
filtri dati 22-13 22-16
attivazione/
disattivazione 22-13
impostazione in
esecuzione 22-16
query e 22-13
filtri sui dati
dataset client 27-3 27-5
con parametri 27-31
__finally, parola chiave 12-7,
12-13
FindClose, procedura 4-8
FindDatabase, metodo 24-21
FindFirst, funzione 4-8
FindFirst, metodo 22-17
FindKey, metodo 22-29, 22-30
EditKey e 22-31
FindLast, metodo 22-17
FindNearest, metodo 22-29,
22-30
FindNext, funzione 4-8
FindNext, metodo 22-17
FindPrior, metodo 22-17
FindResourceHInstance,
funzione 16-12
FindSession, metodo 24-30
finestra
classe 45-4
controlli 45-4
gestione dei messaggi 55-4
handle 45-4, 45-6
procedure 51-3
finestre
ridimensionamento 9-7
finestre di dialogo 57-1 57-7
comuni 8-16
comuni di Windows 57-2
creazione 57-2
esecuzione 57-5
creazione 57-1
DLL, esempio di 7-13
editor di propriet
come 52-10
impostazione dello stato
iniziale 57-2
internazionalizzazione 16-9,
16-10
multipagina 9-16
finestre di dialogo comuni 8-16,
57-1, 57-2
creazione 57-2
esecuzione 57-5
Fire 43-11
FireOnChanged 43-13
FireOnRequestEdit 43-13
First Impression 17-5
First, metodo 22-6
FixedColor, propriet 9-18
FixedCols, propriet 9-18
FixedOrder, propriet 8-52, 9-10
FixedRows, propriet 9-18
FixedSize, propriet 9-10
flag 56-4
FlipChildren, metodo 16-7
I n d i c e I-21
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
FloodFill, metodo 10-5, 50-3
fly-by help 9-17
fmod, funzione A-8
FocusControl, metodo 23-17
FocusControl, propriet 9-4
fogli di stile 29-41
font
altezza del 10-5
Font, propriet 9-3, 9-4, 10-4,
50-3
controlli memo data-
aware 19-9
griglie dati 19-22
intestazioni di colonna 19-23
FontChanged, metodo 51-15
Footer, propriet 33-21
FOREIGN KEY, vincolo 28-14
Format, propriet 20-13
formati A-12
formati dati, predefiniti 23-16
formattazione dei dati
applicazioni
internazionali 16-10
Forms unit
applicazioni Web 33-3
Formula One 17-5
fornitura 28-1, 29-4
Found, propriet 22-17
FoxPro, tabelle
transazioni locali 24-33
frame 8-12, 8-14 8-16
condivisione e
distribuzione 8-16
e modelli di
componenti 8-15, 8-16
grafici 8-16
risorse 8-16
FrameRect, metodo 10-5
FReadOnly 56-9
free, modello di threading 41-7
41-8
FreeBookmark, metodo 22-10
FromCommon 4-32
ftell, funzione A-10
funzionalit
non portabili di
Windows 14-8
funzioni 45-7
API di Windows 45-4, 50-1
argomenti 13-8
assegnazione dei nomi 49-2
C++ e Object Pascal 13-24
grafici 50-1
impostazione di
propriet 52-12
lettura delle propriet 47-7,
52-9, 52-11
matematiche A-8
tipo restituito 49-2
virtuali 13-12
funzioni esportate 7-12, 7-13
funzioni importate 7-11
funzioni membro 3-3
impostazione di
propriet 47-7
fuoco 45-4
campi 23-17
spostamento 9-6
fuoco di input 45-4
campi 23-17
fuoco in ingresso 45-4
G
Generate event support
code 41-11
gerarchia (classi) 46-4
gestione dei messaggi 51-4
51-6
ridefinizione 51-4
gestione della memoria
componenti decisionali 20-8,
20-20
schede 8-5
gestione delle eccezioni 12-1
12-19
blocco try 12-2
costruttori e distruttori 12-6
eccezioni strutturate 12-7
esempio 12-11
sintassi 12-7
filtri 12-9
istruzione catch 12-3
istruzione throw 12-2
opzioni del
compilatore 12-15
puntatori safe 12-5
sintassi C++ 12-2
specifica delleccezione 12-4
VCL 12-15
gestione delle eccezioni
Win32 12-7
gestori di evento 5-3 5-6, 45-7,
48-2, 48-8, 56-8
associazione a eventi 5-5
cancellazione 5-6
condivisi 5-5 5-6, 10-16
definizione 5-3
dichiarazioni 48-5, 48-8,
55-13
disegno di linee 10-27
individuazione 5-4
menu 5-6, 6-11
metodi 48-5
ridefinizione 48-6
modelli di menu 8-43
parametri 48-8, 48-9
eventi di notifica 48-7
parametro Sender 5-5
passaggio di parametri per
riferimento 48-9
predefiniti,
ridefinizione 48-9
risposta ai clic del
pulsante 10-14
scrittura 5-4
tipi 48-3, 48-7 48-8
tipo restituito 48-3
visualizzazione in Code
editor 52-18
vuoti 48-9
gestori di messaggi 51-1, 51-3
creazione 51-6 51-8
dichiarazioni 51-5, 51-6, 51-8
metodi, ridefinizione 51-8
predefiniti 51-4
gestori di messaggio 55-5
GetAliasDriverName,
metodo 24-27
GetAliasNames, metodo 24-27
GetAliasParams, metodo 24-27
GetAttributes, metodo 52-11
GetBookmark, metodo 22-10
GetConfigParams,
metodo 24-27
GetData, metodo
campi 23-18
GetDatabaseNames,
metodo 24-27
GetDriverNames, metodo 24-27
GetDriverParams,
metodo 24-27
getenv, funzione A-11
GetExceptionCode,
funzione 12-7
GetExceptionInformation,
funzione 12-7, 12-9
GetFieldByName, metodo 33-9
GetFieldNames, metodo 21-14,
24-28
GetFloatValue, metodo 52-9
GetGroupState, metodo 27-11
GetHandle 7-31
GetHelpFile 7-31
GetHelpStrings 7-32
I-22 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
GetIDsOfNames, metodo 40-15,
41-14
GetIndexNames, metodo 21-15,
22-28
GetInterface, metodo 13-4
GetMethodValue, metodo 52-9
GetNextPacket, metodo 14-29,
24-34, 27-28, 27-29, 28-4
GetOptionalParam,
metodo 27-16, 28-7
GetOrdValue, metodo 52-9
GetPalette, metodo 50-5, 50-6
GetParams, metodo 28-3
GetPassword, metodo 24-23
GetProcAddress 7-11
GetProcedureNames,
metodo 21-15
GetProcedureParams,
metodo 21-15
GetProperties, metodo 52-11
GetRecords, metodo 28-4, 28-8
GetSessionNames,
metodo 24-30
GetStoredProcNames,
metodo 24-27
GetStrValue, metodo 52-9
GetTableNames, metodo 21-14,
24-28
GetValue, metodo 52-9
GetVersionEx, funzione 17-16
GetViewerName 7-30
GetXML, metodo 30-10
-Gi, opzione del linker 15-13
-Gl, opzione del linker 15-13
Global Offset Table
(GOT) 14-21
Glyph, propriet 8-48, 9-8
GNU assembler
Linux 14-18
GNU make, utilit
Linux 14-16
GotoBookmark, metodo 22-10
GotoCurrent, metodo 22-43
GotoKey, metodo 22-29, 22-30
GotoNearest, metodo 22-29,
22-30
-Gpd, opzione del linker 15-13
-Gpr, opzione del linker 15-13
grafici 45-7, 50-1 50-8
aggiunta di controlli 10-18
controlli owner-draw 6-12
disegno di linee
gestori di evento 10-27
file 10-20 10-22
modifica di immagini 10-21
tipi degli oggetti 10-3 10-4
tracciamento e disegno 10-23
grafici decisionali 20-13 20-19
comportamenti in
esecuzione 20-20
dimensioni 20-14
modelli 20-17
opzioni di
visualizzazione 20-15
personalizzazione 20-16
20-19
serie dei dati 20-18 20-19
stati del pivot 20-9, 20-10
tipi di grafici 20-17
grafici, metodi 50-6
Graph Custom 17-5
Graphic, propriet 10-19, 10-22
GridLineWidth, propriet 9-18
griglie 9-17 9-18, 19-3, 55-1,
55-3, 55-6, 55-13
aggiunta di righe 22-19
associate ai dati 19-16, 19-30
colore 10-6
disegno 19-28 19-29
editing dei dati 19-6, 19-28
inserimento di colonne 19-20
opzioni di esecuzione 19-26
19-28
ottenimento di valori 19-19
personalizzazione 19-18
19-24
rimozione di colonne 19-18,
19-21
riordinamento delle
colonne 19-21
ripristino dello stato
predefinito 19-24
stato predefinito 19-17
visualizzazione dei
dati 19-17, 19-18, 19-30
griglie dati 19-2, 19-3, 19-16,
19-16 19-30
disegno 19-28 19-29
editing dei dati 19-6, 19-28
eventi 19-29 19-30
inserimento di colonne 19-20
opzioni di esecuzione 19-26
19-28
ottenimento di valori 19-19
personalizzazione 19-18
19-24
propriet 19-31
rimozione di colonne 19-18,
19-21
riordinamento delle
colonne 19-21
stato predefinito 19-17
visualizzazione dei
dati 19-17, 19-18, 19-30
ADT, campi 19-24
campi array 19-24
griglie decisionali 20-11 20-13
comportamenti in
esecuzione 20-19
dimensioni
apertura/chiusura 20-11
drill down 20-12
riordinamento 20-12
selezione 20-12
eventi 20-13
propriet 20-12
stati del pivot 20-9, 20-10,
20-12
griglie di disegno 9-18
griglie tabellari 19-30
groglie dati
ripristino dello stato
predefinito 19-24
Grouped, propriet
pulsanti strumento 8-50
GroupIndex, propriet 9-8
menu 8-44
pulsanti di scelta rapida 8-48
GroupLayout, propriet 20-10
Groups, propriet 20-10
gruppi di opzioni 9-14
gruppi di propriet
condivise 44-7
GUI applicazioni 8-1
GUID 38-4, 39-8, 40-5
Guida 52-4
informazioni di tipo 39-9
sensibile al contesto 9-17
suggerimenti 9-17
tool-tip 9-17
guida in linea 52-4
guida rapida 19-34
H
.h, file 15-2, 15-14
handle
connessioni socket 37-7
moduli di risorsa 16-12
Handle, propriet 4-7, 37-7,
45-4, 45-5, 50-3
contesto del dispositivo 10-2
HANDLE_MSG, macro 51-2
HandleException, metodo 51-3
HandleShared, propriet 24-17
I n d i c e I-23
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
HandlesTarget, metodo 8-31
HasConstraints, propriet 23-12
HasFormat, metodo 6-11, 10-24
header
richieste HTTP 32-4
header del messaggio
(HTTP) 32-3
header della richiesta 33-9
header della risposta 33-13
header, controlli 9-16
Header, propriet 33-21
Height, propriet 8-4
caselle di riepilogo 19-12
Help Manager 7-28, 7-29 7-38
Help, selettori 7-35, 7-37
Help, sistemi 7-28
interfacce 7-29
registrazione di oggetti 7-34
Help, visualizzatori 7-28
HelpContext 7-37
HelpContext, propriet 7-36,
9-17
helper, oggetti 4-1
HelpFile property 9-17
HelpFile, propriet 7-37
HelpIntfs, unit 7-29
HelpKeyword 7-37
HelpKeyword, propriet 7-36
HelpSystem 7-36
HelpType 7-36, 7-37
hidesbase, argomento 13-30
Hint, propriet 9-17
Hints, propriet 19-34
holder, classi 36-6
HookEvents, metodo 51-12
HorzScrollBar 9-5
host 29-25, 37-4
indirizzi 37-4
URL 32-4
Host, propriet
TSocketConnection 29-25
HotImages, propriet 8-50
HotKey, propriet 9-6
HTML Result, pagina 34-2
HTML Script, pagina 34-2
HTML, comandi 33-14
generazione 33-15
informazioni di
database 33-19
HTML, documenti 32-5
applicazioni
InternetExpress 29-33
ASP e 42-1
controlli AactiveX
incorporati 43-1
database e 33-18
dataset 33-21
fogli di stile 29-41
generati per
ActiveForms 43-6
incorporamento di
tabelle 33-21
messaggi di risposta
HTTP 32-6
modelli 29-39, 29-41 29-43,
33-14 33-16
produttori di pagine 33-14
33-18
produttori di pagine di
dataset 33-19
produttori di tabelle 33-19
33-21
HTML, modelli 29-41 29-43,
33-14 33-18, 34-4
predefiniti 29-39, 29-41
HTML, schede 29-40
HTML, tabelle 33-15, 33-21
creazione 33-19 33-21
impostazione delle
propriet 33-20
titoli 33-21
HTMLDoc, propriet 29-39,
33-15
HTMLFile, propriet 33-15
HTML-transparente, marcatori
predefiniti 29-42
HTML-trasparente, marcatori
conversione 33-14, 33-16
parametri 33-14
predefiniti 33-15
sintassi 33-14
HTTP 32-3
applicazioni multi-tier 29-11
codici di stato 33-12
connessione allapplication
server 29-26
header del messaggio 32-3
header della richiesta 32-4,
33-9, 42-4
header della risposta 33-13,
42-5
messaggi di richiesta Vedere
messaggi di richiesta
messaggi di risposta Vedere
messaggi di risposta
panoramica 32-5 32-7
SOAP 36-1
HTTP, richieste
immagini 34-40
HTTP, risposte
immagini 34-40
httpsrvr.dll 29-11, 29-14, 29-26
HyperHelp, visualizzatore 7-28
I
IApplicationObject,
interfaccia 42-4
IAppServer interface
estensione 29-17
transazioni 29-19
XML, broker 29-34
IAppServer, interfaccia 27-33,
27-35, 28-3 28-4, 29-4, 29-5
informazioni di stato 29-20
provider locali 28-3
provider remoti 28-3
IAppServer, interface
chiamata 29-29
IAppServerSOAP,
interfaccia 29-5, 29-27
icone 9-20, 29-26, 50-4
aggiunta a component 45-15
aggiunta a menu 8-23
barre strumenti 8-50
oggetti grafici 10-4
viste ad albero 9-12
IConnectionPoint,
interfaccia 41-12
IconnectionPoint,
interfaccia 40-15
IConnectionPointContainer,
interfaccia 41-11, 41-12
IconnectionPointContainer,
interfaccia 40-15
IconnectionPointContainerImpl,
implementazione 41-11
ICustomHelpViewer 7-28, 7-29,
7-30, 7-31
implementazione 7-30
IDE
aggiunta di azioni 58-10
aggiunta di immagini 58-9
58-10
cancellazione di
pulsanti 58-10 58-11
personalizzazione 58-1
identificatori
Vedi anche GUID
caratteri significativi A-3
costanti 10-13
esterni A-3
eventi 48-8
impostazione delle
propriet 47-7
I-24 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
impostazione di
propriet 47-7
lunghezza A-3
membri dati 48-2
metodi 49-2
non validi 8-34
risorse 52-4
sensibilit maiuscole/
minuscole A-3
tipi 10-13
tipi di record dei
messaggi 51-7
IDispatch, interfaccia 38-9,
38-21, 41-13
Automation 38-13, 40-14
identificatori 41-14, 41-15
Idispatch, interfaccia 41-14
41-15
IDL (Interface Definition
Language) 31-5, 38-18, 38-20
Type Library editor 39-8
IDL, compilatore 38-20
IDL, file 31-5, 31-6
CORBA Server Wizard 31-6
CORBA, client 31-14
esportazione da libreria di
tipi 39-20
IDL, file,
compilazione 31-6 31-7
IDOMImplementation 35-3
IEEE
formati in virgola
mobile A-3
IETF, protocolli e standard 32-3
IExtendedHelpViewer 7-29,
7-33
#ifdef, direttiva 14-18
#ifndef, direttiva 14-19
IHelpManager 7-29, 7-37
IHelpSelector 7-29, 7-34
IHelpSystem 7-29, 7-37
IID 40-5
IInterface
gestione della durata 13-5
implementazione 13-3, 13-4
IInvokable 36-2
IIS 42-1
versione 42-3
Il 11-7
Image Editor
utilizzo 45-15
Image, marcatore HTML
(<IMG>) 33-15
ImageIndex, propriet 8-50,
8-52
ImageList 8-21
ImageMap, marcatore HTML
(<MAP>) 33-15
Images, propriet
pulsanti strumento 8-50
IMarshal, interfaccia 41-15,
41-17
IME 16-9
ImeMode, propriet 16-9
ImeName, propriet 16-9
immagini 9-20, 10-18, 19-2, 50-3,
50-3 50-6
aggiunta 10-18
aggiunta a menu 8-38
aggiunta di controlli per 6-13
cambio 10-21
cancellazione 10-23
caricamento 10-20
controlli per 10-2, 10-18
copia 50-7
disegno 54-9
in frame 8-16
internazionalizzazione 16-10
modifica 10-21
pennelli 10-10
pulsanti strumento 8-50
ridisegno 50-7
riduzione dello
sfarfallio 50-6
salvataggio 10-21
scorrimento 10-18
sostituzione 10-21
visualizzazione 9-19
immagini, richieste 34-40
Implementation
Repository 31-4
Import ActiveX Control,
comando 40-2, 40-4
Import Type Library,
comando 40-2, 40-3
ImportedConstraint,
propriet 23-12, 23-23
impostazioni di propriet
lettura 47-9
scrittura 47-9
impostazioni locali 4-23
formati dei dati e 16-10
moduli di risorse 16-11
impostazioni nazionali 16-2
Include Unit Hdr, comando 8-4
include, file
ricerca A-7
Increment, propriet 9-6
Indent, propriet 8-50, 8-52,
9-12
Index Files editor 24-7
index, parola riservata 55-8
Index, propriet
campi 23-12
IndexDefs, propriet 22-41
IndexFieldCount,
propriet 22-28
IndexFieldNames,
propriet 22-28, 26-8, 27-9
IndexName e 22-29
IndexFields, propriet 22-28
IndexFiles, propriet 24-7
IndexName, propriet 24-7,
26-7, 27-10
IndexFieldNames e 22-29
IndexOf, metodo 4-19, 4-20
indicatore di posizione di
file A-9
indici 22-27 22-39, 47-9
cancellazione 27-10
dataset client 27-8 27-11
elenco 21-15, 22-28
intervalli 22-32
operazioni batch e 24-52,
24-53
ordinamento dei
record 22-27 22-29, 27-8
raggruppamento di
dati 27-10 27-11
relazioni master/
detail 22-37
ricerca su chiavi
parziali 22-31
specifica 22-28 22-29
tabelle dBASE 24-6 24-8
indici, definizioni 22-41
indirizzamento delle richieste
WebSnap 34-36
indirizzi
connessioni socket 37-3, 37-4
Indy Clients, pagina
(Component palette) 5-8
Indy Misc, pagina (Component
palette) 5-9
Indy Servers, pagina
(Component palette) 5-9
INFINITE, costante 11-11
informazioni di login
specifica 21-5
informazioni di schema 26-12
26-18
campi 26-16
indici 26-16 26-17
procedure registrate 26-15,
26-17 26-18
I n d i c e I-25
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
tabelle 26-14 26-15
informazioni di stato 9-16
comunicazione 28-8, 29-20
29-21
eventi del mouse 10-25
gestione 44-6
oggetti transazionali 44-13
propriet condivise 44-7
informazioni di tipo 38-17, 39-1
dispinterface 41-13
Guida 39-9
importazione 40-2 40-7
interfaccia IDispatch 41-14
informazioni di tipo in
esecuzione 46-8
informazioni sulla versione
controlli ActiveX 43-5
informazioni di tipo 39-9
Informix, driver
distribuzione 17-10
Inherit (Object Repository) 7-27
inherited, parola chiave 13-8,
13-11, 13-12, 13-14
InheritsFrom, metodo 13-23
.ini, file 14-7
Win-CGI, applicazioni 32-7
InitializeControl, metodo 43-12
InitWidget, propriet 14-13
INITWIZARD0001 58-23
Input Mask editor 23-15
input method editor 16-9
input, parametri 22-53
input/output, parametri 22-53
Insert From Resource, comando
(Menu designer) 8-40, 8-45
Insert from Resource, finestra di
dialogo 8-45
Insert From Template, comando
(Menu designer) 8-40, 8-41
Insert Template, finestra di
dialogo 8-42
Insert, comando (Menu
designer) 8-40
INSERT, istruzione 21-12
INSERT, istruzioni 24-42, 24-45,
28-10
Insert, metodo 22-19, 22-20
Append e 22-19
menu 8-44
stringhe 4-19
InsertObject method 4-21
InsertRecord, metodo 22-22
InsertSQL, propriet 24-42
Install COM+ objects,
comando 44-29
Install Components,finestra di
dialogo 45-20
Install MTS objects,
comando 44-29
Install, comando
(Component) 45-20
installazione
programmi 17-2
supporto 1-3
Installazione di oggetti
transazionali 44-29
InstallShield Express 2-5, 17-1
distribuzione
applicazioni 17-2
BDE 17-9
package 17-3
SQL Links 17-10
instanziazione 13-5
int, tipi A-3
INTAComponent 58-14
INTAServices 58-8, 58-9, 58-18
integer A-6
array e A-5
con segno A-5
conversione in puntatori A-5
divisione A-5
enumerazioni e A-6
puntatori e A-5
right shifted A-5
integer, tipi A-3
IntegralHeight, propriet 9-11,
19-12
integrit dei dati 18-5, 28-13
integrit referenziale 18-5
InterBase, driver
distribuzione 17-10
InterBase, pagina (Component
palette) 5-8, 18-2
InterBase, tabelle 24-9
InterBaseExpress 14-23
interceptor 38-5
interfacce 7-13, 46-4, 46-7, 57-2,
57-3
ActiveX 38-21
personalizzazione 43-8
43-14
aggiunta di metodi 41-10
41-11
aggiunta di propriet 41-10
API Tools 58-1, 58-4 58-7
numeri di versione 58-12
58-13
application server 29-17
29-18, 29-29
applicazioni distribuite 3-4
Automation 41-13 41-15
binding dinamico 31-4,
39-10, 41-13
COM 7-20, 38-1, 38-3 38-5,
39-9 39-10, 40-1, 41-3, 41-9
41-15
dichiarazioni 40-6
eventi 41-11
wrapper 40-6
CORBA 31-2, 31-5 31-13
custom 41-15
dichiarazione 13-2
dispatch 41-14
DOM 35-2
elementi di programma non
visuali 45-5
estensione delleredit
singola 3-4
implementazione 38-6, 41-3
in esecuzione 46-7
in progettazione 46-8
in uscita 41-11, 41-12
internazionalizzazione 16-9,
16-10, 16-13
librerie di tipi 38-19, 40-6,
41-9
multipla, eredit 13-2
oggetti evento COM+ 44-25
propriet, dichiarazione 57-4
registrazione 31-13 31-14
richiamabili 36-2 36-10
sistema di Help 7-29
sistemi di Help 7-29
skeleton 31-3
stub 31-2, 31-3
Type Library editor 39-9
39-10, 39-14, 41-9
Web Services 36-1
XML, nodi 35-5
interfacce del componente
creazione 57-3
propriet, dichiarazione 57-4
interfacce duali 41-13 41-14
Active Server Objects 42-3
chiamata a metodi 40-14
compatibilit dei tipi 41-16
oggetti transazionali 44-3,
44-19
parametri 41-16
interfacce in esecuzione 46-7
interfacce in progettazione 46-8
interfacce richiamabili
chiamata 36-17 36-18
implementazione 36-12
36-14
I-26 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
namespace 36-3
registrazione 36-3
interfacce utente 8-1, 18-16
18-17
a singolo record 19-8
isolamento 18-6
layout 8-4 8-5
multirecord 19-16
organizzazione dei dati 19-8,
19-16
schede 8-1 8-4
__interface 13-2, 36-3
Interface Definition Language
Vedere IDL
Interface Repository
registrazione di interfacce
CORBA 31-13
INTERFACE_UUID,
macro 13-3, 36-3
InternalCalc, campi 23-6, 27-11
27-12
indici e 27-10
internazionalizzazione di
applicazioni 16-1
abbreviazioni 16-9
conversione input di
tastiera 16-9
localizzazione 16-12
Internet Engineering Task
Force 32-3
Internet Information Server
(IIS) 42-1
versione 42-3
Internet, pagina (Component
palette) 5-8
Internet, server 32-1 32-12
Internet, standard e
protocolli 32-3
InternetExpress 7-19, 29-33
29-43
e ActiveForms 29-31 29-32
InternetExpress, pagina
(Component palette) 5-8
intervalli 22-32 22-36
annullamento 22-36
applicazione 22-36
e filtri 22-32
indici e 22-32
limiti estremi 22-35
modifica 22-35 22-36
specifica 22-32 22-35
valori nulli 22-33, 22-34
intestazioni
owner-draw 6-12
intranet
Vedere reti locali
nomi host 37-4
InTransaction, propriet 21-7
Invalidate, metodo 54-10
invio di messaggi 51-8 51-11
Invoke, metodo 41-14
invoker 36-12
InvokeRegistry.hpp 36-5
IObjectContext, interfaccia 42-3,
44-4, 44-5
metodi per terminare una
transazione 44-13
IObjectControl,
interfaccia 38-15, 38-16, 44-2
IoleClientSite, interfaccia 40-17
IOleDocumentSite,
interfaccia 40-17
iostream A-9
IOTAActionServices 58-8
IOTABreakpointNotifier 58-19
IOTACodeCompletionServices
58-8
IOTAComponent 58-14
IOTACreator 58-15
IOTADebuggerNotifier 58-19
IOTADebuggerServices 58-8
IOTAEditLineNotifier 58-19
IOTAEditor 58-14
IOTAEditorNotifier 58-19
IOTAEditorServices 58-8
IOTAFile 58-15, 58-17
IOTAFormNotifier 58-19
IOTAFormWizard 58-3
IOTAIDENotifier 58-19
IOTAKeyBindingServices 58-8
IOTAKeyboardDiagnostics 58-8
IOTAKeyboardServices 58-8
IOTAMenuWizard 58-3
IOTAMessageNotifier 58-19
IOTAMessageServices 58-8
IOTAModule 58-13
IOTAModuleNotifier 58-19
IOTAModuleServices 58-8,
58-13
IOTANotifier 58-19
IOTAPackageServices 58-8
IOTAProcessModNotifier 58-19
IOTAProcessNotifier 58-19
IOTAProjectWizard 58-3
IOTAServices 58-8
IOTAThreadNotifier 58-19
IOTAToDoServices 58-8
IOTAToolsFilter 58-8
IOTAToolsFilterNotifier 58-19
IOTAWizard 58-2, 58-3
IOTAWizardServices 58-8
IP, indirizzi 37-4, 37-6
host 37-4
nomi host e 37-5
IprovideClassInfo,
interfaccia 38-19
IProviderSupport,
interfaccia 28-2
IPX/SPX, protocolli 37-1
Irequest, interfaccia 42-4
Iresponse, interfaccia 42-5
is, operatore 13-23
isalnum, funzione A-8
isalpha, funzione A-8
ISAPI DLLs 17-10
ISAPI, applicazioni 32-7
creazione 33-1, 34-9
debug 32-11
messaggi di richiesta 33-2
iscntrl, funzione A-8
IScriptingContext,
interfaccia 42-3
ISecurityProperty,
interfaccia 44-18
Iserver, interfaccia 42-7
ISessionObject, interfaccia 42-6
islower, funzione A-8
isolamento
transazioni 18-5, 44-11
ISpecialWinHelpViewer 7-29
isprint, funzione A-8
IsSecurityEnabled 44-17
istanze 48-2
istanziazione
COM, server 41-9
istruzioni di assegnazione 47-2
isupper, funzione A-8
IsValidChar, metodo 23-18
ItemHeight, propriet 9-11
caselle combinate 19-12
caselle di riepilogo 19-12
ItemIndex, propriet 9-11
gruppi di pulsanti di
opzione 9-14
Items, propriet
caselle di riepilogo 9-11
controlli pulsanti di
opzione 19-15
gruppi di pulsanti di
opzione 9-14
ITypeComp, interfaccia 38-19
ITypeInfo, interfaccia 38-19
ITypeInfo2, interfaccia 38-19
ItypeLib, interfaccia 38-19
ITypeLib2, interfaccia 38-19
I n d i c e I-27
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
IUnknown
implementazione 13-4
IUnknown, interfaccia 38-3,
38-20
controller Automation 41-14
Iunknown, interfaccia 38-4
gestione della durata 13-5
implementazione 13-3
supporto ATL 38-24 38-25
traccia delle chiamate 41-9
IXMLNode 35-4 35-6, 35-7
J
javascript, librerie 29-33, 29-35
individuazione 29-34, 29-35
just-in-time, attivazione 29-7,
44-5
attivazione 44-5
K
K, note a pi di pagina (sistemi
di Guida) 52-5
KeepConnection,
propriet 21-3, 21-13, 24-19
KeepConnections,
propriet 24-14, 24-19
key-down, messaggi 48-5, 56-9
KeyDown, metodo 51-14, 56-10
KeyExclusive, propriet 22-31,
22-35
KeyField, propriet 19-13
KeyFieldCount, propriet 22-31
KeyPress, metodo 51-14
KeyString, metodo 51-14
KeyUp, metodo 51-14
KeyViolTableName,
propriet 24-55
KeywordHelp 7-36
Kind, propriet
pulsanti bitmap 9-8
L
Last, metodo 22-6
lato server
scripting 34-33 34-36
Layout, propriet 9-8
Left, propriet 8-4
LeftCol, propriet 9-18
lettura dellimpostazione delle
propriet 47-7
.lib, file 15-2, 15-14
package 15-14
$LIBPREFIX, direttiva 7-11
LibraryName, propriet 26-4
libreria di esecuzione 4-1
librerie
controlli personalizzati 45-5
eccezioni 12-19
librerie di componenti
aggiunta di
componenti 45-20
librerie di importazione 7-11,
7-12, 7-15
librerie di tipi 38-11, 38-17
38-20, 39-21
accesso 38-19, 39-14, 40-2
40-7
Active Server Objects 42-3
aggiunta
metodi 39-15 39-16
propriet 39-15 39-16
aggiunta di interfacce 39-14
apertura 39-14
browser 38-19
consultazione 38-20
contenuti 38-17, 39-1, 40-5
40-7
controlli ActiveX 43-3
creazione 38-18, 39-13
39-14
deregistrazione 38-20
disinstallazione 38-19
distribuzione 39-20 39-21
exporting as IDL 39-20
generate dai wizard 39-1
IDL e ODL 38-18
importazione 40-2 40-7
inclusione come
risorse 39-20 39-21, 43-3
interfacce 38-19
modifica di interfacce 39-15
39-16
oggetti transazionali 44-3
ottimizzazione delle
prestazioni 39-9
quando utilizzarle 38-18
38-19
registrazione 38-20, 39-20
registrazione di oggetti 38-19
salvataggio 39-19
strumenti 38-20
tipi validi 39-12 39-13
unit _TBL 38-25, 39-2, 39-14,
40-2, 40-5 40-7, 41-15
vantaggi 38-19 38-20
$LIBSUFFIX, direttiva 7-11
$LIBVERSION, direttiva 7-11
.lic, file 43-7
linee
cancellazione 10-30
disegno 10-6, 10-10, 10-10
10-11, 10-29 10-30
cambio dello spessore
della penna 10-6
gestori di evento 10-27
Lines, propriet 9-3, 47-8
LineSize, propriet 9-6
LineTo, metodo 10-5, 10-8,
10-11, 50-3
link 7-12
link dinamico 7-11, 7-12, 7-13
link ipertestuali
aggiunta a HTML 33-15
Link, marcatore HTML (</
A>) 33-15
Linux
applicazioni
multipiattaforma 14-1
14-30
directory 14-16
e Windows 14-14 14-16
file batch 14-14
notifiche di sistema 51-11
51-16
Registry 14-15
List, propriet 24-30
liste
accesso 4-15
aggiunta 4-14
cancellazione 4-14
disposizione 4-15
persistenti 4-15
raccolte 4-16
stringhe 4-15, 4-16 4-21
liste di stringhe
persistenti 4-15
ListField, propriet 19-14
ListSource, propriet 19-13
livelli di raggruppamento 27-10
aggregati di
manutenzione 27-14
Loaded, metodo 47-14
LoadFromFile, metodo
dataset ADO 25-15
dataset client 18-10, 27-36
grafici 10-20, 50-4
stringhe 4-16
LoadFromStream, metodo
dataset client 27-36
LoadLibrary 7-11
LoadPackage, funzione 15-4
LoadParamListItems,
procedura 21-15
I-28 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
LoadParamsFromIniFile,
metodo 26-5
LoadParamsOnConnect,
propriet 26-5
Local SQL 24-9, 24-10
query eterogenee 24-9
locale, date A-12
locale, orario A-12
LocalHost, propriet
socket client 37-7
localizzazione
localizzazione di
applicazioni 16-2
risorse 16-11, 16-13
localizzazione di
applicazioni 16-13
localizzazioni 16-13
LocalPort, propriet
socket client 37-7
Locate, metodo 22-11
Lock, metodo 11-8
LockList, metodo 11-8
LockType, propriet 25-12,
25-13
LogChanges, propriet 27-5,
27-37
login
connessioni SOAP 29-27
connessioni Web 29-26
login, eventi 21-5
Login, finestra di dialogo 21-4
login, obbligatorio 34-30 34-31
LoginPrompt, propriet 21-4
Lookup, metodo 22-12
LookupCache, propriet 23-10
LookupDataSet, propriet 23-12
LookupKeyFields,
propriet 23-10, 23-12
LookupResultField,
propriet 23-12
Lparam, parametro 51-10
.lpk, file 43-8
LPK_TOOL.EXE 43-8
lunghezza zero, file A-9
M
m_spObjectContext 44-4
m_VclCtl 43-10
macro 13-18, 13-21, 13-29, 51-4
espansione A-8
HANDLE_MSG 51-2
main, funzione A-2
MainMenu, componente 8-33
MainWndProc, metodo 51-3
maiuscole/minuscole,
sensibilit
indici 27-9
make, utilit
Linux 14-16
malloc, funzione A-11
Man, pagine 7-28
mappatura
XML 30-2 30-4
definizione 30-4
mappe di interfacce 38-24
mappe di oggetti 38-24
mappe di tastiera 16-9, 16-10
Mappings, propriet 24-53
Margin, propriet 9-8
marshaling 38-8
custom 41-17
interfacce COM 38-8 38-9,
41-4, 41-15 41-17
interfacce CORBA 31-3
interfaccia IDispatch 38-13,
41-15
oggetti transazionali 44-3
maschere 23-15
master/detail, relazioni 19-16,
22-36 22-39, 22-49 22-50
aggiornamenti in
cascata 28-6
applicazioni multi-tier 29-19
cancellazioni in cascata 28-6
dataset client 27-20
dataset unidirezionali 26-12
indici 22-37
inegrit referenziale 18-6
tabelle annidate 22-38
22-39, 29-20
master/detail, schede 19-16
esempio 22-37 22-38
MasterFields, propriet 22-37,
26-12
MasterSource, propriet 22-37,
26-12
matematiche, funzioni
errori di dominio A-8
errori underflow A-8
Max, propriet
barre di avanzamento 9-17
trackbar 9-5
MaxDimensions,
propriet 20-20
MaxLength, propriet 9-3
controlli memo data-
aware 19-9
controlli rich edit data-
aware 19-10
MaxRecords, propriet 29-37
MaxRows, propriet 33-20
MaxStmtsPerConn,
propriet 26-3
MaxSummaries,
propriet 20-20
MaxTitleRows, propriet 19-26
MaxValue, propriet 23-12
MBCS 4-21
MDAC 17-7
MDI applicazioni
menu attivo 8-44
MDI, applicazioni 7-1 7-3
creazione 7-2
fusione di menu 8-44 8-45
media player 5-7, 10-33 10-35
esempio 10-34
medie, cubi decisionali 20-5
membri dati 3-2
assegnazione del nome 48-2
inizializzazione 13-12
strutture dei messaggi 51-5
memo, controlli 6-7, 9-3, 47-8
modifica 53-1
memorizzazione delle risorse
nella cache 50-2
menu 8-32 8-44
accesso a comandi 8-36
aggiunta 8-33, 8-37 8-38
aggiunta di immagini 8-38
assegnazione dei nomi 8-33
dasttivazione di
elementi 6-10
definizione 8-19
gestione di eventi 5-6, 8-43
importazione 8-45
internazionalizzazione 16-9,
16-10
liste di azioni 8-19
modelli 8-33, 8-40, 8-41, 8-42
owner-draw 6-12
popup 6-11
riutilizzo 8-40
salvataggio come
modelli 8-41, 8-42 8-43
scorciatoie 8-36 8-37
spostamento di
elementi 8-38
spostamento tra 8-40
visualizzazione 8-39, 8-40
menu a discesa 8-37 8-38
menu contestuali
aggiunta di elementi 52-17
52-18
barre strumenti 8-52
I n d i c e I-29
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
Menu designer 8-40
Menu designer 5-6, 8-32 8-37
menu contestuali 8-40
menu popup 6-11 6-12
menu a discesa e 8-37
visualizzazione 8-39
Menu, propriet 8-44
menu, wizard 58-4
MergeChangeLog,
metodo 27-7, 27-37
mesi, restituzione del
corrente 55-9
MESSAGE_HANDLER,
macro 51-4
MESSAGE_MAP, macro 51-8
messages.hpp, file 51-2
messaggi 51-8, 55-4, A-11
applicazioni
multithread 51-10
definiti dellutente 51-6, 51-8
definizione 51-1
identificatori 51-7
intercettazione 51-5
invio 51-8 51-11
Linux Vedere notifiche di
sistema
mouse 56-9
mouse- e key-down 56-9
record
tipi, dichiarazione 51-7
strutture 51-5
tasto 56-9
Windows 51-1 51-11
messaggi definiti
dellutente 51-6, 51-8
messaggi del mouse 56-9
messaggi di errore A-8, A-11,
A-12
internazionalizzazione 16-11
messaggi di richiesta 33-2, 33-3,
42-4
contenuti 33-11
dispatch 33-5
elementi di azione e 33-6
HTTP, panoramica 32-5
32-7
informazioni
dellheader 33-9 33-11
risposta a 33-8 33-9, 33-13
tipi 33-10
trattamento 33-5
XML, broker 29-37
messaggi di risposta 33-3, 42-5
contenuti 33-13, 33-14
creazione 33-11 33-13,
33-14
informazioni database 33-18
33-21
informazioni
dellheader 33-11 33-13
informazioni di stato 33-12
trasmissione 33-8, 33-13
messaggi diagnostici
(ANSI) A-1
messaggi key-down 56-9
messaggi, header (HTTP) 32-4
metadati 21-14 21-15
dbExpress 26-12 26-18
modifica 26-11 26-12
ottenimento da
provider 27-29
metafile 9-20, 10-1, 10-20, 50-4
quando usarli 10-4
Method, propriet 33-10
MethodAddress, metodo 13-23
MethodType, propriet 33-7,
33-10
metodi 3-3, 10-16, 45-7, 49-1,
55-12
aggiunta a controlli
ActiveX 43-9 43-11
aggiunta a interfacce 41-10
41-11
assegnazione dei nomi 49-2
cancellazione 5-6
chiamata 48-6, 49-3, 54-5
dichiarazione 10-16, 46-10,
49-4
public 49-3
disegno 54-9, 54-10
ereditati 48-6
gestione dei messaggi 51-3,
51-5
gestione di messaggi 51-1
gestori di evento 48-5
ridefinizione 48-6
grafici 50-3, 50-4, 50-6, 50-7
tavolozze 50-5, 50-6
inizializzazione 47-14
propriet e 47-5 47-7, 49-1,
49-2, 54-4
protected 49-3
public 49-3
ridefinizione 51-4, 51-5, 51-8,
55-13
virtual 46-9, 49-4
virtuali
eredit 13-2
metodi di elementi grafici
tavolozze 50-6
Microsoft Server DLL 32-7
creazione 33-1, 34-9
messaggi di richiesta 33-2
Microsoft SQL Server
distribuzione di driver 17-10
Microsoft Transaction
Server 7-20
Microsoft Transaction Server
Vedere MTS
midas.dll 27-1, 29-3
midaslib.dcu 17-7, 29-3
MIDI, file 10-34
MIDL 38-20
Vedi anche IDL
MIME, messaggi 32-6
MIME, tipi e costanti 10-23
Min, propriet
barre di avanzamento 9-17
trackbar 9-5
MinSize, propriet 9-7
MinValue, propriet 23-13
misure
conversione 4-27 4-35
unit 4-30
MM, film 10-34
mobile computing 18-15
modali, schede 8-5
modalit di disegno 10-30
modalit di modifica 22-18
modalit edit
annullamento 22-18
Mode, propriet 24-51
penne 10-6
modelli 7-25, 7-27
cancellazione 8-41
componente 8-12
componenti 8-13
grafici decisionali 20-17
HTML 33-14 33-18
menu 8-33, 8-40, 8-41
produttori di pagine 34-4
programmazione 7-3
Web Broker,
applicazioni 33-2
modelli di componente 8-13,
46-2
e frame 8-15, 8-16
modelli di componenti 8-12
modelli di risposta 33-14
modelli di threading 41-5 41-9
controlli ActiveX 43-5
moduli dati remoti 29-15
moduli dati
transazionali 29-16
I-30 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
oggetti Automation 41-5
oggetti COM 41-3
oggetti transazionali 44-19
44-20
registro di sistema 41-6
modello a oggetti 13-1
modifica di script 34-35
Modified, metodo 56-12
Modified, propriet 9-3
Modifiers, propriet 9-7
ModifyAlias, metodo 24-26
ModifySQL, propriet 24-42
moduli
API Tools 58-3, 58-13 58-14
tipi 7-21
tipi Web 34-2
Type Library editor 39-11,
39-18 39-19
moduli dati 18-7
accesso da schede 7-24
applicazioni Web e 33-2
componenti database 24-17
creazione 7-22
editing 7-22
remoti e standard 7-21
Web 34-3, 34-5
Web Broker,
applicazioni 33-4
moduli dati remoti 29-3, 29-13,
29-14 29-17
basati su COM 29-5, 29-22
centralizzazione 29-8 29-9
classe di
implementazione 29-14
figlio 29-22
genitore 29-22
modelli di threading 29-15,
29-16
multipli 29-21 29-22, 29-30
oggetto di
implementazione 29-5
senza stato 29-8, 29-9, 29-20
29-21
moduli dati transazionali 29-7
29-8
attributi della
transazione 29-16
connessioni a database 29-6,
29-8
centralizzazione 29-7
interfaccia 29-18
modelli di threading 29-16
sicurezza 29-10
moduli di fusione 17-3
moduli di risorsa 16-10
moduli di risorse 16-11
moduli Web 33-2 33-3
aggiunta di sessioni
database 33-18
DLL e, avvertenze 33-3
Month, propriet 55-6
MonthCalendar,
componente 9-13
motivi 10-10
motivi di riempimento 10-8,
10-9
motori di database
di terze parti 17-7
mouse, eventi 10-25 10-27
controllo di 10-27
definizione 10-25
drag-and-drop 6-1 6-4
informazioni di stato 10-25
parametri 10-25
mouse, puntatori
drag-and-drop 6-4
mouse-down, messaggi 56-9
MouseDown, metodo 51-14,
56-9
MouseMove, metodo 51-14
MouseToCell, metodo 9-18
MouseUp, metodo 51-14
.mov, file 10-34
Move method
elenchi di stringhe 4-20, 4-21
MoveBy, metodo 22-7
MoveCount, propriet 24-54
MoveFile, funzione 4-9
MovePt 10-30
MoveTo, metodo 10-5, 10-8,
50-3
.mpg, file 10-34
Msg, parametro 51-4
MSI, tecnologia 17-3
MTS 7-20, 29-7, 38-11, 38-15,
44-1
Vedi anche oggetti
transazionali
ambiente di esecuzione 44-2
COM+ e 44-2
oggetti transazionali 38-15
38-16
requisiti 44-3
riferimenti a oggetti 44-27
44-28
server in-process 44-2
transazioni 29-18
MTS executive 44-2
MTS Explorer 44-30
MTS, package 44-7, 44-29
multibyte, caratteri
(MBCS) 14-21, A-2, A-4
applicazioni
multipiattaforma 14-18
multibyte, codici di
caratteri 16-3
multibyte, set di caratteri 16-3
multimedia, applicazioni 10-30
10-35
multipagina, finestre di
dialogo 9-16
multipiattaforma,
applicazioni 14-1 14-30
azioni 8-20
creazione 14-1
database 14-21 14-29
Internet 14-30
multi-tier 29-11
porting in Linux 14-2 14-21
multiple document interface 7-1
7-3
multi-read exclusive-write
synchronizer
avvertenze sulluso 11-9
MultiSelect, propriet 9-11
multi-thread, applicazioni 11-1
multithread, applicazioni
invio di messaggi 51-10
multi-tier, applicazioni 18-3,
18-13
architettura 29-4, 29-5
distribuzione 17-10
multipiattaforma 29-11
panoramica 29-3 29-4
parametri 27-30
relazioni master/
detail 29-19
Multitier, pagina (finestra di
dialogo New Items) 29-2
mutexes
CORBA 31-12
MyBase 27-35
MyEvent_ID, tipo 51-16
N
Name, propriet
campi 23-13
parametri 22-54, 22-55
voci di menu 5-6
namespace 45-14
interfacce richiamabili 36-3
nastri audio digitali 10-34
native tools API 58-2, 58-9
58-12
navigator
I n d i c e I-31
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
suggerimenti 19-34
navigatore 19-2, 19-31 19-34,
22-6
attivazione/disattivazione
dei pulsanti 19-32, 19-33
cancellazione dei dati 22-21
condivisione fra
dataset 19-34
editing 22-18
pulsanti 19-32
NDX, indici 24-7
.Net
Web Services 36-1
NetCLX 7-17
definizione 14-6
NetFileDir, propriet 24-25
Netscape Server DLL
creazione 33-1
neutral, modello di
threading 41-8 41-9
New Field, finestra di
dialogo 23-6
definizione dei campi 23-7,
23-9, 23-11
Field, propriet 23-6
Field, tipo 23-6
Lookup, definizione 23-7
Dataset 23-9
Key Fields 23-9
Lookup Keys 23-9
Result Field 23-10
New Items, finestra di
dialogo 7-25, 7-26, 7-27
New Thread Object, finestra di
dialogo 11-2
New Unit, comando 45-12
New, comando 45-12
newline, caratteri A-9
NewValue, propriet 24-40,
28-12
Next, metodo 22-7
NextRecordSet, metodo 22-57,
26-9
nodefault, parola chiave 47-8
nomi delle connessioni 26-4
26-6
nomi di driver 24-14
nomi di file
ricerca A-7
nomi di host 37-4
nomi di percorso
Linux 14-16
nomi host
indirizzi IP e 37-5
nomi, connessioni
cancellazione 26-5
definizione 26-5
modifica 26-6
non connesso, modello 18-15
non indicizzati, dataset 22-23
non modali, schede 8-5, 8-7
non visuali, componenti 45-5,
57-3
no-nonsense license
agreement 17-17
NOT NULL UNIQUE,
vincolo 28-13
NOT NULL, vincolo 28-13
note di rilascio 17-17
notificatori 58-3
API Tools
notificatori 58-19 58-23
scrittura 58-22
notifiche di sistema 51-11
51-16
NotifyID 7-30
NSAPI, applicazioni 32-7
creazione 33-1, 34-9
debug 32-11
messaggi di richiesta 33-2
null, caratteri A-9
NULL, macro A-8
NULL, puntatori A-8
null, valori
intervalli 22-33
numeri 47-2
internazionalizzazione 16-10
valori della propriet 47-12
NumericScale, propriet 22-48,
22-54, 22-55
numero di contesto (Help) 9-17
NumGlyphs, propriet 9-8
O
OAD 31-4, 31-14
.obj, file 15-2, 15-14
package 15-14
Object Activation Daemon
Vedere OAD
Object Broker 29-27
Object Inspector 5-2, 47-2, 52-7
editing di propriet
array 47-3
guida con 52-4
selezione di menu 8-41
Object Management Group
Vedere OMG
Object Pascal
modello a oggetti 13-1
Object Repository 7-25 7-28
aggiunta di elelementi 7-26
componenti database 24-17
specifica della directory
condivisa 7-26
utilizzo di elementi 7-26
7-27
wizard 58-4
Object Repository, finestra di
dialogo 7-25
Object Repository, wizard 58-4
Object, marcatore HTML
(<OBJECT>) 33-15
ObjectBroker, propriet 29-25,
29-26, 29-27
ObjectContext, propriet
Active Server Objects 42-3
esempio 44-16
Objects, propriet 9-18
elenchi di stringhe 4-20, 6-16
ObjectView, propriet 19-24,
22-39, 23-25
Occultamento di elementi e
categorie non utilizzati nelle
bande di azioni 8-24
.ocx, file 17-5
ODBC, driver
uso con ADO 25-1, 25-2
utilizzo con BDE 24-1
ODBC, drivers
utilizzo con BDE 24-16
ODL (Object Description
Language) 38-18
OEM, set di caratteri 16-3
OEMConvert, propriet 9-3
oggetti
Vedi anche COM, oggetti
argomenti delle
funzioni 13-8
copia 13-6
costruzione 13-8 13-13,
14-13
distribuiti 31-1
drag and drop 6-1
eredit 3-4 3-5
inizializzazione 10-14
posseduti 54-6 54-9
inizializzazione 54-7
scrip 34-35
senza stato 44-13
temporanei 50-6
TObject 3-6
volatili, accesso A-6
oggetti associati ai thread 11-5
oggetti Automation 38-13
oggetti campo 23-1 23-29
I-32 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
accesso ai valori 23-21
23-22
cancellazione 23-11
definizione 23-5 23-11
dinamici 23-2 23-3
e persistenti 23-2
eventi 23-16 23-17
persistenti 23-3 23-17
e dinamici 23-2
propriet 23-1, 23-11 23-16
in esecuzione 23-13
visualizzazione e modifica di
propriet 23-12
oggetti comando 25-17 25-20
oggetti contenuti 38-9
oggetti esterni 38-9
oggetti evento 11-10
oggetti grafici
thread 11-5
oggetti immagine 50-4
oggetti interni 38-9
oggetti posseduti 54-6 54-9
inizializzazione 54-7
oggetti richiesta
informazioni
dellheader 33-4
oggetti thread
definizione 11-2
inizializzazione 11-3
oggetti thread-safe 11-5
oggetti transazionali 38-11,
38-15 38-16, 44-1 44-30
amministrazione 38-16,
44-30
attivit 44-20 44-22
callback 44-28
caratteristiche 44-2 44-3
condivisione di connessioni
database 44-6
condivisione di
propriet 44-7 44-9
contesti di oggetto 44-4
creazione 44-18 44-22
debug 44-28 44-29
disattivazione 44-5
gestione delle risorse 44-3
44-10
installazione 44-29 44-30
interfacce duali 44-3
librerie di tipi 44-3
marshaling 44-3
requisiti 44-3
rilascio di risorse 44-9
senza stato 44-13
sicurezza 44-17 44-18
transazioni 44-5, 44-10
44-17
oggetto drag 6-4
OldValue, propriet 24-40,
28-12
OLE
combinazione di menu 8-44
contenitori 5-7
OLE DB 25-1, 25-2
OleFunction, metodo 40-15
OleObject, propriet 43-15,
43-16
OleProcedure, metodo 40-15
OlePropertyGet, metodo 40-15
OlePropertyPut, metodo 40-15
OLEView 38-20
OMG 31-1, 31-5
OnAccept, evento 37-8, 37-9
socket server 37-10
OnAction, event 33-8
OnAfterPivot, evento 20-10
OnBeforePivot, evento 20-9
OnBeginTransComplete,
evento 21-7, 25-8
OnCalcFields, evento 22-24,
23-7, 23-8, 27-11, 27-12
OnCellClick, evento 19-29
OnChange, evento 23-17, 50-7,
54-8, 55-13, 56-12
OnClick, evento 9-8, 48-1, 48-2,
48-5
menu 5-6
OnColEnter, evento 19-29
OnColExit, evento 19-29
OnColumnMoved,
evento 19-21, 19-29
OnCommitTransComplete,
evento 21-9, 25-8
OnConnect, evento 37-9
OnConnectComplete,
evento 25-8
OnConstrainedResize,
evento 8-5
OnDataChange, evento 19-4,
56-8, 56-11
OnDataRequest, evento 27-34,
28-3, 28-13
OnDblClick, evento 19-29, 48-5
OnDecisionDrawCell,
evento 20-13
OnDecisionExamineCell,
evento 20-13
OnDeleteError, evento 22-21
OnDisconnect, evento 25-8,
37-7, 37-8
OnDragDrop, evento 6-3, 19-29,
48-5
OnDragOver, evento 6-2, 19-29,
48-5
OnDrawCell, evento 9-18
OnDrawColumnCell,
evento 19-29
OnDrawDataCell, evento 19-29
OnDrawItem, evento 6-16
OnEditButtonClick,
evento 19-23, 19-29
OnEditError, evento 22-18
OnEndDrag, evento 6-3, 19-29,
48-5
OnEndPage, metodo 42-3
OnEnter, evento 19-30, 48-5
OnError, evento 37-8
OnExecuteComplete,
evento 25-8
OnExit, evento 19-30, 56-13
OnFilterRecord, evento 22-14,
22-16
OnGetData, evento 28-8
OnGetDataSetProperties,
evento 28-7
OnGetTableName,
evento 24-11, 27-23, 28-13
OnGetText, evento 23-16, 23-17
OnGetThread, evento 37-9
OnHandleActive, evento 37-9
OnHTMLTag, evento 29-42,
33-16, 33-17, 33-18
OnIdle, gestore evento 11-5
OnInfoMessage, evento 25-9
OnKeyDown, evento 19-30,
48-5, 51-13, 56-10
OnKeyPress, evento 19-30, 48-5,
51-13
OnKeyString, evento 51-13
OnKeyUp, evento 19-30, 48-5,
51-13
OnLayoutChange, evento 20-9
OnListening, evento 37-9
OnLogin, evento 21-5
OnMeasureItem, evento 6-15
OnMouseDown, evento 10-25,
10-26, 48-5, 51-13, 56-9
parametri passati a 10-25,
10-26
OnMouseMove, evento 10-25,
10-27, 48-5, 51-13
parametri passati a 10-25,
10-26
OnMouseUp, evento 10-15,
10-25, 10-26, 48-5, 51-13
I n d i c e I-33
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
parametri passati a 10-25,
10-26
OnNewDimensions,
evento 20-9
OnNewRecord, evento 22-19
OnPaint, evento 9-20
OnPassword, evento 24-14,
24-23
OnPopup, evento 6-12
OnPostError, evento 22-21
OnReceive, metodo 37-8, 37-10
OnReconcileError,
evento 14-29, 24-34, 27-22,
27-25
OnRefresh, evento 20-7
OnRequestRecords,
evento 29-37
OnRollbackTransComplete,
evento 21-9, 25-8
OnScroll, evento 9-5
OnSend, metodo 37-8, 37-10
OnSetText, evento 23-17
OnSetText,evento 23-16, 23-17
OnStartDrag, evento 19-30
OnStartPage, metodo 42-3
OnStartup, evento 24-18
OnStateChange, evento 19-5,
20-9, 22-4
OnSummaryChange,
evento 20-9
OnTerminate, evento 11-7
OnTitleClick, evento 19-30
OnTranslate, evento 30-7
OnUpdateData, evento 19-4,
28-8, 28-9
OnUpdateError, evento 14-29,
24-34, 24-39 24-41, 27-25,
28-12
OnUpdateRecord, evento 24-34,
24-38 24-39, 24-42, 24-48
OnValidate, evento 23-17
OnWillConnect, evento 21-5,
25-8
open array 13-17
temporanei 13-18
Open Tools API Vedere API
Tools
Open, metodo
componenti
connessione 21-3
dataset 22-4
query 22-50
sessioni 24-19
socket server 37-8
OPENARRAY, macro 13-19
OpenDatabase, metodo 24-19,
24-20
OpenSession, metodo 24-30
operatori
assegnazione 13-7
bitwise
integer con segno A-5
operazioni batch 24-8 24-9,
24-50 24-55
aggiornamento dati 24-52
aggiornamento dei
dati 24-52
aggiunta di dati 24-52
cancellazione di record 24-53
copia di dataset 24-52
database differenti 24-52
esecuzione 24-54
gestione degli errori 24-54
24-55
impostazione 24-50 24-51
mappatura dei tipi di
dati 24-53 24-54
modalit 24-8, 24-51
operazioni raster 50-7
Options, propriet 9-18
griglie dati 19-26
griglie decisionali 20-13
provider 28-5 28-6
TSQLClientDataSet 27-18
opzione del compilatore
allineamento A-6
opzioni
reciprocamente
esclusive 8-48
opzioni del compilatore 7-3
opzioni del linker
package 15-13
opzioni di progetto 7-3
predefinite 7-3
ora A-12
internazionalizzazione 16-10
ora, formati A-12
Oracle, driver
distribuzione 17-9
Oracle, tabelle 24-13
Oracle8
limiti sulla creazione di
tabelle 22-41
orario A-12
ORB 31-1, 31-6
inizializzazione 31-4
ORB_init 31-8
ORDER BY, clausola 22-27
ordinamento 16-10
dataset client 27-8
discendente 27-9
ore
inserimento 9-13
Orientation, propriet
griglie dati 19-31
track bar 9-6
Origin, propriet 10-29, 23-13
osagent 31-2, 31-3
ottimizzazione delle risorse di
sistema 45-4
out-of-process, server 38-7
ASP 42-7
output, parametri 22-53, 27-29
overload di procedure
registrate 24-13
Overload, propriet 24-13
Owner, propriet 45-17
owner-draw, controlli 4-21, 6-12
caselle di riepilogo 9-11, 9-12
dichiarazione 6-13
disegno 6-15, 6-16
domensionamento 6-15
OwnerDraw, propriet 6-13
P
pacchetti dati 30-4
a sola lettura 28-5
acquisizione 27-28 27-29,
28-8
aggiornamento dei record
aggiornati 28-6
controllo di campi 28-5
conversione in documenti
XML 30-1 30-8
copia 27-15 27-16
editing 28-8
garanzia di record unici 28-5
including field
properties 28-6
informazioni definite
dallapplicazione 27-16,
28-7
limitazione delle modifiche
del client 28-5
mappatura a documenti
XML 30-2
XML 29-31, 29-33, 29-36
modifica 29-37
recupero 29-36 29-37
pacchetti delta 28-8, 28-9
editing 28-8, 28-9 28-10
valutazione degli
aggiornamenti 28-11
XML 29-36, 29-37 29-38
package 15-1 15-16, 52-20
I-34 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
assegnazione del nome 15-10
caricate dinamicamente 15-4
compilazione 15-11 15-14
componenti 15-9, 52-20
creazione 7-10, 15-7 15-13
custom 15-5
di esecuzione 15-3 15-5,
15-8
di progettazione 15-5 15-7
direttive al
compilatore 15-12
distribuzione ad altri
sviluppatori 15-14
distribuzione di
applicazioni 15-14
DLL 15-1, 15-2, 15-12
editing 15-8
elenco Contains 15-7, 15-9,
15-11, 52-20
elenco Requires 15-7, 15-9,
15-10, 52-20
esecuzione 15-1
estensioni del nome del
file 15-1, 15-8, 15-13
file di opzioni del
progetto 15-9
file sorgenti 15-2, 15-8
impostazioni
predefinite 15-8
installazione 15-6 15-7
internazionalizzazione 16-11
, 16-13
mancanti 52-20
opzione per sola
progettazione 15-8
opzioni 15-8
opzioni del linker 15-13
packaging debole 15-12
progettazione 15-1
raccolte 15-15
riferimenti duplicati 15-11
uso in applicazioni 15-3
15-5
utilizzo 7-11
Package Collection Editor 15-15
package di esecuzione 15-1,
15-3 15-5
package di progettazione 15-1,
15-5 15-7
package, argomento 13-30
package, file 17-3
packaging debole 15-12
PacketRecords, propriet 14-29,
24-34, 27-28
page dispatcher 34-10, 34-37
Page, controlli 9-16
PageSize, propriet 9-6
pagina, controlli
aggiunta di pagine 9-16
pagina, moduli 34-2, 34-4 34-5
pagine di codice 16-3
pagine di login
WebSnap 34-28 34-30
pagine di propriet 43-14
43-16
aggiornamento 43-15
aggiornamento dei controlli
ActiveX 43-16
aggiunta di controlli 43-15
43-16
associazione a propriet di
un controllo ActiveX 43-15
controlli ActiveX 40-7, 43-3,
43-16
controlli importati 40-5
creazione 43-14 43-16
paint boxes 9-20
Paint, metodo 50-6, 54-9, 54-10
paintbox 5-7
PaintRequest, metodo 51-14
PaletteChanged, metodo 50-6,
51-15
PanelHeight, propriet 19-31
panels
beveled 9-20
Panels, propriet 9-17
PanelWidth, propriet 19-31
pannelli 9-7
aggiunta di pulsanti di scelta
rapida 8-47
associazione alla parte alta
delle schede 8-47
pulsanti di scelta rapida 9-8
ridimensionamento 9-7
pannelli rialzati 9-20
Paradox, tabelle 24-3, 24-5
accesso ai dati 24-9
aggiunta di record 22-20
assegnazione nuovo
nome 24-8
DatabaseName 24-3
directory 24-25
protezione con
password 24-22 24-24
recupero di indici 22-28
transazioni locali 24-33
ParamBindMode,
propriet 24-12
ParamByName, metodo
procedure registrate 22-55
query 22-48
ParamCheck, propriet 22-47,
26-12
Parameter collection,
editor 22-47, 22-54
Parameters, propriet 25-20
TADOCommand 25-20
TADOQuery 22-47
TADOStoredProc 22-53
parametri
classi come 46-11
da broker XML 29-37
dataset client 27-29 27-31
filtraggio di record 27-31
eventi del mouse 10-25,
10-26
gestori di evento 48-7, 48-8,
48-9
impostazione delle
propriet 47-7
propriet dellarray 47-9
input 22-53
input/output 22-53
interfacce duali 41-16
marcatori HTML 33-14
messaggi 51-4, 51-5, 51-7,
51-10
modalit di
inglobameento 24-12
output 22-53, 27-29
passaggio per
riferimento 48-3
risultato 22-53
TXMLTransformClient 30-10
parametri della transazione
livello di isolamento 21-11
parametri di connessione 24-15
ADO 25-4
dbExpress 26-4, 26-5
informazioni di login 21-5,
25-4
parametri facoltativi 28-7
ParamName, propriet 29-40
Params, propriet
dataset client 27-29, 27-30
procedure registrate 22-53
query 22-48
TDatabase 24-15
TSQLConnection 26-4
XML, broker 29-37
ParamType, propriet 22-48,
22-54
ParamValues, propriet 22-48
Parent, propriet 45-17
ParentColumn, propriet 19-26
I n d i c e I-35
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
ParentConnection,
propriet 29-30
ParentShowHint, propriet 9-17
parola riservata read 54-5
parole chiave 52-5
protected 48-5
parole chiave, help basati
su 7-33
parte query (URL) 32-4
pascalimplementation,
argomento 13-31
passthrough SQL 24-32
password
connessioni implicite e 24-14
tabelle dBASE 24-22 24-24
tabelle Paradox 24-22 24-24
PasteFromClipboard,
metodo 6-10
controlli memo data-
aware 19-10
grafici 19-10
PathInfo, propriet 33-6
.pce, file 15-15
Pen, propriet 10-4, 10-6, 50-3
penne 10-6, 54-6
cambio 54-8
colori 10-6
impostazioni
predefinite 10-6
modalit di disegno 10-30
ottenimento della
posizione 10-8
pennelli 10-5
posizione,
impostazione 10-8, 10-26
spessore 10-6
stile 10-7
pennelli 10-8 10-10, 54-6
cambio 54-8
colori 10-9
propriet delle bitmap 10-10
stili 10-9
PenPos, propriet 10-4, 10-8
penwin.dll 15-13
per utente, sottoscrizioni 40-17
percorsi (URL) 32-4
Perform, metodo 51-9
permessi sui file
Linux 14-15
perror, funzione A-11
persistenti, sottoscrizioni 40-17
personalizzazione dei
componenti 47-1
PickList, propriet 19-22, 19-23
Picture property
in frame 8-16
picture, oggetti 10-3
Picture, propriet 9-20, 10-18
Pie, metodo 10-5
pivot decisionali 20-10
comportamenti in
esecuzione 20-19
orientamento 20-10
propriet 20-10
pulsanti di dimensione 20-10
pixel
lettura e impostazione 10-10
Pixel, propriet 10-4, 50-3
Pixels, propriet 10-5, 10-10
pmCopy, costante 10-30
pmNotXor, costante 10-30
poligoni 10-12
disegno 10-12
Polygon, metodo 10-5, 10-12
PolyLine, metodo 10-5, 10-11
PopupMenu, componente 8-33
PopupMenu, propriet 6-11
Port, propriet 37-7
TSocketConnection 29-25
porte 37-5
connessioni multiple 37-5
servizi e 37-2
socket client 37-6, 37-7
socket server 37-7
porting del codice 14-17 14-21
porting di applicazioni
in Linux 14-2 14-21
Position, propriet 9-6, 9-17
position-independent code
(PIC) 14-9, 14-20
Post, metodo 22-21
Edit e 22-19
PostMessage, metodo 51-10
#pragma, package 52-20
Precision, propriet
campi 23-13
parametri 22-48, 22-54, 22-55
predefinita
classe antenato 46-4
predefinite
opzioni di progetto 7-3
predefiniti
gestori
eventi 48-9
ridefinizione 48-9
parametri 13-22
valori 19-11
valori della propriet
cambio 53-3, 53-4
valori delle propriet 47-7
specifica 47-12 47-13
predefinito
gestori
messaggio 51-4
Prepared, propriet
dataset unidirezionali 26-9
procedure registrate 22-56
query 22-50
pressione tasti, eventi 48-3, 48-9
Preview, pagina 34-2
primari, indici
operazioni batch e 24-52,
24-53
PRIMARY KEY, vincolo 28-14
principale, scheda 8-3
Prior, metodo 22-7
priorit
uso di thread 11-1, 11-3
Priority, propriet 11-3
private, propriet 47-5
PrivateDir, propriet 24-25
ProblemCount, propriet 24-54
ProblemTableName,
propriet 24-54, 24-55
procedure
assegnazione dei nomi 49-2
procedure registrate 18-5, 22-25,
22-52 22-57
basate su BDE 24-2, 24-12
24-13
inglobamento di
parametri 24-12
caricate in
sovrapposizione 24-13
creazione 26-11
dbExpress 26-8
elenco 21-15
esecuzione 22-56
parametri 22-53 22-56
da dataset client 27-31
in esecuzione 22-55
22-56
in progettazione 22-54
22-55
propriet 22-54 22-55
preparazione 22-56
specifica del database 22-52
ProcedureName,
propriet 22-52
processi lenti
uso di thread 11-1
processi parallelli
thread 11-1
produttori di contenuti 33-4,
33-14
I-36 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
gestione di eventi 33-16,
33-17, 33-18
produttori di pagine 33-14
33-18, 34-2, 34-4, 34-7, B-1
concatenamento 33-17
Content, metodo 33-15
ContentFromStream,
metodo 33-15
ContentFromString,
metodo 33-15
conversione modelli 33-16
data-aware 29-39 29-43,
33-19
gestione di eventi 33-16,
33-17, 33-18
modelli 34-4
tipi 34-11
produttori di tabelle 33-19
33-21
profondit dei colori 17-13
programmazione 17-15
progetti
aggiunta di schede 8-1 8-4
progetti, file
distribuzione 2-5
modifica 2-2
progetto, modelli 7-27
progetto, wizard 58-4
programmazione di modelli 7-3
programmazione object-
oriented 46-1 46-11
dichiarazione
metodi 46-10
dichiarazioni 46-3, 46-11
classi 46-5, 46-7, 46-8
Project Manager 8-3
Project Options, finestra di
dialogo 7-3
Project Updates, finestra di
dialogo 31-10
PROP_PAGE, macro 43-16
__property, parola chiave 13-27
Property Page, wizard 43-14
43-15
PROPERTYPAGE_IMPL
macro 43-15
Proportional, propriet 10-3
propriet 3-2, 47-1 47-14
a sola lettura 46-7, 46-8, 47-7,
56-3
a sola scrittura 47-7
accesso 47-5 47-7
aggiornamento 45-7
aggiunta a controlli
ActiveX 43-9 43-11
aggiunta a interfacce 41-10
array 47-3, 47-8, 47-9
cambio 52-7 52-13, 53-3,
53-4
caricamento 47-14
COM 38-3, 39-9
Write By Reference 39-9
come classi 47-2
componenti wrapper 57-4
dichiarazione 47-3, 47-3
47-7, 47-8, 47-13, 48-8, 54-4
tipi definiti
dallutente 54-4
editing
come testo 52-9
ereditate 47-3, 54-3, 55-3
eventi e 48-1, 48-2
finestre di dialogo
comuni 57-2
impostazione 5-2 5-3
interfacce COM 39-9
lettura di valori 52-9
nodefault 47-8
panoramica 45-6
preparazione della
guida 52-4
published 55-3
read e write 47-5
registrazione 47-13
registrazione e caricamento
di non pubblicate 47-14
47-16
registrazione interna dei
dati 47-4, 47-7
ridichiarazione 47-12, 48-5
scrittura di valori 47-7, 52-9
specifica di valori 47-12,
52-10
subcomponent 47-10
tabelle HTML 33-20
tipi 47-2, 47-9, 52-9, 54-4
valori predefiniti 47-7, 47-12
47-13
ridefinizione 53-3, 53-4
visualizzazione 52-9
propriet array 13-24
propriet, controlli memo e rich
edit 9-3
protected
direttiva 48-5
eventi 48-5
parola chiave 47-3, 48-5
sezione delle classi 46-7
protocolli
componenti
connessione 29-9 29-12,
29-24
connessioni di rete 24-16
Internet 32-3
scelta 29-9 29-12
protocollo
Internet 37-1
provider 28-14, 29-3
applicazione degli
aggiornamenti 28-4, 28-8,
28-11, 28-12
associazione a dataset 28-2
associazione con documenti
XML 28-2, 30-8
dataset client e 27-26 27-34
esterni 18-11, 27-20, 27-26,
28-2
eventi generati dal
client 28-13
fornitura dati a documenti
XML 30-9 30-11
gestione errori 28-12
interni 27-20, 27-26, 28-1
locali 27-27, 28-3
remoti 27-27, 28-3, 29-6
utiizzo di oggetti
update 24-11
valutazione degli
aggiornamenti 28-11
vincoli sui dati 28-13
XML 30-8 30-9
Provider, propriet 25-4
ProviderFlags, propriet 28-5,
28-11
ProviderName, propriet 18-13,
27-27, 28-3, 29-23, 29-37, 30-9
proxy 38-7, 38-8
interfacce di evento 40-6
oggetti transazionali 44-3
public
parola chiave 48-5
propriet 47-12
sezione delle classi 46-7
published 47-3
direttiva 47-3, 57-4
parola chiave 48-5
propriet 47-12, 47-13
esempio 54-3, 55-3
sezione delle classi 46-8
__published, parola
chiave 13-28
pulsanti 9-7 9-9
aggiunta alle barre
strumenti 8-47 8-49, 8-50
I n d i c e I-37
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
assegnazione di simboli 8-47
barre strumenti e 8-45
disattivazone sulle barre
strumenti 8-50
navigatore 19-31
pulsanti del mouse 10-25
clic 10-26
eventi di spostamento mouse
e 10-27
pulsanti di opzione 9-9, 19-2
data-aware 19-15
raggruppamento 9-14
selezione 19-15
pulsanti di scelta rapida 9-8
aggiunta alle barre
strumenti 8-47 8-49
assegnazione di simboli 8-47
centratura 8-47
gestori di evento 10-14
modi operativi 8-47
per strumenti di
disegno 10-14
raggruppamento 8-48 8-49
stato iniziale,
impostazione 8-48
utilizzo come
commutatori 8-48
pulsanti strumento 8-50
a capo 8-50
aggiunta di immagini 8-50
disattivazone 8-50
raggruppamento/
separazione 8-50
richiamo della guida 8-52
stato iniziale,
impostazione 8-50
su pi righe 8-50
utilizzo come
commutatori 8-51
puntatori
classi 46-11
conversione in integer A-5
dereferenziati 13-7
gestione delle eccezioni 12-5
implicazioni nella VCL 13-6
NULL A-8
tipi integer A-5
valori predefiniti delle
propriet 47-12
puntatori a classi 46-11
puntatori ad interfacce 38-5
puntatori di trascinamento 6-2
punti terminali
connessioni socket 37-6
puntini (...)
pulsanti nelle griglie 19-23
punto di aggancio 6-6
putenv, funzione A-11
PVCS Version Manager 2-5
Q
QApplication_postEvent,
metodo 51-16
QCustomEvent_create,
funzione 51-16
QEvent 51-13
QKeyEvent 51-13
QMouseEvent 51-13
QReport, pagina (Component
palette) 5-8
Qt widget
creazione 14-13
Qt, eventi
messaggi 51-15
quadrati, disegno 54-10
query 22-25, 22-43 22-52
applicazioni Web 33-21
basate su BDE 24-2, 24-9
24-12
concorrenti 24-18
set risultato live 24-10
24-11
cursor bidirezionali 22-51
cursor unidirezionali 22-51
esecuzione 22-50 22-51
eterogenee 24-9 24-10
filtraggio e 22-13
oggetti update 24-49 24-50
ottimizzazione 22-50, 22-51
parametri 22-46 22-49
con nome 22-46
da dataset client 27-31
impostazione in
esecuzione 22-48
impostazione in
progettazione 22-47
inglobamento 22-47
propriet 22-47 22-48
relazioni master/
detail 22-49 22-50
senza nome 22-46
parametrizzate 22-45
preparazione 22-50
relazioni master/
detail 22-49 22-50
set risultato 22-51
specifica 22-44 22-46, 26-6
26-7
specifica del database 22-44
tabelle HTML 33-21
Query Builder 22-46
query decisionali,
definizione 20-6
query eterogenee 24-9 24-10
Local SQL 24-9
query parametrizzate 22-45,
22-46 22-49
creazione
in esecuzione 22-48
in progettazione 22-47
Query, propriet
oggetti aggiornamento 24-49
QueryInterface, metodo 38-4
aggregazione 38-9
R
raccolte di package, file 15-15
raggruppamento di
componenti 9-14 9-16
RaiseException, funzione 12-13
RC, file 8-45
RDBMS 18-3, 29-1
RDSConnection,
propriet 25-17
Read, metodo
TFileStream 4-2
read, metodo 47-7
read, parola riservata 47-9
ReadBuffer, metodo
TFileStream 4-2
ReadCommitted 21-10
README 17-17
README, documento 17-17
ReadOnly, propriet 9-3, 56-3,
56-9, 56-10
campi 23-13
controlli data-aware 19-6
controlli memo data-
aware 19-9
controlli rich edit data-
aware 19-10
griglie dati 19-22, 19-28
tabelle 22-40
Real, tipo 13-24
Real48, tipo 13-24
realloc, funzione A-11
ReasonString, propriet 33-12
rebar 8-45, 8-51
ReceiveBuf, metodo 37-8
Receiveln, metodo 37-8
RecNo, propriet
dataset client 27-2
Reconcile, metodo 14-29, 24-34
record
acquisizione 27-28 27-29
I-38 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
aggiornamento 19-7, 22-22
22-23, 24-8, 24-52, 27-33,
28-8, 29-37 29-38
da documenti XML 30-10
30-11
dataset client 27-21
27-26
identificazione di
tabelle 28-12
multiple 28-6
operazioni batch 24-8
pacchetti delta 28-8, 28-9
query e 24-11
valutazione degli
aggiornamenti 28-11
aggiunta 22-19 22-20,
22-23, 24-8, 24-52
cancellazione 22-20 22-21,
22-42 22-43, 24-8, 24-53
operazioni batch 24-8
conferma 22-21 22-22
alla chiusura del
dataset 22-22
contrassegno 22-9 22-11
copia 24-8, 24-52
operazioni batch 24-8
criteri di ricerca 22-11, 22-12
filtraggio 22-13 22-16
inoltro 19-6
griglie dati 19-28
iterazione tra 22-8
operazioni 24-8
operazioni batch 24-8, 24-52,
24-53
ordinamento 22-27 22-29
prelievo 26-8 26-9
asincrono 25-11 25-12
ricerca 22-11 22-13, 22-29
22-31
riconciliazione degli
aggiornamenti 27-25
ripetizione della
ricerca 22-31
sincronizzazione del
corrente 22-43
spostamento tra 19-31, 22-5
22-9, 22-17
Type Library editor 39-11,
39-18
visualizzazione 19-30
RecordCount, propriet
TBatchMove 24-54
RecordSet, propriet 25-20
RecordsetState, propriet 25-10
RecordStatus, propriet 25-12,
25-14
Rectangle, metodo 10-5, 10-12,
50-3
Refresh, metodo 19-7, 27-33
RefreshLookupList,
propriet 23-10
RefreshRecord, metodo 27-33,
28-4
register
oggetti e A-5
Register, metodo 10-3
Register, procedura 52-2
RegisterComponents,
funzione 45-14
RegisterComponents,
procedura 15-6, 52-2
RegisterConversionType,
funzione 4-28, 4-29
RegisterHelpViewer 7-38
RegisterNonActiveX,
procedura 43-3
RegisterPooled, flag 29-9
RegisterPropertyEditor,
funzione 52-12
RegisterTypeLib,
funczione 38-19
RegisterViewer, funzione 7-34
registrazione
Active Server Objects 42-8
componenti 45-14, 45-15
controlli ActiveX 43-16
43-17
editor di componenti 52-19
editor di propriet 52-12
52-13
famiglie di conversione 4-28
interfacce CORBA 31-13
oggetti COM 41-17 41-18
registrazione di oggetti
Help 7-34
registro dei tipi remotable 36-5,
36-15
registro delle chiamate 36-3,
36-13
creazione di classi
richiamabili 36-13
registro delle modifiche 27-5,
27-21, 27-36
salvataggio delle
modifiche 27-7
registro modifiche
annullamento delle
modifiche 27-6
Registry 16-10
regole di gestione 29-2, 29-13
ASP 42-1
oggetti transazionali 44-2
REGSERV32.EXE 17-5
relazionali, database 18-1
relazioni uno-a-molti 22-37,
26-12
Release 7-31
Release, metodo 38-4
TCriticalSection 11-8
remotable, classi 36-4, 36-7
36-10
eccezioni 36-15 36-16
esempio 36-9 36-10
gestione della durata 36-8
native 36-8
registrazione 36-5
Remote Data Module,
wizard 29-14 29-15
remote data modules 7-25
Remote Database Management
system 18-3
remote, connessioni
apertura 37-7
interruzione 37-8
multiple 37-5
REMOTEDATAMODULE_IMP
L, macro 29-5
RemoteHost, propriet 37-6
RemotePort, propriet 37-6
RemoteServer, propriet 27-27,
29-23, 29-28, 29-34, 29-36, 30-9
remoti, server di database 18-3
RemoveAllPasswords,
metodo 24-23
RemovePassword,
metodo 24-23
RenameFile, funzione 4-9, 4-10
repainting controls 54-8
RepeatableRead 21-10
reperimento dati
incrementale 27-28, 29-20
report 18-17
Repository
Vedere Object Repository
Request for Comment (RFC),
documenti 32-3
RequestLive, propriet 24-10
RequestRecords, metodo 29-37
Requires, elenco (package) 15-7,
15-9, 15-10, 52-20
.res, file 45-16
ResetEvent, metodo 11-11
resizing controls 17-13
I n d i c e I-39
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
ResolveToDataSet,
propriet 28-4
Resource DLLs
alternanza dinamica 16-12
wizard 16-11
resourcestring, macro 13-22
RestoreDefaults, metodo 19-24
restrizioni A-1
Result, parametro 51-7
Resume, metodo 11-12
reti
connessione a
database 24-16
strato di comunicazione 31-2
reti locali 31-3
rettangoli
disegno 10-11, 54-10
rettangoli arrotondati 10-12
rettangoli di contorno 10-12
ReturnValue, propriet 11-10
RevertRecord, metodo 14-29,
24-34, 27-6
RFC, documenti 32-3
ricerca di file A-7
ricerca incrementale 19-11
ricerche basate su indice 22-29
22-31
ricerche basate su indici 22-12,
22-13
rich edit, controlli 9-3
rich text, controlli 6-7, 19-10
richiamabili, interfacce 36-2
36-10
richieste
adapter 34-38
immagini 34-40
indirizzamento 34-36
richieste dei client 33-9
richieste del client 32-5 32-7
ridefinizione
metodi 51-4, 51-5, 55-13
metodi virtuali 13-11
ridimensionamento dei
controlli 55-4
grafici 50-7
ridimensionamento di
controlli 9-7
riferimenti
a schede 8-3
C++ e Object Pascal 13-6
riferimenti circolari 8-4
riferimenti sicuri 44-27
riferimento a oggetto 13-6
riferimento, campi
visualizzazione 19-26
righe 9-17
griglie decisionali 20-12
rilascio dei pulsanti del
mouse 10-26
rilocabile, codice 14-20
risoluzione 28-1, 29-4
risorse 45-8, 50-1
assegnazione dei nomi 52-4
isolamento 16-10
localizzazione 16-11, 16-13
memorizzazione in
cache 50-2
sistema, ottimizzazione 45-4
stringhe 16-11
risorse, file 8-45
caricamento 8-45
risposte
adapter 34-38
azioni 34-39
immagini 34-40
risposte di azioni 34-39
risposte HTTP
azioni 34-39
risultato, parametri 22-53
ritenzione degli
annullamenti 25-6
ritenzione delle modifiche 25-6
ritracciamento dei
controlli 54-10, 55-4, 55-5
ritracciamento di immagini 50-7
Rollback, metodo 21-9
RollbackTrans, metodo 21-9
root, directory
Linux 14-16
RoundRect, metodo 10-5, 10-12
routine
terminate con null 4-25
4-26
routine globali 4-1
RowAttributes, propriet 33-20
RowCount, propriet 19-14,
19-31
RowHeights, propriet 6-15,
9-18
RowRequest, metodo 28-4
Rows, propriet 9-18
RowsAffected, propriet 22-51
RPC 38-9
RTTI 46-8
C++ e Object Pascal 13-23
interfacce richiamabili 36-2
S
safe array 39-13
safe, puntatori
gestione delle eccezioni 12-5
SafeArray 39-13
SafeRef, metodo 44-27
Samples, pagina (Component
palette) 5-8, 5-9
Save as Template, comando
(Menu designer) 8-40, 8-43
Save Attributes, comando 23-14
Save Template, finestra di
dialogo 8-43
SaveConfigFile, metodo 24-26
SavePoint, propriet 27-6
SaveToFile, metodo 10-21
dataset ADO 25-15
dataset client 18-10, 27-37
elementi grafici 50-4
stringhe 4-16
SaveToStream, metodo
dataset client 27-37
scalabilit 18-11
ScanLine, propriet
esempio con bitmap 10-19
scheda, file 14-2
scheda, wizard 58-4
schede 8-1
aggiunta a progetti 8-1 8-4
aggiunta di campi 10-27
10-29
aggiunta di riferimenti a
unit 8-3
collegamento 8-3
come componenti 57-1
condivisione di gestori di
evento 10-16
creazione in esecuzione 8-6
drill down 19-16
gestione della memoria 8-5
interrogazione di propriet
esempio 8-9
modali 8-5
non modali 8-5, 8-7
ottenimento di dati 8-9
8-12
passaggio di argomenti a 8-8
principale 8-3
referenziazione 8-3
sincronizzazione dei
dati 19-4
tabelle master/detail 19-16
uso di variabili locali per
creare 8-7
variabile globale per 8-6
visualizzazione 8-6
schede, linking 8-3
schermo
I-40 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
aggiornamento 10-2
risoluzione 17-13
programmazione 17-13
ScktSrvr.exe 29-10, 29-14, 29-25
SCM 7-5
scorciatoie di tastiera
aggiunta a menu 8-36 8-37
Screen, variabile 8-2, 16-9
script
active 34-34
generazione in
WebSnap 34-35
modifica e
visualizzazione 34-35
URL 32-4
script di login 21-4 21-6
script per Web 34-8
script, oggetti 34-35
scripting 34-8
scripting lato server 34-8, 34-33
34-36, B-1 B-39
esempi JScript B-19 B-39
oggetti globali B-14 B-19
tipi di oggetti B-2 B-14
ScrollBars, propriet 6-8, 9-18
controlli memo data-
aware 19-9
SDI, applicazioni 7-1 7-3
Sections, propriet 9-16
Seek, metodo
dataset ADO 22-29
segmenti consecutivi di
linee 10-11
segnalazione di eventi 11-10
segnali
Linux 14-15
risposta (CLX) 51-11 51-12
segnalibri 22-9 22-11
filtraggio di record 25-11
segni diacritici 16-10
Select Menu, comando (Menu
designer) 8-40, 8-41
Select Menu, finestra di
dialogo 8-41
SELECT, istruzioni 22-44
SelectAll, metodo 9-4
SelectCell, metodo 55-14, 56-4
Selection, propriet 9-18
SelectKeyword 7-34
SelEnd, propriet 9-6
selettori
Help 7-35
Selezione 34-11
SelLength, propriet 6-9, 9-3
SelStart, propriet 6-9, 9-3, 9-6
SelText, propriet 6-9, 9-3
SendBuf, metodo 37-8
Sender parameter 5-5
Sender, parametro
esempio 10-7
Sendln, metodo 37-8
SendMessage, metodo 51-10
SendStream, metodo 37-8
sensibilit maiuscole/minuscole
identificatori esterni e A-3
Linux 14-14
soppressione A-3
separatori
eventi draw-item 6-16
separatori dei notebook 9-15
sequenza di collazione A-2
sequenza di ordinamento
TSQLTable 26-7
sequenze di escape
file sorgenti A-7
server
Internet 32-1 32-12
Web application
debugger 34-9
server di applicazioni
basati su COM 29-17, 29-22
basato su COM 29-5
server di database
connessione 18-8 18-9
vincoli 23-22, 23-23, 28-13
server in-process 38-7
ActiveX 38-14
ASP 42-7
MTS 44-2
server remoti 24-9, 38-7
accesso non autorizzato 21-4
maintenimento delle
connessioni 24-19
server Web 29-32, 42-7
richieste del client e 32-6
server Web, applicazioni
ASP 42-1
server, applicazioni
CORBA 31-2, 31-4 31-14
registrazione 31-13 31-14
OAD 31-4
server, socket
oggetti socket 37-7
ServerGUID, propriet 29-24
ServerName, propriet 29-24
Servers, pagina (Component
palette) 5-8, 5-9
Service Control Manager 7-5,
7-9
Service Start name 7-9
servizi 7-4 7-9
API Tools 58-2, 58-8 58-14
codice di esempio 7-5, 7-7
CORBA 31-1
directory 31-2, 31-3
disinstallazione 7-5
esempio 7-7
implementazione 37-1
37-2, 37-7
installazione 7-5
Name, propriet 7-9
porte e 37-2
richiesta 37-6
server di rete 37-1
servizio per le sessioni 34-28
servizio, thread di 7-7
Session, variabile 24-3, 24-17
sessioni 24-17 24-31
apertura di
connessioni 24-20
applicazioni multi-
thread 24-13, 24-29 24-31
applicazioni Web 33-18
assegnazione dei nomi 33-19
assegnazione del nome 24-29
attivazione 24-18 24-19
chiusura 24-19
chiusura delle
connessioni 24-20
connessione predefinita,
propriet 24-19
connessioni implicite a
database 24-13
creazione 24-28 24-29,
24-30
database associati 24-21
24-22
database e 24-13 24-14
dataset e 24-3 24-4
gestione alias 24-25
gestione delle
connessioni 24-20 24-22
metodi 24-14
multiple 24-13, 24-28, 24-29
24-31
ottenimento di
informazioni 24-27 24-28
password 24-22
predefinite 24-3, 24-13, 24-17
24-18
riavvio 24-19
stato attuale 24-18
SessionName, propriet 24-3,
24-4, 24-13, 24-29, 24-30, 33-19
sessions service 34-11, 34-27
I n d i c e I-41
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
Sessions, propriet 24-30
Sessions, variabile 24-18, 24-30
set 47-2
set di caratteri 4-21, 16-2, 16-2
16-4, A-2, A-4
ANSI 16-3
conversioni multibyte 16-3
costanti A-7
estesi A-2
mappatura A-4
multibyte 16-3
OEM 16-3
ordinamenti
internazionali 16-10
predefiniti 16-2
verifica A-8
set di tab 9-15
SetAbort, metodo 44-5, 44-9,
44-14
SetBrushStyle, metodo 10-9
SetComplete, metodo 29-18,
44-5, 44-9, 44-14
SetData, metodo 23-18
SetEvent, metodo 11-10
SetFields, metodo 22-22
SetFloatValue, metodo 52-9
SetKey, metodo 22-29
EditKey e 22-31
SetMethodValue, metodo 52-9
SetOptionalParam,
metodo 27-16
SetOrdValue, metodo 52-9
SetPenStyle, metodo 10-7
SetProvider, metodo 27-27
SetRange, metodo 22-34
SetRangeEnd, metodo 22-33
SetRange e 22-34
SetRangeStart, metodo 22-32
SetRange e 22-34
SetSchemaInfo, metodo 26-13
SetStrValue, metodo 52-9
SetUnhandledExceptionFilter,
funzione 12-7
SetValue, metodo 52-9, 52-10
sezioni critiche 11-8
avvertenze sulluso 11-8,
11-9
sfondi 16-10
sfondi trasparenti 16-10
sgancio di controlli 6-7
Shape, propriet 9-20
shared object files Vedere .so, file
Shared Property Manager 44-7
44-9
esempio 44-7 44-9
shell, script
Linux 14-14
Shift, stati 10-25
ShortCut, propriet 8-37
Show, metodo 8-6, 8-8
ShowAccelChar, propriet 9-4
ShowButtons, propriet 9-13
ShowColumnHeaders,
propriet 9-13
ShowFocus, propriet 19-31
ShowHint, propriet 9-17, 19-34
ShowHintChanged,
metodo 51-15
ShowLines, propriet 9-13
ShowModal, metodo 8-6
ShowRoot, propriet 9-13
ShutDown 7-30, 7-31
sicurezza
applicazioni multi-tier 29-2
connessioni SOAP 29-26
connessioni Web 29-11,
29-26
database 18-4, 21-4 21-6,
24-22 24-24
DCOM 29-35
moduli dati
transazionali 29-7, 29-10
oggetti transazionali 44-17
44-18
registrazione di connessioni
socket 29-10
tabelle locali 24-22 24-24
sicurezza basata sul ruolo 44-17
signal, funzione A-9
Simple Object Access Protocol
Vedi SOAP
sincronizzatore multilettura a
scrittura esclusiva 11-9
sincronizzazione dei dati
su pi schede 19-4
sincronizzazione delle
chiamate 44-21 44-22
single document interface 7-1
7-3
single-tier, applicazioni 18-9,
18-13
basate su file 18-10
sistemi di Guida 52-4
file 52-5
parole chiave 52-5
pulsanti strumento 8-52
Size, propriet
campi 23-13
parametri 22-48, 22-54, 22-55
sizeof, operatore 13-18, A-7
skeleton 31-2, 31-2 31-3, 31-6
31-7
delega 31-9
marshaling 31-3
Smart Agents 31-2, 31-3
ubicazione 31-3
smistatore free-threaded 41-7
.so, file 14-9, 14-15
SOAP 36-1
applicazioni multi-tier 29-11
connessione a server di
applicazioni 29-26
connessioni 29-11, 29-26
moduli dati 29-6
pacchetti di errore 36-15
wizard di applicazioni 36-11
SOAP Data Module
wizard 29-16 29-17
socket 37-1 37-11
accettazione richieste del
client 37-3
assegnazione host 37-4
descrizione 37-3
fornitura di
informazioni 37-4
gestione degli errori 37-8
gestione di eventi 37-8
37-10
implementazione di
servizi 37-1 37-2, 37-7
indirizzi di rete 37-3, 37-4
lettura da 37-10
lettura/scrittura 37-10
37-11
scrittura su 37-10
socket client 37-3, 37-6 37-7
assegnazione host 37-4
connessione a server 37-9
gestione di eventi 37-9
identificazione dei
server 37-6
messaggi di errore 37-8
propriet 37-6
richiesta di servizi 37-6
socket dispatcher,
applicazione 29-14, 29-25
socket server 37-7 37-8
accettazione delle richieste
del client 37-7, 37-9
gestione di eventi 37-9
messaggi di errore 37-8
specifica 37-6
socket, componenti 37-5 37-8
socket, oggetti 37-6
client 37-6
I-42 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
socket client 37-6
socket server 37-7
SoftShutDown 7-30
sola lettura
campi 19-6
dataset,
aggiornamento 18-11
propriet 46-7, 46-8, 47-7,
56-3
tabelle 22-40
sola scrittura, propriet 47-7
sollevamento di eccezioni 12-13
sorgenti dati 18-7, 19-3 19-5
attivazione 19-4
disattivazione 19-4
eventi 19-4 19-5
sorgenti decisionali 20-9 20-10
eventi 20-9
propriet 20-9
Sorted, propriet 9-11, 19-12
SortFieldNames, propriet 26-7
sottomenu 8-37
SourceXmlDocument,
propriet 30-7
SourceXmlFile, propriet 30-6
Spacing, propriet 9-8
SparseCols, propriet 20-9
SparseRows, propriet 20-9
specificatori di classe storage
register A-5
spezzate 10-10, 10-11
disegno 10-10
spin edit, controlli 9-6
SPX/IPX 24-16
SQL 18-3, 24-9
esecuzione di comandi 21-11
21-12
locale 24-9
standard 28-13
Decision Query editor
e 20-7
SQL Builder 22-46
SQL Explorer 24-56, 29-3
definizione dei set di
attributi 23-14
SQL Links 17-8, 24-1
distribuzione 17-9, 17-17
driver 24-9, 24-16, 24-32
file driver 17-9
requisiti di licenza 17-17
SQL Monitor 24-57
SQL, dataset client 27-23 27-25
SQL, istruzioni
dataset decisionale 20-5
esecuzione 26-9 26-11
fornite dal client 27-34, 28-6
generati dal provider 28-12
generazione
provider 28-4, 28-10
28-11
TSQLDataSet 26-9
oggetti update and 24-42
24-46
parametri 21-12
passthrough SQL 24-32
SQL, passthrough 24-31
SQL, propriet 22-45 22-46
cambio 22-50
SQL, query 22-44 22-46, 44-13
caricamento da file 22-46
copia 22-46
esecuzione 22-50 22-51
modifica 22-45
oggetti di
aggiornamento 24-48
ottimizzazione 22-51
parametri 22-46 22-49,
24-44 24-45
impostazione in
esecuzione 22-48
impostazione in
progettazione 22-47
inglobamento 22-47
relazioni master/
detail 22-49 22-50
preparazione 22-50
set risultato 22-51
SQL, server
login a 18-4
SQLConnection, propriet 26-3,
26-18
SQLPASSTHRUMODE 24-32
stampa 4-26
stampanti A-3
standard, componenti 5-7 5-9
standard, eventi 48-4
personalizzazione 48-6
Standard, pagina (Component
palette) 5-7
StartTransaction, metodo 21-7
State, propriet 9-9
colonne della griglia 19-17
dataset 22-3, 23-9
griglie 19-17, 19-20
StatusCode, propriet 33-12
StatusFilter, propriet 14-29,
24-34, 25-12, 27-6, 27-21, 28-9
StdConvs, unit 4-27, 4-28, 4-30
Step, propriet 9-17
StepBy, metodo 9-17
StepIt method 9-17
StoredProcName,
propriet 22-52
StrByteType 4-23
stream 4-2
copia di dati 4-3
dimensioni 4-3
lettura e scrittura dati 4-2
posizione 4-3
ricerca 4-3
supporto di
memorizzazione 4-3
stream binari
caratteri null e A-9
stream di file 4-5 4-7
apertura 4-6
cambio della dimensione 4-4
creazione 4-6
eccezioni 4-2
I/O su file 4-5 4-7
ottenimento di un
handle 4-10
portabile 4-5
segnale di fine stream 4-4
strerror, funzione A-12
Stretch, propriet 19-10
StretchDraw, metodo 10-5, 50-3,
50-7
String List editor
visualizzazione 19-11
stringhe 4-21, 47-2, 47-8
associazione a elementi
grafici 6-14
conversioni a 2 byte 16-3
dichiarazione e
inizializzazione 4-26
dimensioni 6-9
modelli HTML 33-15
modifica permanente A-11
ordinamento 16-10
posizione iniziale 6-9
restituzione 47-9
routine
della libreria
runtime 4-21
differenze maiuscole/
minuscole 4-22
supporto dei caratteri
multi-byte 4-23
terminate con null 4-25
4-26
trasformazione 16-2, 16-8,
16-10
troncamento 16-3
stringhe di risorse 13-21
I n d i c e I-43
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
Strings, propriet 4-19
StrNextChar, funzione
Linux 14-18
Structured Query Language
vedi SQL
strumenti di disegno 50-7, 54-6
assegnazione come
predefinito 8-48
cambio 54-8
controllo di 10-13
gestione di pi strumenti in
applicazioni 10-13
modifica 10-14
strumenti di traduzione 16-1
strutture A-6
stub 31-2 31-3, 31-6 31-7,
31-15 31-16
COM 38-8
marshaling 31-3
oggetti transazionali 44-3
variabili globali 31-16
Style, propriet 6-13, 9-11
caselle combinate 9-12, 19-12
caselle di riepilogo 9-11
penne 10-6
pennelli 9-20, 10-9
pulsanti strumento 8-50
Web item 29-41
StyleChanged, metodo 51-15
StyleRule, propriet 29-41
Styles
TApplication 14-6
Styles, propriet 29-41
StylesFile, propriet 29-41
subcomponenti
propriet 47-10
subscriber, oggetti 40-16 40-17
Subtotals, propriet 20-13
suggerimenti 9-17, 19-34
suporto tecnico 1-3
SupportCallbacks,
propriet 29-18
supporto al login
WebSnap 34-26 34-33
supporto allinstallazione 1-3
supporto allo sviluppo 1-3
supporto decisionale,
componenti 18-16, 20-1 20-21
assegnazione dei dati 20-5
20-7
gestione della
memoria 20-20
runtime 20-19 20-20
supporto, opzioni 1-3
Suspend, metodo 11-12
sviluppo, supporto 1-3
switch, istruzioni
valori case A-7
Sybase, driver
distribuzione 17-10
Synchronize, metodo 11-5
system resources,
conserving 45-4
System, pagina (Component
palette) 5-7
T
tab, controlli 9-15
owner-draw 6-12
tabelle 22-24, 22-26 22-43
a sola lettura 22-40
annidate 22-38 22-39
basate su BDE 24-2, 24-5
24-9
aggiornamento di
record 24-8
aggiornamento
record 24-8
aggiunta di record 24-8
blocchi esclusivi 24-6
cancellazione di
record 24-8
chiusura 24-5
collegamento 24-5
copia di record 24-8
copia record 24-8
diritti di accesso 24-6
operazioni batch 24-8
24-9
ricerche basate su
indice 22-29
cancellazione 22-42
creazione 22-40 22-42
campi persistenti 22-41
indici 22-41
dbExpress 26-7 26-8
definizione 22-40 22-41
definizione di campi e indici
precaricamento 22-41
definizioni di campi e
indici 22-40, 22-41
elenco 21-14
griglie non-database 9-17
indici 22-27 22-39
inserimento di record 22-19
22-20, 22-23
intervalli 22-32 22-36
ordinamento 22-27, 26-7
relazioni master/
detail 22-36 22-39
ricerca 22-29 22-31
sincronizzazione 22-43
specifica del database 22-26
svuotamento 22-42 22-43
visualizzazione in
griglie 19-18
tabelle annidate 22-38 22-39,
23-27 23-28, 29-20
tabelle dBASE
accesso ai dati 24-9
aggiunta di record 22-20
tabelle detail annidate
acquisizione su
richiesta 28-6
tabelle Paradox
operazioni batch 24-55
tabelle problem 24-54
Table, marcatore HTML (</
TABLE>) 33-15
TableAttributes,
propriet 33-20
TableName, propriet 22-40,
26-7
TableOfContents 7-34
TableType, propriet 22-40,
24-5 24-6
Tabs, propriet 9-15
TabStopChanged,
metodo 51-15
TAction 8-22
TActionClientItem 8-24
TActionList 8-20, 8-21
TActionMainMenuBar 8-18,
8-19, 8-20, 8-21, 8-23, 8-24
TActionManager 8-18, 8-20,
8-21
TActionToolBar 8-18, 8-19, 8-20,
8-21, 8-23
TActiveForm 43-3, 43-6
TAdapterDispatcher 34-37
TAdapterPageProducer 34-35
TADOCommand 25-2, 25-7,
25-9, 25-17 25-20
TADOConnection 18-9, 21-1,
25-2, 25-2 25-9, 25-10
connessione a datastore 25-3
25-5
TADODataSet 25-2, 25-9, 25-16
25-17
TADOQuery 25-2, 25-9
SQL command 25-17
TADOStoredProc 25-2, 25-9
TADOTable 25-2, 25-9
Tag, propriet 23-13
TApplication 7-29, 7-36
I-44 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
Styles 14-6
Tapplication
eventi di sistema 51-13
TApplicationEvents 8-2
TASM, codice
Linux 14-18
TASPObject 42-2
tasti acceleratori 9-6
TAutoDriver 40-6, 40-14
tavolozze 50-5 50-6
comportamento
predefinito 50-6
specifica 50-5
TBatchMove 24-50 24-55
gestione degli errori 24-54
24-55
TBCDField
formattazione
predefinita 23-16
TBDEClientDataSet 24-2
TBDEDataSet 22-2
TBevel 9-20
TBitmap 50-4
TBrush 9-20
tbsCheck, costante 8-50
TByteDynArray 36-4
TCalendar 55-1
TCanvas
utilizzo 4-21
TCharProperty, tipo 52-8
TClassProperty, tipo 52-8
TClientDataSet 27-20
TClientDataset 7-24
TClientSocket 37-6
TColorProperty, tipo 52-8
TComInterface 40-6, 40-14
TComponent 3-4, 3-7, 45-5
definizione 3-5
interfacce 13-4, 13-5
TComponentClass 45-14
TComponentProperty, tipo 52-8
TControl 3-8, 45-4, 48-5
definizione 3-5
TConvType values 4-28
TConvTypeInfo 4-32
TCoolBand 9-10
TCoolBar 8-46
TCP/IP 24-16, 37-1
applicazioni multi-tier 29-10
29-11
client 37-6
connessione allapplication
server 29-25
server 37-7
TCRemoteDataModule 29-14,
29-15
TCurrencyField
formattazione
predefinita 23-16
TCustomADODataSet 22-2
TCustomClientDataSet 22-2
TCustomContentProducer 33-1
4
TCustomControl 45-4
TCustomEdit 14-8
TCustomGrid 55-1, 55-3
TCustomIniFile 4-12
TCustomizeDlg 8-24
TCustomListBox 45-3
TDatabase 18-8, 21-1, 24-3,
24-17
DatabaseName,
propriet 24-3
istanze temporanee 24-21
interruzione 24-21
TDataSet 22-1
discendenti 22-2 22-3
TDataSetProvider 28-1, 28-2
TDataSetTableProducer 33-21
TDataSource 19-3 19-5
TDateField
formattazione
predefinita 23-16
TDateTime, tipo 55-6
TDateTimeField
formattazione
predefinita 23-16
TDBChart, componente 18-16
TDBCheckBox 19-2, 19-14
19-15
TDBComboBox 19-2, 19-11,
19-11 19-12
TDBCtrlGrid 19-3, 19-30 19-31
propriet 19-31
TDBEdit 19-2, 19-9
TDBGrid 19-2, 19-16 19-30
eventi 19-29
propriet 19-22
TDBGridColumns 19-17
TDBImage 19-2, 19-10 19-11
TDBListBox 19-2, 19-11, 19-11
19-12
TDBLookupComboBox 19-2,
19-11, 19-12 19-14
TDBLookupListBox 19-2, 19-11,
19-12 19-14
TDBMemo 19-2, 19-9 19-10
TDBNavigator 19-2, 19-31
19-34, 22-6
TDBRadioGroup 19-2, 19-15
TDBRichEdit 19-3, 19-10
TDBText 19-2, 19-8 19-9
TDCOMConnection 29-24
TDecisionCube 20-1, 20-5, 20-7
20-9
eventi 20-7
TDecisionDrawState 20-13
TDecisionGraph 20-1, 20-2,
20-13 20-19
TDecisionGrid 20-1, 20-2, 20-11
20-13
eventi 20-13
propriet 20-12
TDecisionPivot 20-1, 20-2, 20-10
propriet 20-10
TDecisionQuery 20-1, 20-5, 20-6
TDecisionSource 20-1, 20-9
20-10
eventi 20-9
propriet 20-9
TDefaultEditor 52-16
TDependency_object 7-9
TDragObject 6-4
TDragObjectEx 6-4
TDrawingTool 10-13
TEdit 9-1
temporanei, file A-11
temporanei, oggetti 50-6
TEnumProperty, tipo 52-8
terminate con null, routine 4-25
4-26
terminate, funzione 12-5
Terminate, metodo 11-6
Terminated, propriet 11-6
testo
cancellazione 6-10
controlli owner-draw 6-12
copia, taglia, incolla 6-9
in controlli 6-7
internazionalizzazione 16-9
lettura da destra a
sinistra 16-6
operazioni con 6-7 6-12
ricerca di 9-3
selezione 6-9, 6-9
stampa 9-3
testo statico, controllo 9-4
testo, stream A-9
TEvent 11-10
TEventDispatcher 40-15
Text, propriet 9-3, 9-12, 9-17
TextChanged, metodo 51-15
TextHeight, metodo 10-5, 50-3
TextOut, metodo 10-5, 50-3
I n d i c e I-45
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
TextRect, metodo 10-5, 50-3
TextWidth, metodo 10-5, 50-3
TField 22-1, 23-1 23-29
eventi 23-16 23-17
metodi 23-17 23-18
propriet 23-1, 23-11 23-16
in esecuzione 23-13
TFieldDataLink 56-5
TFiler 4-3
TFileStream 4-2, 4-5
I/O su file 4-5 4-7
TFloatField
formattazione
predefinita 23-16
TFloatProperty, tipo 52-8
TFMTBcdField
formattazione
predefinita 23-16
TFontNameProperty, tipo 52-9
TFontProperty, tipo 52-9
TForm
propriet della barra di
scorrimento 9-5
TFrame 8-14
TGraphic 50-4
TGraphicControl 45-4, 54-3
THandleComponent 51-12
THeaderControl 9-16
this, argomento 45-17
thread 11-1 11-15
assegnazione dei nomi 11-13
11-15
attesa di 11-10
multipli 11-11
attesa di eventi 11-10
attivit 44-21
BDE e 24-13
blocco dellesecuzione 11-8
blocco di oggetti 11-8
ciclo di messaggi e 11-5
come evitare laccesso
simultaneo 11-8
componenti di accesso ai
dati 11-5
conversione da senza nome a
con nome 11-13
coordinamento 11-4, 11-7
11-11
CORBA 31-12 31-13
creazione 11-12
eccezioni 11-7
esecuzione 11-12
id 11-13
inizializzazione 11-3
interruzione 11-6, 11-12
ISAPI/NSAPI,
programmi 33-2, 33-18
liberazione 11-3, 11-4
limiti sul numero 11-12
oggetti grafici 11-5
priorit 11-1, 11-3
ridefinizione 11-12
servizio 7-7
sezioni critiche 11-8
spazio di processo 11-4
thread della VCL 11-4
uso di elenchi 11-5
valori restituiti 11-10
__thread, modificatore 11-6
thread principale della
VCL 11-4
evento OnTerminate 11-7
Thread Status, casella 11-13
thread, classi
definizione 11-1
thread, funzioni 11-4
thread, oggetti 11-1
thread, variabili
CORBA 31-12
ThreadID, propriet 11-13
throw, istruzione 12-2, 12-18
THTMLTableAttributes 33-20
THTMLTableColumn 33-20
THTTPRio 36-17
THTTPSoapCppInvoker 36-10,
36-12
THTTPSoapDispatcher 36-10,
36-12
TIBCustomDataSet 22-2
TIBDatabase 18-9, 21-1
TickMarks, propriet 9-6
TickStyle, propriet 9-6
TIcon 50-4
tie, classi 31-8 31-9
VCL e 31-8
tier 29-1
TiledDraw, metodo 50-7
TImage
in controlli 8-16
TImageList 8-50
__TIME__, macro A-7
timeout, eventi 11-11
timer 5-7
TIniFile 4-10, 4-11
TIntegerProperty, tipo 52-8
TInterfacedObject 13-4, 13-5
TInvokableClass 36-13
tipi
assegnazione di nomi 10-13
Automation 41-16 41-17
C++ e Object Pascal 13-20
Char 16-3
classi holder 36-6
definiti dellutente 54-4
gestori di evento 48-3
librerie di tipi 39-12 39-13
MIME 10-23
non specificati 13-17
propriet 47-2, 47-9, 52-9
record di messaggio 51-7
Web Services 36-4 36-10
tipi character 16-3
tipi definiti dallutente 54-4
tipi di campo
conversione 23-17, 23-19
23-21
tipi di server 34-9
tipi enumerati 47-2, 54-4
costanti e 10-13
dichiarazione 10-13, 10-14
tipi enumerativi
Type Library editor 39-10,
39-17
tipi non mappati 13-24
tipi semplici 47-2
tipi set 47-2
tipo di dati Char 16-3
Title, propriet
griglie dati 19-22, 19-23
titoli delle colonne 9-16, 19-19,
19-23
TKeyPressEvent 48-3
TLabel 9-4, 45-4
.TLB, file 38-19, 39-2, 39-21
TLCDNumber 9-2
TLIBIMP, strumento della riga
comandi 38-20, 40-2, 40-6,
41-15
TListBox 45-3
TLocalConnection 27-27, 29-5
TMainMenu 8-20
TMaskEdit 9-1
TMemIniFile 4-10, 4-11, 14-7
TMemo 9-1
TMemoryStream 4-2
TMessage 51-5, 51-7
TMetafile 50-4
Tmethod, tipo 51-12
TMethodProperty, tipo 52-8
TMTSASPObject 42-2
TMtsDll 44-4, 44-27
TMultiReadExclusiveWriteSync
hronizer 11-9
TNestedDataSet 22-39
TNotifyEvent 48-7
I-46 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
TObject 3-4, 13-9, 13-23, 13-29,
46-4
definizione 3-5
ToCommon 4-32
TOleContainer 40-17 40-18
Active Documents 38-15
TOleControl 40-6, 40-7
TOleServer 40-6
toolbars
definizione 8-19
Tools API
wizard 58-3, 58-3 58-7
ToolsAPI, unit 58-2
tool-tip help 9-17
Top, propriet 8-4, 8-47
TopRow, propriet 9-18
TOrdinalProperty, tipo 52-8
TPageControl 9-16
TPageDispatcher 34-37
TPageProducer 33-14
TPaintBox 9-20
TPanel 8-46, 9-14
TPersistent 13-7
definizione 3-5
tpHigher, costante 11-3
tpHighest, costante 11-3
TPicture, tipo 50-4
tpIdle, costante 11-3
tpLower, costante 11-3
tpLowest, costante 11-3
tpNormal, costante 11-3
TPopupMenu 8-52
-Tpp, opzione del linker 15-13
TPrinter 4-26
utilizzo 3-4
TPropertyAttributes 52-11
TPropertyEditor, classe 52-8
TPropertyPage 43-14
tpTimeCritical, costante 11-3
TQuery 24-2, 24-9 24-12
dataset decisionali e 20-5
TQueryTableProducer 33-21
track bar 9-5
track bar orizzontali 9-6
track bar verticali 9-6
traduzione 16-9
traduzioni in lingue
straniere 16-1
Transactional Data Module,
wizard 29-15 29-16
Transactional Object
wizard 44-18 44-22
transazionali, moduli dati
classe di
implementazione 29-15
transazioni 18-5, 21-6 21-11
ADO 25-6 25-7, 25-8
ritenzione degli
annullamenti 25-6
ritenzione delle
modifiche 25-6
aggiornamenti in
cache 24-35
annidate 21-7
conferma 21-9
annullamento 21-9 21-10
applicazione degli
aggiornamenti 21-7, 29-18
applicazioni multi-tier 29-18
29-19
atomicit 18-5, 44-11
attributi 44-12 44-13
automatiche 44-14
avvio 21-7 21-8
BDE 24-31 24-33
controllo 24-31 24-32
implicite 24-31
componenti transaction 21-8
composte da pi
oggetti 44-11
conferma 21-8 21-9
congruenza 18-5, 44-11
contesti di oggetto 44-11
controllate dal client 44-15
44-16
controllate dal server 44-16
durabilit 18-5, 44-11
IAppServer 29-19
isolamento 18-5, 44-11
livelli 21-10 21-11
locali 24-33
moduli dati
transazionali 29-7, 29-16,
29-18 29-19
MTS e COM+ 44-10 44-17
oggetti transazionali 44-5,
44-10 44-17
sovrapposte 21-8
su pi database 44-11
tabelle locali 21-7
termine 21-8 21-10, 44-13
44-14
timeout 44-17, 44-28
uso di comandi SQL 21-6
utilizzo di comandi
SQL 24-32
transazioni a due fasi 29-18
transazioni locali 24-33
transazioni, livello di
isolamento 21-10 21-11
specifica 21-10
transazioni locali 24-33
TransformGetData,
propriet 30-9
TransformRead, propriet 30-8
TransformSetParams,
propriet 30-10
TransformWrite, propriet 30-8
TransIsolation, propriet 21-10
transazioni locali 24-33
transitorie, sottoscrizioni 40-16
Transliterate, propriet 23-13,
24-51
Transparent, propriet 9-5
trasferimento dei record 57-2
trasformazione di stringhe di
caratteri 16-2, 16-8, 16-10
trasformazione in stringhe di
caratteri
conversioni 2 byte 16-3
trasparenza, delle barre
strumenti 8-50, 8-52
TReader 4-3
TRegIniFile 14-7
TRegistry 4-10
TRegistryIniFile 4-10, 4-12
TRegSvr 17-5, 38-20
TRemotable 36-7
TRemoteDataModuleRegistrar
29-9
TRichEdit 9-1
trigger 18-5
trinagoli 10-12
__try, parola chiave 12-7
try, blocco 12-2
try, istruzione 12-11
TScrollBox 9-5, 9-15
TSearchRec 4-8
TServerSocket 37-7
TService_object 7-9
TSession 24-17 24-31
aggiunta 24-28, 24-29
TSetElementProperty, tipo 52-8
TSetProperty, tipo 52-8
TSharedConnection 29-30
TSocketConnection 29-25
TSpinEdit control 9-6
TSQLClientDataSet 26-2
TSQLConnection 18-9, 21-1,
26-2 26-6
collegamento 26-3 26-6
monitoraggio dei
messaggi 26-18
TSQLDataSet 26-2, 26-6, 26-7,
26-8
I n d i c e I-47
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
TSQLMonitor 26-18 26-19
TSQLQuery 26-2, 26-6
TSQLStoredProc 26-2, 26-8
TSQLTable 26-2, 26-7
TSQLTimeStampField
formattazione
predefinita 23-16
TStoredProc 24-2, 24-12 24-13
TStream 4-2
TStringList 4-16 4-21, 7-32
TStringProperty, tipo 52-8
TStrings 4-16 4-21
TTabControl 9-15
TTable 24-2, 24-5 24-9
dataset decisionali e 20-6
TTextBrowser 9-2
TTextViewer 9-2
TThread 11-2
TThreadList 11-5, 11-8
TTimeField
formattazione
predefinita 23-16
TToolBar 8-20, 8-46, 8-49
TToolButton 8-46
TTreeView 9-12
TUpdateSQL 24-41 24-50
provider e 24-11
TWebActionItem 33-3
TWebAppDataModule 34-2
TWebAppPageModule 34-2
TWebConnection 29-26
TWebContext 34-36
TWebDataModule 34-2
TWebDispatcher 34-37, 34-41
TWebPageModule 34-2
TWebResponse 33-3
TWidgetControl 14-6
definizione 3-5
TWinControl 3-9, 13-9, 13-11,
16-9, 45-4, 48-5
definizione 3-5
TWMMouse, tipo 51-7
TWriter 4-3
TWSDLHTMLPublish 36-10,
36-16
TWSDLHTMLPublisher 36-12
TXMLDocument 35-3 35-4,
35-9
TXMLTransform 30-6 30-8
documenti sorgente 30-6
TXMLTransformClient 30-9
30-11
parametri 30-10
TXMLTransformProvider 28-1,
28-2, 30-8 30-9
Type Library editor 38-18, 39-2
39-20
aggiornamento 39-19
aggiunta di interfacce 39-14
alias 39-10
aggiunta 39-18
apertura di librerie 39-14
application server 29-17
barra di stato 39-5
barra strumenti 39-3 39-5
CoClass 39-10
aggiunta 39-16 39-17
collegamento di
attributi 43-12
COM+, pagina 44-5
definizioni dei tipi 39-10
39-11
dispinterface 39-10
elementi 39-8 39-11
caratteristiche
comuni 39-8 39-9
interfacce 39-9 39-10
modifica 39-15 39-16
messaggi di errore 39-5, 39-8
metodi
aggiunta 39-15 39-16
moduli 39-11
aggiunta 39-18 39-19
Object list, pannello 39-5
pagina COM+ 44-10
pagina Text 39-8, 39-16
pagine di informazioni di
tipo 39-6 39-8
parti 39-3 39-8
propriet
aggiunta 39-15 39-16
record e union 39-11
aggiunta 39-18
salvataggio e registrazione di
informazioni di tipo 39-19
39-20
selezione di elementi 39-5
tipi enumerati 39-10
aggiunta 39-17
type, parola riservata 10-13
typedef, da Object Pascal a
C++ 13-16
U
UCS, standard 14-21
UDP, protocollo 37-1
Unassociate Attributes,
comando 23-15
underflow, errori
math, funzioni A-8
UndoLastChange, metodo 27-6
unexpected, funzione 12-5
UnhandledExceptionFilter,
funzione 12-7
Unicode, caratteri 16-3, 16-4
stringhe 4-21
UniDirectional, propriet 22-51
unidirezionali, cursor 22-51
union
accesso A-5
membri con tipi
differenti A-5
Type Library editor 39-11,
39-18
unit
aggiunta di
componenti 45-13
C++Builder 45-12
CLX 14-10 14-12
esistenti
aggiunta di un
componente 45-12
VCL 14-10 14-12
unit di base 4-29, 4-31
unit termometriche 4-30
unit, in conversione 4-29
Unlock, metodo 11-8
UnlockList, metodo 11-8
UnRegisterTypeLib,
funzione 38-19
Update SQL editor
SQL, pagina 24-43
Update SQL, editor 24-43
24-44
Options, pagina 24-43
UPDATE, istruzioni 24-42,
24-46, 28-10
update, oggetti 24-41 24-50,
27-20
esecuzione 24-48 24-49
istruzioni SQL 24-42 24-46
parametri 24-44 24-45,
24-48, 24-49 24-50
provider e 24-11
query 24-49 24-50
utilizzo di pi oggetti 24-46
24-49
UpdateBatch, metodo 14-29,
25-13, 25-14
UpdateCalendar, metodo 56-4
UpdateMode, propriet 28-10
dataset client 27-23
UpdateObject, metodo 43-15,
43-16
I-48 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
UpdateObject, propriet 24-11,
24-34, 24-42, 24-47
UpdatePropertyPage,
metodo 43-15
UpdateRecordTypes,
propriet 14-29, 24-34, 27-20
UpdateRegistry, metodo 29-9
UpdatesPending,
propriet 14-29, 24-34
UpdateStatus, propriet 14-29,
24-34, 25-12, 27-20, 28-9
UpdateTarget, metodo 8-31
up-down controls 9-6
up-down, controlli 9-6
URI e URL 32-4
URL 32-4
connessioni Web 29-26
e URI 32-4
indirizzi IP 37-4
librerie javascript 29-34,
29-35
nomi di host 37-4
Web browser 32-5
URL, propriet 29-26, 29-27,
33-9, 36-18
URLs
connessioni SOAP 29-27
Use CORBA Object,
wizard 31-15
user list service 34-11, 34-27
uses, clausola
aggiunta di moduli dati 7-24
uuid, argomento 13-3
V
valori 47-2
booleani 47-2, 47-12, 56-4
collaudo 47-7
dati predefiniti 19-11
predefiniti delle
propriet 47-7, 47-12
47-13
propriet predefinita
ridefinizione 53-3, 53-4
sequenziali 10-13
valori additivi
crosstab 20-3
valori booleani 47-2, 47-12, 56-4
valori di consultazione 19-19
valori di riepilogo
aggregati di
manutenzione 27-14
cubi decisionali 20-20
grafici decisionali 20-15
valori in virgola mobile A-4
caratteri di punto
decimale A-7
valori logici 19-2, 19-14
valori sequenziali, assegnazione
a costanti 10-13
Value, propriet
aggregati 27-14
campi 23-19
parametri 22-48, 22-54, 22-55
ValueChecked, propriet 19-14
Values, propriet
gruppi di pulsanti di
opzione 19-15
ValueUnchecked,
propriet 19-14, 19-15
valuta
esempio di conversione 4-32
formati 16-10
internazionalizzazione 16-10
var, parametri 13-17
variabili di thread 11-5
variabili locali al thread 11-5
evento OnTerminate 11-7
VCL 7-13, 45-1 45-2
classi di eccezioni 12-17
costruzione di oggetti 13-9
e CLX 14-5 14-8
gestione delle
eccezioni 12-15
panoramica 3-1 3-2
ramo Tcomponent 3-7
ramo Tcontrol 3-8
ramo Tobject 3-6
ramo Tpersistent 3-6
ramo TWinControl 3-9
supporto del linguaggio
C++ 13-1 13-31
thread principale 11-4
unit 14-10 14-12
VCL, applicazioni
porting in Linux 14-2 14-16
vcl60.bpl 15-1, 15-10, 17-6
penwin.dll 15-13
VCLCONTROL_IMPL,
macro 43-3, 43-6
VendorLib, propriet 26-4
verifica
componenti 45-17, 45-19,
57-7
valori 47-7
VertScrollBar 9-5
video analogici 10-34
video cassette 10-34
video clip 10-31
video, filmati 10-33
ViewStyle, propriet 9-13
vincoli
controlli 8-4 8-5
data
importazione 27-32
dati 23-22 23-23
creazione 23-22 23-23
dataset client 27-7 27-8,
27-32 27-33
disattivazione 27-32
importazione 23-23,
28-13, 28-14
violazione dellintegrit 24-54
violazioni di chiave 24-54
virgola mobile, valori
specificatori di formato A-3
virtual
metodi 49-4
propriet come 47-2
parola chiave 46-10
virtuali
funzioni 13-12
metodi
editor di propriet 52-9
metodi di classe 13-15
tabella dei metodi 46-10
Visible, propriet 3-2
barre strumenti 8-53
campi 23-13
coolbar 8-53
menu 8-44
VisibleButtons, propriet 19-32,
19-33
VisibleChanged, metodo 51-15
VisibleColCount, propriet 9-18
VisibleRowCount,
propriet 9-18
viste ad albero 9-12
owner-draw 6-12
VisualCLX
definizione 14-5
package 15-10
visualizzazione di script 34-35
visualizzazione tabellare
(griglie) 9-17
VisualSpeller Control 17-5
voci di menu 8-34 8-37
aggiunta 8-34, 8-44
annidamento 8-37
assegnazione dei nomi 8-34,
8-43
barre di separazione 8-36
cancellazione 8-35, 8-40
definizione 8-32
editing 8-39
I n d i c e I-49
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
impostazione delle
propriet 8-39 8-40
lettere sottolineate 8-36
raggruppamento 8-36
segnaposti 8-40
spostamento 8-38
vtable 38-5
classi creatore e 40-6, 40-13
40-14
e dispintrface 39-10
interfacce duali 41-13
librerie di tipi e 38-18
puntatore di interfaccia
COM 38-5
wrapper di componenti 40-7
W
W3C 35-2
WaitFor, metodo 11-10, 11-11
WantReturns, propriet 9-3
WantTabs, propriet 9-3
controlli memo data-
aware 19-9
controlli rich edit data-
aware 19-10
.wav, file 10-34
wchar_t widechar 14-21
wchar_t, costante di
carattere A-4
Web application
debugger 32-10, 33-2, 34-9
Web application, moduli 34-3,
34-3 34-4
Web application, oggetto 33-3
Web Broker 7-17
Web Broker, applicazioni
server 32-1 32-3, 33-1 33-21
accesso a database 33-18
aggiunta ai progetti 33-3
architettura 33-3
creazione 33-1 33-3
creazione di risposte 33-8
gestione delle connessioni ai
database 33-18
gestione eventi 33-5, 33-7,
33-9
interrogazione di
tabelle 33-21
invio di dati a 33-11
invio di file 33-13
modelli 33-2
modelli di risposta 33-14
panoramica 33-1 33-4
Web dispatcher 33-4
Web browser
URL 32-5
Web data, moduli 34-2, 34-3
struttura 34-5
Web Deployment Options,
finestra di dialogo 43-18
Web dispatcher
gestione delle richieste 33-3
oggetti a dispatch
automatico 29-37
Web module 33-4
Web page editor 29-39 29-40
Web page, moduli 34-2, 34-4
34-5
Web server 32-1 32-12
debug 33-2
tipi 34-9
Web server, applicazioni 7-17,
32-12
debug 32-9 32-12
multi-tier 29-33 29-43
panoramica 32-7 32-12
standard 32-3
tipi 32-7
ubicazione delle risorse 32-4
Web Service Definition
Language Vedi WSDL
Web Services 36-18
aggiunta 36-12 36-14
classi di
implementazione 36-12
36-14
classi holder 36-6
client 36-17 36-18
contesto dati 36-8
eccezioni 36-15 36-16
importazione 36-14 36-15
namespace 36-3
registrazione delle classi di
implementazione 36-13
scrittura di server 36-10
36-16
server 36-10 36-17
tipi complessi 36-4 36-10
tipi enumerati 36-6
tipi scalari 36-4
wizard 36-11 36-15
Web Services,
importatore 36-14
Web, applicazioni
ActiveX 38-14, 43-1
ASP 38-14, 42-1
distribuzione 17-10
Web, connessioni 29-11, 29-26
Web, distribuzione 43-17
43-19
applicazioni multi-tier 29-33
Web, moduli 34-2, 34-2 34-5
tipi 34-2
Web, moduli dati 34-5
Web, pagina
InternetExpress, produttori
di pagine 29-39 29-43
Web, pagine 32-5
WebDispatch, propriet 29-37,
36-12
WebPageItems, propriet 29-39
WebServices, pagina
(Component palette) 29-2
WebServices, pagina (New
Items, finestra di dialogo) 29-2
WebSnap 32-1 32-3
diritti di accesso 34-31
34-33
esempi di script lato
server B-19
esercizio 34-12 34-24
login obbligatorio 34-30
34-31
oggetti script globali B-14
pagine di login 34-28 34-30
scripting lato server 34-33
34-36, B-1 B-39
supporto al login 34-26
34-33
wide character, costanti A-4
widechar 14-21
widestring 14-21
widget 3-9
creazione 14-13
e controlli Windows 14-6
WidgetDestroyed,
propriet 51-14
Width, propriet 8-4, 9-17
colonne delle griglia
dati 19-18
griglie dati 19-22
penne 10-6
Win 3.1, pagina (Component
palette) 5-8
WIN32 14-19
Win32, pagina (Component
palette) 5-7
Win-CGI, applicazioni 32-6,
32-7
creazione 33-2, 34-9
file .ini 32-7
Windows
contesti di dispositivo 45-7,
50-1
I-50 G u i d a a l l a p r o g r a mma z i o n e
Copyright 1998, Inprise Corporation. All rights reserved. INPRISE CONFIDENTIAL
April 16, 2002 6:08 am (D:\Lavori\bcb6\DG\BCBonly\bcbdg.ix)
controlli, derivazione di
classe 45-4
eventi 48-4
finestre di dialogo
comuni 57-2
creazione 57-2
esecuzione 57-5
funzioni API 45-4, 50-1, 51-2
Graphics Device Interface
(GDI) 10-1
messaggi 51-3
sistema di messaggi 51-1
51-11
wininet.dll 29-26, 29-27
wizard 7-25
Active Server Object 38-22
Active Server Objects 42-2
42-3
ActiveForm 38-23, 43-6
43-7
COM 38-20 38-25, 41-1
COM+ Event object 38-23
COM+ Event subscriber,
oggetto 44-25
COM+ Event, oggetto 44-24
44-25
Component 45-9
Console Wizard 7-4
controlli ActiveX 38-22, 43-4
43-6
CORBA client 31-14
CORBA Object 31-7, 31-14
CORBA Server 31-5
creazione 58-2, 58-3 58-7
debug 58-11 58-12
installazione 58-7, 58-23
58-25
libreria ActiveX 38-23
oggetti Automation 38-22,
41-4 41-9
oggetti COM 38-22, 39-14
oggetto COM 41-3 41-4,
41-5 41-9
oggetto transazionale 38-23,
44-18 44-22
pagina di propriet 38-23
Property Page 43-14 43-15
Remote Data Module 29-14
29-15
Resource DLL 16-11
risposta agli eventi
dellIDE 58-19
SOAP Data Module 29-16
29-17
tipi 58-3
Tools API 58-3
Transactional Data
Module 29-15 29-16
Type Library 38-23, 39-13
39-14
Use CORBA Object 31-15
Web Services 36-11 36-15
XML Data Binding 35-6
35-10
WM_APP, costante 51-7
WM_KEYDOWN,
messaggio 56-9
WM_LBUTTONBUTTON,
messaggio 56-9
WM_MBUTTONDOWN,
messaggio 56-9
WM_PAINT, messaggi 10-2
WM_RBUTTONDOWN,
messaggio 56-9
WM_SIZE, messaggio 55-4
WndProc, metodo 51-3, 51-5
word, allineamento A-6
WordWrap, propriet 6-7, 9-3
controlli memo data-
aware 19-9
Wparam, parametro 51-10
Wrap, propriet 8-50
Wrapable, propriet 8-50
wrapper 45-5, 57-2
Vedi anche wrapper di
componenti
inizializzazione 57-4
wrapper di componenti
ActiveX, controlli 40-5
COM, oggetti 40-2
Write By Reference
propriet di interfaccia
COM 39-9
Write, metodo
TFileStream 4-2
write, metodo 47-7
write, parola riservata 47-9, 54-5
WSDL 36-2
file 36-16
importazione 36-3, 36-14
36-15, 36-17
pubblicazione 36-16 36-17
WSDL administrator 36-17
WSDL, publisher 36-12
WSDLIMP 36-15
X
XDR, file 35-2
Xerox Network System
(XNS) 37-1
.xfm, file 14-2
XML 30-1, 35-1
applicazioni database 30-1
30-11
dichiarazione del tipo di
documento 35-2
istruzioni di
elaborazione 35-1
mappatura 30-2 30-4
definizione 30-4
parser 35-2
SOAP 36-1
XML Data Binding, wizard 35-6
35-10
XML, broker 29-34, 29-36
29-38
messaggi HTTP 29-37
XML, documenti 30-1, 35-1
35-10
attributi 30-5, 35-5
componenti 35-3 35-4, 35-9
conversione in pacchetti
dati 30-1 30-8
generazione di interfacce
per 35-6
mappatura di nodi a
campi 30-2
nodi 35-2, 35-4 35-6
nodi figlio 35-5 35-6
nodo radice 35-4, 35-7, 35-9
propriet dei nodi 35-6
pubblicazione di
informazioni database 30-9
trasformazione di file 30-1
XML, file 25-15
XML, schemi 35-2
XMLBroker, propriet 29-40
XMLDataFile, propriet 28-2,
30-8
XMLDataSetField,
propriet 29-40
XMLMapper 30-2, 30-4 30-6
XSD, file 35-2
XSLPageProducer 34-5
Y
Year, propriet 55-6