MFC对话框程序基础复习004

来源:互联网 发布:大数据与国家安全 编辑:程序博客网 时间:2024/06/06 03:43

对话框基础复习四 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(); //获取TreeCtrlItem的编辑框

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.复制