call 'User32.ShowWindow' D§WindowHandle &SW_SHOWNORMAL
call 'User32.UpdateWindow' D§WindowHandle
L1:
call 'User32.GetMessageA' FirstMessage 0 0 0 | cmp eax 0 | je L9>
call 'User32.TranslateMessage' FirstMessage
call 'User32.DispatchMessageA' FirstMessage
jmp L1<
L9: call 'Kernel32.ExitProcess' 0
__________________________________________________________________________________
[char: B§ 0 MouseClick: B§ 0] ; 0 = no click yet
[hitpoint:
hitpoint_X: 0 hitpoint_y: 0]
Proc
MainWindowProc:
Arguments @Adressee, @Message, @wParam, @lParam
Local @hitpoint_X @hitpoint_y
Structure @PAINTSTRUCT 64 , @hdc 0
pushad
.If D@Message = &WM_DESTROY
call 'User32.PostQuitMessage' &NULL
.Else_If D@Message = &WM_LBUTTONDOWN
push D@lParam | pop W@hitpoint_x, W@hitpoint_y
mov B§MouseClick &TRUE
call 'User32.InvalidateRect' D@Adressee &NULL &TRUE
.Else_If D@Message = &WM_PAINT
call 'User32.BeginPaint' D@Adressee D@PAINTSTRUCT
If B§MouseClick e &TRUE
call 'GDI32.TextOutA' D@hdc D@hitpoint_x D@hitpoint_y,
ClickString D§ClickStringLen
End_If
call 'User32.EndPaint' D@Adressee D@PAINTSTRUCT
.Else
popad
call 'User32.DefWindowProcA' D@Adressee D@Message D@wParam D@lParam
Exit
.End_If
popad | mov eax &FALSE
EndP
.Else_If D@Message = &WM_LBUTTONDOWN
push D@lParam | pop W@hitpoint_x, W@hitpoint_y
mov B§MouseClick &TRUE
call 'User32.InvalidateRect' D@Adressee &NULL &TRUE
The
window procedure waits for left mouse button click. When it receives WM_LBUTTONDOWN,
lParam contains the coordinate of the mouse cursor in the client area.
It saves the coordinate in a variable of type POINT which is defined as:
[hitpoint: hitpoint_X: 0 hitpoint_y: 0]
and
sets the flag, MouseClick, to TRUE, meaning that there's at least a left
mouse button click in the client area.
push D@lParam | pop W@hitpoint_x, W@hitpoint_y
Since x-coordinate is the low word of lParam, y-coordinate is the high word of lParam and the members of POINT structure are 32-bit in size, we retrieve the wished insformation by pushing the whole dWord and poping twice a Word to store in the lower words of hitpoint_x and hitpoint_y.
After
storing the mouse position, we set the flag, MouseClick, to TRUE in order
to let the painting code in WM_PAINT section know that there's at least
a click in the client area so it can draw the string at the mouse position.
Next we call InvalidateRect function to force the window to repaint
its entire client area.
If B§MouseClick e &TRUE
call 'GDI32.TextOutA' D@hdc D@hitpoint_x D@hitpoint_y,
ClickString D§ClickStringLen
End_If
The
painting code in WM_PAINT section must check if MouseClick is true, since
when the window was created, it received a WM_PAINT message which at that
time, no mouse click had occurred so it should not draw the string in the
client area. We initialize MouseClick to FALSE and change its value to
TRUE when an actual mouse click occurs.
If
at least one mouse click has occurred, it draws the string in the client
area at the mouse position. Note that it calls lstrlen to get the length
of the string to display and sends the length as the last parameter of
TextOut function.