News:

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

Main Menu

Window5 using a normal stack frame.

Started by hutch--, July 06, 2016, 12:33:38 AM

Previous topic - Next topic

hutch--

This version is coming close to conventional MASM style code. I have added 2 macros for direct register calls to a limit of 4 as per the Microsoft binary interface and with the CreateWindowEx() API call I have used Vasily's "invoke" macro as it handles more than the 4 registers of a FASTCALL format. The use of a stack frame enabled with,

    OPTION PROLOGUE:rbpFramePrologue
    OPTION EPILOGUE:rbpFrameEpilogue

allows LOCAL variables and structures to be allocated in the normal manner. The only quirk I have found so far is you cannot use "retn" but must use "ret". In the WndProc the 4 args are preserved in LOCAL values as they are needed through the procedure. The ".if" based notation is contained in vasily's macro file and appears to be reliable and similar enough to 32 bit ML usage.

This is the source.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    OPTION DOTNAME
    option casemap:none

    include \masm64\include\temphls.inc
    include \masm64\include\win64.inc
    include \masm64\include\kernel32.inc
    include \masm64\include\user32.inc
    include \masm64\include\msvcrt.inc

    includelib \masm64\lib\kernel32.lib
    includelib \masm64\lib\user32.lib
    includelib \masm64\lib\msvcrt.lib

    OPTION PROLOGUE:rbpFramePrologue
    OPTION EPILOGUE:rbpFrameEpilogue

    include macros64.inc

    .data
      ClassName db "ML64_Window_Class",0
      AppName   db "ML64 Example Window",0

    .data?
      hInstance dq ?
      hWnd      dq ?
      sWid      dq ?
      sHgt      dq ?
      lft       dq ?
      top       dq ?
      wid       dq ?
      hgt       dq ?
      hIcon     dq ?
      hMnu      dq ?

  .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL wc:WNDCLASSEX

    mov hInstance, retval(GetModuleHandle,0)
    mov hIcon, retval(LoadIcon,hInstance,10)

    mov wc.cbSize,          SIZEOF WNDCLASSEX
    mov wc.style,           0
    mrm wc.lpfnWndProc,     OFFSET WndProc
    mov wc.cbClsExtra,      0
    mov wc.cbWndExtra,      0
    mrm wc.hInstance,       hInstance
    mrm wc.hIcon,           hIcon
    mov wc.hCursor,         10003h
    mov wc.hbrBackground,   COLOR_WINDOW
    mrm wc.lpszMenuName,    0
    mrm wc.lpszClassName,   OFFSET ClassName
    mrm wc.hIconSm,         hIcon

    function RegisterClassEx, lp(wc)

  ; ------------------------------------
  ; centred half height and width window
  ; ------------------------------------
    function GetSystemMetrics,SM_CXSCREEN
    mov r11, rax
    shr rax, 2
    mov lft, rax

    mov rax, r11
    shr rax, 1
    mov wid, rax

    function GetSystemMetrics,SM_CYSCREEN
    mov r11, rax
    shr rax, 2
    mov top, rax

    mov rax, r11
    shr rax, 1
    mov hgt, rax

    invoke CreateWindowEx,0,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW or WS_VISIBLE,\
           lft,top,wid,hgt,0,0,hInstance,0
    mov hWnd, rax

    function LoadMenu,hInstance,100
    function SetMenu,hWnd,rax

    call msgloop

    function ExitProcess, rax

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

msgloop proc

    LOCAL msg   :MSG

    mov r11, rdi                ; preserve rdi
    lea rdi, msg                ; load structure address
    jmp gmsg

  @@:
    function TranslateMessage,rdi
    function DispatchMessage,rdi
  gmsg:
    function GetMessage,rdi,0,0,0
    test rax, rax
    jnz @B

    mov rdi, r11                ; restore rdi
    ret

msgloop endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

WndProc proc

    LOCAL hWin      :QWORD
    LOCAL uMsg      :QWORD
    LOCAL wParam    :QWORD
    LOCAL lParam    :QWORD

    mov hWin, rcx
    mov uMsg, rdx
    mov wParam, r8
    mov lParam, r9

    .if uMsg == WM_COMMAND
      .if wParam == 1000
        function SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL

      .elseif wParam == 10000
        function MessageBox,hWin,txt("Example with icon and menu."),txt("About ML64 Example"),MB_OK

      .endif

    .elseif uMsg == WM_CLOSE
      function MessageBox,0,txt("Seeya round like a Rubens."),txt("WM_CLOSE here"),MB_OK
      function SendMessage,hWin,WM_DESTROY,0,0

    .elseif uMsg == WM_DESTROY
      function PostQuitMessage,NULL

    .endif

    function DefWindowProc,hWin,uMsg,wParam,lParam

    ret

WndProc endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end