Downloadez le fichier en example ici.
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
.data
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
MouseClick db 0 ; 0=pas encore de click
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hitpoint POINT <>
.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,\
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 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
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_LBUTTONDOWN
mov eax,lParam
and eax,0FFFFh
mov hitpoint.x,eax
mov eax,lParam
shr eax,16
mov hitpoint.y,eax
mov MouseClick,TRUE
invoke InvalidateRect,hWnd,NULL,TRUE
.ELSEIF uMsg==WM_PAINT
invoke BeginPaint,hWnd, ADDR ps
mov hdc,eax
.IF MouseClick
invoke lstrlen,ADDR AppName
invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR AppName,eax
.ENDIF
invoke EndPaint,hWnd, ADDR ps
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
La procédure de fenêtre attend qu'on clique sur le bouton gauche de la souris. Quand il reçoit WM_LBUTTONDOWN, lParam prend la valeur de la coordonnée du curseur de la souris dans le secteur client. Il sauvegarde la coordonnée dans une variable de type POINT qui est défini comme ceci:
POINT
STRUCT
x dd ?
y dd ?
POINT
ENDS
et le 'flag' qui contrôle l'état de MouseClick, est mis à TRUE (VRAI), signifiant ainsi qu'il y a au moins le bouton gauche de la souris qu'on peut cliquer sur le secteur client.
mov eax,lParam
and eax,0FFFFh
mov hitpoint.x,eax
Puisque la coordonnée X est le mot de poids faible du double mot lParam et que les 2 membres qui forment la structure du POINT sont d'une taille de 32 bits, nous devons mettre la partie haute de 'eax' à 0 avant le stockage de celle-ci.
shr eax,16
mov hitpoint.y,eax
Puisque la coordonnée Y est le mot de poids fort du double mot lParam, nous devons mettre la partie basse de 'eax' à 0 avant le stockage de celle-ci. Nous pouvons faire ça en déplaçant 16bits de eax vers la droit.
Après le stockage de la position de la souris, nous mettons le flag contrôlant l'état de MouseClick à TRUE (VRAI) pour que le code de la section WM_PAINT sache qu'il y a au moins un clique effectué sur le secteur client. Donc il peut dessiner la chaîne de caractère à la position de la souris. Ensuite nous appelons la fonction InvalidateRect pour forcer la fenêtre à repeindre la totalité de son secteur client.
.IF MouseClick
invoke lstrlen,ADDR AppName
invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR AppName,eax
.ENDIF
Le code de la section WM_PAINT (celui qui sert à repeindre le secteur client de votre fenêtre) doit vérifier si MouseClick est vrai, dès que la fenêtre a été créée. Au tout début il a reçu un message WM_PAINT, pour lequel il n'y avait aucun clique de souris, ainsi il ne doit pas dessiner la chaîne de caractère dans le secteur client. Nous initialisons donc MouseClick à FALSE (FAUX), mais changeons sa valeur à TRUE (VRAI) uniquement quand advient un réel clique de souris.
Si au moins un clique de souris arrive, il dessine la chaîne de caractère sur le secteur client à la position de la souris. Notez qu'il appelle 'lstrlen' pour obtenir la longueur de la chaîne à afficher et renvoie la longueur comme dernier paramètre de la fonction TextOut.