始化 SPS Sps[]={//信息 {"红梅",0,"1000","30","30000"}, {"黄梅",0,"1000","29","29000"}, {"绿梅",0,"1000","28","28000"}, {"青梅",0,"1000","27","27000"}, {"白梅",0,"1000","31","31000"}, {"红梅",1,"1000","30","30000"}, {"黄梅",1,"1000","29","29000"}, {"绿梅",1,"1000","28","28000"}, {"青梅",1,"1000","27","27000"}, {"白梅",1,"1000","31","31000"}}; CImageList Cil1,Cil2;//大小图像列表 (3)在程序初始化处增加表头、图像和列表控制建立代码 BOOL CVCLISTDlg::OnInitDialog() {CDialog::OnInitDialog(); file://......//其它代码 // TODO: Add extra initialization here此处增加代码 LV_ITEM lvitem; LV_COLUMN lvcol; int i,iPos,iItemNum; CVCLISTApp *pApp=(CVCLISTApp *)AfxGetApp();//创建图象列表 Cil1.Create(32,32,TRUE,2,2); Cil1.Add(pApp->LoadIcon(IDI_GJ)); Cil1.Add(pApp->LoadIcon(IDI_XS)); Cil2.Create(16,16,TRUE,2,2); Cil2.Add(pApp->LoadIcon(IDI_GJ)); Cil2.Add(pApp->LoadIcon(IDI_XS));//设置图象列表 m_ListCtrl.SetImageList(&Cil1,LVSIL_NORMAL); m_ListCtrl.SetImageList(&Cil2,LVSIL_SMALL);//向列表控制中添加表列 lvcol.mask=LVCF_FMT|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH; lvcol.fmt=LVCFMT_CENTER;//居中 i=0; lvcol.pszText="品 名"; lvcol.iSubItem=i; lvcol.cx=70; m_ListCtrl.InsertColumn(i++,&lvcol); lvcol.pszText="数 量"; lvcol.iSubItem=i; lvcol.cx=70; m_ListCtrl.InsertColumn(i++,&lvcol); lvcol.pszText="单 价"; lvcol.iSubItem=i; lvcol.cx=70; m_ListCtrl.InsertColumn(i++,&lvcol); lvcol.pszText="金 额"; lvcol.iSubItem=i; lvcol.cx=70; m_ListCtrl.InsertColumn(i++,&lvcol); file://向列表控制中添加表项 iItemNum=sizeof(Sps)/sizeof(SPS); for(i=0;i<iItemNum;i++){ lvitem.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; lvitem.iItem=i; lvitem.iSubItem=0; lvitem.pszText=Sps[i].szPm; lvitem.iImage=Sps[i].Lx; lvitem.lParam=i; iPos=m_ListCtrl.InsertItem(&lvitem);//返回表项插入后的索引号 lvitem.mask=LVIF_TEXT; lvitem.iItem=iPos; lvitem.iSubItem=1; lvitem.pszText=Sps[i].szSl; m_ListCtrl.SetItem(&lvitem); lvitem.iSubItem=2; lvitem.pszText=Sps[i].szDj; m_ListCtrl.SetItem(&lvitem); lvitem.iSubItem=3; lvitem.pszText=Sps[i].szJe; m_ListCtrl.SetItem(&lvitem); } CheckRadioButton(IDC_STDICON,IDC_REPORT,IDC_STDICON); return TRUE; // return TRUE unless you set the focus to a control } (4)完善列表显示方式代码 在利用Classwizard类向导创建各功能按钮显示功能函数之后,必须依次完善这些功能函数的代码,这些功能函数如下: void CVCLISTDlg::OnStdicon()//设置大图标显示方式 { // TODO: Add your control notification handler code here LONG lStyle; lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//获取当前窗口类型 lStyle&=~LVS_TYPEMASK; file://清除显示方式位 lStyle|=LVS_ICON; file://设置显示方式 SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//设置窗口类型 } void CVCLISTDlg::OnSmlicon() file://设置小图标显示方式 { // TODO: Add your control notification handler code here LONG lStyle; lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//获取当前窗口类型 lStyle&=~LVS_TYPEMASK; file://清除显示方式位 lStyle|=LVS_SMALLICON; file://设置显示方式 SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//设置窗口类型 } void CVCLISTDlg::OnList() file://设置列表显示方式 { // TODO: Add your control notification handler code here LONG lStyle; lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//获取当前窗口类型 lStyle&=~LVS_TYPEMASK; file://清除显示方式位 lStyle|=LVS_LIST; file://设置显示方式 SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//设置窗口类型 } void CVCLISTDlg::OnReport() file://详细资料显示方式 { // TODO: Add your control notification handler code here LONG lStyle; lStyle=GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//获取当前窗口类型 lStyle&=~LVS_TYPEMASK; file://清除显示方式位 lStyle|=LVS_REPORT; file://设置显示方式 SetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE,lStyle);//设置窗口类型 } (5)删除功能的实现 要实现删除功能,必须取得选中表项的数和表项总数,并且需要从后向前进行依次删除,其原因是每个表项被删除后,其后各表项的索引号均会发生递减变化,如果采取从前向后删除的方法,就会造成无法正常删除选中的表项,其功能代码如下: void CVCLISTDlg::OnDel() file://删除按钮功能 { // TODO: Add your control notification handler code here int i,iState; int nItemSelected=m_ListCtrl.GetSelectedCount();//所选表项数 int nItemCount=m_ListCtrl.GetItemCount();//表项总数 if(nItemSelected<1) return; for(i=nItemCount-1;i>=0;i--){ iState=m_ListCtrl.GetItemState(i,LVIS_SELECTED); if(iState!=0) m_ListCtrl.DeleteItem(i); } } (6)排序功能的实现 列表控制有一个特殊的功能,当以详细资料方式显示时,列表顶部的表头可以当作按钮来使用,这可以通过列表控制创建时的风格来控制。当鼠标点击列表头名称时,列表控制就会向其父窗口发送一个LNV_COLUMNCLICK消息,利用类导向中列表控制IDC_LISTCTRL对应的LNV_COLUMNCLICK消息加入相应处理函数,就可将表列按照特定顺序进行排列。其函数使用方法见程序,其中iSort为排序的表列索引号,(PFNLVCOMPARE)CompareFunc为进行具体排序的回调函数,也就是说,通过鼠标点击表头实现的排序过程是由第三方开发的专用排序函数来实现的,排序函数只是实现表项的具体比较操作,而整个排序过程是由SortItemS属性通过不断调用这个函数来实现的。正常的排序过程是升序方式,通过调换排序函数中的参数值,就可实现降序排列,即将PARAM1与PARAM2调换位置。这个回调函数的前两个参数为表列中表项的索引号,第三个参数为排序的表列索引号。 void CVCLISTDlg::OnColumnclickListctrl(NMHDR* pNMHDR, LRESULT* pResult) { file://鼠标左键单击表头处理函数 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; } file://排序时比较表项的回调函数 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用来确定树控制的大小和位置;
上一页 [1] [2] [3] [4] [5] [6] 下一页 |