Приложения иногда приспосабливают или изменяют содержимое диалоговых окон в зависимости от текущего состояния обрабатываемых данных. В таких случаях, не целесообразно предусматривать все возможные шаблоны блока диалога как ресурсы в исполняемом файле прикладной программы. А вот, шаблоны созданные в памяти дают приложению больше гибкости, чтобы приспособиться к любым обстоятельствам.
В примере ниже, прикладная программа создает шаблон в памяти для модального диалогового окна, которое содержит сообщение и кнопки OK и Справка (Help).
В шаблоне диалогового окна, все строки символов, такие как заголовки блока диалога и кнопки, должны быть символьными строками Unicode. Этот пример использует функцию MultiByteToWideChar, чтобы создать эти символьные строки Unicode.
Структуры DLGITEMTEMPLATE в шаблоне диалогового окна должны быть выровнены по границам двойного слова (DWORD). Чтобы выровнять эти структуры, в этом примере используется вспомогательная процедура, которая перехватывает указатель ввода и возвращает самый ближайший указатель, который выравнивается по границе двойного слова (DWORD).
Пример
#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); // Определяем окно диалога. lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION; lpdt->cdit = 3; // число органов управления lpdt->x = 10; lpdt->y = 10; lpdt->cx = 100; lpdt->cy = 100; lpw = (LPWORD) (lpdt + 1); *lpw++ = 0; // меню нет *lpw++ = 0; // предопределенный класс окна диалога // (по умолчанию) lpwsz = (LPWSTR) lpw; nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "My Dialog", -1, lpwsz, 50); lpw += nchar; //----------------------- // Определяем кнопку OK. //----------------------- lpw = lpwAlign (lpw); // выравниваем DLGITEMTEMPLATE // по границе DWORD lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->x = 10; lpdit->y = 70; lpdit->cx = 80; lpdit->cy = 20; lpdit->id = IDOK; // идентификатор кнопки OK lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; lpw = (LPWORD) (lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0080; // класс кнопки lpwsz = (LPWSTR) lpw; nchar = 1+MultiByteToWideChar (CP_ACP, 0, "OK", -1, lpwsz, 50); lpw += nchar; lpw = lpwAlign (lpw); // выравниваем данные создания // по границам DWORD *lpw++ = 0; // данных создания нет //----------------------- // Определяем кнопку Help. //----------------------- lpw = lpwAlign (lpw); // выравниваем DLGITEMTEMPLATE // по границе DWORD lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->x = 55; lpdit->y = 10; lpdit->cx = 40; lpdit->cy = 20; lpdit->id = ID_HELP; // идентификатор кнопки Help lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON; lpw = (LPWORD) (lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0080; // атом класса кнопки lpwsz = (LPWSTR) lpw; nchar = 1+MultiByteToWideChar (CP_ACP, 0, "Help", -1, lpwsz, 50); lpw += nchar; lpw = lpwAlign (lpw); // выравниваем данные создания // по границам DWORD *lpw++ = 0; // данных создания нет //------------------------------------------------- // Определяем орган управления статического текста. //------------------------------------------------- lpw = lpwAlign (lpw); // выравниваем DLGITEMTEMPLATE // по границе DWORD lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->x = 10; lpdit->y = 10; lpdit->cx = 40; lpdit->cy = 20; lpdit->id = ID_TEXT; // идентификатор текста lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT; lpw = (LPWORD) (lpdit + 1); *lpw++ = 0xFFFF; *lpw++ = 0x0082; // класс статического органа // управления for (lpwsz = (LPWSTR)lpw; *lpwsz++ = (WCHAR) *lpszMessage++; ); lpw = (LPWORD)lpwsz; lpw = lpwAlign (lpw); // выравниваем данные создания // по границам DWORD *lpw++ = 0; // данных создания нет GlobalUnlock(hgbl); ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE) hgbl, hwndOwner, (DLGPROC) DialogProc); GlobalFree(hgbl); return ret; } |