 |
La déclaration :Appeler une fonction API se fait en 2 parties. Tout
d'abord, avant de faire l'appel de la fonction dans votre code, vous devez écrire une
instruction Declare de tel sorte que Visual Basic sache ou appeler cette fonction externe
(dans quelle bibliothèque ou DLL). Il faut indiquer le nom de la procédure, celui de la
bibliothèque de liaisons dynamiques ainsi que la liste des paramètres. L'instruction
Declare ressemble beaucoup a une déclaration de procédure Visual Basic.
Exemple de déclaration Declare pour procédure Sub :
[Public | Private] Declare Sub name Lib "Libname"
[Alias "aliasname"] [([Arglist])]
Exemple de déclaration Declare pour procédure Function :
[Public | Private] Declare Function name Lib "Libname"
[Alias "aliasname"] [([Arglist])] [As Type]
Regardons d'un peu plus près chaque composants de ces déclarations.
- Public ou Private
ces deux mots clés déterminent en fait, si la procédure est accessible dans toute
l'application ou seulement dans le module ou il a été déclaré.Avec Public la fonction
peut-être appeler de toute l'application, tandis que Private uniquement du même module
ou feuille.
- Declare Sub ou Declare Function
indique simplement si oui ou non la fonction appelée retourne une valeur. Donc comme pour
les fonctions Visual Basic,
Declare Function retourne toujours une valeur. (Sauf exception - très rare)
- name
désigne le nom de la fonction ou de la procédure tel qu'il sera utilisé dans votre code
Visual Basic.
Note : quelques fonctions API ont des noms non autorisé en Visual Basic ou pour d'autres
raisons demande qu'un nom et un alias soit utilisé.
- Lib "libname"
Lib est le nom de la bibliothèque (DLL) ou se trouve la fonction Api appelée.
Note : le nom de la bibliothèque doit être entre "guillemet".
- Alias "aliasname"
Alias est le nom exporté par la bibliothèque ou se trouve la fonction Api.
Note : les guillemets entre "aliasname" sont ici aussi obligatoire.
- (arglist)
Liste d'arguments (comme la liste d'arguments standards d'une fonction VB) indiquant quels
paramètres sont attendus par la procédure, le type de paramètres (long, string,
integer, etc..) et s'ils sont passés par ByVal ou ByRef.
Note : la syntaxe des arguments est : [Optional] [ByVal | ByRef] [ParamArray] nomvariable[(
)] [As type]
Le mot clé ByVal indique un passage de paramètre par valeur, ce qui signifie que
la valeur du paramètre est copiée pour la fonction appelée, qui ne travaille donc pas
sur l'original. Les valeurs des paramètres modifiés sont perdues en sortie.
Le mot clé ByRef indique un passage de paramètre par référence, ce qui signifie que
les adresses des variables sont passées aux fonctions appelées. Dans ce mode, la
fonction appelée travaille directement sur les variables de l'appelant, et toute
modification faite est valable après le retour de l'appel.
- As Type
Utilisé uniquement avec Function, spécifié le type de donnée de retour de la valeur.
Il est peut-être plus facile d'illustrer
les explications ci-dessus avec un exemple, avec la fonction FindWindow. FindWindow
retourne le handle de la fenêtre, qui donne le texte de la barre de titre ou le nom de la
classe.
Private Declare Function FindWindow Lib
"user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Regardons chaque composants de cette déclaration :
- Private
La fonction est déclaré Private au module
- Function FindWindow
Cette procédure retourne une valeur (un handle de fenêtre)
- Lib "user32" Alias
"FindWindowA"
La procédure est exporté de la bibliothèque User32.dll, ou il peut-être trouvé sous
FindWindowA
Note : souvent Api Win32 fournit des versions de ces fonctions, qui manipule des
"strings" en ANSI et UNICODE. Dans Visual Basic, vous utiliserez normalement les
versions ANSI, ainsi de cette façon le "A" se joindra au nom de la fonction.
- ByVal lpClassName As String, ByVal
lpWindowName As String
La fonction prend ces deux paramètres (les 2 sont des string, et sont passés par valeur
-ByVal)
- As Long
La valeur de retour de la fonction est un long.
L'appel :
Appeler une fonction Api peut-être aussi simple
qu'une procédure Visual Basic. Mais ce n'est pas toujours le cas ou quelque fois il faut
des dizaines de lignes de code ("pre-call" et "post-call") pour
extraire une donnée spécifique que l'on désire obtenir de cet appel Api.
Les chaînes sont représentés en C par le
type LPSTR (pointeur vers des caractères), et la plupart des DLL attendent les chaînes
terminées par NULL du language C. VB peut passer ces paramètres à l'aide des
conventions (ByVal paramname As String).
Comme expliqué ci-dessus, les chaînes de caractères transmises à des DLL se terminent
généralement par le caractère NUL (Chr$(0). Si vous déclarez ByVal un paramètre
chaîne, le caractère nul lui est automatiquement ajouté au moment de l'appel de la
routine.
Les fonctions DLL ne peuvent pas renvoyer
directement des chaînes VB, mais elles peuvent modifier des chaînes qu'on leur passe. Il
est par conséquent essentiel de définir à l'avance la longueur de tout paramètre de
chaîne VB qu'un appel DLL pourrait changer.
Lorsque l'on alloue une longueur de chaîne, il faut s'assurer d'allouer suffisamment
d'espace pour le caractère NULL de terminaison utilisée dans les chaînes du language C
(si la chaîne doit contenir X caractère, il faut allouer un tampon de chaîne de
longueur X + 1). Les routines de DLL ne restituent généralement que des chaînes
limitées à 255 caractères. La longueur d'une chaîne de caractère ne peut pas être
modifiée dans une routine de DLL si celle-ci n'a pas été écrite spécialement pour
Visual Basic. Une chaîne de caractère qui renvoie un résultat doit donc être
initialisée avec une longueur maximale (par une instruction du genre chaîne$ =
Space$(255)). Pour transmettre une chaîne vide à une fonction, il suffit de faire
appel à la constante vbNullString. Les chaînes de longueur fixe ne peuvent pas
être transmises à une DLL. Lorsqu'une DLL renvoie une chaîne de caractères, elle se
termine forcément par Chr$(0). L'expression Left$(Résultat$, InStr(Résultat$,
Chr$(0)) - 1) permet de rectifier le résultat.
Pour illustrer ces explications, voici un exemple. La déclaration Win32 Declare pour la
fonction GetComputerName. Cette fonction retourne le nom de l'ordinateur, s'il existe, via
un paramètre chaîne (String).
Private Declare Function GetComputerName Lib "kernel32" Alias
"GetComputerNameA" _
(ByVal lpBuffer As String,
nSize As Long) As Long
GetComputerName prend deux
paramètres : lpBuffer et nSize.
Le paramètre lpBuffer est une valeur chaîne (string) et est passé par ByVal. Il recevra
le nom de l'ordinateur.
Le paramètre nSize est utilisé pour fournir à l'Api la taille de la chaîne lpBuffer
quand la fonction est appelée et reçoit la taille placé dans lpBuffer par la fonction.
Si la fonction réussi, elle retourne une valeur non-zero, et si elle échoue, elle
retourne zero. Notez que les deux paramètres sont passés comme "pointers" : le
premier comme "lpsz" et le second comme pointeur au long integer nSize.
Le fragment de code
suivant montre un apel typique de GetComputerName :
Dim lResult As Long
Dim sBuffer As String
Dim lSize
As Long
' allouer une longueur de chaîne
lSize = 255
sBuffer = Space(lSize)
' appeler la fonction api
lResult = GetComputerName(sBuffer, nSize)
' tester le résultat
If lResult <> 0 Then
' succès - sBuffer contient le nom -
nSize contient la longueur
sBuffer = Left$(sBuffer, nSize)
Else
' la fonction a échouée,
End If
Avant d'appeler la
fonction, on assigne 255 à nSize et on affecte donc 255 espaces à sBuffer.
Dès lors que les paramètres ont été assignés, la fonction Api est appelée et le
résultat est testé. Si la valeur de lResult est non-zero (indique un succès), alors
deux choses sont vrai :
1. le nom de l'ordinateur a été placé dans la chaîne lpBuffer
2. la variable nSize contient la longueur du nom de l'ordinateur de
sBuffer
A ce point, il est simple d'utiliser la fonction Left$() pour extraire le caractère NULL
de terminaison de la gauche.
Finalement, certaines fonctions Api sont vraiment "fainéantes" car ils ne vous
indiquent rien du tout sur la taille de la chaîne retourné. Dans ces cas, vous
pouvez utilisez la fonction InStr() pour trouver la position du premier caractère null
(utilsez vbNullChar) puis Left$() pour extraire tout ce qui se trouve sur la gauche du
caractère null.
Attention
Ne décalez pas la taille que vous envoyez comme paramètre avec la taille actuelle du
tampon (buffer).
Page mise à jour le 13.10.1998
Webmaster : mstoll
|