【问题标题】:MFC: Have CDockablePane receive ON_NOTIFY_REFLECT messages for a CTreeCtrl?MFC:CDockablePane 是否收到 CTreeCtrl 的 ON_NOTIFY_REFLECT 消息?
【发布时间】:2021-04-27 15:25:02
【问题描述】:

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)

但是,我没有收到通知消息?我还需要做些什么才能让它发挥作用吗?

【问题讨论】:

    标签: winapi visual-c++ mfc message-map


    【解决方案1】:

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

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

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

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

    注意:IDR_USRTV 是我在其Create 函数中赋予树视图的 ID 值,如下所示;在您的示例代码中,您使用了 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;
    }
    

    【讨论】:

    • 我刚刚从另一个项目中提取了 ON_NOTIFY_REFLECT,该项目是 CTreeView 的一部分,然后将我已经拥有的旧 Win32 代码转换为 MFC。 MFC 还是新手!谢谢!!
    猜你喜欢
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 2023-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多