MFC: должен ли CDockablePane получать сообщения ON_NOTIFY_REFLECT для CTreeCtrl?

#winapi #visual-c #mfc #message-map

#winapi #visual-c #mfc #сообщение-карта

Вопрос:

Мастер MFC создал проект с a CWorkSpaceBar , который в моем случае фактически основан на CBCGPDockingControlBar эквиваленте MFC CDockablePane . Мастер также создал m_wndTree на основе CBCGPTreeCtrl ( CTreeCtrl ) . Он создал его OnCreate() следующим образом:

 CRect rectDummy;
rectDummy.SetRectEmpty();

// Create tree control:
const DWORD dwViewStyle =   WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS;


if (!m_wndTree.Create(dwViewStyle, rectDummy, this, 1))
{
    TRACE0("Failed to create workspace viewn");
    return -1;      // fail to create
}
 

Теперь я хотел бы обработать некоторые уведомления о просмотре дерева, поэтому я добавил их в CWorkSpaceBar карту сообщений:

 ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, amp;CWorkSpaceBar::OnTvnItemExpanding)
ON_NOTIFY_REFLECT(TVN_GETDISPINFO, amp;CWorkSpaceBar::OnTvnGetDispInfo)
 

Однако я не получаю уведомления? Есть ли что-то еще, что мне нужно сделать, чтобы это заработало?

Ответ №1:

Похоже, вы путаете обработчики ON_NOTIFY_REFLECT and ON_NOTIFY ; или, скорее, окна, для которых должны быть определены эти обработчики.

Из того, что вы описали, ваш CWorkSpaceBar класс / объект является родительским для объекта tree-view ( CTreeCtrl ) ; поэтому, когда элемент раскрывается в этом древовидном представлении, эта родительская панель получает WM_NOTIFY сообщение и вызывается соответствующий ON_NOTIFY обработчик (если он определен в message-map). ON_NOTIFY_REFLECT Обработчик позволяет самому фактическому древовидному представлению перехватывать / получать уведомление.

В моих проектах у меня похожая ситуация, и классы, производные от CDockablePane (например, мои UserPane ), имеют записи карты сообщений, подобные следующим, которые работают должным образом:

     ON_NOTIFY(TVN_ITEMEXPANDING, IDR_USRTV, amp;UserPane::OnItemExpand)
 

Примечание: это IDR_USRTV значение идентификатора, которое я даю древовидному представлению в его Create функции, как показано ниже; в вашем примере кода вы использовали значение 1 (которое может быть или не быть желательным).

 int UserPane::OnCreate(CREATESTRUCT *pCreateStruct)
{
    CRect rc;   rc.SetRectEmpty();
    const DWORD trvstyle = WS_CHILD | WS_VISIBLE |
        TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS | TVS_EDITLABELS;
    if (CDockablePane::OnCreate(pCreateStruct) == -1) return -1;
    if (!m_wndTView.Create(trvstyle, rc, this, IDR_USRTV)) return -1;
    //...
 

Основная схема OnItemExpand функции-члена выглядит следующим образом:

 void UserPane::OnItemExpand(NMHDR *pNotifyStruct, LRESULT *result)
{
    *result = 0;
    NMTREEVIEW *pTV = reinterpret_cast<NMTREEVIEW *>(pNotifyStruct);
    HTREEITEM hItem = pTV->itemNew.hItem;
    uintptr_t itemData = m_wndTView.GetItemData(hItem);
    if (pTV->action == TVE_EXPAND) {
        //...
    }
    else if (pTV->action == TVE_COLLAPSE) {
        //...
    }
    return;
}
 

Комментарии:

1. Я только что вытащил ON_NOTIFY_REFLECT из другого проекта, который был частью CTreeView последующего преобразования старого кода Win32, который у меня уже был, в MFC. Все еще новичок в MFC! Спасибо!!