Autres articles / Other articles

Etendre le vocabulaire graphics pour eForth Windows

publication: 10 mars 2023 / mis à jour 19 novembre 2024

Read this page in english

 


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é:

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:

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