Etendre le vocabulaire graphics pour eForth Windows
publication: 10 mars 2023 / mis à jour 19 novembre 2024
Accéder aux fonctions dans gdi32.dll
eFORTH permet l'accès aux librairies des fonctions Windows grâcce au mot dll
.
Dans le code source de eForth, voici comment s'effectue la connection à la librairie Gdi32:
windows definitions z" Gdi32.dll" dll Gdi32
Ici, le mot Gdi32
devient le point d'entrée pour définir les mots donnant accès à cette librairie Gdi32.dll.
A partir de ce moment, chaque mot défini pour eFORTH utilisant cette librairie Gdi32 se réfère à la documentation Microsoft:
Wingdi.h - Win32 apps
Ici, on va chercher la documentation de la fonction LineTo:
Dans cette documentation, pour la fonction LineTo, il est indiqué:
- accepte trois paramètres en entrée: hdc, x et y
- rend un paramètre en sortie: fl
Définition du mot LineTo
:
z" LineTo" 3 Gdi32 LineTo ( hdc x y -- fl )
La valeur 3 qui précède le mot Gdi32
indique que la fonction appelée doit utiliser trois paramètres.
Exemple:
graphics
: drawLines ( -- )
hdc 20 20 LineTo drop
hdc 50 20 LineTo drop
hdc 50 50 LineTo drop
hdc 20 50 LineTo drop
hdc 45 45 LineTo drop
;
Tous les mots graphiques sont définis dans le vocabulaire graphics
:
graphics definitions windows also \ The LineTo function draw a line. z" LineTo" 4 Gdi32 LineTo ( hdc x y LPPOINT -- fl ) z" Rectangle" 5 gdi32 Rectangle ( hdc left top right bottom -- fl ) z" Ellipse" 5 gdi32 Ellipse ( hdc left top right bottom -- fl ) \ The CloseFigure function close a figure in a path. z" CloseFigure" 1 gdi32 CloseFigure ( hdc -- fl ) \ The GetPixel function retrieves the red, green, blue (RGB) color value \ of the pixel at the specified coordinates. z" GetPixel" 3 gdi32 GetPixel ( hdc x y -- color ) \ The SetPixel function sets the pixel at the specified coordinates \ to the specified color. z" SetPixel" 4 gdi32 SetPixel ( hdc x y colorref -- colorref )
Il est aisé de vérifier la bonne compilation de ces mots dans le vocabulaire graphics
:
gdiError CreateFontA GetCurrentObject SetTextColor TextOutA SetPixel GetPixel
CloseFigure Ellipse Rectangle LineTo MoveToEx
flip poll wait window heart
vertical-flip viewport scale translate }g g{ screen>g box color pressed?
pixel height width event last-char last-key mouse-y mouse-x RIGHT-BUTTON
MIDDLE-BUTTON LEFT-BUTTON FINISHED TYPED RELEASED PRESSED MOTION EXPOSED
RESIZED IDLE internals
Ici, on a mis en évidence les nouveaux mots eFORTH connectés aux fonctions de la libraire Gdi32.
Vous trouverez en ligne tous les mots rajoutés au vocabulaire graphics:
 : Gdi32-definitions.fs
Trouver les fonctions disponibles dans un fichier dll
eForth Windows fait appel aux fonctions de quatre fichiers DLL:
- Gdi32.dll fonctions de gestion graphiques
- Kernel32.dll sert d'interface entre les applications et le noyau du système
- User32.dll fournit une interface de programmation d'applications
- Shell32.dll joue un rôle crucial dans l'interface utilisateur de Windows
Le rôle de eForth Windows est de piocher dans toutes ces fonctions et de proposer des mots à utiliser sans se préoccuper de savoir à quelle librairie est rattaché ce mot.
Les soucis commencent quand on souhaite rajouter un mot. Prenons comme exemple la fonction CreateDialog(), normalement définie dans User32.dll si on se fie à la documentation Microsoft. Tentative de définition en Forth:
z" CreateDialog" 4 User32 CreateDialog
Et là, c'est l'échec!
Dans la documentation Windows, il y a une variante CreateDialogA(). Faisons une nouvelle tentative:
z" CreateDialogA" 4 User32 CreateDialogA
Ca ne passe toujours pas...
La raison est que le système Windows évolue de version en versions. Certaines fonctions disparaissent, d'autres sont réécrites. Il existe un système de prototypes proposant des aalias de fonctions. Mais ces mécanismes ne sont disponibles qu'au travers des APIs de développement Windows.
Pour nous, développeur Forth, si on ne veut pas tâtonner, c'est de répertorier toutes les fonctions intégrées à un fichier DLL installé sur notre machine.
Dependency Walker
Ce programme est disponible ici:
dependencywalker.com
C'est un petit programme, facile à installer et à utiliser.
Au démarrage, cliquer sur File et sélectionnez Open.
On va analyser le fichier User32.dll. Sous windows 11, ce fichier se trouve dans le dossier Windows --> System32.
Ne vous inquiétez pas d'éventuels messages d'erreur.
Résultat de l'ouverture de User32.dll:
Ici, on a retrouvé des fonctions commençant bien par CreateDialog, mais on ne retrouve que des variantes. Aucune chance donc d'effectuer une liaison avec CreateDialog() ou CreateDialogA(). On devra donc utiliser la variante la plus adaptée.
Cette liste peut être copié pour éviter d'avoir à ouvrir User32.dll en permanence.
Vous pouvez renommer une fonction non managée à votre convenance dans votre code eForth:
z" SendMessageA" 4 User32 SendMessage ( hWnd msg wParam iParam -- LRESULT )
Ici, la fonction SendMessageA() est utilisée sous nom SendMessage
dans eForth.
Mais c'est risqué. L'autre solution est de créer un alias:
z" SendMessageA" 4 User32 SendMessageA ( hWnd msg wParam iParam -- LRESULT )
: SendMessage
SendMessageA ;
Certaines fonctions peuvent avoir un nombre de paramètres différent. L'intérêt de passer ensuite par un alias, c'est de traiter les éventuels messages d'erreur:
\ write text z" TextOutA" 5 Gdi32 TextOutA ( hdc x y lpString c -- fl ) : TextOut ( hdc x y lpString c -- fl ) TextOutA dup 0= if abort" TextOut ERROR" then ;
Pour conclure, ne cherchez pas à étendre eFORTH avec toutes les fonctions de chaque libraire. Vous y passeriez des années!
La stratégie la plus rapide et la plus simple consiste à définir exclusivement les mots exmploitant les fonctions qui vous intéressent. La programmation Windows est très complexe et nécessite l'acquisition de bases solides.
Legal: site web personnel sans commerce / personal site without seling