News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

dialog code (won't display)

Started by Rainstorm, February 21, 2008, 02:49:37 PM

Previous topic - Next topic

Rainstorm

hi,

this dialog code assembles properly but i can't get it to display. - its a modal dialog box with a template in memory. - the return value from the DialogBoxIndirectParam function returns -1 which is supposed to mean it failed for some reason other than the parent window parameter being invalid.
the error code(from getLastError) is 1407 - which says 'Cannot find window class.' - I've put the value '30' in the EndDialog call which should be found in the retrn value to DialogBoxIndirectParam if it succeeds.

thankyou.

    DlgBox PROTO :DWORD, :DWORD, :DWORD, :DWORD

    .data?

        hInstance   dd      ?

    .data

        dlgboxtitle       db    "Dialog Foundary",0
        font_name         db    "fixedsys",0
        button_title      db    "OK",0
        dlgtemplatebuff   dd     200 dup(0)
        ret_val           dd     0
        error_code        dd     0       
; -----------------------------------------------

    .code

start:

        mov hInstance, FUNC(GetModuleHandle,NULL)

; ----------------------------------------------------
;          Fill in the dialog box template
; ----------------------------------------------------

    mov edi, offset dlgtemplatebuff

    align 4
    mov dword ptr [edi+0],   WS_POPUP or WS_SYSMENU or WS_CAPTION or DS_SETFONT
    mov dword ptr [edi+4],      0              ; extended styles
    mov  word ptr [edi+8],      1              ; control item-count
    mov  word ptr [edi+10],     400            ; x co-ordinate
    mov  word ptr [edi+12],     400            ; y co-ordinate
    mov  word ptr [edi+14],     500            ; width
    mov  word ptr [edi+16],     500            ; height
   

    mov  word ptr [edi+18],      0             ; Menu array   (0 = no menu)
    mov  word ptr [edi+20],      0             ; Class array  (0 = predefined dialogbox class)

; ···· *Title* - 22 bytes used till here ·····

    add edi,  22                               ; Title array start address

    invoke MultiByteToWideChar, CP_ACP, MB_PRECOMPOSED, addr dlgboxtitle, -1,
                                edi, LENGTHOF dlgboxtitle

    add edi, LENGTHOF dlgboxtitle*2


  ; ========= * Font * ============

    mov word ptr [edi],          9             ; point size value of the font
    add edi,  2
   
  ; -- [ Font name, conerted into a unicode string ] ---------

    invoke MultiByteToWideChar, CP_ACP, MB_PRECOMPOSED, addr font_name, -1,
                                edi, LENGTHOF font_name

    add edi, LENGTHOF font_name*2
   
  ; -----------------------------------------------------------
  ;         Fill in the dialog box items template
  ; -----------------------------------------------------------

       align 4
       mov dword ptr [edi+0] ,   BS_DEFPUSHBUTTON or WS_CHILD or WS_VISIBLE     ; style
       mov dword ptr [edi+4] ,   0           ;  extended style
       mov  word ptr [edi+8] ,   150         ;  x-coordinate
       mov  word ptr [edi+10],   150         ;  y-coordinate
       mov  word ptr [edi+12],   300         ;  width , in dialog box units, of the control
       mov  word ptr [edi+14],   300         ;  height, in dialog box units, of the control
       mov  word ptr [edi+16],   IDCANCEL    ;  control identifier

       mov word ptr [edi+18], 65535        ; indicates that array has 1 additional element
       mov word ptr [edi+20], 128          ; signifies a 'buttonclass' for the control

; ===-- Title array -----=============

       add edi, 22

       invoke MultiByteToWideChar, CP_ACP, MB_PRECOMPOSED, addr button_title, -1,
                                   edi, LENGTHOF button_title

       add edi, LENGTHOF button_title*2

       mov word ptr [edi],  0                ;  creation data
       add edi           ,  2

;===================================================

    invoke DialogBoxIndirectParam, hInstance, addr dlgtemplatebuff, 0,  DlgBox, 0
    mov ret_val, eax
    fn MessageBox, NULL,sstr$(ret_val),"Return Value",MB_OK

    invoke GetLastError
    mov error_code, eax
    fn MessageBox, NULL,ustr$(error_code),"Error Code",MB_OK

; ==============================================

    DlgBox proc hWndDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD


           .if uMsg == WM_COMMAND
               movzx ebx, word ptr [wParam]          ; low word of wParam - control identifier
               .if ebx == IDCANCEL
                   jmp end_dialog
               .endif


           .elseif uMsg == WM_INITDIALOG
               jmp true_

           .else
               jmp false_                           ; default processing
                               
           .endif   

        end_dialog:
           invoke EndDialog, hWndDlg, 30
           


        true_:
        mov eax, 1                              ;  return true
        jmp ret_
   
        false_:
        xor eax, eax                            ; return false
   
    ret_:   
    ret
     
    DlgBox endp

; ---------------------------------------------

end start

MichaelW

Although this is currently not the problem, your code is not aligning the template buffer. If your initialized data items were in descending order by type size (e.g. dq before dd before db), then it would be properly aligned.

        dlgtemplatebuff   dd     200 dup(0)
        ret_val           dd     0
        error_code        dd     0
        dlgboxtitle       db    "Dialog Foundary",0
        font_name         db    "fixedsys",0
        button_title      db    "OK",0


If I set the cdit member of the DLGTEMPLATE structure to 0 then the dialog opened, so this narrowed the problem down to the code that is initializing the DLGITEMTEMPLATE structure. I eventually was able to solve the problem by using the MASM32 memalign macro to align EDI on a DWORD boundary (memalign edi, 4) at the start of the code that is initializing the DLGITEMTEMPLATE structure. As the documentation specifies, the DLGTEMPLATE and DLGITEMTEMPLATE structures must be aligned on a DWORD boundary.

Also, on my system running 1024x768 with large fonts, the dialog is larger than my desktop. Are you aware that coordinates and width and height values in a dialog box are specified in dialog template units instead of pixels? Dialog template units are based on the average width and height of the font used, allowing the dialog box to have essentially the same on-screen proportions and appearance (but not the same apparent size) across different resolutions and/or aspect ratios. For reference, a horizontal dialog template unit is 1/4 the average width of the font, in pixels, and a vertical dialog template unit is 1/8 the average height of the font, in pixels.
eschew obfuscation

Rainstorm

michael wrote..
QuoteAlso, on my system running 1024x768 with large fonts, the dialog is larger than my desktop.
Laughing out loud! : ))
I've yet to get the hang of that. I knew they were in dialog units, but have no idea what they translated to practically.

QuoteI eventually was able to solve the problem by using the MASM32 memalign macro to align EDI on a DWORD boundary (memalign edi, 4) at the start of the code that is initializing the DLGITEMTEMPLATE structure.
I added the  memalign edi, 4   line & it displayed properly after that. - I adjusted the variables in the .Data section & the dialog box units. - yes the beginning of the code in the structures needs to be aligned on DWORD boundaries like you said.
- I don't understand though. In my code I had the 'align 4' line just before the start of the code in the DLGITEMTEMPLATE structure, doesn't that do it ?

       align 4
       mov dword ptr [edi+0] ,   BS_DEFPUSHBUTTON or WS_CHILD or WS_VISIBLE     ; style


appreciate all the help!

Rainstorm
-

MichaelW

QuoteI don't understand though. In my code I had the 'align 4' line just before the start of the code in the DLGITEMTEMPLATE structure, doesn't that do it ?

It's not the code that you need to align it's the data. The memalign macro adjusts the value in EDI so it points to the next DWORD-aligned address in the buffer, and the DLGITEMTEMPLATE structure starts there. The memalign macro uses different instructions than the align_4 macro in dialogs.inc, but the end result is the same.
eschew obfuscation