Mosaic: The finishing touch

The program is finished now, we will just add a little about box to the program.

14.1 - Dialog resource

A dialog is a predefined window with controls etc. defined in the resource file. Dialogs also need a window procedure, but no message pump. You simply call DialogBoxParam and the dialog will be created. First define the dialog resource:

In mosaic.rc:

#define     ID_ABOUTDIALOG      700

ID_ABOUTDIALOG DIALOG DISCARDABLE  0, 0, 164, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Mosaic..."
FONT 8, "MS Sans Serif"
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,57,74,50,14
    ICON            ICON1_BIG,201,7,7,21,20
    LTEXT           "Mosaic 1.0\n\nExample of the Mosaic lesson in the Win32Asm Tutorials.
                    \n\n(C) 2001 by Exagone (Thomas Bleeker)\nhttp://exagone.cjb.net",
                    202,34,7,123,61
END

In mosaic.inc:

ID_ABOUTDIALOG      equ     700

The dialog has ID_ABOUTDIALOG (700) as ID. The dialog contains a default pushbutton, OK, an icon with ICON1_BIG as caption. This will show the big program icon in a static control on the dialog. The LTEXT control is just a left aligned text control. The \n codes are linefeeds.

14.2 - Handler

The dialog has to be shown when the user clicks help, about, or the information button. On both events, the DialogBoxParam is called. iut uses the application instance (hInstance), the ID of the dialog (ID_ABOUTDIALOG), the parent window (hWnd) and a pointer to the dialog procedure (offset DlgProc) to make the dialog. Because the dialog is a modal dialog (DS_MODALFRAME), this function does not return until the dialog is closed.

Add to the handlers in ProcessMenuItem:

;-------------------------------------------------------------------------------
; About
;-------------------------------------------------------------------------------
.ELSEIF ax==MI_ABOUT
    invoke  DialogBoxParam, hInstance, ID_ABOUTDIALOG, hWnd, offset DlgProc, NULL

14.3 - Dialog procedure

This is the dialog procedure:

DlgProc     PROTO   STDCALL :DWORD, :DWORD, :DWORD, :DWORD
;================================================================================
;                           About dlgproc
;================================================================================
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam: LPARAM
mov eax, uMsg
    .IF eax==WM_COMMAND
        mov     eax, wParam
        shr     eax, 16
        .IF     ax==BN_CLICKED
            invoke  EndDialog, hWnd, NULL
        .ENDIF
    .ELSEIF eax==WM_DESTROY
        invoke  EndDialog, hWnd, NULL
    .ELSEIF eax==WM_CLOSE
        invoke  EndDialog, hWnd, NULL
    .ENDIF
xor eax,eax
ret
DlgProc endp

Unlike normal windows, dialog procedures don't use DefWindowProc to pass messages it doesn't handle. The default return value is 0. (xor eax, eax). Don't forget this line because without it the dialog might not show up. On WM_DESTROY and WM_CLOSE the dialog is closed with EndDialog. If a BN_CLICKED notification message is sent with WM_COMMAND, the user has clicked the OK button and the dialog is closed too.

14.4 - Done

The dialog looks like this:

About dialog

(final code on the next chapter)