The macros for the prologue/epilogue are testing up OK so far, still more needs to be done to handle anonymous memory addresses ( [rax+rcx*4+16] etc ...) but the rest seems to be working OK. The macro for "invoke" was reasonably tedious to get up and running but it now means I can use invoke with quoted text support and the address operator "&". I have found a catch 22 with the address operator, to prevent thhe old 32 bit irritation of eax being overwritten by the next function or address I changed the "&" address operator to return an address in the .data? section which means that you can use multiple addresses in the invoke call without the overwrite problem, problem is to use a structure as the target it required more code that I wanted so in some instances for simple code, the "ptr$" macro is more efficient.
This is the source which is starting to look like reasonably clean code. To have a look at the underlying mnemonic code, you need to open the attached zipped EXE with ArkDasm.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
invoke_off equ <0> ; exclude Vasily's invoke
include \masm32\include64\masm64rt.inc
STACKFRAME ; use custom prologue/epilogue
include evokemacro.inc
IFNDEF SB_SETTEXT
SB_SETTEXT equ WM_USER+1
ENDIF
IFNDEF SB_SETPARTS
SB_SETPARTS equ WM_USER+4
ENDIF
.data?
hInstance dq ?
hWnd dq ?
hIcon dq ?
hCursor dq ?
hMnu dq ?
hEdit dq ?
hStatus dq ?
sWid dq ?
sHgt dq ?
.data
classname db "UI Test",0
appname db "UI Test",0
.code
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
entry_point proc
mov hInstance, function(GetModuleHandle,0)
mov hIcon, function(LoadIcon,hInstance,10)
mov hCursor, function(LoadCursor,0,IDC_ARROW)
mov sWid, function(GetSystemMetrics,SM_CXSCREEN)
mov sHgt, function(GetSystemMetrics,SM_CYSCREEN)
call main
invoke ExitProcess,0
ret
entry_point endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL wc :WNDCLASSEX
LOCAL lft :QWORD
LOCAL top :QWORD
LOCAL wid :QWORD
LOCAL hgt :QWORD
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_BYTEALIGNCLIENT or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, ptr$(WndProc)
mov wc.cbClsExtra, 128
mov wc.cbWndExtra, 128
mrm wc.hInstance, hInstance
mrm wc.hIcon, hIcon
mrm wc.hCursor, hCursor
mov wc.hbrBackground, COLOR_BTNSHADOW+1
mov wc.lpszMenuName, 0
mov wc.lpszClassName, ptr$(classname)
mrm wc.hIconSm, hIcon
lea rcx, wc
call RegisterClassEx
mov wid, function(getpercent,sWid,65) ; 65% screen width
mov hgt, function(getpercent,sHgt,65) ; 65% screen height
invoke aspect_ratio,hgt,45 ; height + 45%
cmp wid, rax ; if wid > rax
jle @F
mov wid, rax ; set wid to rax
; ---------------------------------
; centre window at calculated sizes
; ---------------------------------
@@:
mov rax, sWid
sub rax, wid
shr rax, 1
mov lft, rax
mov rax, sHgt
sub rax, hgt
shr rax, 1
mov top, rax
invoke CreateWindowEx,WS_EX_LEFT or WS_EX_ACCEPTFILES,&classname,\
&appname,WS_OVERLAPPEDWINDOW or WS_VISIBLE,\
lft,top,wid,hgt,0,0,hInstance,0
mov hWnd, rax
call msgloop
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
msgloop proc
LOCAL msg :MSG
LOCAL rsireg :QWORD
LOCAL rdireg :QWORD
mov rsireg, rsi ; preserve rsi
mov rdireg, rdi ; preserve rdi
xor rsi, rsi
lea rdi, msg ; load structure address
jmp gmsg
@@:
invoke TranslateMessage,rdi
invoke DispatchMessage,rdi
gmsg:
test rax, function(GetMessage,rdi,rsi,rsi,rsi)
jnz @B
mov rdi, rdireg ; restore rdi
mov rsi, rsireg ; restore rsi
ret
msgloop endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
WndProc proc hWin:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
LOCAL dfbuff[260]:BYTE
mov [rbp+16], rcx
mov [rbp+24], rdx
mov [rbp+32], r8
mov [rbp+40], r9
.switch uMsg
.case WM_CREATE
mov hStatus, function(StatusBar,hWin)
.case WM_SIZE
invoke MoveWindow,hStatus,0,0,0,0,TRUE
.case WM_DROPFILES
invoke DragQueryFile,wParam,0,&dfbuff,260
invoke MessageBox,hWin,&dfbuff,"DragQueryFile",MB_OK
.case WM_CLOSE
invoke SendMessage,hWin,WM_DESTROY,0,0
.case WM_DESTROY
invoke PostQuitMessage,NULL
.endsw
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
WndProc endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
StatusBar proc hParent:QWORD
LOCAL handl :QWORD
LOCAL sbParts[4] :QWORD
mov hParent, rcx
mov handl, function(CreateStatusWindow,WS_CHILD or WS_VISIBLE or SBS_SIZEGRIP,NULL,hParent,200)
; --------------------------------------------
; set the width of each part, -1 for last part
; --------------------------------------------
lea r11, sbParts
mov QWORD PTR [r11+0], 150
mov QWORD PTR [r11+4], 300
mov QWORD PTR [r11+8], 450
mov QWORD PTR [r11+12],-1
invoke SendMessage,handl,SB_SETPARTS,4,&sbParts
mov rax, handl
ret
StatusBar endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end