Could anyone help me with this code, it does nothing. When it should display a dialog box with no title and button. as far as I know it follows the procedure for creating in memory dialog box's to the letter.
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
;include c:\masm32\macros\ucmacros.asm
.data
align 4
dlgtmp DLGTEMPLATE <WS_OVERLAPPED or WS_SYSMENU or DS_CENTER,0,1,0,0,50,50>
dw 0
dw 0
dw 0;change this to WSTR dlgcaption,"Test" later
align 4
dlgitemtmp DLGITEMTEMPLATE <WS_VISIBLE or WS_CHILD,0,10,10,50,50,735>
dw 0ffffh
dw 080h
dw 0;change to WSTR btntext,"OK" later
dw 0
.code
DlgProc proc uses edi esi ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
xor eax,eax
inc eax
ret
DlgProc endp
start:
invoke GetModuleHandle,NULL
invoke DialogBoxIndirectParam,eax,offset dlgtmp,0,DlgProc,0
invoke ExitProcess,eax
end start
The DialogBoxIndirectParam function is returning -1 indicating that it failed, and GetLastError is returning ERROR_CANNOT_FIND_WND_CLASS. The problem is with the definition of the DLGTEMPLATE structure in windows.inc:
DLGTEMPLATE STRUCT DWORD
style DWORD ?
dwExtendedStyle DWORD ?
cdit WORD ?
x WORD ?
y WORD ?
lx WORD ?
ly WORD ?
DLGTEMPLATE ENDS
The specified DWORD (4-byte) alignment is causing ML to pad the length to a multiple of the alignment, 20 bytes when it is supposed to be 18 bytes. The fix is to remove the alignment specification. I have reported the problem.
actually it's microsofts documentation that is at fault it says:
QuoteIn a dialog box template, the DLGTEMPLATE structure is always immediately followed by three variable-length arrays that specify the menu, class, and title for the dialog box.
not true.
if I follow DLGTEMPLATE with only 2 variable length arrays such as
dw 0
dw 0
align 4
or
dw 0
WSTR dlgcaption,"Testi"
align 4
it works ok, it's as though either the menu or the class has been dropped and the documentation is out of date! I know it's not the align statement because, if I align manually the same applies.
The most strange thing is that in my second example that works fine doesn't seem to be in the same format as Dialogs.inc (which I know works fine i've used it before) in that file they pad an extra 2 bytes between the end of the DlgBoxIndirectParam and the caption text, weird! :dazzled:
Yes i've confirmed it:
there are 20 bytes between the start of my DLGTEMPLATE and where I insert the caption text.
but,
in Dialogs.inc
Dialog MACRO quoted_text_title,quoted_font,fsize,dstyle,ctlcnt,tx,ty,wd,ht,bsize
push esi
push edi
invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,bsize
mov esi, eax
mov edi, esi
mov DWORD PTR [edi+0], DS_SETFONT or dstyle
mov WORD PTR [edi+8], ctlcnt
mov WORD PTR [edi+10], tx
mov WORD PTR [edi+12], ty
mov WORD PTR [edi+14], wd
mov WORD PTR [edi+16], ht
add edi, 22
ustring quoted_text_title
mov WORD PTR [edi], fsize
add edi, 2
ustring quoted_font
ENDM
there are 22 bytes!
i'll show you my complete working code again THIS CODE WORKS FINE. but it should NOT!
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
include c:\masm32\macros\ucmacros.asm
.data
align 4
dlgtmp DLGTEMPLATE <WS_OVERLAPPED or WS_SYSMENU or DS_CENTER,0,1,0,0,250,250>
dw 0
WSTR ,"Testing"
align 4
dlgitemtmp DLGITEMTEMPLATE <WS_VISIBLE or WS_CHILD,0,10,10,50,50,735>
dw 0ffffh
dw 080h
WSTR btntext,"OK"
dw 0
.code
DlgProc proc uses edi esi ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg==WM_INITDIALOG
xor eax,eax
inc eax
ret
.elseif uMsg==WM_COMMAND
mov edx,wParam
and edx,0ffffh
.if edx==735
invoke EndDialog,hWnd,0
.endif
.endif
xor eax,eax
ret
DlgProc endp
start:
invoke GetModuleHandle,NULL
invoke DialogBoxIndirectParam,eax,offset dlgtmp,0,DlgProc,0
invoke ExitProcess,0
end start
notice that either the menu or the class has no empty entry for it: there is only one 'dw 0' between the DLGTEMPLATE and the cation text. weird!
I was able to identify the problem with the DLGTEMPLATE definition because I have encountered it before, and after much head scratching and experimentation I determined that the structure was the wrong size. This code works:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
_DLGTEMPLATE STRUCT
style DWORD ?
dwExtendedStyle DWORD ?
cdit WORD ?
x WORD ?
y WORD ?
lx WORD ?
ly WORD ?
_DLGTEMPLATE ENDS
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
align 4
dlgtmp _DLGTEMPLATE <WS_OVERLAPPED or WS_SYSMENU or DS_CENTER,0,1,0,0,50,50>
dw 0
dw 0
;dw 0 ;change this to WSTR dlgcaption,"Test" later
dw 'T','e','s','t',0
align 4
dlgitemtmp DLGITEMTEMPLATE <WS_VISIBLE or WS_CHILD,0,9,23,30,10,735>
dw 0ffffh
dw 080h
;dw 0 ;change to WSTR btntext,"OK" later
dw 'O','K',0
dw 0
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DlgProc proc uses edi esi ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
SWITCH uMsg
CASE WM_COMMAND
SWITCH wParam
CASE 735
MsgBox 0, 0, "OK", 0
CASE IDCANCEL
invoke EndDialog, hWnd, 0
ENDSW
CASE WM_CLOSE
invoke EndDialog, hWnd, 0
ENDSW
return 0
DlgProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke GetModuleHandle,NULL
invoke DialogBoxIndirectParam,eax,offset dlgtmp,0,DlgProc,0
invoke ExitProcess,eax
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
The Dialog macro is skipping over the menu and class arrays so it can initialize the title array. One non-obvious and essential detail here is that the GMEM_ZEROINIT flag on the GlobalAlloc call causes the memory to be initially filled with zeros. So skipping over the menu and class arrays leaves the first word of each set to zero, indicating that there is no menu and that the system should use the system-defined dialog class.
Your "working" code is working because ML pads the structure with zeros, and the pad at the end of the structure is serving as the menu array.
so even though the definition of the DLGTEMPLATE structure reads correctly, it would seem (as you origonally pointed out,thank you.) that the alignment is causing the probleb. not only is it aligning the start of the the structure but also altering the position at the end. This must be a serious fault with the structure alignment directive and the behaviour is not documented. This could cause all kinds of problems.
The behavior is documented, and it has nothing to do with aligning the start of the structure. See Alignment Value and Offsets for Structures, about half way down the page here (http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_05.htm). I think the alignment on the structure definition is from years ago, and it was never corrected because the structure is not commonly used.
Thanks for all your help MichealW. :U