Original: masm32\example1\generic
.586 ;minimum processor needed for 32 bit ASM code
.model flat,stdcall ;FLAT memory model & STDCALL calling
option casemap:none ; set code to case sensitive
;########################################################################
include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\user32.lib
return MACRO arg
mov eax,arg
ret
ENDM
WinMain PROTO
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
;########################################################################
.data
szDisplayName db 'Generic',0
ClassName db 1,0
TheMsg db "Assembler, Pure & Simple",0
TheText db "Please Confirm Exit",0
hInstance equ 400000h
wc WNDCLASSEX
.data?
msg MSG <>
.code
start:
invoke WinMain
invoke ExitProcess,eax ;cleanup & return
;###########################################################################
WinMain proc uses esi edi ebx
;==========================================
;Fill WNDCLASSEX structure with required variables
;==========================================
xor ebx,ebx
invoke LoadIcon,hInstance,500 ; icon ID resource icon
mov wc.hIcon,eax
invoke LoadCursor,ebx,IDC_ARROW ;system cursor
mov wc.hCursor,eax
invoke RegisterClassEx,ADDR wc ;register the window class
;=========================================
;Center window at following size
;=========================================
Wwd equ 500
Wht equ 350
invoke GetSystemMetrics,SM_CXSCREEN; get screen width in pixels
mov esi,eax
invoke GetSystemMetrics,SM_CYSCREEN
shr esi,1
shr eax,1
sub esi,Wwd/2
sub eax,Wht/2
;==================================
;Create the main application window
;==================================
invoke CreateWindowEx,WS_EX_OVERLAPPEDWINDOW,
addr ClassName,
ADDR szDisplayName,
WS_OVERLAPPEDWINDOW or WS_VISIBLE,
esi,eax,Wwd,Wht,
ebx,ebx,hInstance,ebx
mov edi,eax
;=====================================
;Loop until PostQuitMessage is sent
;=====================================
mov esi, offset msg
StartLoop:
invoke GetMessage,esi,ebx,ebx,ebx ;get each message
or eax,eax ;exit if GetMessage()
je ExitLoop ;returns 0
invoke TranslateMessage, esi ;translate it
invoke DispatchMessage,esi ;send it to message proc
jmp StartLoop
ExitLoop:
return msg.wParam
WinMain endp
;###########################################################################
WndProc proc uses edi ebx hWin :DWORD,
uMsg :DWORD,
wParam:DWORD,
lParam:DWORD
mov eax,uMsg
xor ebx,ebx
mov edi,hWin
.IF eax == WM_COMMAND
;============ menu commands ==============
.IF wParam == 1000
invoke SendMessage,edi,WM_SYSCOMMAND,SC_CLOSE,ebx
.ELSEIF wParam == 1900
invoke MessageBox,edi,ADDR TheMsg,ADDR szDisplayName,ebx
.endif
;=========== end menu commands =============
.ELSEIF eax == WM_CLOSE
invoke MessageBox,edi,ADDR TheText,ADDR szDisplayName,MB_YESNO
.IF eax == IDYES
mov eax,WM_CLOSE
jmp d
.ENDIF
.ELSEIF eax == WM_DESTROY
invoke PostQuitMessage,ebx
.ELSE
d: invoke DefWindowProc,edi,eax,wParam,lParam
jmp r
.ENDIF
xor eax,eax
r: ret
WndProc endp
end start
.586 ;minimum processor needed for 32 bit ASM code
The 586 is the pentium class processor, and the first 32 bit capable Intel processor was the 386.....
Is there some other reason for the .586 (rather that .386 or .486)?
I know that Agners docs don't have timings for the (3/4)86, and as your doing optimisations timings are important.
MirnoAlex,
This simple callback is an example of why I build authodox style
message handling procedures, they can be read and maintained yet
they are simple too big for a register style approach. This one
is very simple, I have some that are nested 4 conditions deep and
are multiple screens long in things like an application's main
message processing procedure.
The reason why I go for code like the above is so it can be written
error free and modified easily without having to have a major
re-write each time for no worthwhile advantage. I agree with your
approach at an algorithm level but at an architecture level, its
very poor code design as it is very difficult to read and maintain.
The introductory code examples in MASM32 are just that, they are
written to be clear and easy to understand and they are written
with an extendable architecture that does not need major recoding
for each change.
Putting static structures in the .DATA section is something you can
do in a very small test aplication as it is very rare to have much
in it so there is no real code size change but this will not work
in an application size architecture, when you have multiple windows
with different characteristics that require different registered
classes, this practice just blows out the size of the .DATA section.
Like other people who understand the difference, I have rewritten
apps that were originally written in TASM with a mountain of static
data in the .DATA section into a later design with dynamic code and
the size drops considerably.
Very small apps don't need a .DATA section, an uninitialised .DATA?
section does the job and string data can easily be written into the
.CODE section and you get a full section reduction in the size of the
code.
Regards,
hutch@pbq.com.au
; #########################################################################
EditProc proc hCtl :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
LOCAL xPos :DWORD
LOCAL yPos :DWORD
.if uMsg == WM_CHAR
; ------------------------------------------
; Process key combinations for pasting text
; to ensure it is pasted in CF_TEXT format
; ------------------------------------------
.elseif uMsg == WM_KEYDOWN
.if wParam == VK_SHIFT
mov pFlag, 1 ; set shift flag
.elseif wParam == VK_CONTROL
mov cFlag, 1 ; set control flag
.elseif wParam == VK_V
.if cFlag == 1
invoke SendMessage,hEdit,EM_PASTESPECIAL,CF_TEXT,0
mov eax, 0
ret
.endif
.elseif wParam == VK_INSERT
.if pFlag == 1
invoke SendMessage,hEdit,EM_PASTESPECIAL,CF_TEXT,0
mov eax, 0
ret
.endif
.endif
.elseif uMsg == WM_KEYUP
.if wParam == VK_F1
.elseif wParam == VK_F2
invoke CallSearchDlg
.elseif wParam == VK_F3
invoke TextFind,ADDR SearchText,TextLen
.elseif wParam == VK_SHIFT
mov pFlag, 0
.elseif wParam == VK_CONTROL
mov cFlag, 0
.endif
.endif
invoke CallWindowProc,lpEditProc,hCtl,uMsg,wParam,lParam
ret
EditProc endp
; #########################################################################
:)
It's just happend accidently.
I left the comments from the original code.
Of course .386 was right for the comments.
But I usually replace .386 to .586
it does no harm just allow some Pentium instruction to
be included in source.
To avoid keeping in mind what number of proccessor I
allowed at the beginning.
That's it.
The Svin.
By using anything 'less' than .586 you restrict the instructions you can use, the most handy one for example is rdtsc which reads the pentiums cycle counters, so If you're timing a bit of code it's a good one to have. Using it with .386 will cause an 'unrecognised instruction' error.
umbongo
The bottom line these days is .486 as it will run 32 bit windows,
.386 works with most of the integer instructions as it directs
the assembler to build 32 bit code.
The problem with building code with .686 .XMM and the like is that
it will only run on a PIII and there are a lot of computers out
there that cannot run it.
Even using .586 .MMX excludes pentiums without MMX so unless you
are writing code for later model machines only and can be sure
about it, selecting higher processors limit what machines can run
it.
Regards,
hutch@pbq.com.au
Here we go again :)
Steve,
The main question for you is:
Why you are so afraid of .DATA section grows up while not afraid of .CODE section grows up?
:)
It's simple arithmetics
.dataA = 1
.codeA = 1
.codeB = 3
.codeB > (.dataA + .codeA)
You are wrong about big application not good for my style:
The bigger application, the more classes it uses THE FASTER AND SHORTER will
be app in my design.
Cause
1.camulative size of .data and .code section will be less than alone .code in C++ style
2.registration and loading will be faster 'cause WNDCLASSEX member wich can be initialized
will be done.
Now about classes and modular programming.
It's very simple -
in C++ style when you put all members in struct in run time all source of class is
in .code section exept for names.
In classes with WNDCLASSEX you just put in .data the structure
.data
wcOneClass < here is members,offset OneClassWndProc, ..ect>
.code
here is rest of ini of wcOneClass
invoke RegisterClassEx,addr wcOneClass
---------------------------------------------
----
separate
OneClassWndProc proc hWnd,uMsg,wParam,lParam
.....
One ClassWndProc endp
TwoClassWndProc ..
...endp
if each class uses it's own callback. In fact I often use the same one callback with different classes
and one class with different callbacks, but it's long story, not basics ...
usually I include all Classes callbacks before start point, and register classes after start point.
But in dependes. There are lots of types of big progs to talk of uniforms.
And simple utility may be written to put and check in dlgbox everything concern to possible values
in WNDCLASSEX for specific class so that after it generates this <> filled with choosen values of members.
As for the rest I'll answer you in comments.
I can only say I don't use either Icz stile to handle msgs or this one.
I just optimize Icz style handling in the example that's all. I use some style close to J.Gordon one
but not exact one. But it's not the time to talk about it yet.
Readable code style is one you get used to.
The Svin.
svin somethings wrong with your code. when run the menu item exit doesnt work. since the original generic one does work i thought i should mension this.
smurf
I've just copied it from this very post. Compiled and
cheked in both Win98 and Win NT 4.
Menu exit worked.
Check again.
The Svin.
i tested it again by pasting the code from your post and it doesnt work. i use windows 2000 sp1 and didnt think it would be a windows 2000 specific problem. maybe another win2k user can confirm this.
smurf
Tell me, please, then:
What doesn't work? -
1. MsgBox doesn't appear at all?
2. When you confirm your exit it doesn't exit?
The Svin
okies when i click on the exit from the menu the message box doesnt appear.
smurf
But code that make MsgBox appear is exactly the same as in the original!
The difference is how it handles exit after IDYES click.
If the oirginal worked in your OS with the MsgBox, this one must work too.
If you copied it indeed from the post, something wrong must be in the rsrc.rc, it doesn't send
correct menu id.
Anyway, to be sure, I'll send you sompiled version of the code.
Could you check it for me of your machine?
The Svin.
dont waste your time. i figured out the problem. it was my fault sorry for wasting your time.
smurf
This message was edited by smurf, on 4/20/2001 6:01:29 AM