Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Создание ComboBox и парент...


Автор: Darked 2.11.2005, 16:33
Вообщем нужно создать комбобокс в тулбаре, и, естественно, потом хотелось бы полчать от него сообщения. Пишу в WTL. Создаю в CMainFrame переменную CComboBox m_Combo. Дальше завист от реализации, если создаю так:
Код

       m_Combo.Create(m_hWndStatusBar, CRect(0, 0, 50, 10), NULL,  WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST, NULL, ID_COMBOBOX, NULL);

то в CMAinFrame сообщения не ловятся.
Код

BEGIN_MSG_MAP(CMainFrame)
        . . .
        COMMAND_HANDLER(ID_COMBOBOX, CBN_SELCHANGE, OnSelChange)
            . . .
        CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
        CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
    END_MSG_MAP()


Если же создаю так:
Код

        m_Combo.Create(m_hWnd, CRect(0, 0, 50, 10), NULL,  WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST, NULL,ID_COMBOBOX, NULL);

    m_Combo.SetParent(m_hWndStatusBar);
        . . .


То сообщения от комбобокса ловяться в CMainFrame. Не понимаю в чем именно различие? Догадываюсь что происходят изменения в маршрутизации сообщений, но как и почему?

Автор: Coocky 2.11.2005, 17:55
Могу только догадаться
что ты в методе create не указываешь родителя.
А если класс не может обработать сообщение, то он передает его родителю, и так далее.

Автор: Darked 2.11.2005, 19:35
Coocky, да нет, первый параметр это hwnd родителя, я его ставлю m_hWndStatusBar. Комбобокс появляется, строки отображаются, но вот сообщения от него не ловятся в базовом классе CMainFrame. Если же я ставлю парентом m_hWnd (хендл CmainFrame), а потом через SetParent устанавливаю родителем статусбар (m_hWndStatusBar), то сообщения начинают ловится в CMainFrame.

Автор: Earnest 2.11.2005, 19:58
А чего бы MainFrame ловил уведомления неизвесно от кого?

Фокус тут в разнице между двумя понятиями - PARENT и OWNER. Парент - это окно, в котором расположен контрол, а OWNER - окно, которому посылаются уведомления. По-умолчанию (после создания) они совпадают.

Если m_hWndStatusBar - это твой тулбар, то ему и посылаются сообщения, когда ты создаешь комбобокс первым способом. Можешь их там ловить и пересылать главному окну (автоматически это, конечно, не происходит).

Когда ты создаешь комбобокс вторым способом, ты меняешь ему парента, а OWNER'ом остается главное окно, как при создании. Вот оно и получает уведомления.

Автор: Darked 2.11.2005, 22:09
Earnest, то есть я правильно понимаю - во всех функциях create указывается именно owner, и это же значение заодно назначается паренту, который потом можно изменить?

Автор: Earnest 3.11.2005, 18:26
Темное это дело, Darked, если честно. Для child-окон, ИМХО, указывается именно parent, он же owner. А для pop-up окон - owner.

Нигде не встречала, чтобы это дело было подробно изложено.
Остается экспериментировать и пользоваться Спаем в сомнительных случаях - он тебе все расскажет, про парентов и owner'ов.

В MSDN недавно прочитала, что MFC имеет свою концепцию owner'ов, отличную от концепции "Owned windows" API. У WTL, которой ты пользуешься, тоже может быть своя точка зрения.


Автор: Darked 5.11.2005, 19:01
Earnest, спасибо за объяснение.

Автор: GremlinProg 6.11.2005, 09:14
неправильно!!!
Овнер есть только тогда, когда стиль WS_POPUP указан, в остальных случаях - это парент, не надо путать. А чтобы ещё и винду не путать, вместо GetParent вызывай GetAncestor

Автор: Earnest 8.11.2005, 17:16
Да, так про owner'ов в MSDN написано. Однако, owner'ы бывают и у child окон - достаточно Спаем посмотреть, на те же тулбары. Кроме того, как я уже писала, у MFC есть свое представление об owner'ах - они могут быть у любого окна ...

Автор: GremlinProg 10.11.2005, 09:38
Не хочу показаться навязчивым, но подумай, чем отличается парент от овнера? Ну, самое главное отличие: Owned окно, по отношению к Owner'у может находиться вне области Owner'а. А это значит, что парент не может быть овнером в понимании WinAPI. Именно поэтому я изначально предложил использовать именно GetAncestor, а не GetParent. В MSDN'е именно так и написано, если сомневаешься, почитай эту вечную библию программиста. Я уже давно проверил это на практике.

PS:Спай можешь и сама написать. Периодически в этом отношении ошибка с овнером неоднократно замечается программистами, но видно очень быстро забывается, к сожалению.

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