Platform SDK: Windows User Interface |
Applications sometimes adapt or modify the content of dialog boxes depending on the current state of the data being processed. In such cases, it is not practical to provide all possible dialog box templates as resources in the application's executable file. But creating templates in memory gives the application more flexibility to adapt to any circumstances.
In the following example, the application creates a template in memory for a modal dialog box that contains a message and OK and Help buttons.
In a dialog template, all character strings, such as the dialog box and button titles, must be Unicode strings. This example uses the MultiByteToWideChar function to generate these Unicode strings, because Windows 95/98 and Windows NT/Windows 2000 support MultiByteToWideChar
The DLGITEMTEMPLATE structures in a dialog template must be aligned on DWORD boundaries. To align these structures, this example uses a helper routine that takes an input pointer and returns the closest pointer that is aligned on a DWORD boundary.
#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; }