hi
am having a prob with this code. - it contains a dialogbox with a button & an edit control, assembles properly but doesn't run correctly..seems to just quit off. - i've tested the button control individually & it works proper.
i inserted a MessageBox before the CreateDialogIndirectParam function & it displays
but if i insert it after that function it doesn't. i tried a couple of things without any luck.
----------
t y
[attachment deleted by admin]
For some reason the code that sets editbox_title in the edit control template is causing CreateDialogIndirectParam to fail and return zero. This code is actually trying to set the initial text of the control. Also, the memalign edi, 4 ahead of the creation data is not necessary.
Quote from: MichaelW on November 02, 2008, 10:32:12 AM
Also, the memalign edi, 4 ahead of the creation data is not necessary.
memalign MACRO reg, number
add reg, number - 1
and reg, -number
ENDM
"Not necessary" is maybe too gentle an expression: If there were non-aligned members in the structure, this would break the code.
memalign is not the same as
.align...
Anyway, taking the 4 memaiigns out does not solve your problem.
Two of the memaligns are necessary, just not the ones above the creation data definitions. The point is to align the the pointer in edi so the data in the template will be properly aligned. The templates structures must be dword aligned, but the arrays in the template only word aligned, and since the templates are dword aligned and everything in the templates is either a dword or a word, alignment of the arrays is automatic.
thanks for the responses.
Michael,
I just added the memalign for the creation-data to check. Thing is, the SDK seems to say in some places that the creation-data should be word aligned.. & in other places it seems to say that it should be dword aligned, like this for example..
QuoteIn addition, any creation data that follows a control definition must be aligned on a DWORD boundary.
-- that's from the 'about dialogboxes' overview in the SDK. - while on the DLGITEMTEMPLATE PAGE it says that the creation data should be word aligned like you said.
anyhow after the CreateDialogIndirectParam function the app seems to just quit of its own.
Quote from: MichaelW on November 02, 2008, 10:53:54 AM
Two of the memaligns are necessary, just not the ones above the creation data definitions.
Thanks for clarifying this. I thought this was kind of a structure, but now I realise I was on the wrong track. :red
Hi,
I just hacked around a bit picking up on what Michael said about the title array & kinda got the dialog to display. - all is still not working as desired.. & still don't know why the old code doesn't work,..but at least the dialog displays now with the button & the editbox.
What i tried is however not documented, in the SDK i have, in the description of the DLGITEMTEMPLATE structure (controls),.... however such a capability is mentioned in the DLGTEMPLATE structure.(dialogs) - So i don't know if its Safe
I set the first word of the title array to 0 , which for dialog templates is supposed to indicate that there is no title & no other elements in the array.
Would still be nice to know why my orginal code doesn't work though
here is the modification i made for the title section of the edit control
new code add edi, 22
mov word ptr [edi], 0 ; indicates no title
add edi, 2 ; update the pointer
old code
add edi, 22
invoke MultiByteToWideChar, CP_ACP, MB_PRECOMPOSED, addr editbox_title, -1,
edi, LENGTHOF editbox_title
add edi, LENGTHOF editbox_title*2
Using my own test code, I cannot find any way to set the initial text for an edit control from the title array, and depending on how I attempt to do it the application may not run. And I cannot find any way to specify creation data that will be passed in the WM_INITDIALOG message. The PSDK actually specifies that the address of the creation data will be passed in the lParam parameter of the WM_CREATE message.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
hInstance dd 0
buffer db 10 dup(0)
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DlgProc proc hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
SWITCH uMsg
CASE WM_INITDIALOG
mov eax, lParam
;mov eax, [eax]
invoke dwtoa, eax, ADDR buffer
invoke MessageBox, 0, ADDR buffer, 0, 0
CASE WM_COMMAND
.IF wParam == IDCANCEL
invoke EndDialog, hDlg, 0
.ENDIF
CASE WM_CLOSE
invoke EndDialog, hDlg, 0
ENDSW
xor eax, eax
ret
DlgProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke GetModuleHandle, NULL
mov hInstance, eax
Dialog "Test", \
"MS Sans Serif",10, \
WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
2,0,0,100,75,1024
DlgButton "Close",0,34,45,30,10,IDCANCEL
DlgEdit WS_BORDER or ES_MULTILINE,6,5,85,30,100
align_2 edi
ustring "initial text"
;add edi, 20
;add edi,2
;align_4 edi
;mov WORD PTR [edi], 6
;add edi, 2
;mov DWORD PTR [edi],1234
;add edi,4
CallModalDialog hInstance, 0, DlgProc, NULL
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
When I designed these "in memory dialog" macros years ago it was done the hard way in win9x as the documentation was wrong in a number of important instances. The alignment control is critical and intolerant so experiments will often fail without explanation.
Michael wrote..QuoteAnd I cannot find any way to specify creation data that will be passed in the WM_INITDIALOG message. The PSDK actually specifies that the address of the creation data will be passed in the lParam parameter of the WM_CREATE message.
in the CreateDialogIndirectParam Function the initialization data can be passed in the last parameter. all those functions with 'Param' in the end can do that i think. i.e pass the value in the lParam parameter of WM_INITDIALOG. - the sdk seems to say the creation data will just be passed on automatically in WM_CREATE.
edit
==========
just realised that after i got the dialogbox to display by making the title
0(of the edit control), if i add the WS_TABSTOP style to the the edit control it quits off again.(without displaying i.e)
mov dword ptr [edi+0] , ES_LEFT or ES_AUTOHSCROLL or WS_CHILD or WS_VISIBLE or WS_TABSTOP
can't make any sense of that
The CallModalDialog macro actually calls DialogBoxIndirectParam and passes the last macro parameter in the dwInitParam function parameter. In my test code (above) whatever value I pass in the last macro parameter is passed in the lParam parameter of the WM_INITDIALOG message and displayed in the message box.
Now that I look my code again I see two stupid errors that should have been obvious. The first error is that the creation data is for the edit control, not the dialog. So far I cannot see any simple way to properly test the creation data. The second error is that the DlgEdit macro skips over the title and creation data arrays leaving the first elements set to zero, so it's not possible to append the title array after the macro. The solution is to create a version of the macro that accepts an initial text parameter that it loads into the title array. This seems to work OK, so your problem is probably an error in your code.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
_DlgEdit MACRO quoted_initial_text,dstyle,tx,ty,wd,ht,ctlID
align_4 edi
mov DWORD PTR [edi+0], WS_VISIBLE or WS_CHILD or dstyle
mov WORD PTR [edi+8], tx
mov WORD PTR [edi+10], ty
mov WORD PTR [edi+12], wd
mov WORD PTR [edi+14], ht
mov WORD PTR [edi+16], ctlID
mov WORD PTR [edi+18], 0FFFFh
mov WORD PTR [edi+20], 0081h ;; edit control
add edi, 22
ustring quoted_initial_text
align_2 edi
add edi, 2
ENDM
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
hInstance dd 0
buffer db 10 dup(0)
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DlgProc proc hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
SWITCH uMsg
CASE WM_INITDIALOG
CASE WM_COMMAND
.IF wParam == IDCANCEL
invoke EndDialog, hDlg, 0
.ENDIF
CASE WM_CLOSE
invoke EndDialog, hDlg, 0
ENDSW
xor eax, eax
ret
DlgProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke GetModuleHandle, NULL
mov hInstance, eax
Dialog "Test", \
"MS Sans Serif",10, \
WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
2,0,0,100,75,1024
_DlgEdit "initial text",WS_BORDER,6,5,85,30,100
DlgButton "Close",0,34,45,30,10,IDCANCEL
CallModalDialog hInstance, 0, DlgProc, 12345
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Michael thanks a lot for the testing.
its something to do with the title array, but i don't know what.
update:
==================
if i change the code this way , it works & the editcontrol displays in the dialog, (but don't see the initial text) i don't know exactly why though. - My current button & edit control Templates have an identical structure & this line is not needed for the title array in the button control, so it looks strange. also if i make the line; memalign edi, 2 it doesn't work
add edi, 22
memalign edi, 4 ; --- * Inserted this line * ---
invoke MultiByteToWideChar, CP_ACP, MB_PRECOMPOSED, addr editbox_title, -1,
edi, LENGTHOF editbox_title
add edi, LENGTHOF editbox_title*2
old code
----------------- add edi, 22
invoke MultiByteToWideChar, CP_ACP, MB_PRECOMPOSED, addr editbox_title, -1,
edi, LENGTHOF editbox_title
add edi, LENGTHOF editbox_title*2
Quote from: Rainstorm on November 04, 2008, 06:21:24 AM
also if i make the line; memalign edi, 2 it doesn't work
The alignment seems a key issue, because with unicode the edi+x means valid wide char for valid alignment, and invalid wide char for "bad" alignment. Have you tried passing a unicode string directly, i.e. with a lbl dd "a", 0 etc.?
jj, didn't fully get all that you said, but the title array is supposed to be word aligned according to the documentation. then again as hutch said in older versions the documentation was wrong in a number of places.
Another thing, Am using the same format in the button control for the title & there doesn't seem to be any problems there.(don't need to align the title array there) - the template is supposed to be the same for all control items. - follwing edi till the title array, shows that the start of the title array is already aligned on a word boundary. - so i don't actually need to align it
In what i described in the earlier post, the dialog now shows with the edit control but the text still doesn't show.
t y
-----
Quote from: Rainstorm on November 04, 2008, 09:47:39 AM
jj, didn't fully get all that you said, but the title array is supposed to be word aligned according to the documentation
mov WORD PTR [edi+20], 0081h ;; edit control
add edi, 22
; now here at edi+22 the OS expects a Unicode string
memalign edi, 4 ; --- * Inserted this line * ---
; and you gave it some nullwords - same as a zero delimiter, so no text!
I haven't seen your latest full code, but I would drop the memalign and instead play with
; one of these:
add edi, 22-1 ; this won't work ;-)
add edi, 22+0
add edi, 22+1
add edi, 22+2
etc. until a string is displayed. For testing, you can also replace the call to MultiByteToWideChar:
add edi, 22+0
ustring "My title"
Another additional road: Try playing with the
start of the edit sequence
; one of these:
dec edi
inc edi
add edi, 2
; then:
mov DWORD PTR [edi+0], WS_VISIBLE
the dialog displays at add edi, 24. the initial text is not displayed in the box though
add edi, 22+2
; memalign edi, 4
invoke MultiByteToWideChar, CP_ACP, MB_PRECOMPOSED, addr editbox_title, -1,
edi, LENGTHOF editbox_title
add edi, LENGTHOF editbox_title*2
Also the dialog still doesn't display if i add the WS_TABSTOP style to the editbox
mov dword ptr [edi+0] , ES_LEFT or ES_AUTOHSCROLL or WS_CHILD or WS_VISIBLE or WS_TABSTOP ; style
thx
Ok, try
invoke MultiByteToWideChar, CP_ACP, MB_PRECOMPOSED, addr editbox_title, -1,
edi, LENGTHOF editbox_title*2
doesn't make any diff
(tried it with edi at 22 & 24.. same results)
I didn't have time to test or examine the dump closely, but this version is supposed to dump a working template. Build as a console app so the print macro will work.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
_DlgEdit MACRO quoted_initial_text,dstyle,tx,ty,wd,ht,ctlID
align_4 edi
mov DWORD PTR [edi+0], WS_VISIBLE or WS_CHILD or dstyle
mov WORD PTR [edi+8], tx
mov WORD PTR [edi+10], ty
mov WORD PTR [edi+12], wd
mov WORD PTR [edi+14], ht
mov WORD PTR [edi+16], ctlID
mov WORD PTR [edi+18], 0FFFFh
mov WORD PTR [edi+20], 0081h ;; edit control
add edi, 22
ustring quoted_initial_text
align_2 edi
add edi, 2
ENDM
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
hInstance dd 0
buffer db 2000 dup(0)
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DlgProc proc hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
SWITCH uMsg
CASE WM_INITDIALOG
CASE WM_COMMAND
.IF wParam == IDCANCEL
invoke EndDialog, hDlg, 0
.ENDIF
CASE WM_CLOSE
invoke EndDialog, hDlg, 0
ENDSW
xor eax, eax
ret
DlgProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke GetModuleHandle, NULL
mov hInstance, eax
Dialog "Test", \
"MS Sans Serif",10, \
WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
2,0,0,100,75,1024
_DlgEdit "initial text",WS_BORDER,6,5,85,30,100
DlgButton "Close",0,34,45,30,10,IDCANCEL
mov ecx, edi
sub ecx, esi
invoke HexDump, esi, ecx, ADDR buffer
print ADDR buffer,13,10
CallModalDialog hInstance, 0, DlgProc, 12345
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
40 08 08 00 00 00 00 00 - 02 00 00 00 00 00 64 00
4B 00 00 00 00 00 54 00 - 65 00 73 00 74 00 00 00
0A 00 4D 00 53 00 20 00 - 53 00 61 00 6E 00 73 00
20 00 53 00 65 00 72 00 - 69 00 66 00 00 00 00 00
00 00 80 50 00 00 00 00 - 06 00 05 00 55 00 1E 00
64 00 FF FF 81 00 69 00 - 6E 00 69 00 74 00 69 00
61 00 6C 00 20 00 74 00 - 65 00 78 00 74 00 00 00
00 00 00 00 00 00 00 50 - 00 00 00 00 22 00 2D 00
1E 00 0A 00 02 00 FF FF - 80 00 43 00 6C 00 6F 00
73 00 65 00 00 00 00 00 -
Quote from: Rainstorm on November 04, 2008, 08:13:24 PM
doesn't make any diff
I checked the docu again, and you are right, it's cch
WideChar. No luck...
Does the call to MultiByteToWideChar succeed?
Could you post your current code?
.if uMsg == WM_COMMAND ; lParam = handle of control
movzx ecx, word ptr [wParam] ; low word of wParam - control identifier
; movzx ebx, word ptr [wParam+2] ; ebx?? high word of wParam - notification msg
.if ecx == IDCANCEL
invoke GetDlgItemText, hdlg, IDCANCEL, addr editcontrol_buff, 1000
jmp end_dialog
.endif
jmp false_
Gotcha!
(ebx is not the culprit, but not a good idea either)
EDIT: Code attached.
[attachment deleted by admin]
damnn!!!
missed that : |
appreciate all the testing & assistance everyone,
thx.
edit
--------
i took out the memalign edi, 2 line too since the WORD alignment as mentioned in the documentation there seems right,
jj wrote..
Quote(ebx is not the culprit, but not a good idea either)
just curious, why its not a good idea there
Quote from: Rainstorm on November 06, 2008, 11:01:49 AM
jj wrote..Quote(ebx is not the culprit, but not a good idea either)
why is it not a good idea there?
I am not sure, but I vaguely remember that using esi edi ebx in callback procedures may choke the OS... the question is then if DlgProc qualifies as a callback proc. Apart from these "legal" aspects, it seemed to work (although it does not anything useful - ebx does not appear a second time in your code).
was just trying stuff when i put it there, but I wasn't aware of the ebx thing, thanks.
also i changed the jmp false_ to jmp true_ since the app processed the msg.
jmp false_ might be better on second thoughts
just a few more more questions. I have'nt included a winmain there & though it seems to work proper, would it be safer to have a WinMain ?
another thing is i don't know why i can't get the msgbox after the 'call create_dialog' instruction,.. to display. think i'm miscalculating the flow somewhere. - I was thinking that after the below code the control would return back to after the 'call create_dialog' instruction in the beginning. ExitMsgLoop:
mov eax, msg.wParam
ret
[attachment deleted by admin]
there are 2 ret instructions in my code, one in theWndProc corresponds to returns to calls made by the system & the other one after mov eax, msg.wParam in the Messageloop which should return back to the next instruction after my call