Ringrazio particolarmente Romain Strieff e Dan Howard per i loro consigli e per il gentile contributo alla rilettura di questo articolo
Visual dBASE consente di realizzare praticamente tutto ciò che si può immaginare, grazie alla ricchezza delle funzioni e del suo linguaggio che deriva dalle precedenti versioni, che rappresentavano il primo linguaggio per Database su PC. L’avvento delle ultime versioni sotto Windows, e l’introduzione della programmazione orientata agli oggetti come struttura portante per la gestione di dati e l’interfaccia uomo-macchina, hanno fornito al prodotto migliori capacità per realizzare applicazioni di qualità eccellente.
Una applicazione sviluppata e concepita per Visual dBASE è, prima di tutto, un’applicazione Windows. In altre parole, essa si deve adeguare alle regole e rispettare i limiti di questo sistema operativo. Per mantenere una certa omogeneità e garantire una buona integrazione con questo sistema, Visual dBASE deve sfruttare al meglio le risorse e le librerie messe a disposizione da questo sistema operativo per gestire un’applicazione. Queste risorse sono accessibili tramite l'Application programming interface di Windows, comunemente chiamate API Windows.
Visual dBASE, attraverso i tools visuali di ultima generazione messi a disposizione per la creazione di una applicazione, orientata o meno alla gestione dei dati, consente di realizzare con una estrema semplicità la maggior parte delle complesse operazioni che vengono richieste dall’applicazione, offrendo un eccellente compromesso fra la gestione complessa delle API e la ricchezza delle possibilità offerte. Una applicazione Visual dBASE, essendo prima di tutto una applicazione Windows, utilizza già numerose funzioni offerte ’ API 32 di Windows ; ma il vantaggio principale è che trasforma, in un modo semplice, delle cose che erano riservate inizialmente ai soli specialisti e, soprattutto, consente di concentrare lo sforzo dello sviluppo non più sulla programmazione del sistema ma sulle specificità dell’applicazione.
Tuttavia, per rispondere a situazioni particolari, certe caratteristiche non sono immediatamente disponibili dal linguaggio Visual dBASE. In questo caso, bisogna abbandonare l’ambiente di sviluppo tradizionale e avventurarsi negli arcani della programmazione Windows, per poter direttamente utilizzare le l’API Windows 32 bits.
I contenuti di questo articolo sono:
I creatori di Visual dBASE hanno inserito nel prodotto un’apertura in maniera da rendere utilizzabili le funzioni delle librerie 32 bits contenute nei file DLL. A questo proposito, Visual dBASE 7.01 può usare solo librerie 32 bits, al contrario della versione 5.7 che conosceva solo il mondo a 16 bits, compatibilità obbligata con Windows 3.1.
I files DLL sono files binari che contengono del codice e/o delle risorse (bitmaps, icone) che possono essere utilizzate in maniera simultanea da più applicazioni. Lo stesso Windows è costruito attorno a queste DLLs, che utilizziamo nelle nostre applicazioni.
Queste funzioni sono chiamate in Visual dBASE "funzioni esterne". L’uso di tali funzioni viene spiegato sull’help in linea, cercando alla voce "extern" oppure digitando help extern nella finestra comandi.
Vedremo come utilizzare questo tipo di funzioni, in modo particolare quelle offerte da l’API Windows 32, per conoscere le loro possibilità ed i limiti di impiego. Scopo è quello di acquisire una tecnica che permetta di utilizzare le funzioni l'API 32.
La difficoltà maggiore sarà quella di identificare, fra la pletora di funzioni disponibili, quelle che ci consentono di effettuare l’azione desiderata.
Visual dBASE 7.01 viene fornito con un file di aiuto particolare chiamato "Win 32 Programmer's Reference" che chiameremo "Aiuto su API 32". Questo file si trova nella directory _DBWINHOME\Help\MSHelp ( dove _DBWINHOME rappresenta la directory dove è installato Visual dBASE).
Cominceremo con la funzione chiamata : ShellExecute che consente di lanciare, da Visual dBASE, un’altra applicazione Windows, senza che appaia la finestra DOS, a differenza del comando RUN() che fa parte del linguaggio.
Cercando questa funzione nel file di aiuto API 32 , troveremo la seguente pagina:
Vediamo in dettaglio le indicazioni scritte in rosso:
L’interfaccia di programmazione Windows può sembrare all’inizio oscura, specialmente per chi proviene da un linguaggio di alto livello come Visual dBASE. In effetti, è stata concepita , realizzata in linguaggio C ed era inizialmente destinata ad essere utilizzata dai programmatori di C. Di conseguenza, le difficoltà per utilizzare questa interfaccia, dipendono dal fatto che ci si deve adattare alle particolari esigenze di questo linguaggio.
Scopo di questo capitolo non è quello di apprendere il linguaggio C, né ancor meno il C++. Si tratta di capire semplicemente gli elementi essenziali del linguaggio che serviranno per utilizzare le funzioni API.
Una delle principali differenze fra C e Visual dBASE dipende dal tipo e dalla struttura dei dati. Contrariamente a Visual dBASE, in C i dati devono essere sempre dichiarati con in tipo esplicito. C distingue anche fra variabili semplici e variabili puntatori. Risulta importante comprendere le differenze essenziali:
Ritornando ai tipi di dati, l’API Windows utilizza naturalmente i tipi nativi del C che sono in lettere minuscole. I tipi derivati sono, in genere, in maiuscolo.
Un puntatore può essere dichiarato in modo esplicito in C, in questo caso, il nome della variabile è preceduto da un asterisco (*). Nei tipi derivati, l' * è generalmente contenuto nel nome del tipo come, per esempio, quelli di Windows, il cui nome del tipo inizia spesso con le lettere LP, ossia Long Pointer.
Ecco, per esempio, alcune dichiarazioni di variabili C:
char c = 'a'
// Variabile carattere di un byte inizializzata con la lettera 'a'.
int *k
// Puntatore a un intero
Esempio di array in C :
short tab[2][3]
// Crea un array di 2 x 3 elementi che sono di tipo "short".
// tab è in realtà un puntatore al primo elemento short
// della zona di memoria riservata all’array
Esempio di stringhe in C :
char st[] = "Bonjour!"
// Crea una stringa il cui spazio di memoria è esattamente
// la sua lunghezza + 1 (a causa del Null finale),
// alla quale punta il puntatore st.
// Questa stringa viene considerata come fissa in memoria.
char st_tab[256]
// Qui sono riservati 256 bytes per memorizzare,
// sino al massimo 255 caratteri + '\0'
La tabella, fornisce i tipi di base e i puntatori
utilizzati da Windows, che derivano dai tipi di C :
Spazio di memoria (bytes) | Esempio di altri Tipi equivalenti usati in Windows | Tipi Visual dBASE | Dichiarazione di variabili nei prototipi delle funzioni Visual dBASE | Dichiarazione di puntatore nei prototipi delle funzioni Visual dBASE | |
char | 1 | BYTE | Numeric | CCHAR | |
unsigned char | 1 | UCHAR | Numeric | CUCHAR | |
short | 2 | WORD | Numeric | CSHORT | CPTR SHORT |
unsigned short | 2 | USHORT | Numeric | CUSHORT | CPTR CUSHORT |
int | 4 | DWORD, HWND, BOOL, HDC | Numeric | CINT | CPTR CINT |
UINT | 4 | Numeric | CUINT | CPTR CUINT | |
long | 4 | LPVOID | Numeric | CLONG | CPTR CLONG |
unsigned long | 4 | ULONG | Numeric | CULONG | CPTR CULONG |
float | 4 | Numeric | CFLOAT | CPTR CFLOAT | |
double | 8 | Numeric | CDOUBLE | CPTR CDOUBLE | |
LDOUBLE | 10 | Numeric | CLDOUBLE | CPTR CLDOUBLE | |
LOGICAL | 1 | Logical | CLOGICAL | CPTR CLOGICAL | |
void | N/A | N/A | CVOID |
Alcune precisazioni sulla tabella:
Nella dichiarazione di funzioni, Windows utilizza numerosi altri tipi derivati dai tipi di base C che risultano nella tabella. Tutti questi altri tipi possono essere definiti nelle dichiarazioni EXTERN a partire da tipi nativi di Visual dBASE.
Una sola categoria non è supportata
da Visual dBASE, si tratta della funzione CALLBACK,
che non analizzeremo. In breve si tratta di un equivalente del tipo Function
Pointer (FP) di Visual dBASE.
Stringhe
di caratteri e puntatori C
Dopo aver visto i tipi semplici, questo capitolo tratta le stringhe e i puntatori in C, ed il loro utilizzo con Visual dBASE nei prototipi delle funzioni API.
Una stringa è una serie di caratteri che possono essere memorizzati :
Eseguite il codice seguente per vedere come le stringhe sono memorizzate in dBASE. Osservate che iniziano da 0.
s = new String("Bonjour")
for j = 0 to (s.Length*2)-1
?s.getByte(j), chr(s.getByte(j))
next j
Quando si fornisce una stringa ad una funzione API, bisogna rispettare obbligatoriamente il tipo atteso, byte o Unicode.
Nota: Una cosa importante da conoscere che riguarda le stringhe ed il linguaggio C : esso impone che l’ultimo carattere di una stringa sia obbligatoriamente il carattere chr(0), chiamato anche Null char, o '\0'. Visual dBASE tiene conto di questa regola quando chiama le funzioni esterne ma questa regola deve essere sempre tenuta presente, in particolar modo quando si fanno conversioni byte <- Unicode.
Una stringa C è sempre composta da CHAR o da WORD (se è Unicode), alla quale punta un "puntatore" C di tipo CHAR o WORD. Questo stesso puntatore è una variabile che contiene come indirizzo di memoria, l’indirizzo del primo carattere della stringa puntata. Dichiarando una stringa si dichiara sempre un puntatore, cioè un indirizzo di memoria, a questa stringa. La lunghezza della stringa è fissata implicitamente dal primo Null della stringa.
Per usare le stringhe, in Visual dBASE esistono
due prototipi di parametri : CSTRING
e CPTR.
Designano entrambi un puntatore alla stringa ma hanno le seguenti differenze:
Dichiarazione CPTR | |
Conversione
automatica implicita da Unicode a Byte quando
si chiama una funzione esterna.
La stringa può contenere caratteri Null, ma ho incontrato problemi con questo stringhe contenenti Null. |
Nessuna
conversione alla chiamata
La stringa può contenere caratteri Null. |
Conversione
automatica implicita da Byte a Unicode se
la funzione restituisce una stringa.
La regola del carattere Null si applica alla stringa restituita, con le stesse restrizioni di impiego. |
Il tipo restituita dalla funzione non può essere CPTR. |
Il
prototipo e la dichiarazione delle funzioni API con Visual dBASE
Ritorniamo alla funzione ShellExecute vista nel capitolo Presentazione delle funzioni l'API 32. E vediamo il prototipo, ossia dobbiamo indicare questa funzione, prima di utilizzarla, per esplicitare in quale modo Visual dBASE deve chiamarla dal programma.
Vediamo prima la sintassi generica di una dichiarazione di funzione esterna. L’help in linea, alla voce "extern", propone due modi, ma possiamo far riferimento alla seconda espressione:
Troviamo nell’ordine :
Per fortuna , il lavoro è in parte già fatto, Nella directory _DBWINHOME\Include esistono dei files prototipo, (con estensione .h), che contengono l’insieme delle dichiarazioni usate con le funzioni l’API 32.
Compiliamo ora il programma costituito da queste linee: Viene prodotto un errore dovuto alla dichiarazione, HWND , che pone dei problemi. Infatti, HWND è una parola chiave di Visual dBASE, da qui il conflitto.
La soluzione migliore è quella di sostituire HWND con HANDLE., per cui:
// Déclaration du Prototype
de la fonction ShellExecute
extern HINSTANCE ShellExecute(HANDLE, LPCSTR,
LPCSTR, LPCSTR, ;
LPCSTR, CINT) shell32 ;
from "ShellExecuteA"
Ricompiliamo ora senza errori e la funzione dichiarata è pronta per essere usata.
Il problema legato a HWND è l’unico incontrato. Tutte le altre funzioni di win32API.prg che ho utilizzato sino ad ora funzionano correttamente.
Per spiegare ciò che è stato detto prima a proposito della parola chiave from di questo comando, sostituiamo la dichiarazione nel modo seguente, eliminando la parola from :
// Déclaration du Prototype
de la fonction ShellExecuteA, sans le mot clé from
extern HINSTANCE ShellExecuteA(HANDLE, LPCSTR,
LPCSTR, LPCSTR, ;
LPCSTR, CINT) shell32
Compilate. Ora bisognerà usare la funzione ShellExecuteA(<Paramètres) invece di shellExecute(<Paramètres).
Riassumendo, i passi delicati nella dichiarazione di prototipi di funzioni API sono limitati a:
Riprendiamo l’help della funzione ShellExecute e osserviamo il parametro nShowCmd che specifica il modo in cui sarà aperta la finestra del nuovo programma. I valori ammessi sono:
Il file ha le seguenti dichiarazioni:
. . .
//
// ShowWindow() Commands
//
#define SW_HIDE
0
#define SW_SHOWNORMAL
1
#define SW_NORMAL
1
#define SW_SHOWMINIMIZED
2
#define SW_SHOWMAXIMIZED
3
#define SW_MAXIMIZE
3
#define SW_SHOWNOACTIVATE
4
#define SW_SHOW
5
#define SW_MINIMIZE
6
#define SW_SHOWMINNOACTIVE 7
#define SW_SHOWNA
8
#define SW_RESTORE
9
#define SW_SHOWDEFAULT
10
#define SW_MAX
10
. . .
Per dichiarare tutte le costanti nel nostro
esempio, basta includere:
// Inclure le fichier Winuser.h
#include <Winuser.h
Invece di usare il file include per la dichiarazione di costanti e funzioni API , si potrebbe dichiararle direttamente nel nostro codice, con delle primitive #define e con tipi disponibili in Visual dBASE. Sarebbe possibile ma fastidioso perché bisogna riprendere tutte le definizioni di funzione e costanti con il rischio di errori. I files include di Visual dBASE servono per questo.
Per chiudere il capitolo, i puristi avranno
osservato che dal momento che si include il file Winuser.h,
la dichiarazione di includere anche Windef.h
diventa superflua. Infatti, il file Winuser.h.
effettua lui stesso (per essere sicuri guardate la prima linea del file)
l'inclusione del file Windef.h.
Nel nostro caso, sarebbe sufficiente includere Winuser.h
per usare ShellExecute.
Esecuzione
di una funzione API 32
Vediamo come eseguire la funzione. Lanceremo la calcolatrice di windows che si trova nella directory C:\Windows, il nome del file eseguibile è: Calc.exe
Guardiamo ancora l’help in linea la funzione ShellExecute , che specifica i seguenti parametri:
// Inclure le fichier Winuser.h
#include <Winuser.h
// Déclaration du Prototype
de la fonction ShellExecute
extern HINSTANCE ShellExecute(HANDLE, LPCSTR,
LPCSTR, LPCSTR, ;
LPCSTR, CINT) shell32 ;
from "ShellExecuteA"
ShellExecute( _app.FrameWin.hwnd, "open", "calc.exe", Null, "C:\Windows", SW_SHOWNORMAL )
Eseguite il comando e verrà visualizzata la calcolatrice. Questo esempio mostra l’utilizzo di parametri di tipo diverso, numerico, stringa, costanti API 32.
Resta da presentare un tipo di parametri
di cui abbiamo solamente rivelato l‘esistenza, si tratta delle strutture
C. Sono oggetto del prossimo capitolo in quanto prima bisognava conoscere
le nozioni elementari spiegate nei capitoli precedenti.
Le
strutture C e Visual dBASE
Se C è rimasto per tanto tempo un riferimento nel mondo dello sviluppo, prima dell’introduzione della programmazione ad oggetti, è senza dubbio grazie alla potenza che gli conferiscono le strutture.
Per illustrare le strutture C, utilizzeremo la funzione API 32 chiamata GetVersionEx, che consente di ottenere la versione del sistema operativo.
Cerchiamo prima questa funzione sull’help in linea delle API :
Questa funzione usa un solo parametro chiamato lpVersionInformation, che è un puntatore C ad una struttura chiamata OSVERSIONINFO. Facciamo click su questo link OSVERSIONINFO indicato dal parametro e otteniamo la seguente finestra:
Vediamo in dettaglio le differenti indicazioni scritte in rosso:
Classes et Objets | |
La
struture C è un’entità statica.
Si tratta di un insieme di variabili o di puntatori dichiarati, di lunghezza fissa. Esso sono posti in memoria uno di seguito all’altro nell’ordine in cui sono dichiarati. La loro posizione in memoria non cambia mai. Lo spazio di memoria occupato dalla struttura C è fisso e corrisponde esattamente alla somma dello spazio di memoria occupato dai singoli membr. |
Un
oggetto è invece un’entità
dinamica.
Comprende elementi (proprietà, metodi) che possono essere modificati, aggiunti e cancellati ecc... I membri non sono sempre inseriti in memoria in maniera contigua dato che viene effettuata una gestione dinamica della memoria. Lo spazio di memoria di un oggetto è variabile e dipende dal suo contenuto in un dato momento. |
Una struttura contiene solamente variabili o puntatori. | Un oggetto può contenere proprietà( che sono esse stesse variabili o puntatori) e metodi . |
Per comprendere meglio una struttura, ecco l’occupazione di memoria della struttura C OSVERSIONINFO :
Campo della struttura | |
Offset : n a n + 3 | DwOSVersionInfoSize |
Offset : n + 4 a n + 7 | DwMajorVersion |
Offset : n + 8 a n + 11 | DwMinorVersion |
Offset : n + 12 a n + 15 | DwBuildNumber |
Offset : n + 16 a n + 19 | DwPlatformId |
Offset : n + 20 a n + 147 | SzCSDVersion |
Poiché strutture e classi sono, per loro natura, differenti, non è possibile usare direttamente le seconde per simulare le prime.
Per modificare il contenuto di una struttura con Visual dBASE bisogna avere accesso ad un blocco di memoria, rappresentato dal contenuto della struttura (i diversi membri) sui quali si interviene direttamente a livello di byte.
Fondamentalmente, il solo meccanismo offerto, consiste nel considerare il blocco di memoria come una stringa di caratteri Visual dBASE, e poi, grazie ai metodi setByte e getByte, si legge e si modifica il contenuto della stringa byte per byte. Anche se questo sistema funzione, bisogna dire che è estremamente arduo e pesante e che bisogna lavorare molto per ottenere un buon risultato.
Per fortuna esiste un metodo molto più efficace
Anche se Visual dBASE non ha strutture, abbiamo qualche cosa di molto più potende delle strutture C: gli oggetti e le classi..
Vedremo come possiamo simulare il comportamento di una struttura C ed ottenere, con un linguaggio di classi come Visual dBASE, la sostituzione delle strutture con le classi.
Fra le utility e gli esempi forniti con Visual dBASE 7.01, ci sono dei files che consentono di fare ciò. I files sono :
Questa classe Structure mette a disposizione la proprietà .value così come i metodi addMember(), setMember(), getMember(), e length() che permettono dei parametri e il controllo dell’oggetto creato a partire dalla classe Structure.
Pe descrivere questo membro, bisogna indicare,
come in C, il suo tipo ed il suo nome.
I membri devono essere dichiarati nello
stesso ordine che compaiono nella struttura
C. Grazie al tipo fornito dalla
chiamata a addMember,
la posizione e l’occupazione del membro nella
stringa .value
viene calcolata e conservata con la descrizione
del membro.
Vediamo ora un caso concreto. Chiameremo la funzione API 32 GetVersionEx , e quindi avremo accesso ai membri della struttura OSVERSIONINFO.
Le linee di codice che segue, non figurano necessariamente nello stesso ordine in cui dovrebbero essere eseguite, ma questo aiuta alla comprensione ed alla spiegazione.
Per prima cosa vediamo il file Include. Una
rapida ricerca sulla costanti ed i tipi API utilizzati con GetVersionEx
e OSVERSIONINFO
mostra che dobbiamo includere i file indicati successivamente.
Inoltre dobbiamo includere il file StructAPI.h
dato che useremo la classe Structure :
// Files Include necessari
#include <Windef.h
#include <Winbase.h
#include <StructAPI.h
Dobbiamo quindi caricare la descrizione della classe Structure, contenuta nel file _DBWINHOME\Samples\Structure.prg:
// Carichiamo la classe Structure
set procedure to '&_dbwinhome.samples\structure.prg'
additive
Vediamo ora come dichiarare la classe OSVERSIONINFO corrispondente alla struttura C. Questa è un’istanza della classe Structure, definita nel file _DBWINHOME\Samples\Structure.prg che abbiamo appena caricato. Quindi con il metodo addMember dichiariamo i membri della struttura. Questo metodo usa come parametri:
// Questa definizione di classe corrisponde alla definizione della struttura C
// del tipo _OSVERSIONINFO. La funzione addMember crea i membri
della struttura,
// usando il tipo ed il nome del campo.
class _OSVERSIONINFO of Structure
super::addMember( TYPE_DWORD,
"dwOSVersionInfoSize" )
super::addMember( TYPE_DWORD,
"dwMajorVersion" )
super::addMember( TYPE_DWORD,
"dwMinorVersion" )
super::addMember( TYPE_DWORD,
"dwBuildNumber" )
super::addMember( TYPE_DWORD,
"dwPlatformId" )
super::addMember( TYPE_STRING,
"szCSDVersion", 128 )
// questa linea inizializza
il primo membro della struttura che
// deve, come precisato dall’help in linea API, contenere
la dimensione della //struttura.
// Il metodo length() della classe Structure consente
di ottenere la //dimensione
// totale espressa in bytes. Quando viene creato
un oggetto, usando la classe //_OSVERSIONINFO, questo membro viene automaticamente
inizializzato.
super::setMember( "dwOSVersionInfoSize",
this.length( ))
endclass
Avrete certamente visto che l’ultima linea della classe _OSVERSIONINFO richiama il metodo setMember. Infatti, l’help sulla struttura OSVERSIONINFO indica che il membro dwOSVersionInfoSize deve contenere la dimensione della struttura. Chiamando il metodo length che restituisce la dimensione della struttura, questo membro viene inizializzato automaticamente.
Per adesso la chiamata alla funzione GetVersionEx richiede un prototipo che può essere ottenuto ricopiando la linea corrispondente nel file _DBWINHOME\Include\Win32api.prg :
// Prototype della funczione GetVersionEx come viene fornita
in Win32api.prg
extern BOOL
GetVersionEx( LPSTRUCTURE ) kernel32 ;
from "GetVersionExA"
Vengono definite alcune variabili locali,
in particolar modo OSVERSIONINFO
che contiene l’oggetto creato a partire dalla classe _OSVERSIONINFO
:
local OSVERSIONINFO, dwPlatformId
L’oggetto OSVERSIONINFO viene ora creato con una istanza della classe _OSVERSIONINFO :
// Crée l'objet structure
OSVERSIONINFO = new _OSVERSIONINFO( )
Ora che è stato creato l’oggetto struttura OSVERSIONINFO, si può chiamare la funzione GetVersionEx per aggiornare il contenuto dell’oggetto.
Osservate che viene passato come parametro la proprietà .value , dato che questa stringa rappresenta il blocco di memoria nel quale sono memorizzati i membri della struttura :
// Achiamata alla funzione GetVersionEx passando come parametro
//OSVERSIONINFO.value, che rappresenta ilk contenuto della struttura
in memoria
GetVersionEx( OSVERSIONINFO.value )
Il rimanente codice visualizza il contenuto dei membri usando il metodo getMember come è stato aggiornato da GetVersionEx.
Un comando macro, chiamato LOWORD, è stato dichiarato nel file Windef.h, e consente di recuperare solamente i 16 bit low da una parola di 32 bit al contrario di HIWORD che restituisce i 16 più alti. Guardate il file Windef.h, che contiene utili macro per separare o unire delle parole binarie.
// visualizza il contenuto del membri della struttura
? ’ Major Version', OSVERSIONINFO.getMember(
'dwMajorVersion' )
? 'Minor Version', OSVERSIONINFO.getMember(
'dwMinorVersion' )
? 'Build Number', LOWORD( OSVERSIONINFO.getMember(
'dwBuildNumber' ))
dwPlatformId = OSVERSIONINFO.getMember( 'dwPlatformId'
)
do case
case dwPlatformId == VER_PLATFORM_WIN32s
? 'Win32s on Win 3.1'
case dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
? 'Win32 on Windows 95'
case dwPlatformId == VER_PLATFORM_WIN32_NT
? 'Win32 on Windows NT'
endcase
Il programma completo dBASE relativo a questo
esempio, può essere scaricato usanto il link al fondo della pagina.
Eseguendo il programma, vengono visualizzate nella finestra di comando
Visual dBASE il numero della versione Windows, il numero di costruzione
e la versione del Sistema operativo.
Creazione
di un eseguibile usando i files di struttura
Quello che abbiamo visto nel capitolo precedente, si può usare in un programma eseguibile generato con Visual dBASE, a patto di seguire le seguenti istruzioni:
Anche se la classe Structure di Structure.prg è un buon punto di partenza, essa soffre di alcune piccole lacune che limitano, in alcuni casi, il suo campo d’applicazione.
Per questo motivo ho creato la mia classe StructureEx, compatibile con la classe Structure, che può sostituire questa classe e che migliora i seguenti punti.
Ecco alcuni miglioramenti:
In fin dei conti, l’uso delle chiamate dirette a l'API 32 di Windows da Visual dBASE 7.01 non è molto difficile quando si affronta in modo razionale. Questo argomento non è stato trattato in maniera esaustiva, ma vuole rappresentare solo un punto di partenza. Esistono altri metodi ed ognuno è libero di usare le tecniche personali, ma ritengo che questo semplice approccio, unito a nozioni elementari del linguaggio C, risulti utile.
Visual dBASE dimostra ancora una volta, che grazie alla sua programmazione ad oggetti, si può adattare a situazioni per le quali non era previsto il suo utilizzo.
In ogni caso API Windows sono un po’ difficili a causa della loro concezione iniziale.
Ora è il vostro turno!
Nicolas Martin