想完成右键单击树叶子节点时才弹出菜单的功能,现在的情况是,在定义树的区域右键都能弹,想通过HTREEITEM HitTest(_In_ TVHITTESTINFO* pHitTestInfo)方法来获取右键点击的节点,但是怎么都得不到;使用HitTest(_In_ CPoint pt, _In_ UINT* pFlags = NULL)这个方法也不行,而且弹出菜单的位置还不对。求大神解答一下。
顺便问一问,HitTest(_In_ TVHITTESTINFO* pHitTestInfo)这个方法是不是在获取到节点之后会把值直接赋给pHitTestInfo里的HTREEITEM hItem变量,而不是写成HTREEITEM hItem = m_model_tree.HitTest(pHitTestInfo)?
struct TreeItemMap
{
HTREEITEM m_item;
int       m_subitem_id;
CString   m_subitem_name;
};
//初始化树
void CTestPrepareDlg::InitModelTree()
{
TreeItemMap map; HTREEITEM root = m_model_tree.InsertItem(_T("root"),TVI_ROOT);
HTREEITEM sub1 = m_model_tree.InsertItem(_T("sub1"),root,TVI_LAST);
HTREEITEM itemaaa = m_model_tree.InsertItem(_T("aaa"),sub1,TVI_LAST);
HTREEITEM itembbb = m_model_tree.InsertItem(_T("bbb"),sub1,TVI_LAST); map.m_item = itembbb;
map.m_subitem_id = 100;
map.m_subitem_name = _T("bbb");
m_tree_map.push_back(map);
map.m_item = itemaaa;
map.m_subitem_id = 101;
map.m_subitem_name = _T("eee");
m_tree_map.push_back(map);
HTREEITEM sub2 = m_model_tree.InsertItem(_T("sub1"),root,sub1);
m_model_tree.Expand(root,TVE_EXPAND);
}/右键树叶子节点弹出编辑菜单
void CTestPrepareDlg::OnNMRClickTreeModel(NMHDR *pNMHDR, LRESULT *pResult)
{
//TODO:判断是否为叶子节点,是则弹出,否则不弹出
TVHITTESTINFO* pHitTestInfo = new TVHITTESTINFO;
::GetCursorPos(&(pHitTestInfo->pt)); HTREEITEM hItem = m_model_tree.HitTest(pHitTestInfo); m_popup_tree.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
pHitTestInfo->pt.x, pHitTestInfo->pt.y, this);
*pResult = 0;
}

解决方案 »

  1.   

    *pResult = 0;  ///<这一行要放在函数的开始位置
    //------右键选中节点--------------
    CPoint pos ;
    if(!GetCursorPos(&pos))
    return ;
    m_model_tree.ScreenToClient(&pos); UINT uflags;
    HTREEITEM hitem = m_model_tree.HitTest(pos, &uflags);
    if ((hitem != NULL) && (TVHT_ONITEM & uflags))
    {
    m_model_tree.Select(hitem,TVGN_CARET);
    } if ((hitem != NULL) && !(TVHT_ONITEM & uflags))
    {
    return;
    }//--------显示右键菜单----------
    HTREEITEM item = m_model_tree.GetSelectedItem(); CMenu* pPop =  m_popup_tree.GetSubMenu(0);
    CPoint pt1;
    GetCursorPos(&pt1);
    pPop->TrackPopupMenu(TPM_LEFTALIGN,pt1.x,pt1.y,this);
    给你段右键选中节点并弹出菜单的代码参考一下
      

  2.   

    谢谢关注,你贴的代码我也看了很多,解决不了问题,还有就是我想用的是HitTest(_In_ TVHITTESTINFO* pHitTestInfo)这个来获取,使用HitTest(_In_ CPoint pt, _In_ UINT* pFlags = NULL)这个方法的话,弹出菜单的位置有问题。
      

  3.   

    第一次用MFC 不知道是不是树构造的时候的问题,大神在哪里啊
      

  4.   

    HitTest函数的两种用法都是可以的,其功能的实现都是相同的。菜单的位置弹出有问题,可能是你获取到的鼠标的位置不对,你获取了鼠标的位置后,有没有用ScreenToClient()将其转换为屏幕的位置啊?
      

  5.   

    对于HitTest(_In_ TVHITTESTINFO* pHitTestInfo)这个函数来说,如果你在TVHITTESTINFO结构体对象中传入的鼠标位置没有转换为屏幕位置的话,且与其对应的位置没有树节点的话,则其返回的HTREEITEM指针为NULL。你用这个函数获取不到树节点,可能是传入的鼠标位置不对造成的。你试试将获取的鼠标位置用m_model_tree.ScreenToClient(&pos);转换为屏幕位置后,在传入试试。
      

  6.   

    在父类:
    BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) 
    {
    // TODO: Add your specialized code here and/or call the base class
    if(pMsg->message==WM_RBUTTONDOWN)
    {
    POINT point=pMsg->pt;
    ScreenToClient(&point); 
    // convert to tree 
    MapWindowPoints((CWnd*)&tree_ctrl,&point, 1); // to tree 
    UINT flags=TVHT_ONITEM;
    HTREEITEM hTreeItem=tree_ctrl.HitTest(point,&flags);
    CString text=tree_ctrl.GetItemText(hTreeItem);
    afxDump << text << "\n";
    }
    return CFrameWnd::PreTranslateMessage(pMsg);
    }
    在派生类:
    void cTree::OnRButtonDown(UINT nFlags, CPoint point) 
    {
    UINT flags=TVHT_ONITEM;
    HTREEITEM hTreeItem=HitTest(point,&flags);
    CString text=GetItemText(hTreeItem);
    afxDump << text << "\n";
    CTreeCtrl::OnRButtonDown(nFlags, point);
    }