Re: Control в виде диалога

From
Konst Erman (2:5020/63.100)
To
All ()
Date
1998-04-27T19:58:52Z
Area
SU.WINDOWS.NT.PROG
Hello All!

Sunday April 26 1998, Konst Erman writes to All:

 KE>    Не делал ли кто-нибудь уже такую штуку, как ATL Control, пpедставляющий
 KE> собой по сути MFC Dialog? Т.е. что-то вpоде sub-диалога, котоpый можно
 KE> вставлять в большой host-диалог как ActiveX control.

   Короче, разобрался я с этой проблемой!
   Во-первых, я нашёл две статьи на MSDN, которые относятся к делу.
   Первая статья... та-ак, уже куда-то потерялась, но в ней рекламировался доступный с микрософта (Software Library) примерчик DlgX.EXE. Этот примерчик показывает как сделать ActiveX Control на основе dialog template на чистом MFC. Т.е. контрол наследуется от COleControl. Мне этот подход очень не понравился - куча какого-то громоздкого кода, зависимость от конкретной версии MFC (использование недокументированных свойств MFC), какие-то другие грязные трюки на 20 пунктов, и после всего этого дурацкие ограничения, вроде КомбоБоксы не работают и т.п.
   Вторая статья "HOWTO: Write a Dialog-based ActiveX Control Using ATL"
Article ID: Q175503. Здесь чистый ATL. Примера как такового нет, но кратенько расписано как делать. Уже лучше, но диалоги то, собственно, удобно было лепить MFC'шным Class Wizard'ом, а теперь его нет... Тоска...
   В общем, идея, которая с самого начала пришла мне в голову, что собственно контрол надо делать на ATL, а вот диалог на MFC, похоже, оказалась самой краткой по коду и удобной в поддержке и реализации.
   Хитрых моментов в моей реализации три:

   1. Создать диалог в качестве контрола

HWND CMyCtl::CreateControlWindow(HWND hWndParent, RECT& rcPos) {
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    VERIFY(m_dlg.Create(CMyDialog::IDD, CWnd::FromHandle(hWndParent)));
    m_hWnd = m_dlg.GetSafeHwnd();
    return m_dlg.GetSafeHwnd();
}

   2. Запретить активацию. Тем самым sub-диалог прикинется частью "большого" диалога, перестанет отбирать фокус у кнопок и мышь начнёт работать правильно.

HRESULT CMyCtl::InPlaceActivate(LONG iVerb, const RECT* prcPosRect) {
    if (OLEIVERB_UIACTIVATE == iVerb) {
        return S_OK;
    }
    return CComControl<CMyCtl>::InPlaceActivate(iVerb, prcPosRect);
}

   3. В Dialog editor назначить sub-диалогу стиль "Control". Это заставит нормально работать клавиатуру (TAB order, etc.)

   ... и всё!! Ни sub-dialog, ни host dialog не надо никак специально доделывать для работы в этом качестве. По-моему C00l получилось!

Best regards, Konst

...C:\NOWHERE\WINDOWS.NT

* Crossposted in SU.WINDOWS.NT.PROG
* Crossposted in SU.WIN95.PROG
* Crossposted in SU.WINDOWS.PROG

--- GoldED/W32 3.00.Beta3+
 * Origin:  ----> E-mail: Konst.Erman@relcom.ru <----  (2:5020/63.100)