Phase Verocity,
DBUG is just a flag defined previously, and determines whether you want the debug code assembled or not. After the program works OK, I usually turn off the debug code. My example was meant to be a code snippet, not a whole functioning program. Lots of things are not shown. A user defined window MUST be registered to specify the WINPROC. That code is missing from the snippet. Also missing but still referenced is the WINMAIN structure, the BYTER macro function, and the code that shows the registers ESI, EBP being loaded. I especially wanted to show the GetMessage loop and how it exits when the return is zero or less than zero. Notice how much easier it is to read when the code is indented. If you need to push a parameter more than once, try to use a register. Only one byte of code to push a register. I believe stack frames and the Proc directive are evil. Just my opinion and available if you ask. If you want to see the whole program, let me know. Will reply if you have any other questions. Ratch
Posted on 2003-12-01 10:58:11 by Ratch
Yep, I would love to look at the code. I'm a newbie so anything to feed on is good for me.
Posted on 2003-12-01 11:03:44 by Phase Verocity
Okay, I've figured out what you were saying and implemented it into the code.. the sectoin is now debugable :alright:

There is one thing that is buggin me but.. I couldn't understand the byter thing you did with the messagebox.. I tried it so that I wouldn't need extra variable space but it didn't work for me :rolleyes:

here is the code.. I also used the IFDEF function so that I wouldn't need the extra variable space for the debug option if I didn't use it. i.e. I'll just comment it out.

I have fully commented it as far as I can tell how it works. I will put it up in seperate thread in case anyone wants to see it.



.386 ;This is the Machine type
.model flat,stdcall ;This is the syntax to use for calls
option casemap:none ;This allows the keys to be case sensitive


include windows.inc ;various include bits
include kernel32.inc
include user32.inc
includelib kernel32.lib ;and there associated libraries
includelib user32.lib


;have to define the prototype before calling it as a procedure.
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

.CONST ;numerical variables that don't change.
; DBUG equ 1 ;we uncomment this to run debug instructions on the program

.DATA

AppName db "An Application",0 ;String variables that don't change
ClassName db "A Class Name",0 ;always finish with a terminating 0 as
ErrorHandle db "Incorrect Parent Handle",0 ;it is in ascii format
ErrorMsgBoxTitle db "Critical Error",0
ErrorWindow db "Could not create or update the window",0
.DATA?

hInstance HINSTANCE ? ;strings that change
CommandLine LPSTR ?

.code ;start of code section

start: ;our first label

invoke GetModuleHandle,NULL ;grab the handle for our module
mov hInstance,eax ;put it into hInstance
invoke GetCommandLine ;grab the command line
mov CommandLine,eax ;put it in CommandLine
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT ;invoke our procedure
invoke ExitProcess,eax ;then exit


;this is the beginning of our procedure
WinMain proc hInst:HINSTANCE,
hPrevInst:HINSTANCE,
CmdLine:LPSTR,
CmdShow:DWORD


LOCAL wc:WNDCLASSEX ;set up local variables. wc is our windows class, msg is the messenger variable
LOCAL msg:MSG ;and hWnd is the handle of our Main Window.
LOCAL hWnd:HWND

mov wc.cbSize,SIZEOF WNDCLASSEX ;set the variables for the wc class
mov wc.style,CS_HREDRAW+CS_VREDRAW
mov wc.lpfnWndProc,OFFSET WinProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke RegisterClassEx,addr wc ;register our class
invoke CreateWindowEx, ;begin the creation of the window
NULL, ;this will give us our window handle
ADDR ClassName,
ADDR AppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL
mov hWnd,eax ;place the handle in hWnd
invoke ShowWindow,hWnd,SW_SHOWNORMAL ;make the window visible
invoke UpdateWindow,hWnd ;keep the window refreshed
;**** The window doesn't display if the procedure is not running

IFDEF DBUG ;This section is only attached to the code if the DBUG variable is defined. ;debug section only
;used to check for errors
.IF !EAX ;execute next instruction if there was an error creating the window
INVOKE MessageBox,ESI,addr ErrorWindow,addr ErrorMsgBoxTitle,MB_OK ;message and exit if failure
JMP EXIT ;after creating a notification box we jump to the exit
.ENDIF

ENDIF ;not that the . in front of IF means it is run at run time. No . means it is run at assembly time

.WHILE TRUE ;enter the message loop

invoke GetMessage,addr msg,NULL,0,0 ;get our message. usually wm_paint first up.

IFDEF DBUG ;more debug script.. only gets assembled if we create the variable DBUG
.IF eax==-1 ;another way of checking for values. check to see if eax is -1
invoke MessageBox, NULL,addr ErrorHandle,addr ErrorMsgBoxTitle, MB_OK
JMP EXIT ;invoke a message box and exit
.ENDIF
ENDIF ;end of our debug section which was used to check if there was an error in the window handle.

.BREAK .IF (!EAX) ;this is realtime code.. breaks the loop if eax is 0. i.e. program is finished.
invoke TranslateMessage, ADDR msg ;translate message to ansi code.
invoke DispatchMessage, ADDR msg ; dispatch the message and run the procedure
mov eax,msg.wParam ;load the message for the exit process
.ENDW ;I'm not sure if this is how the procedure is run.. i'm just guessing at present.
EXIT: ;our exit label.. so that we can jump to the end of the loop if there is an error.
ret ;return to the calling function.. i.e. top of this program after invoke WinMain. The next line is invoke exitprocess

WinMain endp ;the end of our WinMain procedure.. this probably never really gets executed.

WinProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM ;the start of the window procedure

.IF uMsg==WM_DESTROY ;if we got the exit message from getmessage in WinMain.
invoke PostQuitMessage,NULL ;then we invoke the quitmessage grabber
.ELSE ;otherwise we run the default window cleaning stuff which takes care of all the
invoke DefWindowProc,hWnd,uMsg,wParam,lParam ;other messages.
ret ;then we return to WinMain..
.ENDIF ;if we use post quitmessage we will end up here to exit the loop.

xor eax,eax ;after recieving the post quit message, we execute a zero out of eax. I.E. this makes it 0

ret ;then we return control to WinMain So that it can exit, because it has a 0 message.

WinProc endp ;this is just the end of the procedure

end start ;and this is the end of our program, that displayed a window.
Posted on 2003-12-01 13:04:41 by Phase Verocity
Phase Verocity,
There is one thing that is buggin me but.. I couldn't understand the byter thing you did with the messagebox.. I tried it so that I wouldn't need extra variable space but it didn't work for me

As I said in the previous post, BYTER is a function that is referenced but not defined. It IS defined in the enclosed ZIP file.
here is the code.. I also indented it so you can read it but my indenting isn't showing up in this message for some reason. I also used the IFDEF function so that I wouldn't need the extra variable space for the debug option if I didn't use it. i.e. I'll just comment it out.

You need to put your code between "left bracket"CODE"right bracket" ..your code here.."left bracket"/CODE"right bracket" markers on this newsgroup to preserve spacing. Use the Preview Reply function to see what it looks like. Forget about IFDEF in this program. DBUG is defined.

Be sure to read Readme.txt in the ZIP file. Down with procs and stack frames! Ratch
Posted on 2003-12-01 13:50:51 by Ratch
Phase Verocity,
I don't know why the ZIP file did not transfer with my last post. Here's trying it again. Ratch
Posted on 2003-12-01 13:52:47 by Ratch
Thanks Ratch, I'm looking through it now.
Posted on 2003-12-01 15:55:10 by Phase Verocity
Phase Verocity,
I have to apologize for including a bum file with the last ZIP I sent you. The file is Callback.inc. It is the WINPROC routine and it is not reentrant code because it stores EDI in a global storage. I have updated it to make it smaller, faster, reentrant, and more straightforward. If you have any questions about it, just ask. Ratch
Posted on 2003-12-02 21:59:57 by Ratch
actually I had assembled it, I just had to comment out a true definition of -1 in you're personal own include file.. I thought it was a little funny that you put a whole lot of variables in the main section and nearly no code, but that just gave me more idea's, and that is really what I am looking for at the moment. I have learn't so much in the last couple of days and remembered so much from my olden days that i'd almost stop calling myself a newbie soon. I loved the opcode tables I found in the intel's programming manual vol. 2. I figured they might make a good start to creating a debugger, seeing as how I haven't found any descent ones so far myself. Anyway this is a bit past the scope of this subject so I'll just say

thankyou to everyone who has replied to it..

I'm now starting to look at tutorial 4. Its pretty much the same except that he uses some paint structures.
Posted on 2003-12-02 23:32:01 by Phase Verocity