对话框基础复习四 2011.4.26
Menu 控件:(CMenu类)
为对话框程序添加普通菜单:
①在 resources 里添加一个菜单
②在 对话框类里 创建一个CMenu 的对象 m_menu
③在构造函数里
m_menu.LoadMenu(IDR_*);
④SetMenu 为对话框设置菜单
为特定控件添加右键菜单:
①在 resources 里添加一个菜单,并在第0项 Properties 设置 Pop-up,在这第0项之下的弹出菜单就是要在右键弹出的菜单了
②对控件 鼠标右键点击WM_RBUTTONDOWN 进行消息映射
ClientToScreen(&point); 把客户区坐标转换成屏幕坐标,符合弹出位置
③用一个 CMenu指针 指向第0项(刚才①设置的)
CMenu *pPopMenu = m_PopMenu.GetSubMenu(0);
④利用③获取到的指针 弹出③指向的Pop-up菜单
pPopMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
TreeCtrl 控件:(CTreeCtrl类)
简单的使用:
①关联一个 TreeCtrl 的控制对象
②InsertItem 给树状视图添加Item
...**.insert(" *** ");//插入一个根节点,assume返回 h1
...**.insert(" ** ", h1);//在h1下插入一个节点
③在 Dialog 类中响应 TVN_SELCHANGED 消息
HTREEITEM 树的Item的结构体句柄
GetSelectItem 返回正在选中的Item的一个HTREEITEM结构体实例
也可以 给TreeCtrl关联一个类, 在类中响应 TVN_SELCHANGED 消息,在消息响应函数中,有个LRESULT* pResult 的参数,用来确认是否向父窗口也得到反射消息。
当 pResult = 0 ,向父窗口继续递交消息
当 pResult = 1 ,不向父窗口继续递交消息
要让TreeCtrl 中的Item 在单击的时候变成可编辑的状态 要设置TVS_EDITLABLS风格
第一种方法:在properties页面 勾选 Edit Labels
第二种方法:利用系统API来实现(这也可以应用于其他windows窗口)
GetWindowLong 获取window的各种信息
参数2个 hwnd 和 nIndex标识(其中 GWL_STYLE 是窗口的style)
返回值类型为 LONG
SetWindowLong 设置 windows 的各种信息
参数3个 hwnd 、nIndex和 要设置的LONG型值
所以,只要获取到窗口风格然后和 TVS_EDITLABLS 进行与运算,得到的结果设置到控件就行了
TVN_BEGINLABELEDIT 编辑开始的消息
编辑之前,要实现限制编辑消息的长度,就必须处理 TVN_BEGINLABELEDIT 消息
CEdit* pEdit = GetEditControl(); //获取TreeCtrl中Item的编辑框
ASSERT(pEdit); //assert[ə'sə:t]vt.断言, pEdit指向是null,那程序在调试的时候就会停 下来,返回错误调试信息,只在DEBUG模式下有效
if(pEdit)
{
GetEditControl()->LimitText(15); //如果超过15个字节就会提示
*pResult = 0; //返回0表示处理不成功,不会继续消息映射
}
TVN_ENDLABELEDIT 编辑结束的消息
编辑之后,要实现标签可保存,实现不允许重复的标签,就必须处理 TVN_ENDLABELEDIT 消息
HTREEITEM hParent = GetParentItem(pTVDispInfo->item.hItem);
HTREEITEM hChild = GetChildItem(hParent ? hParent : TVI_ROOT);
这种做法就可以获取到同层的Item了,注意上面的三元运算符,好技巧啊
通过 GetitemText(hChild) 获取hChild的文本
通过 hChild = GetNextSiblingItem(hChild); 获取下一个子节点
CString 有一个比较函数 CompareNoCase 是不区分大小写的比较,很方便
为TreeCtrl控件添加上下文菜单:
①添加 WM_RBUTTONDOWN 消息响应函数
②HTREEITEM hCurrSel = GetSelectedItem();
③HTREEITEM hNewSel = HitTest(point, &nFlags);
//用 HitTest进行点击测试,在不同的控件类中都有不同的HitTest,所以要注意了,要么就为TreeCtrl控件关联一个类,在这个类里添加消息响应函数。
④if(NULL == hNewSel) SelectItem(NULL); //右键点了空白区域
else if (hCurrSel != hNewSel) { SelectItem(hNewSel); SetFocus(); }
//右键点了 非当前选择 的另一个item,激活当前选择item
⑤然后就可以弹出菜单了,参考上面的Menu控件。
利用递归功能一次展开/折叠所有节点:
注意:凡事使用递归实现时候都要小心,如果视图控件有大量的数据,就有可能造成堆栈的溢出。
void ExpandAllBranches(Bool bExpand) //用于确认是张开还是折叠
{
HTREEITEM hItem = m_tree.GetRootItem();
do
{
ExpandBranch(hItem, bExpand); //展开
}while((hItem = m_tree.GetNextSiblingItem(hItem)) != NULL); //遍历所有根
m_tree.Select(hItem, TVGN_FIRSTVISIBLE); //选中最先看到的节点
}
void ExpandBranch(HTREEITEM hItem, BOOL bExpand)
{
if(m_tree.ItemHasChildren(hItem))
{
m_tree.Expand(hItem, bExpand ? TVE_EXPAND : TVE_COLLAPSE);
bItem = m_tree.GetChildItem(hItem);
do
{
ExpandBranch(hItem, bExpand);
}while((hItem = m_tree.GetNextSiblingItem(hItem)) != NULL);
//递归遍历所有它的兄弟
}
}
collapse [kə'læps] v.折叠,崩溃 n.崩溃
sibling ['sibliŋ] n.兄弟
duplicate ['dju:plikit] n/a完全一样(的)v.复制