Procédure pas à pas : appel des API Windows (Visual Basic)

Les API Windows sont des bibliothèques de liens dynamiques (DLL) qui font partie du système d’exploitation Windows. Vous les utilisez pour effectuer des tâches lorsqu’il est difficile de rédiger vous-même des procédures équivalentes. Par exemple, Windows fournit une fonction nommée FlashWindowEx qui vous permet de rendre la barre de titre d’une application alternative entre les nuances claires et sombres.

L’avantage d’utiliser des API Windows dans votre code est qu’elles peuvent gagner du temps de développement, car elles contiennent des dizaines de fonctions utiles déjà écrites et en attente d’être utilisées. L’inconvénient est que les API Windows peuvent être difficiles à utiliser et ne pardonnent pas lorsque les choses tournent mal.

Les API Windows représentent une catégorie spéciale d’interopérabilité. Les API Windows n’utilisent pas de code managé, n’ont pas de bibliothèques de type intégrées et utilisent des types de données différents de ceux utilisés avec Visual Studio. En raison de ces différences, et parce que les API Windows ne sont pas des objets COM, l’interopérabilité avec les API Windows et le .NET Framework est effectuée à l’aide d’un appel de plateforme ou de PInvoke. L'appel de code non managé est un service qui permet au code managé d'appeler des fonctions non managées implémentées dans des DLL. Pour plus d’informations, consultez Consommation de fonctions DLL non managées. Vous pouvez utiliser PInvoke en Visual Basic à l’aide de l’instruction ou de l’application Declare de l’attribut DllImport à une procédure vide.

Les appels d’API Windows étaient une partie importante de la programmation Visual Basic dans le passé, mais sont rarement nécessaires avec Visual Basic .NET. Dans la mesure du possible, vous devez utiliser du code managé à partir du .NET Framework pour effectuer des tâches, au lieu d’appels d’API Windows. Cette procédure pas à pas fournit des informations pour les situations dans lesquelles l’utilisation des API Windows est nécessaire.

Notes

Il est possible que pour certains des éléments de l'interface utilisateur de Visual Studio, votre ordinateur affiche des noms ou des emplacements différents de ceux indiqués dans les instructions suivantes. L'édition de Visual Studio dont vous disposez et les paramètres que vous utilisez déterminent ces éléments. Pour plus d’informations, consultez Personnalisation de l’IDE.

Appels d’API à l’aide de Declare

Le moyen le plus courant d’appeler des API Windows consiste à utiliser l’instruction Declare.

Déclarer une procédure DLL

  1. Déterminez le nom de la fonction que vous souhaitez appeler, ainsi que ses arguments, types d’arguments et valeur de retour, ainsi que le nom et l’emplacement de la DLL qui le contient.

    Notes

    Pour plus d’informations sur les API Windows, consultez la documentation du Kit de développement logiciel (SDK) Win32 dans l’API Windows du SDK de plateforme. Pour plus d’informations sur les constantes utilisées par les API Windows, examinez les fichiers d’en-tête tels que les Windows.h inclus dans le Kit de développement logiciel (SDK) de plateforme.

  2. Ouvrez un nouveau projet d’application Windows en cliquant sur Nouveau dans le menu Fichier, puis sur Projet. La boîte de dialogue Nouveau projet apparaît.

  3. Sélectionnez Application Windows dans la liste des modèles de projet Visual Basic. Le nouveau projet s’affiche.

  4. Ajoutez la fonction Declare suivante à la classe ou au module dans lequel vous souhaitez utiliser 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
    

Parties de l’instruction Declare

L’instruction Declare inclut les éléments suivants.

Modificateur automatique

Le modificateur Auto indique au Common Language Runtime de convertir la chaîne basée sur le nom de la méthode en fonction des règles Common Language Runtime (ou du nom d’alias si spécifié).

Mots clés Lib et Alias

Le nom suivant le mot clé Function est le nom utilisé par votre programme pour accéder à la fonction importée. Il peut être identique au nom réel de la fonction que vous appelez, ou vous pouvez utiliser n’importe quel nom de procédure valide, puis utiliser le mot clé Alias pour spécifier le nom réel de la fonction que vous appelez.

Spécifiez le mot clé Lib, suivi du nom et de l’emplacement de la DLL qui contient la fonction que vous appelez. Vous n’avez pas besoin de spécifier le chemin d’accès des fichiers situés dans les répertoires système Windows.

Utilisez le mot clé Alias si le nom de la fonction que vous appelez n’est pas un nom de procédure Visual Basic valide ou est en conflit avec le nom d’autres éléments de votre application. Alias indique le nom vrai de la fonction appelée.

Déclarations d’argument et de type de données

Déclarez les arguments et leurs types de données. Cette partie peut être difficile, car les types de données que Windows utilise ne correspondent pas aux types de données Visual Studio. Visual Basic effectue beaucoup de travail pour vous en convertissant des arguments en types de données compatibles, un processus appelé marshaling. Vous pouvez contrôler explicitement la façon dont les arguments sont marshalés à l’aide de l’attribut MarshalAsAttribute défini dans l’espace de noms System.Runtime.InteropServices.

Notes

Les versions précédentes de Visual Basic vous ont permis de déclarer des paramètres As Any, ce qui signifie que les données d’un type de données peuvent être utilisées. Visual Basic nécessite que vous utilisiez un type de données spécifique pour toutes les instructions Declare.

Constantes de l’API Windows

Certains arguments sont des combinaisons de constantes. Par exemple, l’API MessageBox indiquée dans cette procédure pas à pas accepte un argument entier appelé Typ qui contrôle l’affichage de la boîte de message. Vous pouvez déterminer la valeur numérique de ces constantes en examinant les instructions #define dans le fichier WinUser.h. Les valeurs numériques sont généralement affichées en hexadécimal. Vous pouvez donc utiliser une calculatrice pour les ajouter et les convertir en décimales. Par exemple, si vous souhaitez combiner les constantes pour le style MB_ICONEXCLAMATION d’exclamation 0x00000030 et le style MB_YESNO Oui/Non 0x00000004, vous pouvez ajouter les nombres et obtenir un résultat de 0x00000034, ou 52 décimales. Bien que vous puissiez utiliser directement le résultat décimal, il est préférable de déclarer ces valeurs en tant que constantes dans votre application et de les combiner à l’aide de l’opérateur Or.

Déclarer des constantes pour les appels d’API Windows
  1. Consultez la documentation relative à la fonction Windows que vous appelez. Déterminez le nom des constantes qu’il utilise et le nom du fichier .h qui contient les valeurs numériques de ces constantes.

  2. Utilisez un éditeur de texte, tel que le Bloc-notes, pour afficher le contenu du fichier d’en-tête (.h) et rechercher les valeurs associées aux constantes que vous utilisez. Par exemple, l’API MessageBox utilise la constante MB_ICONQUESTION pour afficher un point d’interrogation dans la boîte de message. La définition est MB_ICONQUESTION dans WinUser.h et apparaît comme suit :

    #define MB_ICONQUESTION 0x00000020L

  3. Ajoutez des instructions Const équivalentes à votre classe ou module pour rendre ces constantes disponibles pour votre application. Par exemple :

    Const MB_ICONQUESTION As Integer = &H20
    Const MB_YESNO As Integer = &H4
    Const IDYES As Integer = 6
    Const IDNO As Integer = 7
    
Appeler la procédure DLL
  1. Ajoutez un bouton nommé Button1 au formulaire de démarrage de votre projet, puis double-cliquez dessus pour afficher son code. Le gestionnaire d’événements du bouton s’affiche.

  2. Ajoutez du code au gestionnaire d’événements Click pour le bouton que vous avez ajouté, pour appeler la procédure et fournir les arguments appropriés :

    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. Exécutez le projet en appuyant sur F5. La boîte de message s’affiche avec les boutons Oui et Non de réponse. Cliquez sur l’une ou l’autre.

Marshalling des données

Visual Basic convertit automatiquement les types de données de paramètres et les valeurs de retour pour les appels d’API Windows, mais vous pouvez utiliser l’attribut MarshalAs pour spécifier explicitement les types de données non managés attendus par une API. Pour plus d’informations sur le marshaling d’interopérabilité, consultez Marshaling d’interopérabilité.

Utiliser Declare et MarshalAs dans un appel d’API
  1. Déterminez le nom de la fonction que vous souhaitez appeler, ainsi que ses arguments, types de données et valeur de retour.

  2. Pour simplifier l’accès à l’attribut MarshalAs, ajoutez une instruction Imports en haut du code de la classe ou du module, comme dans l’exemple suivant :

    Imports System.Runtime.InteropServices
    
  3. Ajoutez un prototype de fonction pour la fonction importée à la classe ou au module que vous utilisez et appliquez l’attribut MarshalAs aux paramètres ou à la valeur de retour. Dans l’exemple suivant, un appel d’API qui s’attend à ce que le type void* soit marshalé comme suit AsAny :

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

Appels d’API à l’aide de DllImport

L’attribut DllImport fournit un deuxième moyen d’appeler des fonctions dans des DLL sans bibliothèques de type. DllImport équivaut approximativement à l’utilisation d’une instruction Declare, mais permet de mieux contrôler la façon dont les fonctions sont appelées.

Vous pouvez utiliser DllImport avec la plupart des appels d’API Windows tant que l’appel fait référence à une méthode partagée (parfois appelée statique). Vous ne pouvez pas utiliser de méthodes qui nécessitent une instance d’une classe. Contrairement aux instructions Declare, les appels DllImport ne peuvent pas utiliser l’attribut MarshalAs.

Appeler une API Windows à l’aide de l’attribut DllImport

  1. Ouvrez un nouveau projet d’application Windows en cliquant sur Nouveau dans le menu Fichier, puis sur Projet. La boîte de dialogue Nouveau projet apparaît.

  2. Sélectionnez Application Windows dans la liste des modèles de projet Visual Basic. Le nouveau projet s’affiche.

  3. Ajoutez un bouton nommé Button2 au formulaire de démarrage.

  4. Double-cliquez sur Button2 pour ouvrir la vue de code du formulaire.

  5. Pour simplifier l’accès à DllImport, ajoutez une instruction Imports en haut du code de la classe de formulaire de démarrage :

    Imports System.Runtime.InteropServices
    
  6. Déclarez une fonction vide précédant l’instruction End Class du formulaire et nommez la fonction MoveFile.

  7. Appliquez les modificateurs Public et Shared à la déclaration de fonction et définissez les paramètres de MoveFile en fonction des arguments utilisés par la fonction API Windows :

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

    Votre fonction peut avoir n’importe quel nom de procédure valide ; l’attribut DllImport spécifie le nom dans la DLL. Elle gère également le marshaling d’interopérabilité pour les paramètres et les valeurs de retour. Vous pouvez donc choisir des types de données Visual Studio similaires aux types de données utilisés par l’API.

  8. Appliquez l’attribut DllImport à la fonction vide. Le premier paramètre est le nom et l’emplacement de la DLL contenant la fonction que vous appelez. Vous n’avez pas besoin de spécifier le chemin d’accès des fichiers situés dans les répertoires système Windows. Le deuxième paramètre est un argument nommé qui spécifie le nom de la fonction dans l’API Windows. Dans cet exemple, l’attribut DllImport force les appels à MoveFile être transférés MoveFileW dans KERNEL32.DLL. La méthode MoveFileW copie un fichier du chemin d’accès src au chemin d’accès 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. Ajoutez du code au gestionnaire d’événements Button2_Click pour appeler la fonction :

    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. Créez un fichier nommé Test.txt et placez-le dans le répertoire C:\Tmp sur votre disque dur. Créez le répertoire Tmp si nécessaire.

  11. Appuyez sur F5 pour démarrer l'application. Le formulaire principal s’affiche.

  12. Cliquez sur Button2. Le message « Le fichier a été déplacé correctement » s’affiche si le fichier peut être déplacé.

Voir aussi