The wsprintf function gives me an error when closing the Message box.
I must be missing something in using the WSPRINTF.
Any help appreciated!
.Const
.Data
MESSAGES DD WM_CREATE, OnCreate
DD WM_CLOSE, OnClose
DD WM_COMMAND, OnClickBtn
sCap DB 'Screen Size', 0
.Code
winMainProcedure Frame hWnd, uMsg, wParam, lParam
Mov Eax, [uMsg]
Mov Ecx, SizeOf MESSAGES / 8
Mov Edx, Addr MESSAGES
: Dec Ecx
Js >L2
Cmp [Edx + Ecx * 8], Eax
Jne <
Call [Edx + Ecx * 8 + 4]
Ret
L2: Return (FALSE)
EndF
OnCreate:
UseData winMainProcedure
;==================================
;Write the initialization code here
;==================================
Return (TRUE)
EndU
OnClose:
UseData winMainProcedure
;=========================
;Write the final code here
;=========================
Invoke IsModal, [hWnd]
Or Eax, Eax ;Cmp Eax, FALSE
Jz >
Invoke EndModal, [hWnd], IDCANCEL
Mov Eax, TRUE ;Return (TRUE)
: Ret
EndU
OnClickBtn:
UseData winMainProcedure
Local sbuf[64]:B, cxScreen:D, cyScreen:D
Mov Eax, [wParam]
Cmp Ax, IDC_WINMAIN_BTNSCREEN
Jnz >>.exitProcedure
Shr Eax, 16
Cmp Ax, BN_CLICKED
Jnz >>.exitProcedure
Invoke GetSystemMetrics, SM_CXSCREEN
Mov [cxScreen], Eax
Invoke GetSystemMetrics, SM_CYSCREEN
Mov [cyScreen], Eax
Invoke wsprintf, Addr sbuf, "The screen is %d pixels wide by %d pixels high.", \
[cxScreen], [cyScreen]
Invoke MessageBox, NULL, Addr sbuf, Addr sCap, 0
Return (TRUE)
.exitProcedure
Return (FALSE)
EndU
BPak
Hi BPak,
In the MSDN library there is the following note:
Note: It is important to note that wsprintf uses the C calling convention (_cdecl), rather than the standard call (_stdcall) calling convention. As a result, it is the responsibility of the calling process to pop arguments off the stack, and arguments are pushed on the stack from right to left. In C-language modules, the C compiler performs this task.
High level languages and also Masm restore the stack but GoAsm does not, so you have to accomplish this task after calling wsprintf. In your code, as you pass four DWord arguments (that is, 4-byte each) to wsprintf, you have to add 16 bytes (4*4) to the Esp register like this:
....
Invoke wsprintf, Addr sbuf, "The screen is %d pixels wide by %d pixels high.", \
[cxScreen], [cyScreen]
Add Esp, 16
Invoke MessageBox, NULL, Addr sbuf, Addr sCap, 0
....
That's all!
Ramon
Hi Ramon,
Quoteuses the C calling convention (_cdecl),
Thanks for the solution. I will put that in my notes and keep look out for those _cdecl functions!
Working fine now!
BPak
BPak,
Donkey coded a macro to call C functions, it takes care of stack balancing :
CInvoke(%Function,%0,%1,%2,%3,%4,%5,%6,%7,%8,%9) MACRO
#IF ARGCOUNT = 11
push %9
#ENDIF
#IF ARGCOUNT > 9
push %8
#ENDIF
#IF ARGCOUNT > 8
push %7
#ENDIF
#IF ARGCOUNT > 7
push %6
#ENDIF
#IF ARGCOUNT > 6
push %5
#ENDIF
#IF ARGCOUNT > 5
push %4
#ENDIF
#IF ARGCOUNT > 4
push %3
#ENDIF
#IF ARGCOUNT > 3
push %2
#ENDIF
#IF ARGCOUNT > 2
push %1
#ENDIF
#IF ARGCOUNT > 1
push %0
#ENDIF
call %Function
#IF ARGCOUNT = 11
add esp,40
#ENDIF
#IF ARGCOUNT = 10
add esp,36
#ENDIF
#IF ARGCOUNT = 9
add esp,32
#ENDIF
#IF ARGCOUNT = 8
add esp,28
#ENDIF
#IF ARGCOUNT = 7
add esp,24
#ENDIF
#IF ARGCOUNT = 6
add esp,20
#ENDIF
#IF ARGCOUNT = 5
add esp,16
#ENDIF
#IF ARGCOUNT = 4
add esp,12
#ENDIF
#IF ARGCOUNT = 3
add esp,8
#ENDIF
#IF ARGCOUNT = 2
add esp,4
#ENDIF
ENDM
GoAsm header file set and macros by Donkey :
http://www.quickersoft.com/donkey/headers/headers.zip