MFC: Have CDockablePane receive ON_NOTIFY_REFLECT messages for a CTreeCtrl?

249 views Asked by At

The MFC Wizard created a project with a CWorkSpaceBar which in my case is actually based on CBCGPDockingControlBar, the MFC equivalent is CDockablePane. The wizard also created a m_wndTree based on CBCGPTreeCtrl (CTreeCtrl). It created it in its OnCreate() like this:

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 view\n");
    return -1;      // fail to create
}

Now I would like to handle some of the TreeView notifications so I added these to the CWorkSpaceBar message map:

ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, &CWorkSpaceBar::OnTvnItemExpanding)
ON_NOTIFY_REFLECT(TVN_GETDISPINFO, &CWorkSpaceBar::OnTvnGetDispInfo)

However, I'm not getting the notification messages? Is there something else I need to do to make it work?

1

There are 1 answers

1
Adrian Mole On BEST ANSWER

You appear to be confusing the ON_NOTIFY_REFLECT and ON_NOTIFY handlers; or rather, the windows for which those handlers should be defined.

From what you have described, your CWorkSpaceBar class/object is the parent of the tree-view (CTreeCtrl) object; so, when an item is expanded in that tree-view, that parent pane receives a WM_NOTIFY message and the relevant ON_NOTIFY handler (if defined in the message-map) is called. The ON_NOTIFY_REFLECT handler allows the actual tree-view itself to intercept/receive the notification.

In my projects, I have a similar situation, and the class(es) derived from CDockablePane (such as my UserPane) have message map entries like the following, which work as expected:

    ON_NOTIFY(TVN_ITEMEXPANDING, IDR_USRTV, &UserPane::OnItemExpand)

Note: The IDR_USRTV is the ID value that I give to the tree-view, in its Create function, as shown below; in your example code, you have used the value of 1 (which may or may not be advisable).

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;
    //...

A basic outline for the OnItemExpand member function is as follows:

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;
}