Tutorial 5: Encore plus
A propos des Textes

Allons plus loin avec les attributs de texte, c'est-à-dire. La fonte (Fonte = Assortissement complet de caractères de même type)et la couleur.

Downloadez le fichier en exemple ici.

Théorie:

Le système de couleur de Windows est basé sur le système RGB, R=red, G=Green, B=Blue. Si vous souhaitez définir une couleur dans Windows, vous devez exprimer votre couleur recherchée en combinant ces trois couleurs principales. Chaque plage de couleur (R,G, ou B) a une gamme de 0 à 255 (valeur exprimée en octet). Par exemple, si vous voulez la couleur rouge pur, vous devez employer 255,0,0. Ou si vous voulez la couleur blanc pur, vous devez employer 255,255,255. Vous verrez en expérimentant, qu'obtenir la couleur dont vous avez besoin est très difficile avec ce système puisque vous devez avoir un bon 'felling' pour mélanger les couleurs correspondantes.
Pour la couleur du texte et du fond, vous employez SetTextColor et SetBkColor, tous deux exigent l'handle du contexte de dispositif et une valeur RGB sur 32 bits. La structure de la valeur 32 bits RGB est définie ainsi :

RGB_value struct
    unused   db 0
    blue       db ?
    green     db ?
    red        db ?
RGB_value ends

Notez que le premier octet n'est pas utilisé et doit être à zéro. L'ordre des trois octets restant est inversé, il s'agit du Bleu, vert, rouge (et non pas RGB). Cependant, nous n'emploierons pas cette structure puisque elle est encombrante à initialiser et à employer. Nous créerons une macro à la place. La macro recevra trois paramètres : les valeurs rouges, vertes et bleues. Ceci produira la valeur RGB désirée, et le stockera sur 32 bits dans eax. La macro est la suivante :

RGB macro red,green,blue
    xor    eax,eax
    mov  ah,blue
    shl     eax,8
    mov  ah,green
    mov  al,red
endm

Vous pouvez mettre cette macro dans le fichier INCLUDE pour une utilisation future.
Vous pouvez "créer" une fonte en appelant CreateFont ou CreateFontIndirect. La différence entre ces deux fonctions est que CreateFontIndirect reçoit seulement un paramètre : 'un indicateur logique sur la structure de la fonte', à savoir : LOGFONT. CreateFontIndirect est le plus flexible de deux en particulier si vos programmes ont besoin de changer fréquemment de fontes. Cependant, dans notre exemple, nous "créerons" seulement une fonte pour la démonstration, nous échapperons donc à CreateFont. Après l'appel à CreateFont, il renverra l'handle à une fonte que vous devez choisir dans le contexte de dispositif. Après cela, chaque texte affiché par la fonction API (Paint) emploiera la fonte que nous avons choisie dans le contexte de dispositif.
 

Contenu:

.386
.model flat,stdcall
option casemap:none

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib

RGB macro red,green,blue
        xor eax,eax
        mov ah,blue
        shl eax,8
        mov ah,green
        mov al,red
endm

.data
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
TestString db "Win32 assembly is great and easy!",0
FontName db "script",0

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?

.code
 start:
    invoke GetModuleHandle, NULL
    mov    hInstance,eax
    invoke GetCommandLine
    mov CommandLine,eax

    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
   LOCAL wc:WNDCLASSEX
   LOCAL msg:MSG
   LOCAL hwnd:HWND
   mov   wc.cbSize,SIZEOF WNDCLASSEX
   mov   wc.style, CS_HREDRAW or CS_VREDRAW
   mov   wc.lpfnWndProc, OFFSET WndProc
   mov   wc.cbClsExtra,NULL
   mov   wc.cbWndExtra,NULL
   push  hInst
   pop   wc.hInstance
   mov   wc.hbrBackground,COLOR_WINDOW+1
   mov   wc.lpszMenuName,NULL
   mov   wc.lpszClassName,OFFSET ClassName
   invoke LoadIcon,NULL,IDI_APPLICATION
   mov   wc.hIcon,eax
   mov   wc.hIconSm,eax
   invoke LoadCursor,NULL,IDC_ARROW
   mov   wc.hCursor,eax
   invoke RegisterClassEx, addr wc
   invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
   nbsp;       WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
           hInst,NULL
   mov   hwnd,eax
   invoke ShowWindow, hwnd,SW_SHOWNORMAL
   invoke UpdateWindow, hwnd
   .WHILE TRUE
               invoke GetMessage, ADDR msg,NULL,0,0
               .BREAK .IF (!eax)
               invoke TranslateMessage, ADDR msg
               invoke DispatchMessage, ADDR msg
   .ENDW
   mov     eax,msg.wParam
   ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
   LOCAL hdc:HDC
   LOCAL ps:PAINTSTRUCT
   LOCAL hfont:HFONT

   .IF uMsg==WM_DESTROY
       invoke PostQuitMessage,NULL
   .ELSEIF uMsg==WM_PAINT
       invoke BeginPaint,hWnd, ADDR ps
       mov    hdc,eax
       invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,\
                                      OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                                      DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\
                                      ADDR FontName
       invoke SelectObject, hdc, eax
       mov    hfont,eax
       RGB    200,200,50
       invoke SetTextColor,hdc,eax
       RGB    0,0,255
       invoke SetBkColor,hdc,eax
       invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString
       invoke SelectObject,hdc, hfont
       invoke EndPaint,hWnd, ADDR ps
   .ELSE
       invoke DefWindowProc,hWnd,uMsg,wParam,lParam
       ret
   .ENDIF
   xor    eax,eax
   ret
WndProc endp

end start
 

Analyse:

        invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,\
                                       OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                                       DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\
                                       ADDR FontName

CreateFont crée une fonte logique(mélangée RGB) qui est la couleur la plus proche des paramètres sélectionnés et des données de fonte disponibles. Cette fonction a plus de paramètres qu'aucune autre fonction de Windows. Il renvoie l'handle de la fonte logique qui doit être utilisé par la fonction SelectObject. Nous allons examiner ces paramètres en détail.

CreateFont proto nHeight:DWORD,\
                            nWidth:DWORD,\
                            nEscapement:DWORD,\
                            nOrientation:DWORD,\
                            nWeight:DWORD,\
                            cItalic:DWORD,\
                            cUnderline:DWORD,\
                            cStrikeOut:DWORD,\
                            cCharSet:DWORD,\
                            cOutputPrecision:DWORD,\
                            cClipPrecision:DWORD,\
                            cQuality:DWORD,\
                            cPitchAndFamily:DWORD,\
                            lpFacename:DWORD

nHeight  est la hauteur désirée des caractères. On prend 0 par défaut pour utiliser la taille moyenne.
nWidth  est la largeur désirée des caractères. Normalement cette valeur doit être 0,ce qui permet à Windows de faire correspondre la largeur à la hauteur. Cependant, dans notre exemple, la largeur par défaut fait que les caractères sembles difficile à lire, donc on emploiera la largeur 16 à la place de cela.
nEscapement   Sert à spécifier l'inclinaison des caractères qui suivent cette instruction. On compte en dixième de degré. Normalement, cette valeur est à 0. On la met à 900 pour avoir tous les caractères va vers le haut, à 1800 pour écrire vers l'arrière, ou 2700 pour écrire chaque caractère du haut vers le bas.
nOrientation   Indique de combien doivent être tournés les caractères (en dixième de degré). 900 pour avoir tous les caractères couchés tournés vers le haut, 1800 pour le contraire, etc.
nWeight   Donne l'épaisseur de chaque caractère. Windows définit les tailles suivantes :

cItalic  0 pour normal, une autre valeur pour caractères italiques.
cUnderline  0 pour normal, une autre valeur pour les caractères soulignés.
cStrikeOut  0 pour normal, une autre valeur pour des caractères (barrés) avec une ligne par le centre.
cCharSet C'est le jeu de caractères de la fonte (ex : ARIAL). Ce doit normalement être OEM_CHARSET, ce qui permet à Windows de choisir la fonte.
cOutputPrecision Indique à quel point la fonte choisie doit être proche des caractéristiques que nous voulons. Doit normalement on prend OUT_DEFAULT_PRECIS par défaut.
cClipPrecision Indique la précision de la coupure. La coupure c'est ce qui définit les bords de la zone d'écriture. Le texte sera coupé en arrivant près des bords et cette zone de coupure peut être plus ou moins étendue dans l'intérieur du secteur client. Vous pouvez utiliser la valeur CLIP_DEFAULT_PRECIS qui définit le comportement de coupure par défaut.
cQuality Indique la qualité de production. La qualité de production définit précisément comment le GDI doit essayer de calquer au mieux les attributs de la fonte logique à ceux d'une fonte physique réelle. Il y a trois choix : DEFAULT_QUALITY, PROOF_QUALITY et DRAFT_QUALITY.
cPitchAndFamily Spécifie la hauteur et la type de fonte. Vous devez combiner ces 2 valeurs avec l'opérateur "or".
lpFacename C'est un NULL qui indique la police de caractères de la fonte.

La description ci-dessus n'est en aucun cas complète. Vous devez attribuer à votre API Win32 les références pour plus de détails.

        invoke SelectObject, hdc, eax
        mov    hfont,eax

Après avoir obtenu l' handle de la fonte logique, nous devons l'employer pour choisir la fonte dans le contexte de dispositif en appelant SelectObject. SelectObject met les nouveaux objets du GDI tels que les stylos, les brosses et les fontes dans le contexte de dispositif pour être employés par des fonctions du GDI. Il renvoie l' handle (de l'objet à replacé) que nous devons sauvegarder pour de futures appels de la fonction SelectObject. Après l'appel SelectObject, n'importe quelle fonction de production de texte emploiera la fonte que nous venons juste de choisir dans le contexte de dispositif.

        RGB    200,200,50
        invoke SetTextColor,hdc,eax
        RGB    0,0,255
        invoke SetBkColor,hdc,eax

Employez la macro RGB pour créer une valeur RGB sur 32 bits pour être employée par SetColorText et SetBkColor.

        invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString

Appelez la fonction TextOut pour dessiner le texte sur le secteur client. Le texte sera dans la fonte et la couleur que nous avons spécifié précédemment.

        invoke SelectObject,hdc, hfont

Quand on as fini de se servir de cette fonte, on doit rétablir l'ancienne fonte dans le contexte de dispositif. Vous devez toujours rétablir l'objet que vous avez remplacé dans le contexte de dispositif.


[Iczelion's Win32 Assembly HomePage]


Traduit par Morgatte