News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

The Ultimate Message Loop

Started by Zen, May 21, 2014, 05:12:26 AM

Previous topic - Next topic

Zen

...Clearly DAVE has given this alot of thought,...
We REALLY should have a DAVE tribute thread (where we can savagely attack his character and humiliate him,...)
...All kidding aside,...in reality, I was writing a message loop for an MDI application, and, had (no surprise) totally trashed it,...
Dave is (I think) psychic, because he provided the perfect solution,...:shock:

dedndave

it will work fine, Jochen - no problem
but, in contrast...

    .DATA?

msg MSG <>

    .CODE

WinMain PROC

    mov     esi,offset msg

;message loop

    INVOKE  ExitProcess,[esi].MSG.wParam

WinMain ENDP


EBP is now free to use

which brings up another issue.....

Start:  INVOKE  GetModuleHandle,NULL
        mov     hInstance,eax
        INVOKE  GetCommandLine
        INVOKE  WinMain,hInstance,hPrevInstance,eax,nCmdShow
        INVOKE  ExitProcess,eax

WinMain PROC hInst:HINSTANCE,hPrevInstance:HINSTANCE,lpCmdLine:LPSTR,nCmdShow:DWORD

    mov     eax,msg.wParam
    ret

WinMain ENDP

    END     Start


more compiler twaddle - lol
we are assembly programmers - that stuff is all meaningless

dedndave

Zen aka Baltoro.....

if you are interested in MDI, here's a small example
it includes the arrange menu items, a working MDI child menu, and accelerators
as you create and destroy MDI children, they are added and removed from the File menu

it maintains a count of children, initialized to 1 because the first child is created for you

Gunther

Dave,

thank you for providing the source.  :t Works fine and should be instructive for starters.

Gunther
You have to know the facts before you can distort them.

Zen

DAVE !!!
I have previously downloaded a number of your "greatest hits", including several varieties of MDI projects,,,THANKS,...

jj2007

Quote from: dedndave on May 22, 2014, 03:49:19 AMEBP is now free to use

That's correct, but what for? That's just a boring message loop, not an ultrahighspeedfancyinnermostloopthatneedsallmyregisters ;-)

dedndave

MDI windows are a little tricky - lol

first, there is the window hierarchy
    Frame
        MDIClient
            MDIChild
            MDIChild
            MDIChild


then, there are the create structures

after you get all that right, there is the matter of arranging, creating, destroying windows

and, the kicker is.....
how you exit WndProc makes a big difference
you have to allow many WM_COMMAND messages to exit via DefFrameProc so it can maintain the menu

dedndave

Quote from: jj2007 on May 22, 2014, 04:35:40 AM
Quote from: dedndave on May 22, 2014, 03:49:19 AMEBP is now free to use

That's correct, but what for? That's just a boring message loop, not an ultrahighspeedfancyinnermostloopthatneedsallmyregisters ;-)

it's not just a free register
it's also the absence of a bunch of unnecessary stack frame code
stuff that doesn't glare at you when you examine the source code
when you look at a disassembled program, it looks idiotic, in my opinion

dedndave

one of the things that makes me laugh is hInstance
how many copies of that thing you gonna need ?   :lol:

you've got hInstance, a global that's initialized in the startup code
you've got hInst, the argument for WndProc
you've got wc.hInstance, the WNDCLASSEX member (often, on the stack frame)

i even see some guys create another local and
    push    hInst
    pop     hInstance

wtf ?????

i get it one time, store it in an uninitialized global WNDCLASSEX structure
and, when i want it, it's always there, in wc.hInstance

jj2007

Quote from: dedndave on May 22, 2014, 04:51:06 AM
i even see some guys create another local and
    push    hInst
    pop     hInstance

wtf ?????

i get it one time, store it in an uninitialized global WNDCLASSEX structure
and, when i want it, it's always there, in wc.hInstance

If you have many uses of hInstance, the local version saves some bytes.

hutch--

I tend to use a global in the uninitialised data section and for local code this works fine but there are enough instances where you are writing library modules where its easier to get it locally than require another parameter for the procedure. This is more like "object" creation than a simple library module but it has its place where you want a working "black box" without having to make too much effort to get it going.

hutch--

Whats wrong wth a signed compare ? 0 or lower.


MsgLoop proc

    LOCAL msg:MSG

    push ebx
    lea ebx, msg
    jmp getmsg

  msgloop:
    invoke TranslateMessage, ebx
    invoke DispatchMessage,  ebx
  getmsg:
    invoke GetMessage,ebx,0,0,0
    cmp eax, 0
    jg msgloop

    pop ebx
    ret

MsgLoop endp

jj2007

Quote from: hutch-- on May 22, 2014, 07:44:46 PM
Whats wrong wth a signed compare ? 0 or lower.

Theoretically, -2 could be a valid message. Documentation is scarce, so for my part, I'll stick with Dave's wasteful inc eax/shr eax, 1/.Break .if Zero? solution - which happens to need exactly the same number of bytes, since cmp eax, 0 is a looong instruction ;-)

hutch--

 :biggrin:


MsgLoop proc

    .data?
      msg MSG <>
    .code

    push ebx
    push esi

    mov ebx, OFFSET msg
    xor esi, esi
    jmp getmsg

  msgloop:
    invoke TranslateMessage, ebx
    invoke DispatchMessage,  ebx
  getmsg:
    invoke GetMessage,ebx,esi,esi,esi
    cmp eax, esi
    jg msgloop

    pop esi
    pop ebx

    ret

MsgLoop endp

dedndave

no need to preserve EBX and ESI in most WinMain situations
but, the idea is sound
according to Alex, the "success" condition is always positive, so that might be a good method