Win32 API. Диалоговые окна - Создание шаблона в памяти

ОГЛАВЛЕНИЕ

Создание шаблона в памяти

Прикладные программы время от времени изменяют или модифицируют содержимое диалоговых окон, в зависимости от текущего состояния обрабатываемых данных. В подобных случаях не практично давать все возможные шаблоны диалогового окна как ресурсы в исполняемом файле прикладной программы. Однако создание шаблонов в памяти дает прикладной программе больше гибкости для адаптации к любым обстоятельствам.

В примере ниже прикладная программа создает шаблон в памяти для модального диалогового окна, которое содержит сообщение и кнопки ОК и Справка (Help).

В шаблоне блока диалога все символьные строки, такие как названия диалоговых окон и кнопок, должны быть строками Уникода. Этот пример использует функцию MultiByteToWideChar для создания этих строчек Уникода, поскольку и Windows NT и Windows 95 поддерживают MultiByteToWideChar.

Структуры DLGITEMTEMPLATE в шаблоне диалогового окна должны быть выровнены по границам ДВОЙНОГО СЛОВА (DWORD). Чтобы выровнять эти структуры, этот пример использует подпрограмму - помощника, которая получает введенный указатель, а возвращает самый близкий указатель, который выравнен по границе ДВОЙНОГО СЛОВА - DWORD (4 байта).

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