News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Ratch and his RegisterClass codes

Started by Technomancer, June 08, 2006, 01:52:28 PM

Previous topic - Next topic

Technomancer

Quote from: ratch
Alawna,
     I push every member of the WNDCLASS structure onto the stack, and then INVOKE RegisterClass with the stack address pointing to the WNDCLASS structure.  PUSHes use less memory than MOV's, and I suspect they might be faster too.  I can send you a code snippet if you are really interested.  It seems to me to be more efficient, and that is the name of the game with MASM isn't it.  Ratch
Ok, requested in public instead of PMs. Do you mind posting it so newbies like me can learn from it?

Much thanks.

hutch--

echno,

Its no big deal, take the arguments from a WNDCLASSEX structure, push them in exact reverse order the call RegisterClassEx() with ESP as the argument. Balance the stack after with ADD ESP, BYTECOUNT_WNDCLASSEX .

It is basically a minor size optimisation at the expense of clarity and speed as pushes are slow. Not that it matters much in this instance.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Ratch

#2
Technomancer,

Quote
Ok, requested in public instead of PMs. Do you mind posting it so newbies like me can learn from it?

     hutch-- is right, it is not rocket science.  And because the RegisterClass operation is so small no matter how it is coded, my code is more for elegancy than speed and memory.  I did not invent this method, and I am not the only one who uses it.  I am posting the whole WinMain template I use, even though you are probably only interested in the RegisterClass within.  Because it is a template, the program name, and software switches must be supplied and set by the programmer.  And of course, you can use as little or as much of this code as you want.  Possibly you can improve on it.  I can't think of everything.  Note the following.

1) Error checking is turned on/off by a softswitch called DBUG.

2) There is a lot of extra processing code in this template that a simple program does not use, such as dialog box processing, accelerator processing, and roll your own icons and cursors.  These are controlled by softswitches TRUE/FALSE. 

3) The MACRO RPUSHIT simple pushes parameters onto the stack in reverse order.  Ask if you need the MACRO definition of RPUSHIT.

4) If you are interested in the message dispatcher, notice that it checks for the -1 error, which a lot of message dispatchers including icztutes do not.  But the GetMessage documentation says that -1 is a possible error to expect. 

5) Notice how a PUSH of zero is done by PUSHing EBP, which has been set to zero.  PUSH 0 is two bytes and PUSH EBP is one byte.

6) Notice that invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT is not used in this code.

7) Notice that most of my PUSHes are registers and constants, which I am not so sure are slow as hutch-- claims.


;*****WINMAIN*******************************************************************
WMSTRUC STRUC
msg MSG {}      ;message structure ****ALWAYS KEEP MSG STRUCTURE AT BEGINNING
WMSTRUC ENDS

MAIN:
XOR EBP,EBP     ;handy constant zero
SUB ESP,WMSTRUC ;make local space

INVOKE GetModuleHandle,EBP

MOV ESI,EAX     ;now ESI=module handle
MOV [hInst],EAX

;*****CLASS REGISTRATION********************************************************
APPNAME EQU '%%%%%'
IF TRUE ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
RPUSHIT EBP,LTEXT(szAppName,APPNAME,0)    ;for no menu
ELSE ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><
RPUSHIT LTEXT(szAppName,APPNAME,0),@ szAppName ; for menu
ENDIF ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

IF TRUE ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
PUSH COLOR_WINDOW+1                      ;for window background color
ELSE ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><
INVOKE CreateSolidBrush,WHITE_BRUSH   ;
PUSH EAX
ENDIF ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

INVOKE LoadCursor,EBP,IDC_ARROW
PUSH EAX                                 ;cursor handle

IF TRUE ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
INVOKE LoadIcon,EBP,IDI_APPLICATION      ;EBP=0
ELSE ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><
INVOKE LoadIcon,ESI,#########            ;ESI=hInst
ENDIF ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

S1=CS_HREDRAW OR CS_VREDRAW
RPUSHIT S1,@ WINCALLBACK,EBP,EBP,ESI,EAX ;ESI=hInst
INVOKE RegisterClass,ESP

IF DBUG
TEST EAX,EAX
.IF ZERO?
   INVOKE MessageBox,ESI,TEXT('Class registration failed.',0),EBP,EBP ;EBP=0
   JMP EXIT
.ENDIF
ENDIF

ADD ESP,WNDCLASS                        ;balance stack from WNDCLASS
; ADD ESP,WNDCLASSEX                      ;balance stack from WNDCLASSEX

;*****END OF CLASS REGISTRATION*************************************************
;*****WINDOW CREATION***********************************************************

S1=WS_OVERLAPPEDWINDOW

INVOKE CreateWindowEx,EBP,@ szAppName,@ szAppName,\
                        S1,CW_USEDEFAULT,CW_USEDEFAULT,\
                        CW_USEDEFAULT,CW_USEDEFAULT,EBP,EBP,ESI,EBP ;EBP=0
IF DBUG
TEST EAX,EAX
.IF ZERO?
   INVOKE MessageBox,ESI,TEXT('Main CreateWindow call error',0),EBP,EBP ;EBP=0
   JMP EXIT
.ENDIF
ENDIF

MOV [hwnd],EAX        ;window handle
MOV ESI,EAX           ;now ESI=hwnd=window handle

;*****END OF WINDOW CREATION****************************************************

INVOKE ShowWindow,ESI,SW_SHOWNORMAL

INVOKE UpdateWindow,ESI

IF DBUG
TEST EAX,EAX
.IF ZERO?
   INVOKE MessageBox,ESI,TEXT('UpdateWindow call error',0),EBP,EBP ;EBP=0
   JMP EXIT
.ENDIF
ENDIF

MOV EBX,ESP  ;EBX=ESP=&msg

.WHILE NOT 0 ;beginning of message loop
   INVOKE GetMessage,EBX,EBP,EBP,EBP ;
   TEST EAX,EAX

   IF DBUG
    JS GMERR ;jump out on GetMessage error
   ELSE
    JS EXIT  ;jump out on GetMessage error
   ENDIF

   .BREAK .IF ZERO? ;jump out on WM_QUIT message

   IF FALSE ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   CMP [hDlgModeless],EBP
   JZ F@

   INVOKIT IsDialogMessage,[hDlgModeless],EBX ;ESI=dialog box handle,EBX=&msg
   TEST EAX,EAX
   .CONTINUE .IF !ZERO?
   @@:
   ENDIF ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

   IF FALSE ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   INVOKE TranslateAccelerator,ESI,[EBX.WMSTRUC.hAccel],EBX ;EBX=&msg

   TEST EAX,EAX
   .CONTINUE .IF !ZERO?
   ENDIF ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

   INVOKE TranslateMessage,EBX ;EBX=&msg
   INVOKE DispatchMessage, EBX ;EBX=&msg
.ENDW                         ;repeat message loop

MOV EAX,[ESP.MSG.wParam]

EXIT:
ADD ESP,WMSTRUC               ;recover local space

INVOKE ExitProcess,EAX

IF DBUG
GMERR:                         ;display error message via message box & jmp to EXIT
INVOKE MessageBox,ESI,TEXT('GetMessage call error',0),EBP,EBP ;EBP=0
JMP EXIT
ENDIF

;*****END OF WINMAIN************************************************************


Ratch

To the Ineffable All,

     Someone suggested that I put my code in code brackets.  I did so, but the code display system of this forum insists on swallowing one space from the beginning of each line if available.  That means that the indentations are flattened somewhat.  I don't know if what I did helps readability or not.  Perhaps I should submit a ZIP file instead?  I will be glad to explain any parts you don't understand.  Ratch

hutch--

Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

zooba

I can't say I've come across the 'swallowing one space' issue before, but indenting almost always reads much better with a fixed-space font. And really, it shouldn't make much difference (unless you've been indenting things with one space... :wink )

Cheers,

Zooba :U

Mark Jones

I seem to recall trying to single-space the leading character of paragraphs, and having this editor reject them. Yes, I had to put in two spaces before any space would appear.
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08