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

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

В примере ниже, прикладная программа создает шаблон в памяти для модального диалогового окна, которое содержит сообщение и кнопки 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; 
}

 

Назад в оглавление
На главную страницу

Hosted by uCoz