The MASM Forum

64 bit assembler => 64 bit assembler. Conceptual Issues => Topic started by: greenozon on November 22, 2022, 12:45:47 AM

Title: Message loop in masm64
Post by: greenozon on November 22, 2022, 12:45:47 AM
A question regarding message loop

in masm32 one could write the following one:

    .WHILE TRUE
                invoke GetMessage, ADDR msg,NULL,0,0
                .BREAK .IF (!eax)
                invoke TranslateMessage, ADDR msg
                invoke DispatchMessage, ADDR msg
    .ENDW

but it doesn't compile in masm64

any hints why?
Title: Re: Message loop in masm64
Post by: BugCatcher on November 22, 2022, 02:12:13 AM
Read masm64 help file. .WHILE
Title: Re: Message loop in masm64
Post by: greenozon on November 22, 2022, 04:09:39 AM
ml64  complains on this piece of code

.BREAK .IF (!eax)
Title: Re: Message loop in masm64
Post by: C3 on November 22, 2022, 05:30:05 AM
Hi greenozon,

I'll answer your both questions, this is how I use .while/.endw and how I have implemented message-loop:


    .while TRUE
        invoke GetMessage,ADDR msg,NULL,0,0
        .break .if (rax==0)
        invoke TranslateAccelerator,hwnd,hAccel,ADDR msg
        .if (rax==0)
            invoke TranslateMessage,ADDR msg
            invoke DispatchMessage,ADDR msg
        .endif
    .endw


I think you have problem with the macros, use lowercase for .while and .endw
Title: Re: Message loop in masm64
Post by: greenozon on November 22, 2022, 06:10:58 AM
Excellent info!
thanks a lot

PS in case my app does not have accelerators - I guess the block of TranslateAccelerator might be omitted..
Title: Re: Message loop in masm64
Post by: C3 on November 22, 2022, 06:16:20 AM
Yes, you don't need TranslateAccelerator unless you someday want to add Accelerator Resource to your Window. Just remove pieces that are not useful.
Title: Re: Message loop in masm64
Post by: C3 on December 19, 2022, 07:35:25 AM
Reading thru the MASM64 Examples (awesome content)..
There is a other view of how to build MSG loop.


msgloop proc

    LOCAL msg   :MSG
    LOCAL pmsg  :QWORD
    LOCAL .r15  :QWORD
    LOCAL .r14  :QWORD

    mov .r15, r15
    mov .r14, r14

    lea r15, msg                                    ; load msg address into r15
    xor r14, r14                                    ; set r14 to zero

    jmp gmsg                                        ; jump directly to GetMessage()

  mloop:
    rcall TranslateMessage,r15
    rcall DispatchMessage,r15
  gmsg:
    test rax, rvcall(GetMessage,r15,r14,r14,r14)    ; loop until GetMessage returns zero
    jnz mloop

  mquit:
    mov r15, .r15
    mov r14, .r14

    ret

msgloop endp


Assembly is awsome, you can build things so many way. Thank you for this! Mine example were bit like C-syntax loop.
Title: Re: Message loop in masm64
Post by: Caché GB on December 19, 2022, 10:57:52 AM
This works for me.

;#############################################################################################################

WinMainW proc public

     local  wMsg:MSG

            add  rsp,-28h
            and  rsp,-10h

         FNINIT

         invoke  GetModuleHandle, null
            mov  hInstance, rax

         invoke  InitializeWindow

         invoke  RtlZeroMemory, &wMsg, sizeof(MSG)
            mov  rax, g_hwnd
            mov  wMsg.hwnd, rax

        MsgLoop:

         invoke  GetMessage, &wMsg, null, 0, 0
             or  eax, eax
             je  short  MainExit
         invoke  TranslateMessage, &wMsg
         invoke  DispatchMessage, &wMsg
            jmp  short MsgLoop
 
       MainExit:

            mov  rcx, null
           call  ExitProcess

            ret

WinMainW endp

;#############################################################################################################
Title: Re: Message loop in masm64
Post by: jj2007 on December 19, 2022, 12:05:11 PM
There are several variants to code a message loop. Most do not care for...
a) CreateWindowEx failure (which means you have a zombie running)
b) GetMessage error (https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage):
QuoteIf the function retrieves the WM_QUIT message, the return value is zero.
If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle

Here is a fool-proof variant:
  invoke RegisterClassEx, rbx ; the window class needs to be registered
  wsStyle=WS_OVERLAPPEDWINDOW or WS_VISIBLE or WS_CLIPCHILDREN
  invoke CreateWindowEx, 0, wc.lpszClassName, Chr$("Hello World"), wsStyle, 600, 127, 300, 200, NULL,\
rv(LoadMenu, wc.hInstance, 100), wc.hInstance, NULL

msgLoop: inc eax
shr eax, 1
je @F ; quit if GetMessage returned 0 (exit OK) or -1 (error), or if CwEx failed
  invoke TranslateMessage, addr msg ; translates virtual-key messages into character messages
invoke DispatchMessage, addr msg ; dispatches a message to a window procedure
invoke GetMessage, addr msg, 0, 0, 0 ; retrieve a message from the queue, and return a BOOL
  jmp msgLoop
@@: invoke ExitProcess, msg.wParam
Title: Re: Message loop in masm64
Post by: hutch-- on December 19, 2022, 01:50:40 PM
Minimal, authodox, reliable.

msgloop proc

    LOCAL msg    :MSG
    LOCAL pmsg   :QWORD

    mov pmsg, ptr$(msg)                     ; get the msg structure address
    jmp gmsg                                ; jump directly to GetMessage()

  mloop:
    rcall TranslateMessage,pmsg
    rcall DispatchMessage,pmsg
  gmsg:
    test rax, rvcall(GetMessage,pmsg,0,0,0) ; loop until GetMessage returns zero
    jnz mloop

    ret

msgloop endp
Title: Re: Message loop in masm64
Post by: jj2007 on December 19, 2022, 09:02:49 PM
Quote from: hutch-- on December 19, 2022, 01:50:40 PMtest rax, rvcall(GetMessage,pmsg,0,0,0) ; loop until GetMessage returns zero
    jnz mloop

Quote from: jj2007 on December 19, 2022, 12:05:11 PM
GetMessage (https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage):
If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle

\Masm64\Examples\Simple\progress_win\progress.asm
    mov classname, "x" ; create an error in line 100
    invoke CreateWindowEx,WS_EX_LEFT or WS_EX_ACCEPTFILES, \


And, voilĂ , you have a zombie - check your Task Manager :tongue:

RichMasm:
Quote\Masm64\Examples\Simple\progress_win\progress.exe
(ID 11252) is running or open in debugger
Try to kill it?
Title: Re: Message loop in masm64
Post by: hutch-- on December 20, 2022, 03:22:05 AM
> If there is an error ........

Don't make errors.  :icon_idea: