Een sjabloon maken in het geheugen

Toepassingen soms aanpassen of wijzigen van de inhoud van dialoogvensters afhankelijk van de huidige status van de gegevens die worden verwerkt. In dergelijke gevallen is het niet praktisch om alle mogelijke dialoogvenster vak sjablonen als middelen in het uitvoerbare bestand van de toepassing. Maar de toepassing meer flexibiliteit aan te passen aan elke omstandigheden creŽren van templates in geheugen geeft.

In het volgende voorbeeld wordt de toepassing maakt u een sjabloon in het geheugen voor een modaal dialoogvenster met een bericht en de knoppen OK en Help.

In een dialoogvenster sjabloon worden alle tekenreeksen, zoals het dialoogvenster vak en knop titels, Unicode-tekenreeksen. In dit voorbeeld wordt de MultiByteToWideChar functie voor het genereren van deze Unicode-tekenreeksen, omdat zowel Windows als Windows NT MultiByteToWideChar ondersteunt

De DLGITEMTEMPLATE structuren in een dialoogvenster sjabloon moeten worden uitgelijnd op DWORD grenzen. In dit voorbeeld wordt uitlijnen van deze structuren, een helper routine, dat neemt een input pointer en geeft als resultaat de dichtstbijzijnde aanwijzer die is uitgelijnd op de grens van een DWORD (4 byte).

#define ID_HELP   150
#define ID_TEXT   200

LPWORD lpwAlign ( LPWORD lpIn)
{
    ULONG ul;

    ul = (ULONG) lpIn;
    ul +=3;
    ul >>=2;
    ul <<=2;
    return (LPWORD) ul;
}

LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner, 
    LPSTR lpszMessage)
{
    HGLOBAL hgbl;
    LPDLGTEMPLATE lpdt;
    LPDLGITEMTEMPLATE lpdit;
    LPWORD lpw;
    LPWSTR lpwsz;
    LRESULT ret;
    int nchar;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
    if (!hgbl)
        return -1;
 
    lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);
 
    // Define a dialog box.
 
    lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU
                   | DS_MODALFRAME | WS_CAPTION;
    lpdt->cdit = 3;  // number of controls
    lpdt->x  = 10;  lpdt->y  = 10;
    lpdt->cx = 100; lpdt->cy = 100;

    lpw = (LPWORD) (lpdt + 1);
    *lpw++ = 0;   // no menu
    *lpw++ = 0;   // predefined dialog box class (by default)

    lpwsz = (LPWSTR) lpw;
    nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "My Dialog", 
                                    -1, lpwsz, 50);
    lpw   += nchar;

    //-----------------------
    // Define an OK button.
    //-----------------------
    lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x  = 10; lpdit->y  = 70;
    lpdit->cx = 80; lpdit->cy = 20;
    lpdit->id = IDOK;  // OK button identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;

    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;    // button class

    lpwsz = (LPWSTR) lpw;
    nchar = 1+MultiByteToWideChar (CP_ACP, 0, "OK", -1, lpwsz, 50);
    lpw   += nchar;
    lpw = lpwAlign (lpw); // align creation data on DWORD boundary
    *lpw++ = 0;           // no creation data

    //-----------------------
    // Define a Help button.
    //-----------------------
    lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x  = 55; lpdit->y  = 10;
    lpdit->cx = 40; lpdit->cy = 20;
    lpdit->id = ID_HELP;    // Help button identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;

    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;                 // button class atom

    lpwsz = (LPWSTR) lpw;
    nchar = 1+MultiByteToWideChar (CP_ACP, 0, "Help", -1, lpwsz, 50);
    lpw   += nchar;
    lpw = lpwAlign (lpw); // align creation data on DWORD boundary
    *lpw++ = 0;           // no creation data

    //-----------------------
    // Define a static text control.
    //-----------------------
    lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x  = 10; lpdit->y  = 10;
    lpdit->cx = 40; lpdit->cy = 20;
    lpdit->id = ID_TEXT;  // text identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;

    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0082;                         // static class

    for (lpwsz = (LPWSTR)lpw;    
        *lpwsz++ = (WCHAR) *lpszMessage++;
    );
    lpw = (LPWORD)lpwsz;
    lpw = lpwAlign (lpw); // align creation data on DWORD boundary
    *lpw++ = 0;           // no creation data

    GlobalUnlock(hgbl); 
    ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE) hgbl, 
        hwndOwner, (DLGPROC) DialogProc); 
    GlobalFree(hgbl); 
    return ret; 
}