Le API di Windows: differenze tra VB 6 e VB .Net (2a parte)
a cura di Alessandro Del Sole (requisiti: conoscenza intermedia di VB6)Premessa
In questo articolo vorrei integrare quanto descritto nel precedente circa le varie differenze nell'utilizzo delle API tra VB 6 e il nuovo .Net, facendo un più approfondito il discorso sui tipi di dato in VB .Net.Poiché l'Application Programming Interface non si compone solo di funzioni, ma anche di tipi (oltre che di costanti), questa volta descriverò come avvengono le dichiarazioni dei tipi (cosa rivoluzionata in .Net e che tornerà utile anche nel caso non utilizziae i tipi API) e l'utilizzo dell'attributo DllImport.
I tipi di dato in Visual Basic .Net
In VB .Net uno dei cambiamenti inerenti il linguaggio riguarda i tipi di dato. E' stato soppresso il tipo di dato Any in modo che lo sviluppatore debba utilizzare dati precisi, inoltre alcuni tipi di dato sono stati modificati come riassunto nella seguente tabella:
Visual Basic 6 Visual Basic .Net Integer Short Long Integer Currency Decimal Char Long Questa (molto) sintetica tabella evidenzia alcune differenze tra i tipi di dato in Vb 6 e Vb .Net, quindi attenzione a quando effettuate il cosiddetto porting del codice da una all'altra versione.
Una funzione API dichiarata in VB 6 utilizzerà parametri quasi sempre di tipo Long di conseguenza in VB .Net il tipo di dato corretto da utilizzare sarà Integer.
In particolare per i tipi numerici il cambiamento è avvenuto anche in considerazione delle CPU di nuova generazione, in grado di elaborare numeri decisamente più grandi.Le dichiarazioni dei tipi: i vecchi UDT e le nuove strutture
Come ben sapete, numerose funzioni API utilizzano, come parametro, un tipo di dato particolare, il tipo struttura, composto da più membri a loro volta di tipo diverso. In Visual Basic 6 un tipo di dato di questo genere viene definito UDT (User Defined Type), e viene creato utilizzando il costrutto Type...End Type. Riporto a titolo esemplificativo la dichiarazione del tipo RGBQUAD utilizzato da alcune delle API grafiche:Type RGBQUAD rgbBlue As Byte rgbGreen As Byte rgbRed As Byte rgbReserved As Byte End TypeIl tipo RGBQUAD, utilizzato per la definizione dei colori utilizzando le componenti RGB (rosso, verde e blu), espone 4 membri di tipo Byte. Visual Basic .Net consente la creazione di tipi user-defined attraverso il costrutto Structure...End Structure.
In apparenza sembra solo un cambiamento di parole chiave, in realtà la nuova versione del linguaggio impone cambiamenti notevoli nella sintassi e (ovviamente...) potenzia la creazione di propri tipi di dato.
Prima di passare ad un esempio pratico, va sottolineato che ogni membro della struttura, ad esempio nel caso precedente rgbBlue, deve essere dichiarato con Dim, Private o Public, in modo da definirne le possibilità di accesso da parte dell'utente.
In più è stata data la possibilità allo sviluppatore di aggiungere all'interno di una struttura una o più funzioni!
Ma vediamo come in Visual Basic .Net viene trasformato il codice precedente:Structure RGBQUAD Dim rgbBlue As Byte Dim rgbGreen As Byte Dim rgbRed As Byte Dim rgbReserved As Byte End Type
Non vorrei dilungarmi sulla definizione di array all'interno di tipi, in primo luogo perché è un concetto non semplice, in secondo luogo perché anch'io sto continuando a documentarmi, comunque Vb .Net non consente di definire delle matrici ben precise all'interno di una struttura, ma dovrà essere fatto successivamente. Sottolineo, inoltre, che tutte le matrici hanno base zero pertanto il vecchio codice VB 6Dim x(0 To 10)non sarà più corretto. Ad esempio il codice seguente genera errore:
Structure RGBQUAD Dim rgbBlue(2) As Byte ...Una soluzione al problema è quella di definire la matrice una volta creata un'istanza della struttura, più o meno in questo modo:
Structure Prova Dim Elemento() As Byte End Structure Private Sub Genera() Dim P as Prova P.Elemento = New Byte() {2} 'Il numero è tra parentesi graffe End SubPoiché lo scopo dell'articolo non è quello di illustrare la creazione di matrici, vi rimando per questo ad altri approfondimenti, l'importante è avere capito come avviene la creazione di un tipo di dato definito dall'utente, cosa molto frequente se si utilizzano le dichiarazioni API "vecchio stile", per intenderci nella modalità VB 6 anche in VB .Net, se si vuole rendere meno traumatico il passaggio ai nuovi NameSpaces e alle classi del .Net Framework.
L'attributo
Visual Basic .Net fornisce un modo migliore per dichiarare delle funzioni contenute in delle librerie DLL esterne, l'attributo.
Tale attributo permette di dichiarare la funzione esterna senza dover implementare alcun tipo di codice, in quanto si sottintende che l'implementazione sia presente nella Dll stessa.
Per poterlo utilizzare è necessario includere la seguente riga di codice nelle dichiarazioni del modulo (ad esempio in AssemblyInfo.vb):Imports System.Runtime.InteropServicesAd esempio supponiamo di voler dichiarare la funzione Api GetPixel per leggere il colore di un pixel alle coordinate specificate.
' Dichiarazione in VB 6 Declare Function GetPixel Lib "gdi32" Alias "GetPixel" _ (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long ' Dichiarazione in VB .Net con l'istruzione Declare Declare Function GetPixel Lib "gdi32" Alias "GetPixel" _ (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer) As Integer ' Dichiarazione in VB .Net conFunction GetPixel(ByVal hdc As Integer, _ ByVal x As Integer, ByVal y As Integer) As Integer 'Niente da digitare End Function L'utilizzo della funzione rimarrà invariato.
Disclaimer :o)
Alla fine di questo articolo vorrei scusarmi per eventuali imprecisioni od imperfezioni, ma come per molti di voi anche per me il mondo di Visual Basic .Net è una continua scoperta, di conseguenza è possibile che io sbagli qualcosa anche se cerco di limitare i danni!Per eventuali quesiti, critiche o suggerimenti, vi ricordo comunque che potete contattarmi al mio indirizzo e-mail.