2

MFC 向导创建了一个项目CWorkSpaceBar,在我的情况下实际上是基于 的CBCGPDockingControlBar,MFC 等效项是CDockablePane. 该向导还基于CBCGPTreeCtrl( CTreeCtrl) 创建了一个 m_wndTree。它是这样创建的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 view\n");
    return -1;      // fail to create
}

现在我想处理一些 TreeView 通知,所以我将它们添加到CWorkSpaceBar消息映射中:

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

但是,我没有收到通知消息?我还需要做些什么才能使其正常工作吗?

4

1 回答 1

3

您似乎混淆了ON_NOTIFY_REFLECTON_NOTIFY处理程序;或者更确切地说,应该定义这些处理程序的窗口。

根据您的描述,您的CWorkSpaceBar类/对象是树视图()对象的父级;CTreeCtrl因此,当在该树视图中展开项目时,该父窗格会收到一条WM_NOTIFY消息并调用相关的ON_NOTIFY处理程序(如果在消息映射中定义)。处理程序允许实际的ON_NOTIFY_REFLECT树视图本身拦截/接收通知。

在我的项目中,我有类似的情况,并且派生自CDockablePane(例如 my UserPane)的类具有如下消息映射条目,它们按预期工作:

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

注意:IDR_USRTV是我给树视图的 ID 值,在它的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;
}
于 2021-01-23T09:58:24.507 回答