Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > RichEdit: определить имя класса


Автор: Alca 28.4.2009, 14:07
RichEdit: определить имя класса.
Цитата

Creating a Template in Memory

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.

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 ++;
    ul >>=1;
    ul <<=1;
    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; 
}


Есть такая строка:
Код

    *lpw++ = 0x0082;        // Static class

надо определить класс для RichEdit:
Код

    *lpw++ = ?x????;        // RichEdit class

Автор: GremlinProg 28.4.2009, 14:54
это не стандартный класс, его можно создать пожалуй только через Custom Control, смотри в эту сторону

кстати, есть причина, по которой диалог нельзя поместить в ресурс, или я не понял задачу?

Автор: Alca 28.4.2009, 15:00
Цитата

кстати, есть причина, по которой диалог нельзя поместить в ресурс, или я не понял задачу?

Есть
Цитата

его можно создать пожалуй только через Custom Control

Это как? Мне на чистом АПИ надо, без использования ресурсов.

Автор: GremlinProg 28.4.2009, 15:05
Цитата(Alca @  28.4.2009,  17:00 Найти цитируемый пост)
Есть

какая? ты ведь делаешь двойную работу
Цитата(Alca @  28.4.2009,  17:00 Найти цитируемый пост)
Это как? Мне на чистом АПИ надо, без использования ресурсов.

Цитата(DLGITEMTEMPLATE @ MSDN)

Immediately following each DLGITEMTEMPLATE structure is a class array that Specifies the window class of the control. If the first element of this array is any value other than 0xFFFF, the system treats the array as a null-terminated Unicode string that specifies the name of a registered window class. If the first element is 0xFFFF, the array has one additional element that specifies the ordinal value of a predefined system class. The ordinal can be one of the following atom values.


Добавлено через 43 секунды
Цитата(DLGITEMTEMPLATE @ MSDN)
If the first element of this array is any value other than 0xFFFF, the system treats the array as a null-terminated Unicode string that specifies the name of a registered window class


Автор: Alca 28.4.2009, 15:30
Цитата

какая? 

Нужен мсжбокс с ртф-ом. 
И чтобы подключять можно было тока хедер (с моей функцией MyRtfMsgBox(...)) 
и не делать лишних движений с ресурсами.
Цитата

ты ведь делаешь двойную работу

Я знаю, а то и тройную.

Автор: GremlinProg 28.4.2009, 15:43
тогда практичнее будет этот ресурс сгенерировать отдельно, res-компилятором, а получившийся бинарник преобразовать в строковый массив, железно:
Код

BYTE rtf_msg_box[] = {0x01,0x02,0x03,...};
::GlobalAlloc(...)
lp_msg_box = GlobalLock(...);
::memmove(lp_msg_box,rtf_msg_box,sizeof(rtf_msg_box));
::GlobalUnlock(...);
::DialogBoxIndirectParam(...)
...

в коде останутся только накладные расходы на работу с глобальной памятью

Автор: Alca 28.4.2009, 15:50
Извратился следующим образом:
DialogBoxIndirect -> DialogBoxIndirectProc -> WM_INITDIALOG -> ::CreateWindowEx(0x00000000, "RICHEDIT", ...)

Добавлено @ 15:52
Цитата

это не стандартный класс

Что значит не стандартный? RICHEDIT_CLASS???

Добавлено @ 15:53
Может где-то прописан дефайн на эту константу? Кто знает?
Код

*lpw++ = 0x0082;        // Static class

Код

#define ???? 0x0082 

Автор: GremlinProg 28.4.2009, 16:00
Цитата(Alca @  28.4.2009,  17:50 Найти цитируемый пост)
Что значит не стандартный? RICHEDIT_CLASS???

он не закреплен за конкретной библиотекой в API, нет для него единого имени: разные версии - под разными именами, и в разных DLL
он не включен в пакет Common Controls, т.е. нужно подключать его библиотеку либо динамически, либо статически, но в любом случае - руками
Цитата(Alca @  28.4.2009,  17:50 Найти цитируемый пост)
Извратился следующим образом:

этот способ в любом случае надежнее, чем в ресурсе: зашьешь в ресурс какую-нибудь 4-5 версию, а её не окажется в наличии, в итоге - компонент не будет создан, отсюда и все побочные следствия

Автор: Alca 28.4.2009, 16:04
Цитата

т.е. нужно подключать его библиотеку либо динамически

Я так делаю:
Код

HMODULE hmRichEdtDll = ::LoadLibrary("RICHED32.DLL");  
//..
::FreeLibrary(hmRichEdtDll);

Автор: GremlinProg 28.4.2009, 16:10
ну да, верно,
это первая версия, на сколько помню

Автор: Alca 28.4.2009, 16:19
А где можно глянуть константу 0x0082, где она определена?

Автор: Alca 28.4.2009, 16:36
http://msdn.microsoft.com/en-us/library/ms644997(VS.85).aspx
Цитата

Value    Meaning
0x0080    Button
0x0081    Edit
0x0082    Static
0x0083    List box
0x0084    Scroll bar
0x0085    Combo box

Автор: GremlinProg 28.4.2009, 16:39
этих объявлений нет в заголовочных файлах, только в MSDN:
Цитата

Value Meaning 
0x0080 Button 
0x0081 Edit 
0x0082 Static 
0x0083 List box 
0x0084 Scroll bar 
0x0085 Combo box 

в заголовки не попадает ничего, что имеет непостоянный размер,
объявления, их сопровождаемые, видимо тоже

а здесь спецификация ресурса диалога, который как раз постоянный размер иметь не может

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)