News:

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

question on some example code in masm32

Started by Rainstorm, February 18, 2008, 04:33:37 PM

Previous topic - Next topic

Rainstorm

hi,

in the following code i can't figure out why align 2 is used in the end since all the prior stuff seems to be word aligned after the first 2 DWORD elements, & the character strings are unicode so they are word aligned too. ( the macro is in H:\masm32\include\dialogs.inc )

Thanks!

    ; ------------
    ; push button
    ; ------------
      DlgButton MACRO quoted_caption,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  ;; class array
        mov WORD  PTR [edi+20], 0080h   ;; button
        add edi, 22
        ustring quoted_caption
        align_2 edi
        add edi, 2
      ENDM



Rainstorm

In the topic 'about dialog boxes' in the SDK for creation data, it says...
QuoteIn addition, any creation data that follows a control definition must be aligned on a DWORD boundary. All of the other variable-length arrays in a dialog box template must be aligned on WORD boundaries.

on the DLGITEMTEMPLATE page it says
QuoteThe creation data array must be aligned on a WORD boundary.

doesn't the stuff mentioned about the 'creation data' contradict each other on those 2 pages, or am i getting something wrong .

thanks.

MichaelW

QuoteIn addition, any creation data that follows a control definition must be aligned on a DWORD boundary. All of the other variable-length arrays in a dialog box template must be aligned on WORD boundaries.
As far as I know the "aligned on a DWORD boundary" part is incorrect, and if you look at the documentation for the DLGITEMTEMPLATE structure you should see:
Quote
Each DLGITEMTEMPLATE structure in the template must be aligned on a DWORD boundary. The class and title arrays must be aligned on WORD boundaries. The creation data array must be aligned on a WORD boundary.
And in any case, the In-Memory Dialog macros do not support control creation data. The trailing:

add edi, 2

Skips over the first element of the creation data array, leaving it set to zero (no creation data).

I developed a system of procedures for FreeBASIC that is based on the MASM32 macros. Here are the relevant parts of the documentation:
Quote
The dialog box template consists of a DLGTEMPLATE structure followed by three or four variable-length arrays, followed by zero or more DLGITEMTEMPLATE structures each followed by three variable-length arrays. The DLGTEMPLATE structure and the associated arrays define the dialog window. The DLGITEMTEMPLATE structures and the associated arrays define the controls in the dialog.

The variable-length arrays consist of WORD (16-bit) elements. The first three arrays following the DLGTEMPLATE structure specify the menu, class, and title for the dialog. The three arrays following each DLGITEMTEMPLATE structure specify the class, title, and creation data for the control. Each of these arrays will have at least one element, and the system will interpret the contents of the array based on the value of the first element. For the dialog menu, class, and title arrays, and the control creation data array, if the first element is zero then the array is effectively empty. For the dialog menu and class arrays, and the control class and title arrays, if the first element is FFFFh then the second element contains the ordinal value of a resource or a predefined class and the array contains no other elements. For the dialog menu, class, and title arrays, and the control class and title arrays, if the first element is any value other than zero or FFFFh then the array is assumed to be a null-terminated Unicode string. Depending on the array, this Unicode string can specify the name of a menu resource, a registered class, the dialog title, or the initial text for a control. For the control creation data array, if the first element is non-zero then it contains the length, in bytes, of the creation data that follows. The fourth array following the DLGTEMPLATE structure, which is present only when the dialog style includes DS_SETFONT, specifies the font point size value in the first element, followed by the name of the typeface as a null-terminated Unicode string.

For the align_2 edi, as far as I know it's not necessary, but there is a common saying in the USA that I think is applicable, "If it ain't broke, don't fix it." The in-memory dialog macros work reliably, and with all of the API code involved, the extra instructions make no significant difference in the time it takes to open the dialog.
eschew obfuscation

Rainstorm

Michael,
I had been reading from the Win SDK that I have on disk & writing the code as i went along, I was looking at the macros when i found them cause they dealt with the same topic.. & asked about the align_2 since i couldn't figure out how it was being used there.

Michael, concerning the alignment of the creation data the documentation on the web says the same stuff too & seems to contradict each other on the 2 pages.......here are the links...

http://msdn2.microsoft.com/en-us/library/ms644994(VS.85).aspx

that one says the creation data must be DWORD (its right down just before the template header topic)

http://msdn2.microsoft.com/en-us/library/ms644997(VS.85).aspx
this one says.. the creation data should be on a word boundary

========

just a related question....... when creating the templates in memory how do i calculate the amount of memory to allocate before creating the template ? - just manually count the amount of bytes in strings etc that i will need or is there some other way ?

many thanks,
Rainstorm.
-

hutch--

Rainstorm,

I wrote these back in the win98 days where one mistake would give you a black screen of death with a reset button reboot. The technical reference data is not entirely correct and I had to experiment to get them reliable but basically the dialog engine in Windows which the in memory template method uses is fault intolerant so you must align them exactly or they go BANG.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Rainstorm

hutch,
        many thanks for clearing that up.

MichaelW

Quote from: Rainstorm on February 19, 2008, 07:03:06 AM
concerning the alignment of the creation data the documentation on the web says the same stuff too & seems to contradict each other on the 2 pages...

The Microsoft documentation does contain contradictions, but as I stated the macros do not support control creation data, and I have never encountered a problem with the first word of the creation data array (set to zero in the macros) being aligned on a WORD boundary. To determine what the alignment of the creation data actually needs to be you could create a "custom" control that uses creation data, and a macro to create a template for the control, and then experiment with it.

Quote
when creating the templates in memory how do i calculate the amount of memory to allocate before creating the template ? - just manually count the amount of bytes in strings etc that i will need or is there some other way ?

I know of no easy way to calculate the amount of memory to allocate before creating the template, but you can easily determine the size of the template after it is created. The Dialog macro stores the base address of the template memory in ESI and EDI, and then EDI is used to track the current address in the template, so the size of the template can be calculated at any point in the creation of the template as EDI - ESI. So you could start out by specifying a memory buffer size much larger than necessary, and then create the template to get the required size. For example:

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      hInst dd  0
      state dd  100 dup(0)
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DlgProc proc uses ebx hDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

    LOCAL rc:RECT

    Switch uMsg

      Case WM_COMMAND

        mov ebx, wParam

        .IF ebx == IDCANCEL
          invoke EndDialog, hDlg, NULL
        .ELSEIF state[ebx*4-400]
          invoke SetDlgItemText, hDlg, ebx, 0
          mov state[ebx*4-400], 0
        .ELSE
          invoke SetDlgItemText, hDlg, ebx, chr$("X")
          mov state[ebx*4-400], 1
        .ENDIF

      Case WM_CLOSE

        invoke EndDialog, hDlg, NULL

    EndSw

    return 0

DlgProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke GetModuleHandle, NULL
    mov hInst, eax

    Dialog  "Test", \                         ; caption
            "FixedSys", 12, \                 ; font,pointsize
            WS_OVERLAPPED or WS_SYSMENU or \  ; window style
            WS_MINIMIZEBOX or DS_CENTER, \
            100, \                            ; number of controls
            0,0,122,132, \                    ; x, y, width, height
            10000                             ; memory buffer size

    ; -----------------------------------------------------------
    mov eax, edi
    sub eax, esi
    invoke MessageBox, 0, ustr$(eax), chr$("SIZEOF Template "), 0
    ; -----------------------------------------------------------

    CID = 100
    COL = 10
    WHILE COL LE 100
      ROW = 10
      WHILE ROW LE 100
        DlgButton 0, WS_TABSTOP, ROW, COL, 9, 9, CID
        CID = CID + 1
        ROW = ROW + 10
      ENDM
      COL = COL + 10
    ENDM

    ; -----------------------------------------------------------
    mov eax, edi
    sub eax, esi
    invoke MessageBox, 0, ustr$(eax), chr$("SIZEOF Template "), 0
    ; -----------------------------------------------------------

    CallModalDialog hInst, 0, DlgProc, NULL

    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
eschew obfuscation

Rainstorm

michael wrote
QuoteThe Microsoft documentation does contain contradictions...,
thanks for clearing that up

QuoteEDI is used to track the current address in the template, so the size of the template can be calculated at any point in the creation of the template as EDI
:U

[edit] Michael, just one question.. why did you put the dlgproc before the start label ?

ty
Rainstorm

MichaelW

Quotewhy did you put the dlgproc before the start label

Because to avoid an undefined symbol error DlgProc must be defined before it is referenced in the CallModalDialog macro call. It's easier to accomplish this by defining DlgProc above the reference to it, than it is to define it after the reference and add a prototype above the reference. Prototypes make sense when they are in an include file, but for something like this they are an unnecessary complication.
eschew obfuscation