Cours de programmation win32asmAmad disant qu'il serait bien qu'il y ai des cours de programmation dans Immortal je me suis mis a en écrire un. Ce tut va juste vous apprendre a afficher une boite de dialogue en assembleur pour windows. Cependant ce genre de tut existe beaucoup sur le net c'est pourquoi je ferais ce tut uniquement pour le compilateur Tasm32. Beh oui Masm est utile, mais c'est un produit microsoft, et de plus vous ne devriez pas avoir de mal a trouver des cours pour ce compilateur. Bon treve de bavardage, passons aux choses serieuses. Pour creer votre dialogbox il va tout d'abord falloir la creer grace a un editeur specialise. Moi j'utilise visual c++ 6 mais vous pouvez le faire avec borland resource workshop ou d'autres logiciels. Voila comment on procede avec vc++ : Faites sous vc++ : File->New->File->resource script puis choisissez le nom que vous lui donnez. Maintenant faites : Insert->resource voila ce que vous avez sous les yeux :
Pour faire un prog 32 bits on declare tout d'abord toutes les apis qu'on utilise. On definit aussi tous les attributs de la classe windows. (voir source final). Passons maintenant au code source en lui meme. Pour afficher une boite de dialogue il faut le faire en quelques etapes. La premiere est de donner a windows le handle du programme :
wc WNDCLASS >
hinst dd 0
push 0
call GetModuleHandleA ; initialise le proggy
mov [hinst], eax
Ensuite on donne les caracteristiques de la fenetre et la fonction qui gere celle ci: (voir le source complet pour cette fonction)
mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS
mov [wc.clsLpfnWndProc], offset WndProc
mov [wc.clsCbClsExtra], 0
mov [wc.clsCbWndExtra], 0
Puis on met l'hinstance dans eax et on la donne a la fenetre:
mov eax, [hinst]
mov [wc.clsHInstance], eax
Ensuite on passe a notre DialoBox. On l'affiche grace a l'API DialogBoxParamA et on lui assigne la fonction DlgProc qui la gerera :
push 0
push offset DlgProc ;fonction qui gère la dialogbox
push 0
push 1000 ;Id de la dialogbox
push [hinst] ;le handle du programme
call DialogBoxParamA ;affiche la boite
puis on ecrit la fonction qui gere notre boite de dialogue :
DlgProc proc hwnd:DWORD, umsg:DWORD, wparam:DWORD, lparam:DWORD
cmp [umsg], WM_CLOSE
jz destroydialog ; saute si on ferme la boite
ret
DlgProc endp
Voila donc a quoi correspondrait le source complet :
.386P ;pour processeurs superieurs ou egaux a un 386
;----------pour pas encombrer votre prog mettez ceci dans un autre fichier-------
;----------par exemple dialog.inc, puis écrivez simplement include dialog.inc----
Extrn DialogBoxParamA:PROC
Extrn ExitProcess:PROC
Extrn GetModuleHandleA:PROC
Extrn DefWindowProcA:PROC
UINT EQU <dd> ; 32 bits for WIN32
ULONG EQU <dd>
WNDCLASS struc
clsStyle UINT ?
clsLpfnWndProc ULONG ?
clsCbClsExtra UINT ?
clsCbWndExtra UINT ?
clsHInstance UINT ?
clsHIcon UINT ?
clsHCursor UINT ?
clsHbrBackground UINT ?
clsLpszMenuName ULONG ?
clsLpszClassName ULONG ?
hIconSm UINT ?
WNDCLASS ends
WM_CLOSE = 0010h
CS_VREDRAW = 0001h
CS_HREDRAW = 0002h
CS_GLOBALCLASS = 4000h ; Global window class
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
.Model Flat, StdCall
.Data
wc WNDCLASS <?>
hinst dd 0
;--------------------------------------------------------------------------------
.Code
Start:
push 0
call GetModuleHandleA ; initialise le proggy
mov [hinst], eax
mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS
mov [wc.clsLpfnWndProc], offset WndProc
mov [wc.clsCbClsExtra], 0
mov [wc.clsCbWndExtra], 0
mov eax, [hinst]
mov [wc.clsHInstance], eax
push 0
push offset DlgProc
push 0
push 1000
push [hinst]
call DialogBoxParamA ; affiche la boite
jmp finish
;--------------------------------------------------------------------------------
DlgProc proc hwnd:DWORD, umsg:DWORD, wparam:DWORD, lparam:DWORD
cmp [umsg], WM_CLOSE
jz destroydialog ; saute si on ferme la boite
ret
DlgProc endp
;--------------------------------------------------------------------------------
WndProc proc hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
defwndproc:
push [lparam] ; on definit les procedures
push [wparam]
push [umsg]
push [hwnd]
call DefWindowProcA
finish:
ret
WndProc endp
;--------------------------------------------------------------------------------
destroydialog:
call ExitProcess
End Start
Et vous compilez comme ceci: tasm32 /mx /m3 /z /q dialog tlink32 -x /Tpe /aa /c dialog,dialog,,import32.lib,,resource.res Bon maintenant il faudrait afficher la boite de message quand on clique sur le bouton. C'est tres simple, on se souvient qu'on a mit l'ID du bouton a 2000. Il suffit pour cela de modifier la DlgProc. Quand le prog recoit un message il est de la forme WM_COMMAND. Donc on regarde d'abord s'il y a un message, puis on regarde s'il y a eu appui sur le bouton et enfin on affiche la MessageBoxA. Pour tout cela il faut que lparam soit différent de 0. Voila, c'est assez chaud a comprendre si vous avez jamais programme mais ceux qui connaissent le c++ auront pas de problemes. (ce qui change par rapport au programme precedent est en bleu).
.386P ;pour processeurs superieurs ou egaux a un 386
;----------pour pas encombrer votre prog mettez ceci dans un autre fichier-------
;----------par exemple dialog.inc, puis écrivez simplement include dialog.inc----
Extrn MessageBoxA:PROC
Extrn DialogBoxParamA:PROC
Extrn ExitProcess:PROC
Extrn GetModuleHandleA:PROC
Extrn DefWindowProcA:PROC
UINT EQU <dd> ;32 bits for WIN32
ULONG EQU <dd>
WNDCLASS struc
clsStyle UINT ?
clsLpfnWndProc ULONG ?
clsCbClsExtra UINT ?
clsCbWndExtra UINT ?
clsHInstance UINT ?
clsHIcon UINT ?
clsHCursor UINT ?
clsHbrBackground UINT ?
clsLpszMenuName ULONG ?
clsLpszClassName ULONG ?
hIconSm UINT ?
WNDCLASS ends
WM_CLOSE = 0010h
WM_COMMAND = 0111h
CS_VREDRAW = 0001h
CS_HREDRAW = 0002h
CS_GLOBALCLASS = 4000h ; Global window class
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
.Model Flat, StdCall
.Data
wc WNDCLASS <?>
hinst dd 0
message db '!!! Les cours de TiPiaX ca dechire !!!',0
titre db 'Hehe',0
;--------------------------------------------------------------------------------
.Code
Start:
push 0
call GetModuleHandleA ; initialise le proggy
mov [hinst], eax
mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS
mov [wc.clsLpfnWndProc], offset WndProc
mov [wc.clsCbClsExtra], 0
mov [wc.clsCbWndExtra], 0
mov eax, [hinst]
mov [wc.clsHInstance], eax
push 0
push offset DlgProc
push 0
push 1000
push [hinst]
call DialogBoxParamA ; affiche la boite
jmp finish
;--------------------------------------------------------------------------------
DlgProc proc hwnd:DWORD, umsg:DWORD, wparam:DWORD, lparam:DWORD
cmp [umsg], WM_CLOSE
jz destroydialog ; saute si on ferme la boite
cmp [umsg], WM_COMMAND ;si pas WM_COMMAND
jnz fin ;on se barre
mov eax,wparam
cmp lparam,0 ;si lparam =0
jz fin ;on saute
cmp ax, 2000 ;on a clique le bouton ?
jnz fin ;si oui on saute pas
call boitedemessage ;et on affiche la boite de message
fin:
ret
DlgProc endp
;--------------------------------------------------------------------------------
WndProc proc hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
defwndproc:
push [lparam] ; on definit les procedures
push [wparam]
push [umsg]
push [hwnd]
call DefWindowProcA
finish:
ret
WndProc endp
;--------------------------------------------------------------------------------
boitedemessage proc
push 0 ;bouton ok
push offset titre ;le titre
push offset message ;le message
push 0 ;le handle
call MessageBoxA
ret
boitedemessage endp
;--------------------------------------------------------------------------------
destroydialog:
call ExitProcess
End Start
Le resultat en images :
Voila, voila, j'espere que ce tut vous servira car j'ai pris du temps pour le faire. J'aurais aussi un truc a dire. Je connais beaucoup de gars qui rejetent le c++ et qui disent que le mieux c'est l'asm. Cependant ils programment en Masm. Avant je ne connaissais rien a Masm mais maintenant que je m'y suis interresse, je remarque que Masm est une sorte de clone de l'asm, c'est vrai que les IF et invoke ca fait pas trop asm pur. Je ne dis pas que ca n'est pas utile, bien au contraire mais bon moi je trouve qu'on se rapproche quand meme pas mal du c quoi. Personnellement, je crois que je vais me mettre a programmer en opcodes comme ca je serais vraiment bas niveau, hehe. Non serieusement, il y a de fortes chances que je fasse des tuts sur Masm car c'est quand meme tres utile et puis moi j'aime le c++, lol. Si vous ne captez pas quelquechose n'hesiter pas a me mailer, je me ferais un plaisir de vous repondre. ps: le prog et le source sont joints. TiPiaX |