关于MFC中树控件的选中焦点问题

芊芊绝唱 2011-11-29 06:16:48
假设一个树控件(三层)是这样的

根目录
子项1
a
b
c
d
子项2
e
f

而且,我已经实现了右击abcdef才能弹出一个菜单,而右击“子项1”和“子项2”是不会弹出的。

那么现在的问题是,如果我事先左击了“子项1”,然后去直接右击a,这样是不会弹出菜单的,一旦右键弹起,选中状态又恢复到了“子项1”,就好比选中的状态只是暂时转移到了a,也就是如果要直接右击a来弹出菜单,就必须先左击a。
同样,如果事先左击了a,那么再在“子项1”上右击,也能弹出菜单。

我想知道怎么样才能通过右击也把焦点转过来而不要用左击?是不是要修改树的属性什么的?
...全文
462 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
macong1989 2012-09-26
  • 打赏
  • 举报
回复
回复看看最终结果
dahaiI0 2011-11-30
  • 打赏
  • 举报
回复
The DestroyMenu function is used, before an application closes, to destroy the menu and free memory that the loaded menu occupied.
这就跟new和delete类似,不delete也不见得程序会崩溃
芊芊绝唱 2011-11-30
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 visualeleven 的回复:]
C/C++ code

NM_RCLICK
void CXXXDlg::OnRclickTree1(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
CPoint point;
GetCursorPos(&point)……
[/Quote]
多谢7楼,你的方法可以,你又一次帮到我了。。嘿嘿
不过我还想问下,你代码里面最后那句m.DestroyMenu();我没有加好像也没什么问题。那么加上是为了更严谨么?
芊芊绝唱 2011-11-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 allen_lanyuhai 的回复:]
其实,我觉得改成这样子,应该会可以实现想要的效果:
处理右键的消息:
UINT uFlags;
CPoint point;
::GetCursorPos(&point);
HTREEITEM t=m_tree.GetSelectedItem();//获得选中的项
if ((hItem != NULL) && (TVHT_ONITEM &……
[/Quote]
6楼的大哥,这样还是没有效果,跟我3楼的一样了。
芊芊绝唱 2011-11-30
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 dingxz105090 的回复:]
引用 5 楼 ziyue007 的回复:
给树形控件添加事件处理程序,消息类型为NM_RCLICK,然后再控件中获取选中项(根,子目录均可),设置不同的右击menu,并添加相应的函数就行了,网上例子挺多的

问题就是控件中获取选中项啊,右击不能将该项设为选中,必须左击才行。。。
[/Quote]
恩,所以5楼的不行。。
凌乱哥 2011-11-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 ziyue007 的回复:]
给树形控件添加事件处理程序,消息类型为NM_RCLICK,然后再控件中获取选中项(根,子目录均可),设置不同的右击menu,并添加相应的函数就行了,网上例子挺多的
[/Quote]
问题就是控件中获取选中项啊,右击不能将该项设为选中,必须左击才行。。。
Eleven 2011-11-30
  • 打赏
  • 举报
回复
NM_RCLICK
void CXXXDlg::OnRclickTree1(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
CPoint point;
GetCursorPos(&point);
CPoint pt(point);
m_tree.ScreenToClient(&point);
HTREEITEM hItem = m_tree.HitTest(point);
if(hItem)
{
m_tree.SelectItem(hItem);

if(!m_tree.ItemHasChildren(hItem))//如果没有子项则弹出菜单
{
CMenu m;
m.LoadMenu(IDR_MENU3);
m.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,pt.x,pt.y,this);
m.DestroyMenu();
}
}
*pResult = 0;
}
allen_lanyuhai 2011-11-30
  • 打赏
  • 举报
回复
其实,我觉得改成这样子,应该会可以实现想要的效果:
处理右键的消息:
UINT uFlags;
CPoint point;
::GetCursorPos(&point);
HTREEITEM t=m_tree.GetSelectedItem();//获得选中的项
if ((hItem != NULL) && (TVHT_ONITEM & uFlags))
{
m_tree.Select(hItem,TVIS_SELECTED);
}
if(!m_tree.ItemHasChildren(hItem))//如果没有子项则弹出菜单
{
CMenu m;
m.LoadMenu(IDR_MENU3);
m.GetSubMenu(0)->TrackPopupMenu (TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,point.x,point.y,this);
}
ziyue007 2011-11-30
  • 打赏
  • 举报
回复
给树形控件添加事件处理程序,消息类型为NM_RCLICK,然后再控件中获取选中项(根,子目录均可),设置不同的右击menu,并添加相应的函数就行了,网上例子挺多的
芊芊绝唱 2011-11-30
  • 打赏
  • 举报
回复
忘了说了,上面:
HTREEITEM t=m_tree.GetSelectedItem();//获得选中的项
这样获得的“选中项”也是根据鼠标左击来定的,而不是右击
求解啊。。。为什么我3楼的做法,不管怎么样,都没有菜单弹出
芊芊绝唱 2011-11-29
  • 打赏
  • 举报
回复
貌似不行哦。。下面是我在OnRclickTree中的代码

UINT uFlags;
CPoint point;
::GetCursorPos(&point);
HTREEITEM t=m_tree.GetSelectedItem();//获得选中的项
HTREEITEM hItem = m_tree.HitTest(point, &uFlags);
if ((hItem != NULL) && (TVHT_ONITEM & uFlags))
{
m_tree.Select(hItem, TVGN_CARET);
}

// CString s1=m_tree.GetItemText(hItem);
// CString s2=m_tree.GetItemText(t);
// CString s=s1+":"+s2;
// MessageBox(s);//经测试,s1永远是空的,而s2则能正确获得选择项的文本
if(!m_tree.ItemHasChildren(hItem))//如果没有子项则弹出菜单
{
CMenu m;
m.LoadMenu(IDR_MENU3);
m.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,point.x,point.y,this);
}

我这么写的话,不管怎么样,都没有菜单弹出
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 yuucyf 的回复:]
在RButtonDown中处理,用HitTest判断是否单击的地方是树节点,如果是的话判断是否是你要弹起菜单的节点,如果是的话,设置SelectItem(),然后弹出菜单,这样应该就OK了.
楼主试试.
[/Quote]

up
yuucyf 2011-11-29
  • 打赏
  • 举报
回复
在RButtonDown中处理,用HitTest判断是否单击的地方是树节点,如果是的话判断是否是你要弹起菜单的节点,如果是的话,设置SelectItem(),然后弹出菜单,这样应该就OK了.
楼主试试.

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧