Le jargon API
L'utilisation en VBA des fonctions API est assez contraignante. Elle impose de se plier aux règles de programmation Windows. C'est à dire notamment de déclarer avec précision les fonctions et les variables (ce dont VBA sait généralement se passer), et d'utiliser un vocabulaire assez différent de celui du VBA.
• Les déclarations de fonctions doivent être faites dans un module standard. Elles se présentent sous la forme :
Declare Function MessageBeep Lib "user32" (ByVal wType As Long) As Long
Dans cet exemple, la dll utilisé est user32 et la fonction visée est MessageBeep. Elle utilise un seul paramètre wType de type Long et renvoie une valeur de type Long.
Si la fonction nécessite plusieurs paramètres, ils sont séparés par des virgules :
Declare Function WinExec Lib "kernel32" (ByVal lpCmdLine As String, ByVal nCmdShow As Long) As Long (un paramètre String et un paramètre Long).
• Il est parfois utile de changer le nom de la fonction de dll. C'est par exemple nécessaire pour éviter des conflits si le nom de la fonction de dll a une autre signification en VBA. On utilise alors un Alias. Par exemple, Beep est une fonction VBA (aucun paramètre). C'est aussi le nom d'une fonction API de la dll kernel32 (deux paramètres). Si on souhaite pouvoir utiliser en même temps les deux fonctions, il suffit de renommer la fonction de dll :
Declare Function beep_api Lib "kernel32" Alias "Beep" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
.
• Pour manipuler des variables texte dont la longueur est inconnue, les API utilisent souvent des tampons (buffer), chaines vides de longueur fixée qui peuvent recevoir des caractères :
Declare Function nom_utilisateur Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
La fonction GetUserNameA va renvoyer le nom d'utilisateur dan sun tampon (lpBuffer) de longueur nSize.
Il y a plusieurs méthodes pour créer un tampon zaza de longueur 100. Il faut toujours le déclarer :
La méthode plus rapide :
Dim zaza As String * 100
La plus classique :
Dim zaza As String
zaza=String(100, Chr$(0))
ou encore :
Dim zaza As String
zaza=space(100)
ou bien :
Dim zaza As String
zaza=string(100," ")
Attention a toujours prévoir une longueur suffisante pour que le buffer puisse contenir tous les caractères de la chaine renvoyée par la fonction.
Une fois la chaine renvoyée par la fonction dans le tampon zaza, il faut n'en conserver que les caractères non vides :
on peut par exemple écrire :
Left(zaza, InStr(1, zaza, Chr(0)) - 1)
Par exemple, la macro suivante renvoie le nom de l'ordinateur :
Declare Function nom_ordi Lib "kernel32" Alias "GetComputerNameA" (ByVal lbbuffer As String, nsize As Long) As Long
Sub nom_de_l_ordinateur()
Dim zaza As String
zaza = Space(50)
Call nom_ordi(zaza, 51)
MsgBox Left(zaza, InStr(1, zaza, Chr(0)) - 1)
End Sub
• Autre notion importante, le pointeur (handle).
Il s'agit simplement d'un numéro identifiant (par exemple) une fenêtre. Il peut être récupéré par des fonctions comme GetActiveWindow, GetWindow, FindWindowA, GetWindowDC, GetDC... et il est utilisé par toutes les fonctions relatives aux fenêtres.
L'exemple qui suit montre comment accéder au titre de la fenêtre active :
GetActiveWindow() renvoie le pointeur de le fenêtre active.
Ce pointeur est utilisé par la fonction GetWindowTextA qui renvoie le titre dans un tampon.
Declare Function get_titre Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare Function GetActiveWindow Lib "user32" () As Long
Sub nom_de_la_fenetre()
Dim nom_fenetre As String * 200
Call get_titre(GetActiveWindow(), nom_fenetre, 201)
MsgBox Left(nom_fenetre, InStr(nom_fenetre, Chr$(0)) - 1)
End Sub
Avec une boucle, on peut de la même façon faire la liste de toutes les fenêtres ouvertes (cliquez ici).
• Les fonctions API utilisent souvent d'autres types de données que les données String, Long, les pointeurs ou les tampons.
Elles utilisent souvent des données de type personnalisé qui faut aussi déclarer. Par exemple pour manipuler les coordonnées d'un point, on utilise un type personnalisé qui contient à la fois l'abscisse et l'ordonnée du point :
Par exemple, GetCursorPos va renvoyer les coordonnées du curseur de la souris :
Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Type POINTAPI
x As Long
y As Long
End Type
Sub coordonnées()
Dim point As POINTAPI
GetCursorPos point
MsgBox "la souris est en " & point.x & " / " & point.y
End Sub
Les API
Les correspondances entre macros VBA, macros Excel 4, fonctions de feuilles de calcul et API.