问题描述
我对CTreeView上下文菜单有一个奇怪的问题。我只是在下面的代码中调用pPopup->TrackPopupMenu()
。没问题,但是不会自动更新状态文本和图标。因此,在Internet上搜索后,我发现MFC功能包中有一个ContextMenuManager
(我现在使用的是BCGControlBar Pro,它是功能包所基于的)。
我尝试在下面的代码中使用ContextMenuManager
(将#if 1更改为0),并且在它起作用时,我发现有时(多次)之后,选定的树项将不会显示突出显示,只是闪烁并返回到右键单击的项目,例如TVGN_DROPHIILITE
仍处于打开状态。 (我确认TVGN_DROPHILITE
是右键单击通过OnNMRClick()
函数上的调试打印项选择树项的工具)。另外,如果我启用了treeCtrl.SelectDropTarget(NULL)
,它可以解决此问题,但是我不必这样做吗?
我真的很想使用ContextMenuManager
,但是这个问题是个表演障碍。有人知道发生了什么吗?
void CMyTreeView::OnNMRClick(NMHDR *pNMHDR,LRESULT *pResult)
{
CDebugPrint::DebugPrint(_T("NMRClick: In DropHighlightItem %p\n"),GetTreeCtrl().GetDropHilightItem());
// Send WM_CONTEXTMENU to self
SendMessage(WM_CONTEXTMENU,(WParaM)m_hWnd,GetMessagePos());
CDebugPrint::DebugPrint(_T("NMRClick: Out DropHighlightItem %p\n"),GetTreeCtrl().GetDropHilightItem());
*pResult = 0;
}
void CMyTreeView::OnContextMenu(CWnd* pWnd,CPoint ptMousePos)
{
HTREEITEM htItem;
CTreeCtrl &treeCtrl=GetTreeCtrl();
//
// ...
//
// the popup is stored in a resource
cmenu menu;
menu.LoadMenu(IDR_TREE_CONTEXT_MENU);
cmenu* pPopup = menu.GetSubMenu(0);
#if 1
UINT id=pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RETURNCMD,ptMousePos.x,ptMousePos.y,this);
#else
CBCGPContextMenuManager *manager = theApp.GetContextMenuManager();
UINT id;
if (manager) {
id=manager->TrackPopupMenu(pPopup->GetSafeHmenu(),this);
// treeCtrl.SelectDropTarget(NULL); // fixes issue
}
else id=0;
#endif
//
// ...
//
}
解决方法
TVGN_DROPHILITE
是一个临时选择,仅在拖放操作期间有效。为什么你搞砸了?
如果有的话,您应该使用TVGN_CARET
。
但是,问题是右键单击没有选择被单击的项目。如果您喜欢这种行为(我喜欢),请自行选择。
奇怪的是,您// Send WM_CONTEXTMENU to self
-WM_CONTEXTMENU
应该由系统发送给您,以响应右键单击。