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 |