值,就可实现降序排列,即将PARAM1与PARAM2调换位置。这个回调函数的前两个参数为表列中表项的索引号,第三个参数为排序的表列索引号。
void CVCLISTDlg::OnColumnclickListctrl(NMHDR* pNMHDR, LRESULT* pResult) { //鼠标左键单击表头处理函数
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here static int iSorted=-1;//排列序号
if (pNMListView->iSubItem==iSorted) return; iSorted=pNMListView->iSubItem;
m_ListCtrl.SortItems((PFNLVCOMPARE)CompareFunc,iSorted); *pResult = 0; }
//排序时比较表项的回调函数
int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort) { char *text1,*text2; switch (lParamSort){
case 0L:text1=Sps[lParam1].szPm; text2=Sps[lParam2].szPm;break; case 1L:text1=Sps[lParam1].szSl; text2=Sps[lParam2].szSl;break; case 2L:text1=Sps[lParam1].szDj; text2=Sps[lParam2].szDj;break; case 3L:text1=Sps[lParam1].szJe; text2=Sps[lParam2].szJe;break; }
return (strcmp(text1,text2));//结果为>0 =0 <0 }
同样,也可以通过专用按钮来实现排序功能,如本文的排序按钮对应的功能代码如下: void CVCLISTDlg::OnSort()
{ // TODO: Add your control notification handler code here m_ListCtrl.SortItems((PFNLVCOMPARE)CompareFunc,0);} 7、列表视的演练技巧
在使用列表视时,其方法与列表控制基本相同,只不过列表视是在窗口中来实现的而列表控制是在对话框中实现,列表视的各种功能是通过菜单来实现的而列表控制是通过按钮等方式来实现的,列表控制需要在对话框中创建列表控制控件而列表视直接占据整个窗口,在设计过程中只要将按钮和列表控制设计过程变为菜单设计,并注意在功能增加是在类向导中是通过菜单命令来操作,同时在每个功能函数前面增加取得列表视引用的命令( CListCtrl& ListCtrl = GetListCtrl()),而其余数据结构和代码均不需要修改,实现起来比较容易。 笔者实现的列表控制和视程序的运行结果如下: 列表控制演练示例结果 列表视演练示例结果
第4章 演练CTree 4.1 树控制的主要功能
树控制和视(Tree Control&View)主要用来显示具有一定层次结构的数据项,如资源管理器中的磁盘目录等,以供用户在其中进行各种选择。树控制中的每个数据项包括数据项名称的文本字符串和用于表示该数据项的图像,每个数据项下面均可包含各种子项,整个结构就象目录树一样。对于包含各种子项的数据项,可通过鼠标双击来展开或合拢,这可以通过控制树的不同风格来实现树控制的不同显示形态。这些风格主要包括: TVS_HASLINES表示用连线来连接父项和它下面的各个子项,这可以使树的显示层次结构更加清晰,但在无父项的各子项之间并没有连线;
TVS_LINESATROOT表示在无父项的各子项即根下面的各子项之间存在连线;
TVS_HASBUTTONS 表示在带有子项的父项前面增加一个带“+”或“-”的按钮,这使得用户也可以通过单击这个小按钮来实现子项的展开和合拢,当存在子项时,按钮的初始状态为 “+”,当子项被展开时,按小按钮由“+”变为“-”号,当子项合拢时,小按钮由“-”变为“+”号,这一风格同样对于根项无效,如果需要可通过组合 TVS_LINESATROOT风格来实现;
TVS_EDITLABELS表示允许让用户单击具有输入焦点的数据项来修改其名称。
对于树控制,MFC中也以两种形式来封装,即树控制(CTREECTRL)和树视(CTREEVIEW),来满足用户的不同需求,对于一般要求的用户如在对话框中应用,使用树控制比较方便,而对于具有较高要求的用户,在使用树视时还具有视窗口的各种方便特性,可以更好地满足文档/视结构的要求。当在窗口中使用树视时,树视会占满两个窗口的客户区域并自动随窗口的框架结构的调整而调整,并能够很好地处理诸如菜单、加速键和工具条中的各种命令消息。在使用树视时只要利用其成员函数CtreeView取得其一个引用,就可以象树控制一样方便地应用:CtreeCtrl &treeCtrl = GetTreeCtrl()。 4.2 树控制的对象结构 4.2.1 树控制的建立方法
CtreeCtrl&treeCtrl 建立树控制对象结构 Create 建立树控制并绑定对象
树控制CTreeCtrl::Create的调用格式如下:
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
其中参数dwStyle用来确定树控制的类型;rect用来确定树控制的大小和位置;pParentWnd用来确定树控制的父窗口,通用是一个对话框并且不能为NULL;nID用来确定树控制的标识。树控制的风格可以是下列值的组合:
TVS_HASLINES 表示树控制在各子项之间存在连线; TVS_LINESATROOT 表示树控制在根项之间存在连线;
TVS_HASBUTTONS 表示树控制视在父项左侧存在展开合拢控制按钮; TVS_EDITLABELS 表示可以控制鼠标单击修改树项的名称;
TVS_SHOWSELALWAYS 表示选中项即使在窗口失去输入焦点时仍然保持选中状态; TVS_DISABLEDRAGDROP表示禁止树控制发送TVN_BEGINDRAG消息 4.2.2 树控制的属性类
树控制属性类包括取得树控制中项数GetCount、取得树控制中项相对于父项的偏移值GetIndent、取得树控制图像列表控制句柄 GetImageList、设置树控制图像列表控制句柄SetImageList、取得匹配下一个树项GetNextItem、判断给定树项是否包含子项 ItemHasChildren、取得树项子项GetChildItem、取得下一个同属树项GetNextSiblingItem、取得前一个同属树项 GetPrevSiblingItem、取得父树项GetParentItem、取得第一个可视树项GetFirstVisibleItem、取得下一个可视树项GetNextVisible Item、取得前一个可视的树项GetPrevVisibleItem、取得被选中的树项GetSelectedItem、取得根树项 GetRootItem、
取得树项的属性GetItem、设置树项的属性SetItem、取得树项的状态GetItemState、设置树项的状态 SetItemState、取得与树项关联图像GetItemImage、设置与树项关联图像SetItemImage、取得树项文本 GetItemText、设置树项文本SetItemText和取得树项编辑控制句柄GetEditControl等。 4.2.3 树控制的操作方法
树控制的操作方法包括插入一个树项InsertItem、删除一个树项DeleteItem、删除所有树项DeleteAllItems、展开或合拢树项的子项Expand、选中特定树项SelectItem、选择一个树项作为第一个可视树项SelectSetFirstVisible、编辑一个可视的树项 EditLabel和排序给定父树项的子树项SortChildren等。 4.3 树控制的数据结构
在使用树控制时需要了解两个个非常重要的数据结构TV_ITEM和TV_INSERTSTRUCT,前一个数据结构是用来表示树控制的树项信息,后一个数据结构是用来定义将树项增加到数据控制中所需要的数据内容。另外,还需要NM_TREEVIEW、TV_DISPINFO和TV_HITTESTINFO三个数据结构,这几个数据结构的定义方法如下: 4.3.1 基本数据项结构
typedef struct _TV_ITEM {
UINT mask; //结构成员有效性屏蔽位 HTREEITEM hItem; //数据项控制句柄 UINT state; //数据项状态
UINT stateMask; //状态有效性屏蔽位 LPSTR pszText; //数据项名称字符串
int cchTextMax; //数据项名称的最大长度 int iImage; //数据项图标索引号
int iSelectedImage;//选中数据项图标索引号 int cChildren; //子项标识
LPARAM lParam; //程序定义的32位数据 } TV_ITEM, FAR *LPTV_ITEM; 4.3.2 插入树项结构
typedef struct _TV_INSER TSTRUCT { HTREEITEM hParent; //父项控制句柄
HTREEITEM hInsertAfter; //插入树项的位置 TV_ITEM item; //数据项的结构
} TV_INSERTSTRUCT, FAR *LPTV_INSERTSTRUCT;
其中插入的位置如果是TVI_FIRST 或TVI_LAST ,则分别插入到树控制的最前面或最后面,如果是TVI_SORT ,则插入的树项自动插入到合适的位置。 4.3.3 树控制通知消息结构
typedef struct _NM_TREEVIEW { NMHDR hdr; //通知消息句柄 UINT action; //通知消息标志
TV_ITEM itemOld; //原来的数据结构 TV_ITEM itemNew; //新的数据结构 POINT ptDrag; //拖动指针 } NM_TREEVIEW;
4.3.4 取得或设置数据结构
typedef struct _TV_DISPINFO { tvdi NMHDR hdr; //通知消息控制句柄 TV_ITEM item; //数据项结构 } TV_DISPINFO;
4.3.5 指4.3.6 针测试数据结构
typedef struct _TVHITTESTINFO { tvhtst POINT pt; //客户区域屏幕坐标指针 UINT flags; //存放测试结果的变量 HTREEITEM hItem; //测试的数据项结构
} TV_HITTESTINFO, FAR *LPTV_HITTESTINFO; 其中flags测试结果可以是如下值: TVHT_ABOVE 在客户区域上面 TVHT_BELOW 在客户区域下面
TVHT_NOWHERE 在客户区域中并在最后一项下面 TVHT_ONITEM 在与树项关联的位图或标签内 TVHT_ONITEMBUTTON 在与树项关联的按钮上 TVHT_ONITEMICON 在与树项关联的位图上 TVHT_ONITEMINDENT 在与树项关联的联线上 TVHT_ONITEMLABEL 在与树项关联的标签上 TVHT_ONITEMRIGHT 在树项的右侧区域中
TVHT_ONITEMSTATEICON 在用户定义的状态图标上 TVHT_TOLEFT 在客户区域的左侧 TVHT_TORIGHT 在客户区域的右侧 4.4 树控制的应用技巧示例
这里仍以基于对话框演示实例来具体介绍树控制及其和图像列表相结构的应用技巧:
通过“FILE->NEW->PROJECTS->MFC AppWizard(EXE)”建立名为VCTREE的工程,在建立过程中选择基于对话框(Dialog based)的应用;将对话框中的默认控件删除,并将所有对话框属性中的Language域设置为Chinese(P.R.C.),以使应用程序支持中文;建立两个图标IDI_PM和IDI_CJ,用来表示图标的选中和非选中状态,对于每个图标都应建立32X32和16X16两种大小,以保证程序的需要;在对话框窗口中添加树控制对象(TREE CONTROL),并设置五个按钮“增加|删除|查看|排序|关闭”,其对应标识分别如下: 控制名称 标题名称 标识符号 树控制 IDC_TREECTRL 按钮 增 加 IDC_ADD 删 除 IDC_DEL 查 看 IDC_VIEW 排 序 IDC_SORT 关 闭 IDOK 5、选中树控制控件,选择“VIEW->ClassWizard->Memory Variables。??骺刂艻DC_TREECTRL 引入成员变量,其变量类型为: 变量名 种类 变量类型
m_TreeCtrl Control CTreeCtrl
同时利用“MESSAGES MAP”为各命令按钮增加控制功能函数。 6、然后在代码文件VCTREEDlg.CPP中分别加入如下控制代码:
(1)在文件开始处增加图像列表定义 CImageList Cil1,Cil2;//大小图标像列表 (2)在初始化文件开始处增加代码 BOOL CVCTREEDlg::OnInitDialog() { CDialog::OnInitDialog(); ......//原来其它代码
// TODO: Add extra initialization here // 此处开始增加代码
CVCTREEApp *pApp=(CVCTREEApp *)AfxGetApp();//创建图象列表 Cil1.Create(16,16,ILC_COLOR,2,2); Cil1.Add(pApp->LoadIcon(IDI_PM)); Cil1.Add(pApp->LoadIcon(IDI_CJ));
m_TreeCtrl.SetImageList(&Cil1,TVSIL_NORMAL); //设置图象列表
DWORD dwStyles=GetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE);//获取树控制原风格 dwStyles|=TVS_EDITLABELS|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT; SetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE,dwStyles);//设置风格
char * CJ[4]={玉溪卷烟厂,云南卷烟厂,沈阳卷烟厂,成都卷烟厂};//根数据名称 char * PM[4][5]={
{红梅一,红梅二,红梅三,红梅四,红梅五},//产品数据项 {白梅一,白梅二,白梅三,白梅四,白梅五}, {绿梅一,绿梅二,绿梅三,绿梅四,绿梅五}, {青梅一,青梅二,青梅三,青梅四,青梅五}}; int i,j;
HTREEITEM hRoot,hCur;//树控制项目句柄
TV_INSERTSTRUCT TCItem;//插入数据项数据结构 TCItem.hParent=TVI_ROOT;//增加根项
TCItem.hInsertAfter=TVI_LAST;//在最后项之后
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽 TCItem.item.pszText=数据选择; TCItem.item.lParam=0;//序号 TCItem.item.iImage=0;//正常图标
TCItem.item.iSelectedImage=1;//选中时图标
hRoot=m_TreeCtrl.InsertItem(&TCItem);//返回根项句柄 for(i=0;i<4;i++){//增加各厂家 TCItem.hParent=hRoot;
TCItem.item.pszText=CJ[i];
TCItem.item.lParam=(i+1)*10;//子项序号 hCur=m_TreeCtrl.InsertItem(&TCItem); for(j=0;j<5;j++){//增加各产品 TCItem.hParent=hCur;
TCItem.item.pszText=PM[i][j];
TCItem.item.lParam=(i+1)*10+(j+1);//子项序号 m_TreeCtrl.InsertItem(&TCItem); }
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库常用控件用法(3)在线全文阅读。
相关推荐: