Hello;
I am trying Mikl__'s samples. Thank you Mikl__ btw.
I have wrote a small code to open a dialog from template. I can see the template but i cannot close it from X button. Alt+F4 combination also doesn't works
OPTION DOTNAME ; required for macro files
option casemap:none ; case sensitive
; _____________________________________________________________________________
; include files
include \masm64\include64\win64.inc ; main include file
include \masm64\include64\kernel32.inc
include \masm64\include64\user32.inc
include \masm64\include64\comctl32.inc
; _____________________________________________________________________________
; libraries
includelib \masm64\lib64\user32.lib
includelib \masm64\lib64\kernel32.lib
includelib \masm64\lib64\comctl32.lib
; _____________________________________________________________________________
; MASM64 macros
include \masm64\macros64\vasily.inc ; main macro file
include \masm64\macros64\macros64.inc ; auxillary macro file
; _____________________________________________________________________________
; constant variables
.const
; Main Dialog
IDD_DIALOG EQU 1000
; _____________________________________________________________________________
; initialized variables
.data
lpTitle db ".title",0
lpMessa db ".message",0
.code
WinMainCRTStartup proc hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPSTR, nCmdShow:DWORD
invoke InitCommonControls
invoke DialogBoxParam,hInstance, IDD_DIALOG,0,addr DlgProc,NULL
invoke ExitProcess,NULL
WinMainCRTStartup endp
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax,uMsg
.if edx==WM_INITDIALOG
invoke MessageBox,hWnd,addr lpMessa,addr lpTitle,MB_OK
.elseif edx==WM_COMMAND
; code here
.elseif edx==WM_CLOSE
invoke EndDialog,hWnd,0
ret
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
end
I have debug the code via debugger and understand that in DlgProc the uMsg does not carry the WM_xxxx messages?
Where am i doing wrong.
PS. I am using masm64 sdk.
I have attached my radasm2 project.
Nevermind this post. Mikl__ has answered better than I could have.
See his post below this one.
I removed my comments and code to avoid further confusion. :undecided:
Hi, blue_devil!
DialogAppx64.asm; GUI #
include win64a.inc ; main include file
; constant variables
IDD_DIALOG EQU 1000
IMAGE_BASE EQU 400000h
; _____________________________________________________________________________
; initialized variables
.data
lpTitle db ".title",0
lpMessa db ".message",0
.code
WinMain proc hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPSTR, nCmdShow:DWORD
invoke InitCommonControls
invoke DialogBoxParamA,IMAGE_BASE, IDD_DIALOG,0,addr DlgProc,NULL
invoke RtlExitUserProcess,NULL
WinMain endp
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov hWnd,rcx
cmp edx,WM_INITDIALOG
je wmINITDIALOG
cmp edx,WM_COMMAND
je wmCOMMAND
cmp edx,WM_CLOSE
je wmCLOSE
xor eax,eax;eax=FALSE
jmp exit_
wmINITDIALOG:
mov edx,offset lpMessa
mov r8d,offset lpTitle
invoke MessageBoxA,hWnd,,,MB_OK
jmp wmBYE
wmCOMMAND:; code here
jmp wmBYE
wmCLOSE:invoke EndDialog,hWnd,0
wmBYE: mov eax,TRUE
exit_: leave
ret
DlgProc endp
end
DialogAppx64.rc#include "resource.h"
#define IDD_DIALOG 1000
#define FW_NORMAL 400
#define FALSE 0
IDD_DIALOG DIALOGEX 6,6,189,99
FONT 8,"MS Sans Serif",FW_NORMAL, FALSE, 1
STYLE WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION
| WS_SYSMENU | WS_THICKFRAME
BEGIN
END
Hi Mikl__
I noticed that you too have not called GetModuleHandle for the instance handle. Does it work without?
I'm on my 32 bit box so can't test it
Your example has some strange looking code. I might have to load up 64 bit OS to investigate
Seems mixing 32 and 64 bit registers. ?? How odd.
Hi, Swordfish!
hInstance = IMAGE_BASE = 400000h
the GetModuleHandle function returns this value because the /BASE:0x400000 key was specified during assembly
Doh!!! I totally missed that. But why even set the image base manually. I don't understand.
So what about the mixed 32 and 64 bit register usage. Looks odd to me in a relatively mundane function.
I haven't coded anything 64 bit in a few years, maybe I need a refresher course. :biggrin:
QuoteSo what about the mixed use of 32 and 64 bit registers.
a value in a 32-bit register is padded with zeros to 64 bits, but when encoded, 32-bit registers take up less space
Some tricks for Win x64 (https://wasm-in.translate.goog/threads/skazki-djadjushki-rimusa-o-x64.31832/?_x_tr_sl=ru&_x_tr_tl=en&_x_tr_hl=ru&_x_tr_pto=wapp#post-383749)
Quote from: Mikl__ on August 29, 2022, 11:34:49 AM
QuoteSo what about the mixed use of 32 and 64 bit registers.
a value in a 32-bit register is padded with zeros to 64 bits, but when encoded, 32-bit registers take up less space
Ok. Never knew that one, about the padding that is. No movzx to accomplish it, cool. As said it's been years since I dabbled in 64 bit code. Thanks for the clarification. I removed my code and comments in my first post here as you have explained much better than I could have.
Quote from: blue_devil on August 29, 2022, 09:28:30 AM
WinMainCRTStartup proc hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPSTR, nCmdShow:DWORD
invoke InitCommonControls
invoke DialogBoxParam,hInstance, IDD_DIALOG,0,addr DlgProc,NULL
invoke ExitProcess,NULL
WinMainCRTStartup endp
Actually
WinMainCRTStartup is
void __stdcall WinMainCRTStartup (void)so that hInstance is bogus.
https://docs.microsoft.com/en-us/cpp/build/reference/entry-entry-point-symbol?view=msvc-170
Thank you all for your replies, i've fixed the situation:
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov hWnd,rcx
mov uMsg,edx
.if uMsg==WM_INITDIALOG
invoke MessageBox,hWnd,addr lpMessa,addr lpTitle,MB_OK
.elseif uMsg==WM_COMMAND
; code here
.elseif uMsg==WM_CLOSE
invoke EndDialog,hWnd,0
ret
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
* According to the x64 Microsoft Calling Conventions (https://en.wikipedia.org/wiki/X86_calling_conventions) we know that first 4 parameters pass to the rcx,rdx,r8,r9. So as you can see above i passed rcx to hWnd and rdx to uMsg variables. So in our MASM64 sdk is this line useless: hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM Am I right?
I can write this dialog proc like that:
DlgProc proc
LOCAL hWnd:HWND
LOCAL uMsg:UINT
mov hWnd,rcx
mov uMsg,edx
.if uMsg==WM_INITDIALOG
invoke MessageBox,hWnd,addr lpMessa,addr lpTitle,MB_OK
.elseif uMsg==WM_COMMAND
; code here
.elseif uMsg==WM_CLOSE
invoke EndDialog,hWnd,0
ret
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
hutch-- has lot of examples like above. So is this the way, that I should write my assembly programs? Is this MASM64 convention(I mean according to the MASM32)?
Quote from: blue_devil on August 29, 2022, 08:34:25 PMSo in our MASM64 sdk is this line useless: hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
No, it's not useless, it shows the args. There are also ways to get these arguments filled by the assembler, instead of fumbling with the registers rcx, rdx etc.
Quote from: jj2007 on August 29, 2022, 08:42:35 PM
Quote from: blue_devil on August 29, 2022, 08:34:25 PMSo in our MASM64 sdk is this line useless: hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
No, it's not useless, it shows the args. There are also ways to get these arguments filled by the assembler, instead of fumbling with the registers rcx, rdx etc.
Hello jj, how're you?
I am looking for the way to get those arguments fiilled by assemblers. What/How is that way?
If i omit main functions parameters i can compile my code but the executable do not show dialog:
WinMainCRTStartup proc ;hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPSTR, nCmdShow:DWORD
LOCAL hInstance:HINSTANCE
mov hInstance,rcx
invoke InitCommonControls
invoke DialogBoxParam,hInstance, IDD_DIALOG, 0, addr DlgProc, NULL
invoke ExitProcess,NULL
WinMainCRTStartup endp
use this to get hInstance
invoke GetModuleHandle,NULL
like this invoke GetModuleHandle,NULL
invoke DialogBoxParam,rax, IDD_DIALOG,0,addr DlgProc,NULL
I think i cannot express myself right
This compiles and runs:
WinMainCRTStartup proc hInst:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPSTR, nCmdShow:DWORD
invoke InitCommonControls
invoke GetModuleHandle,NULL
invoke DialogBoxParam,rax, IDD_DIALOG,0,addr DlgProc,NULL
invoke ExitProcess,NULL
WinMainCRTStartup endp
This also compiles but does not run:
WinMainCRTStartup proc
invoke InitCommonControls
invoke GetModuleHandle,NULL
invoke DialogBoxParam,rax, IDD_DIALOG,0,addr DlgProc,NULL
invoke ExitProcess,NULL
WinMainCRTStartup endp
Is it possible for me to make assembler to pass arguments to these arguments lines:
hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPSTR, nCmdShow:DWORD
or
hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
Merhaba blue_devil!
böyle yapmayı deneWinMainCRTStartup proc
enter 30h,0; <---
invoke InitCommonControls
invoke GetModuleHandle,NULL
invoke DialogBoxParam, eax, IDD_DIALOG, 0, addr DlgProc, NULL
invoke ExitProcess,NULL
WinMainCRTStartup endp
Quote from: Mikl__ on August 29, 2022, 09:38:57 PM
invoke DialogBoxParam, eax, IDD_DIALOG, 0, addr DlgProc, NULL
only for /LARGEADDRESSAWARE:NO in x64 and not using /BASE:0x400000
But in in Windows 7 x64 this is possible and Desktop is owner of dialog
ExitProcess(DialogBoxParam(0, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)MainDlgProc, 0));
Thanks Timo!
I forgot that rax is possibly equal 0x140000000
STACKFRAME macro is interesting. If i use STACKFRAME macro at the very beginning like in the examples of Mikl__ code compiles but does not run.
Final workaround -maybe- I put STACKFRAME macro just before DlgProc and everything is fine.
OPTION DOTNAME ; required for macro files
option casemap:none ; case sensitive
; _____________________________________________________________________________
; MASM64 macros
include \masm64\macros64\vasily.inc ; main macro file
include \masm64\macros64\macros64.inc ; auxillary macro file
; _____________________________________________________________________________
; include files
include \masm64\include64\win64.inc ; main include file
include \masm64\include64\kernel32.inc
include \masm64\include64\user32.inc
include \masm64\include64\comctl32.inc
;STACKFRAME ; create a default stack frame
; _____________________________________________________________________________
; libraries
includelib \masm64\lib64\user32.lib
includelib \masm64\lib64\kernel32.lib
includelib \masm64\lib64\comctl32.lib
; _____________________________________________________________________________
; constant variables
.const
; Main Dialog
IDD_DIALOG EQU 1000
; _____________________________________________________________________________
; initialized variables
.data
.code
WinMainCRTStartup proc hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPSTR, nCmdShow:DWORD
invoke InitCommonControls
invoke DialogBoxParam,hInstance, IDD_DIALOG, 0, addr DlgProc, NULL
invoke ExitProcess,NULL
WinMainCRTStartup endp
STACKFRAME
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
;LOCAL hWnd:HWND
;LOCAL uMsg:UINT
;LOCAL wParam:WPARAM
;LOCAL lParam:LPARAM
;mov hWnd,rcx
;mov uMsg,edx
;mov wParam,r8
;mov lParam,r9
.if uMsg==WM_INITDIALOG
; code that runs before dialog shows up
.elseif uMsg==WM_COMMAND
; code of controls, buttons, checkboxes...
.elseif uMsg==WM_CLOSE
invoke EndDialog,hWnd,0
ret
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
end
Why it doesn't work if i write STACKFRAME at the beginning(look above code, i have commented it out)
Now look Mikl__'s tute03 code. The STACKFRAME macro is above and everything works fine:
OPTION DOTNAME ; required for macro files
option casemap:none ; case sensitive
include \masm64\include64\win64.inc ; main include file
include \masm64\macros64\vasily.inc ; main macro file
include \masm64\macros64\macros64.inc ; auxillary macro file
STACKFRAME ; create a default stack frame
;include \masm64\m64lib\m64lib.inc ; include file for m64lib library
; ------------------------
; system API include64 files
; ------------------------
include \masm64\include64\kernel32.inc
include \masm64\include64\user32.inc
;includelib \masm64\m64lib\m64lib.lib ; m64lib library
; ------------------------
; system API library files
; ------------------------
includelib \masm64\lib64\kernel32.lib
includelib \masm64\lib64\user32.lib
.data
ClassName db "SimpleWin64Class", 0 ; the name of our window class
AppName db "Our First Window", 0 ; the name of our window
.data?
hIcon dq ?
hCursor dq ?
;OPTION PROLOGUE:rbpFramePrologue
;OPTION EPILOGUE:rbpFrameEpilogue
.code
WinMainCRTStartup proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
invoke LoadIcon,hInst,IDI_APPLICATION
mov hIcon, rax
invoke LoadCursor,hInst,IDC_ARROW
mov hCursor, rax
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
lea rdi, WndProc
mov wc.lpfnWndProc, rdi;offset WndProc
mov wc.cbClsExtra, 0
mov wc.cbWndExtra, 0
mov wc.hInstance, 0;hInst
mov rax, hIcon
mov wc.hIcon, rax;hIcon
mov rbx, hCursor
mov wc.hCursor, rbx;hCursor
mov wc.hbrBackground, COLOR_WINDOW + 1
mov wc.lpszMenuName, 0
lea rdi, ClassName
mov wc.lpszClassName, rdi;offset ClassName
mov wc.hIconSm, rax;hIcon
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,NULL,addr ClassName,addr AppName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,0,NULL
mov hwnd, rax
invoke ShowWindow,hwnd, SW_SHOWNORMAL
invoke UpdateWindow,hwnd
.while TRUE
invoke GetMessage,addr msg, NULL,0,0
.if (rax == 0)
.break
.endif
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
.endw
mov rax, msg.wParam
ret
WinMainCRTStartup endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg==WM_CLOSE
invoke MessageBox,hWnd,addr ClassName, addr AppName,MB_OK
invoke ExitProcess,NULL
.elseif uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
end
Merhaba bluedevil !
This works for me.code
WinMainCRTStartup proc
enter 30h,0
invoke InitCommonControls
invoke GetModuleHandle,NULL
invoke DialogBoxParam,rax, IDD_DIALOG,0,addr DlgProc,NULL
invoke ExitProcess,NULL
WinMainCRTStartup endp
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov hWnd,rcx
mov uMsg,edx
mov wParam,r8
mov lParam,r9
.if uMsg==WM_INITDIALOG
; code that runs before dialog shows up
.elseif uMsg==WM_COMMAND
; code of controls, buttons, checkboxes...
.elseif uMsg==WM_CLOSE
invoke EndDialog,hWnd,0
.else
xor eax,eax
leave
retn
.endif
mov eax,TRUE
leave
retn
DlgProc endp
This works for meWinMainCRTStartup proc
LOCAL shadow[4] : QWORD ; create shadow space
invoke InitCommonControls
invoke GetModuleHandle,NULL
invoke DialogBoxParam,rax,IDD_DIALOG,0,addr DlgProc,NULL
invoke ExitProcess,NULL
WinMainCRTStartup endp
align 8
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL shadow[4] : QWORD ; create shadow space
mov hWnd,rcx
mov uMsg,edx
mov wParam,r8
mov lParam,r9
.if uMsg==WM_INITDIALOG
; code that runs before dialog shows up
.elseif uMsg==WM_COMMAND
; code of controls, buttons, checkboxes...
.elseif uMsg==WM_CLOSE
; invoke EndDialog,hWnd,0
; invoke EndDialog,rcx,0
invoke EndDialog,,0
.else
xor eax,eax
ret
.endif
mov eax,TRUE
ret
DlgProc endp
poasm users might remember this.