cmp iMsg, WM_CREATE
should work.Anyway here is what I added to my program.I think it's better to put these includes and defines before all sections.
Const Section
#include winuser.h
#include windows.h
#define linkfiles
You must create an INCLUDE environment variable with the path to these header filesso you want something like
See "Include files - using #include and INCBIN" in the GoAsm manual for details
INCLUDE=G:\GoAsm\include
SET PATH=G:\GoAsm;%PATH%
that adds the G:\GoAsm folder to the already existing list of other folders that you haveSet INCLUDE=g:\jpsdhrs
Set PATH=g:\jpshdrs
Set PATH=g:\goasm.exe
GoAsm /l/b/c MyProg.asm
SET PATH=G:\jpshdrs;G:\goasm;%PATH%
i am not so sure that you really want the header files in the PATH, howeverSet INCLUDE=g:\jpsdhrs
Set PATH=g:\goasm;%PATH%
GoAsm /l/b/c MyProg.asm
G:\
--- GoAsm
------- Asm (this is where you want to put your projects)
------- Bin (this is where the GoAsm EXE files go - AND the batch files used to assemble/link)
------- Help (this is where the CHM and HTML help files go)
------- Include (this is where the headers go, with all the sub-folders)
i would then modify the system-wide environment variables (My Computer/Properties/Advanced tab)Set INCLUDE=g:\jpsdhrs
Set PATH=g:\goasm;%PATH%
GoAsm /l/b/c MyProg.asm
@ECHO OFF
SET PATH=G:\GoAsm\Bin;%PATH%
SET INCLUDE=G:\GoAsm\Include
G:
CD \GoAsm\Asm
INVOKE LoadCursor,NULL,IDI_APPLICATION
mov hIcon,eax ;optional
mov wc.hIcon,eax
mov wc.hIconSm,eax
#define LINKFILES
#include windows.h
#include winuser.h
This is how LINKFILES is defined in MyProg:
#define LINKFILES
#define windows.h
Down to 3 errors at link time.dwvalue is not the same as dwValue :P
rc, dwvalue and hInst
RC with RECT
dwValue with dwtoa
Local msg, MSG, hWnd, hBrush, rc, wc_WNDCLASSEXA, cc:codecode
LOCAL msg:MSG, hWnd:HWND, hBrush:HBRUSH, wc:WNDCLASSEX, cc:codecode
i am not sure about the last one.data
TM3 db 'at start',0
.code
start:
invoke MessageBox, NULL,TM3,TM3,MB_YESNO
invoke ExitProcess,0
end start
INVOKE MessageBox, NULL, ADDR TM3, ADDR TM3, MB_YESNO
WinMain:
FRAME hInst, hPrevInst, CmdLine, CmdShow
INVOKE GetCommandLine
mov [pCmdLine],eax
INVOKE WinMain, [hInstance], NULL, [pCmdLine], SW_SHOWDEFAULT
Local hWnd:DWORD
I changed MSG to msg as directed in your last statement.
Here is the error msg I get: "The following symbol was not defined in the object file
or files:- msg.wParam"
invoke GlobalLock, eax
mov [pinf04],eax t
mov ebx,eax
invoke EnumPrintersA, PRINTER_ENUM_LOCAL,NULL,4,eax,\
[dwNeeded],[dwNeeded],[dwReturned]
lea eax,[ebx+PRINTER_INFO_4.pPrinterName]
invoke CreateDC, NULL,eax,NULL,NULL
pusha
;
;
;
popa
PUSHA and POPA push and pop words !!! INVOKE CreateWindowEx, NULL,addr szDisplayName,addr AppName,\
WS_OVERLAPPEDWINDOW,[rc.left],[rc.top],[rc.right],\
[rc.bottom],NULL,NULL,[hInst],NULL
mov [hWnd],eax
.if !eax
invoke GetLastError
invoke MessageBox,0,uhex$(eax),0,0
invoke ExitProcess,0
.endif
INVOKE CreateWindowEx, NULL,addr szDisplayName,addr AppName,\
WS_OVERLAPPEDWINDOW,[rc.left],[rc.top],[rc.right],\
[rc.bottom],NULL,NULL,[hInst],NULL
mov [hWnd],eax
.if !eax
INVOKE GetLastError
sub esp,512
xor ecx,ecx
mov edx,esp
INVOKE FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,ecx,eax,ecx,edx,512,ecx
mov edx,esp
xor ecx,ecx
INVOKE MessageBox,ecx,edx,ecx,ecx
add esp,512
INVOKE ExitProcess,0
.endif
INVOKE CreateWindowEx, NULL,addr szDisplayName,addr AppName,\
WS_OVERLAPPEDWINDOW,[rc.left],[rc.top],[rc.right],\
[rc.bottom],NULL,NULL,[hInst],NULL
mov [hWnd],eax
or eax,eax
jnz around
INVOKE GetLastError
sub esp,512
xor ecx,ecx
mov edx,esp
INVOKE FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,ecx,eax,ecx,edx,512,ecx
mov edx,esp
xor ecx,ecx
INVOKE MessageBox,ecx,edx,ecx,ecx
add esp,512
INVOKE ExitProcess,0
around:
Instead a windows message occurs stating that the program has stopped working.
INVOKE DefWindowProc,hWnd,uMsg,wParam,lParam
ret
WndProc FRAME hWnd,iMsg,wParam,lParam
USES ebx,edi,esi
LOCAL hMemory,stm:SYSTEMTIME,ps,hdc,hdcPrn
mov eax,[iMsg]
.WM_CREATE
cmp eax,WM_CREATE
jne >>.WM_CHAR
CONST SECTION
; ******************** Window message table **********************
;
MESSAGES DD WM_CREATE, CREATE ;the message then the code address
DD WM_DESTROY, DESTROY
DD WM_PAINT, PAINT
DD WM_KEYDOWN, KEYDOWN
DD WM_TIMER, TIMER
CODE SECTION
WndProc:
FRAME hwnd, Msg, wParam, lParam ;establish stack frame, get params
;--------------------------------------
;FIND THE A MESSAGE WE'RE INTERESTED IN
;--------------------------------------
mov eax, [Msg] ;get in eax message sent by Windows
mov ecx, SIZEOF MESSAGES/8 ;get number of messages to look at
mov edx, ADDR MESSAGES
P1:
dec ecx ;count down to -1
js >.notfound ;if = -1 then call default win procedure
cmp [edx+ecx*8],eax ;check table if entry is correct message
jnz <P1 ;no, so loop back for next table entry
call [edx+ecx*8+4] ;call the correct procedure for the message
jnc >.exit
;----------------------------------------
;NO MATCH, SO PASS PARAMS BACK TO WINDOWS
;USE DEFAULT WINDOWS PROCEDURE
;----------------------------------------
.notfound
push [lParam]
push [wParam]
push [Msg]
push [hwnd]
call DefWindowProc
;------------------------------
;DESTROY STACK FRAME, EXIT BACK TO WINDOWS HERE
;------------------------------
.exit
ret
ENDF
;_________________________________________________________________________
;_________________________________________________________________________
PAINT: ; RE-DRAW WINDOW
USEDATA WndProc ;use parameters sent to WndProc
USES ebx,ecx,edx,esi,edi ;only save registers that you use in this procedure
;-------------------------------------------------------------
;---------------
;CALL BEGINPAINT
;---------------
invoke BeginPaint, [hwnd], ADDR ps
mov [hdc], eax
;updating/refreshing the window goes here
;-------------
;CALL ENDPAINT
;-------------
invoke EndPaint, [hwnd], ADDR ps
;---------
;EXIT HERE
;---------
xor eax,eax ;return not carry and eax = 0
ret
ENDU ;finished using parameters sent to WndProc
;_________________________________________________________________________
;_________________________________________________________________________
CREATE: ; PROGRAM INITIALIZATION
USEDATA WndProc ;use parameters sent to WndProc
USES ebx,ecx,edx,esi,edi ;only save registers that you use in this procedure
;-------------------------------------------------------------
;program init goes here
;---------
;EXIT HERE
;---------
xor eax,eax ;return not carry and eax = 0
ret
ENDU ;finished using parameters sent to WndProc
;_________________________________________________________________________
;_________________________________________________________________________
DESTROY: ; PROGRAM CLEAN-UP
USEDATA WndProc ;use parameters sent to WndProc
USES ebx,ecx,edx,esi,edi ;only save registers that you use in this procedure
;-------------------------------------------------------------
invoke PostQuitMessage, NULL ;kill the application
;---------
;EXIT HERE
;---------
xor eax,eax ;return not carry and eax = 0
ret
ENDU ;finished using parameters sent to WndProc
;_________________________________________________________________________
;_________________________________________________________________________
KEYDOWN: ; PROCESS KEYPRESSES
USEDATA WndProc ;use parameters sent to WndProc
USES ebx,ecx,edx,esi,edi ;only save registers that you use in this procedure
;-------------------------------------------------------------
mov eax, [wParam]
;----------------------
;COMPARE TO ESCAPE KEY?
;----------------------
cmp eax, VK_ESCAPE
jne >E9
invoke PostQuitMessage, NULL ;kill the application
;---------
;EXIT HERE
;---------
E9:
xor eax,eax ;return not carry and eax = 0
ret
ENDU ;finished using parameters sent to WndProc
;_________________________________________________________________________
;_________________________________________________________________________
TIMER: ; PROCESS TIMERS
USEDATA WndProc ;use parameters sent to WndProc
USES ebx,ecx,edx,esi,edi ;only save registers that you use in this procedure
;-------------------------------------------------------------
;code if you process timers
;I always use timer proc outside the window
;---------
;EXIT HERE
;---------
xor eax,eax ;return not carry and eax = 0
ret
ENDU ;finished using parameters sent to WndProc
Blindly pushing all the registers makes for slow code.
And it wasn't that long ago, was it? I realized (while) you all were having that discussion the answer was basically rule #1 in assembly: "Preserve that and only that which you use." It's actually quite simple, and the same whether we're talking 65x, 68x, or x86. At the time I thought there might be some hard and fast rule among the hard-cores here, so I decided to ask. Turns out there wasn't. My simple question turned into quite a lengthy discussion, didn't it?Blindly pushing all the registers makes for slow code.
Sounds familiar (http://masm32.com/board/index.php?topic=250.msg1314#msg1314) :biggrin:
it's not just a percentage--it's a hard count.
BTW, how does one expect nanoseconds and cycles, yet precision is not necessary?
xor ecx, ecx
@@: dec ecx
jne @B
is a good exercise for your lazy CPU :bgrin:I can literally see mouse activity in the task manager.
This is not about my main problem but am curious why this messagebox is causing problems.
This code causes the messagebox to go into a loop from which I have to
reboot the puter to get out of it. It never goes to WM_CREATE.
WndProc:
FRAME hWnd,iMsg,wParam,lParam
USESebp,ebx,edi,esi
Local hMemory,stm:SYSTEMTIME,ps:PAINTSTRUCT,hdc,hdcPrn
; USED ONLY DURING TESTING PHASE
DATA SECTION <--Try adding this
;TM8 db 'begin of wndproc',0
CODE SECTION <--and this
pushad <-- why?
invoke MessageBox, NULL,addr TM8,NULL,MB_OK
popad <-- why?
; test end
WndProc:
FRAME hWnd,iMsg,wParam,lParam
USES ebx,edi,esi
Local hMemory,stm:SYSTEMTIME,ps:PAINTSTRUCT,hdc,hdcPrn
invoke MessageBox, NULL,addr TM8,NULL,MB_OK
;.WM_CREATE
cmp D[iMsg],WM_CREATE
jne >>.WM_CHAR
even if that does "work", it's going to generate a lot of message boxes - lolWndProc:
FRAME hWnd,iMsg,wParam,lParam
USES ebx,edi,esi
Local hMemory,stm:SYSTEMTIME,ps:PAINTSTRUCT,hdc,hdcPrn
invoke Beep,800,40
;.WM_CREATE
cmp D[iMsg],WM_CREATE
jne >>.WM_CHAR
Hi JJ,
Here is the ".exe" of my attempt at GoAsm. I have zipped it to
conform to Hutches regs.
It is NOT a working program. It will take you to the Wndproc
and die right there.
Have fun. I sure am ;)
jmp >.Return0 ;<--- at the end of each message that you process, usually should return 0
.WM_DESTROY
cmp D[iMsg],WM_DESTROY
jne >.Default ;<--- no more messages to check, so pass do DefWindowProc
.Return0
xor eax,eax ;<--- message processed, usually return 0
.Return
ret
.Default
INVOKE DefWindowProc, [hWnd], [iMsg], [wParam], [lParam]
ret
cmp D[holdR],5
jl >>L2
;
;
SomeLabel:
;
;
L2:
; from the SystemTime structure
xor ebx,ebx
mov bx, [stm.wDay] ; or: movzx ebx, W[stm.wDay] and eliminate the xor code
; stm.day has the value of 14h
;Doesn't work
cmp D[ebx],0000000eh ;this is comparing the value at the address contained in ebx to 0eh ( try: cmp ebx, 0eh [means cmp 14h to 0eh])
jbe >>.Somewhere ;there is no address in ebx, only a value (14h)
jmp >.ddd
; short jump
.ddd
You have a System Time Value in bx. The brackets around ebx are telling it to treat the value in ebx (the day) as a ptr to an address (00000014h), which doesn't exist in your process space (means compare value at address 00000014h to 0eh). Does it crash?... If all you want to do is compare the value held in ebx to the number 0eh, then just remove the brackets (and the D--it's implied in this case). The 'D" is like "DWORD PTR" in Masm, just shortened up a bit in GoAsm. try: cmp ebx, 0eh (means cmp 14h to 0eh);eeej defined in the data section
eeej dd 0000000eh
;Doesn't work
cmp D[ebx],addr eeej
jbe >>.Somewhere
jmp >.ddd
; short jump
.ddd
GoAsm doesn't type-check, ...
GoAsm dw 255 (WORD)
MOV EBX,ADDR wParamwhich means the same thing"
or if you prefer
MOV EBX,OFFSET wParam
invoke GlobalAlloc, GHND,addr dwNeeded
The second argument should be [dwNeeded].
Okay. The call should be set up to succeed. Make sure the buffer is large enough and that you use valid pointers. The INFO_4 structure is 12 bytes per device. Two ptrs and an attributes dword.
invoke MessageBox, NULL,addr TM2,[PrintCString],MB_OK
invoke MessageBox, NULL,addr TM2,[PrintCString+12],MB_OK
invoke MessageBox, NULL,addr TM2,[PrintCString+24],MB_OK
invoke MessageBox, NULL,addr TM2,[PrintCString+36],MB_OK
invoke MessageBox, NULL,addr TM2,[PrintCString+48],MB_OK
invoke MessageBox, NULL,addr TM2,[PrintCString+60],MB_OK
4045E4: PUSH EBP
4045E5: ADD D[ESP],-54
4045E9: PUSH [EBP+14]
4045EC: CALL EndPaint(USER32.dll)
4045F1: MOV ESP,EBP
4045F3: POP ESI
4045F4: POP EDI
4045F5: POP EBX
4045F6: POP EBP
4045F7: RET 10