Procedura dettagliata: chiamata delle API di Windows (Visual Basic)

Le API Windows sono librerie a collegamento dinamico (DLL) che fanno parte del sistema operativo Windows. È possibile usarle per eseguire attività quando è difficile scrivere procedure equivalenti personalizzate. Ad esempio, Windows fornisce una funzione denominata FlashWindowEx che consente di impostare la barra del titolo per un'applicazione alternativa tra sfumature chiare e scure.

Il vantaggio dell'uso delle API di Windows nel codice è che possono risparmiare tempo di sviluppo perché contengono decine di funzioni utili già scritte e in attesa di essere usate. Lo svantaggio è che le API di Windows possono essere difficili da usare e non perdonano quando si verificano dei problemi.

Le API Windows rappresentano una categoria speciale di interoperabilità. Le API Di Windows non usano codice gestito, non dispongono di librerie di tipi predefinite e usano tipi di dati diversi da quelli usati con Visual Studio. A causa di queste differenze e poiché le API di Windows non sono oggetti COM, l'interoperabilità con le API di Windows e .NET Framework viene eseguita tramite platform invoke o PInvoke. Platform invoke è un servizio che consente al codice gestito di chiamare funzioni non gestite implementate nelle DLL. Per altre informazioni, vedere Utilizzo di funzioni di DLL non gestite. È possibile utilizzare PInvoke in Visual Basic usando l'istruzione Declare o applicando l'attributo DllImport a una routine vuota.

Le chiamate API di Windows erano una parte importante della programmazione Visual Basic in passato, ma raramente sono necessarie con Visual Basic .NET. Quando possibile, è consigliabile usare il codice gestito di .NET Framework per eseguire attività, anziché le chiamate API di Windows. Questa procedura dettagliata fornisce informazioni per le situazioni in cui è necessario usare le API di Windows.

Nota

I nomi o i percorsi visualizzati per alcuni elementi dell'interfaccia utente di Visual Studio nelle istruzioni seguenti potrebbero essere diversi nel computer in uso. La versione di Visual Studio in uso e le impostazioni configurate determinano questi elementi. Per altre informazioni, vedere Personalizzazione dell'IDE.

Chiamate API tramite Declare

Il modo più comune per chiamare le API di Windows consiste nell'usare l'istruzione Declare.

Per dichiarare una routine DLL

  1. Determinare il nome della funzione che si desidera chiamare, oltre ai relativi argomenti, tipi di argomento e valore restituito, nonché il nome e il percorso della DLL che lo contiene.

    Nota

    Per informazioni complete sulle API di Windows, vedere la documentazione di Win32 SDK nell'API Windows di Platform SDK. Per altre informazioni sulle costanti usate dalle API di Windows, esaminare i file di intestazione come Windows.h inclusi in Platform SDK.

  2. Aprire un nuovo progetto applicazione Windows facendo clic su Nuovo dal menu File e quindi su Progetto. Verrà visualizzata la finestra di dialogo Nuovo progetto .

  3. Selezionare Applicazione Windows dall'elenco dei modelli di progetto di Visual Basic. Viene visualizzato il nuovo progetto.

  4. Aggiungere la funzione Declare seguente alla classe o al modulo in cui si vuole usare la DLL:

    Declare Auto Function MBox Lib "user32.dll" Alias "MessageBox" (
        ByVal hWnd As Integer,
        ByVal txt As String,
        ByVal caption As String,
        ByVal Typ As Integer) As Integer
    

Parti dell'istruzione Declare (Declare Statement)

L'istruzione Declare include gli elementi seguenti.

Modificatore automatico

Il modificatore Auto indica al runtime di convertire la stringa in base al nome del metodo secondo le regole di Common Language Runtime (o al nome alias, se specificato).

Parole chiave Lib e Alias

Il nome che segue la parola chiave Function è il nome usato dal programma per accedere alla funzione importata. Può essere uguale al nome reale della funzione che si sta chiamando oppure è possibile usare qualsiasi nome di procedura valido e quindi usare la parola chiave Alias per specificare il nome reale della funzione che si sta chiamando.

Specificare la parola chiave Lib, seguita dal nome e dalla posizione della DLL che contiene la funzione che si sta chiamando. Non è necessario specificare il percorso dei file che si trovano nelle directory di sistema di Windows.

Usare la parola chiave Alias se il nome della funzione che si sta chiamando non è un nome di routine di Visual Basic valido o è in conflitto con il nome di altri elementi nell'applicazione. Alias indica il nome vero della funzione chiamata.

Dichiarazioni di argomenti e tipi di dati

Dichiarare gli argomenti e i relativi tipi di dati. Questa parte può risultare complessa perché i tipi di dati usati da Windows non corrispondono ai tipi di dati di Visual Studio. Visual Basic esegue molte operazioni convertendo argomenti in tipi di dati compatibili, un processo denominato marshalling. È possibile controllare in modo esplicito la modalità di marshalling degli argomenti usando l'attributo MarshalAsAttribute definito nello spazio dei nomi System.Runtime.InteropServices.

Nota

Le versioni precedenti di Visual Basic hanno consentito di dichiarare i parametri As Any, ovvero che è possibile usare i dati di qualsiasi tipo di dati. Visual Basic richiede l'uso di un tipo di dati specifico per tutte le istruzioni Declare.

Costanti dell'API Windows

Alcuni argomenti sono combinazioni di costanti. Ad esempio, l'API MessageBox illustrata in questa procedura dettagliata accetta un argomento integer denominato Typ che controlla la modalità di visualizzazione della finestra di messaggio. È possibile determinare il valore numerico di queste costanti esaminando le istruzioni #define nel file WinUser.h. I valori numerici vengono in genere visualizzati in formato esadecimale, pertanto è consigliabile usare una calcolatrice per aggiungerli e convertirli in decimali. Ad esempio, se si desidera combinare le costanti per lo stile esclamativo MB_ICONEXCLAMATION 0x00000030 e lo stile Sì/No MB_YESNO 0x00000004, è possibile aggiungere i numeri e ottenere un risultato di 0x00000034 o 52 decimali. Sebbene sia possibile usare direttamente il risultato decimale, è preferibile dichiarare questi valori come costanti nell'applicazione e combinarli usando l'operatore Or.

Per dichiarare delle costanti per le chiamate API di Windows
  1. Consultare la documentazione relativa alla funzione di Windows che si sta chiamando. Determinare il nome delle costanti utilizzate e il nome del file con estensione h che contiene i valori numerici per queste costanti.

  2. Usare un editor di testo, ad esempio Blocco note, per visualizzare il contenuto del file di intestazione (h) e trovare i valori associati alle costanti in uso. Ad esempio, l'API MessageBox usa la costante MB_ICONQUESTION per visualizzare un punto interrogativo nella finestra di messaggio. La definizione per MB_ICONQUESTION è in WinUser.h e viene visualizzata come segue:

    #define MB_ICONQUESTION 0x00000020L

  3. Aggiungere istruzioni Const equivalenti alla classe o al modulo per rendere disponibili queste costanti per l'applicazione. Ad esempio:

    Const MB_ICONQUESTION As Integer = &H20
    Const MB_YESNO As Integer = &H4
    Const IDYES As Integer = 6
    Const IDNO As Integer = 7
    
Per chiamare la procedura DLL
  1. Aggiungere un pulsante denominato Button1 al modulo di avvio per il progetto e quindi fare doppio clic su di esso per visualizzarne il codice. Viene visualizzato il gestore eventi per il pulsante.

  2. Aggiungere codice al gestore eventi Click per il pulsante aggiunto, per chiamare la routine e fornire gli argomenti appropriati:

    Private Sub Button1_Click(ByVal sender As System.Object,
        ByVal e As System.EventArgs) Handles Button1.Click
    
        ' Stores the return value.
        Dim RetVal As Integer
        RetVal = MBox(0, "Declare DLL Test", "Windows API MessageBox",
            MB_ICONQUESTION Or MB_YESNO)
    
        ' Check the return value.
        If RetVal = IDYES Then
            MsgBox("You chose Yes")
        Else
            MsgBox("You chose No")
        End If
    End Sub
    
  3. Eseguire il progetto premendo F5. La finestra di messaggio viene visualizzata con pulsanti di risposta e No. Fare clic su uno dei due.

Marshalling dei dati

Visual Basic converte automaticamente i tipi di dati dei parametri e i valori restituiti per le chiamate API di Windows, ma è possibile usare l'attributo MarshalAs per specificare in modo esplicito i tipi di dati non gestiti previsti da un'API. Per altre informazioni sul marshalling di interoperabilità, vedere Marshalling di interoperabilità.

Per usare Declare e MarshalAs in una chiamata API
  1. Determinare il nome della funzione che si desidera chiamare, oltre ai relativi argomenti, tipi di dati e valore restituito.

  2. Per semplificare l'accesso all'attributo MarshalAs, aggiungere un'istruzione Imports all'inizio del codice per la classe o il modulo, come nell'esempio seguente:

    Imports System.Runtime.InteropServices
    
  3. Aggiungere un prototipo di funzione per la funzione importata alla classe o al modulo in uso, e applicare l'attributo MarshalAs ai parametri o al valore restituito. Nell'esempio seguente, viene eseguito il marshalling di una chiamata API, che prevede il tipo void*, come AsAny:

    Declare Sub SetData Lib "..\LIB\UnmgdLib.dll" (
        ByVal x As Short,
        <MarshalAsAttribute(UnmanagedType.AsAny)>
            ByVal o As Object)
    

Chiamate API con DllImport

L'attributo DllImport fornisce un secondo modo per chiamare le funzioni nelle DLL senza librerie dei tipi. DllImport è approssimativamente equivalente all'uso di un'istruzione Declare, ma fornisce un maggiore controllo sul modo in cui vengono chiamate le funzioni.

È possibile usare DllImport con la maggior parte delle chiamate API di Windows, purché la chiamata faccia riferimento a un metodo condiviso (talvolta chiamato statico). Non è possibile utilizzare metodi che richiedono un'istanza di una classe. A differenza delle istruzioni Declare, le chiamate DllImport non possono usare l'attributo MarshalAs.

Per chiamare un'API di Windows usando l'attributo DllImport

  1. Aprire un nuovo progetto applicazione Windows facendo clic su Nuovo dal menu File e quindi su Progetto. Verrà visualizzata la finestra di dialogo Nuovo progetto .

  2. Selezionare Applicazione Windows dall'elenco dei modelli di progetto di Visual Basic. Viene visualizzato il nuovo progetto.

  3. Aggiungere un pulsante denominato Button2 al modulo di avvio.

  4. Fare doppio clic su Button2 per aprire la visualizzazione del codice per il modulo.

  5. Per semplificare l'accesso a DllImport, aggiungere un'istruzione Imports all'inizio del codice per la classe del modulo di avvio:

    Imports System.Runtime.InteropServices
    
  6. Dichiarare una funzione vuota che precede l'istruzione End Class per il form e denominare la funzione MoveFile.

  7. Applicare i modificatori Public e Shared alla dichiarazione di funzione e impostare i parametri per MoveFile in base agli argomenti usati dalla funzione API di Windows:

    Public Shared Function MoveFile(
        ByVal src As String,
        ByVal dst As String) As Boolean
        ' Leave the body of the function empty.
    End Function
    

    La funzione può avere qualsiasi nome di procedura valido; l'attributo DllImport specifica il nome nella DLL. Gestisce anche il marshalling dell'interoperabilità per i parametri e i valori restituiti, quindi è possibile scegliere tipi di dati di Visual Studio simili ai tipi di dati usati dall'API.

  8. Applicare l'attributo DllImport alla funzione vuota. Il primo parametro è il nome e il percorso della DLL contenente la funzione che si sta chiamando. Non è necessario specificare il percorso dei file che si trovano nelle directory di sistema di Windows. Il secondo parametro è un argomento denominato che specifica il nome della funzione nell'API di Windows. In questo esempio, l'attributo DllImport forza le chiamate a MoveFile da inoltrare a MoveFileW in KERNEL32.DLL. Il metodo MoveFileW copia un file dal percorso src al percorso dst.

    <DllImport("KERNEL32.DLL", EntryPoint:="MoveFileW", SetLastError:=True,
        CharSet:=CharSet.Unicode, ExactSpelling:=True,
        CallingConvention:=CallingConvention.StdCall)>
    Public Shared Function MoveFile(
        ByVal src As String,
        ByVal dst As String) As Boolean
        ' Leave the body of the function empty.
    End Function
    
  9. Aggiungere codice al gestore eventi Button2_Click per chiamare la funzione:

    Private Sub Button2_Click(ByVal sender As System.Object,
        ByVal e As System.EventArgs) Handles Button2.Click
    
        Dim RetVal As Boolean = MoveFile("c:\tmp\Test.txt", "c:\Test.txt")
        If RetVal = True Then
            MsgBox("The file was moved successfully.")
        Else
            MsgBox("The file could not be moved.")
        End If
    End Sub
    
  10. Creare un file denominato Test.txt e inserirlo nella directory C:\Tmp sul disco rigido. Creare la directory Tmp, se necessario.

  11. Premere F5 per avviare l’applicazione. Viene visualizzato il modulo principale.

  12. Fare clic su Button2. Il messaggio "Il file è stato spostato correttamente" viene visualizzato se il file può essere spostato.

Vedi anche