Crearea unui șablon în memorie

Cererile uneori se adapteze sau să modifice con?inutul de casete de dialog în funcție de starea actuală a datelor prelucrate. În astfel de cazuri, nu este practic să ofere toate șabloanele de caseta de dialog posibil ca resurse în fișier executabil aplicației. Dar crearea șabloane în memorie oferă aplicarea mai multă flexibilitate pentru a adapta circumstan?ele.

În exemplul următor, aplicarea creează un șablon în memorie pentru o casetă de dialog modale care conține un mesaj și butoanele OK și ajutor.

Într-un șablon de dialog, toate șiruri de caractere, cum ar fi titlurile caseta și butonul dialog, trebuie să fie siruri de caractere Unicode. Acest exemplu utilizează MultiByteToWideChar funcție pentru a genera aceste siruri de caractere Unicode, deoarece Windows și Windows NT acceptă MultiByteToWideChar

Structuri de DLGITEMTEMPLATE într-un șablon de dialog trebuie aliniat la limitele DWORD . Pentru a alinia aceste structuri, acest exemplu utilizează o rutina de ajutor care ia un indicator intrare și returnează indicatorul cel mai apropiat, care este aliniat pe marginea un DWORD (4 octet).

#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; 
}