Author Topic: Message loop in masm64  (Read 598 times)

greenozon

  • Regular Member
  • *
  • Posts: 46
Message loop in masm64
« 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?

BugCatcher

  • Member
  • **
  • Posts: 84
Re: Message loop in masm64
« Reply #1 on: November 22, 2022, 02:12:13 AM »
Read masm64 help file. .WHILE

greenozon

  • Regular Member
  • *
  • Posts: 46
Re: Message loop in masm64
« Reply #2 on: November 22, 2022, 04:09:39 AM »
ml64  complains on this piece of code

.BREAK .IF (!eax)

C3

  • Regular Member
  • *
  • Posts: 30
Re: Message loop in masm64
« Reply #3 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:

Code: [Select]
    .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

greenozon

  • Regular Member
  • *
  • Posts: 46
Re: Message loop in masm64
« Reply #4 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..

C3

  • Regular Member
  • *
  • Posts: 30
Re: Message loop in masm64
« Reply #5 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.

C3

  • Regular Member
  • *
  • Posts: 30
Re: Message loop in masm64
« Reply #6 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.

Code: [Select]
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.

Caché GB

  • Member
  • **
  • Posts: 109
  • MASM IS HOT
Re: Message loop in masm64
« Reply #7 on: December 19, 2022, 10:57:52 AM »
This works for me.
Code: [Select]
;#############################################################################################################

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

;#############################################################################################################
Caché GB's 1 and 0-nly language:MASM

jj2007

  • Member
  • *****
  • Posts: 13657
  • Assembly is fun ;-)
    • MasmBasic
Re: Message loop in masm64
« Reply #8 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:
Quote
If 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:
Code: [Select]
  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

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 10313
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Message loop in masm64
« Reply #9 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
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

jj2007

  • Member
  • *****
  • Posts: 13657
  • Assembly is fun ;-)
    • MasmBasic
Re: Message loop in masm64
« Reply #10 on: December 19, 2022, 09:02:49 PM »
    test rax, rvcall(GetMessage,pmsg,0,0,0) ; loop until GetMessage returns zero
    jnz mloop

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
Code: [Select]
    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?

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 10313
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Message loop in masm64
« Reply #11 on: December 20, 2022, 03:22:05 AM »
> If there is an error ........

Don't make errors.  :icon_idea:
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy: