MFC:CDockablePane 是否收到了 CTreeCtrl 的 ON_NOTIFY_REFLECT 消息?
MFC: Have CDockablePane receive ON_NOTIFY_REFLECT messages for a CTreeCtrl?
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)
但是,我没有收到通知消息?我还需要做些什么才能让它发挥作用吗?
您似乎混淆了 ON_NOTIFY_REFLECT
和 ON_NOTIFY
处理程序;或者更确切地说,应该定义那些处理程序的windows。
根据您的描述,您的 CWorkSpaceBar
class/object 是树视图 (CTreeCtrl
) 对象的 parent;因此,当一个项目在该树视图中展开时, 父窗格 会收到一条 WM_NOTIFY
消息和相关的 ON_NOTIFY
处理程序(如果在消息中定义 -地图)被调用。 ON_NOTIFY_REFLECT
处理程序允许实际的树视图本身 intercept/receive 通知。
在我的项目中,我有类似的情况,从CDockablePane
派生的class(es)(例如我的UserPane
)有如下消息映射条目,按预期工作:
ON_NOTIFY(TVN_ITEMEXPANDING, IDR_USRTV, &UserPane::OnItemExpand)
注:IDR_USRTV
是我给tree-view的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;
}
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)
但是,我没有收到通知消息?我还需要做些什么才能让它发挥作用吗?
您似乎混淆了 ON_NOTIFY_REFLECT
和 ON_NOTIFY
处理程序;或者更确切地说,应该定义那些处理程序的windows。
根据您的描述,您的 CWorkSpaceBar
class/object 是树视图 (CTreeCtrl
) 对象的 parent;因此,当一个项目在该树视图中展开时, 父窗格 会收到一条 WM_NOTIFY
消息和相关的 ON_NOTIFY
处理程序(如果在消息中定义 -地图)被调用。 ON_NOTIFY_REFLECT
处理程序允许实际的树视图本身 intercept/receive 通知。
在我的项目中,我有类似的情况,从CDockablePane
派生的class(es)(例如我的UserPane
)有如下消息映射条目,按预期工作:
ON_NOTIFY(TVN_ITEMEXPANDING, IDR_USRTV, &UserPane::OnItemExpand)
注:IDR_USRTV
是我给tree-view的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;
}