VS2010/MFC编程入门之二十九(常用控件:列表视图控件List Control 下)
来自:鸡啄米   |  时间:2012-07-04 20:35:57 

原文链接: http://www. 

相关主题: 11090039 11010015 

       上一节是关于 列表视图控件List Control的上半部分 ,简单介绍了列表视图控件,其通知消息的处理和有关结构体的定义。本节继续讲解下半部分,包括列表视图控件的创建、CListCtrl类的主要成员函数和CListCtrl类应用实例。 

       列表视图控件的创建 

        MFC 同样为列表视图控件的操作提供了CListCtrl类。 

       如果我们不想在对话框模板中直接拖入List Control来使用列表视图控件,而是希望动态创建它,则要用到CListCtrl类的成员函数Create函数,原型如下:

virtual BOOL Create( 
   DWORD dwStyle, 
   const RECT& rect, 
   CWnd* pParentWnd, 
   UINT nID 
); 

       参数rect为列表视图控件的位置和尺寸,pParentWnd为指向父窗口的指针,nID指定列表视图控件的ID,最复杂的一个参数同样还是dwStyle,它用于设定列表视图控件的风格,可以是以下风格的组合:

               风格                                                含义 
       LVS_ALIGNLEFT                        显示格式是大图标或小图标时,标签放在图标的左边 
       LVS_ALIGNTOP                         显示格式是大图标或小图标时,标题放在图标的上边 
       LVS_AUTOARRANGE                 显示格式是大图标或小图标时,自动排列控件中的列表项 
       LVS_EDITLABELS                      用户可以修改标签文本 
       LVS_ICON                                 指定大图标显示格式 
       LVS_LIST                                  指定列表显示格式 
       LVS_NOCOLUMNHEADER         在报表格式中不显示列的表头 
       LVS_NOLABELWRAP                显示格式是大图标时,使标签文本单行显示。默认是多行显示 
       LVS_NOSCROLL                       列表视图控件无滚动条,此风格不能与LVS_LISTLVS_REPORT组合使用 
       LVS_NOSORTHEADER              报表格式的列表视图控件的表头不能作为排序按钮使用 
       LVS_OWNERDRAWFIXED        由控件的拥有者负责绘制表项 
       LVS_REPORT                           指定报表显示格式 
       LVS_SHAREIMAGELISTS           使列表视图共享图像序列 
       LVS_SHOWSELALWAYS           即使控件失去输入焦点,仍显示出项的选择状态 
       LVS_SINGLESEL                       指定只能有一个列表项被选中。默认时可以多项选择 
       LVS_SMALLICON                      指定小图标显示格式 
       LVS_SORTASCENDING             按升序排列列表项 
       LVS_SORTDESCENDING          按降序排列列表项 

       与前面的控件一样,除了以上风格一般我们还要为列表视图控件设置WS_CHILDWS_VISIBLE风格。对于直接在对话框模板中创建的列表视图控件,其属性页中的属性与上述风格是对应的,例如,属性Alignment默认为Left,也就等价于指定了LVS_ALIGNLEFT风格。

       CListCtrl类的主要成员函数 

       CListCtrl类有很多成员函数,鸡啄米这里就为大家介绍几个常用的主要成员函数。

        UINT GetSelectedCount( ) const; 

       该函数返回列表视图控件中被选择列表项的数量。

       POSITION GetFirstSelectedItemPosition( ) const; 

       获取列表视图控件中第一个被选择项的位置。返回的POSITION值可以用来迭代来获取其他选择项,可以当作参数传入下面的GetNextSelectedItem函数来获得选择项的索引。如果没有被选择项则返回NULL

       int GetNextSelectedItem(POSITION& pos) const; 

       该函数获取由pos指定的列表项的索引,然后将pos设置为下一个位置的POSITION值。参数pos为之前调用GetNextSelectedItemGetFirstSelectedItemPosition得到的POSITION值的引用。返回值就是pos指定列表项的索引。

       int GetItemCount( ) const; 

       获取列表视图控件中列表项的数量。

       int InsertColumn(int nCol,const LVCOLUMN* pColumn ); 
       int InsertColumn(int nCol,LPCTSTR lpszColumnHeading,int nFormat = LVCFMT_LEFT,int nWidth = -1,int nSubItem = -1 ); 

       这两个函数用于在报表式列表视图控件中插入列。第一个函数中,nCol参数为插入列的索引,pColumn参数指向LVCOLUMN结构,其中包含了插入列的属性。第二个函数中,nCol参数也是插入列的索引,lpszColumnHeading参数为列标题字符串,nFormat参数为列中文本的对齐方式,可以是LVCFMT_LEFTLVCFMT_RIGHTLVCFMT_CENTERnWidth参数为列宽,nSubItem为插入列对应列表子项的索引。两个函数在成功时都返回新列的索引,失败都返回-1

       BOOL DeleteColumn(int nCol); 

       该函数用于删除列表视图控件中的某列。参数nCol为删除列的索引。删除成功则返回TRUE,失败返回FALSE

       int InsertItem(int nItem,LPCTSTR lpszItem); 

       向列表视图控件中插入新的列表项。参数nItem为要插入项的索引,参数lpszItem为要插入项的标签字符串。如果插入成功则返回新列表项的索引,否则返回-1

       BOOL DeleteItem(int nItem); 

       从列表视图控件中删除某个列表项。参数nItem指定了要删除的列表项的索引。删除成功则返回TRUE,否则返回FALSE

       CString GetItemText(int nItem,int nSubItem) const; 

       获取指定列表项或列表子项的显示文本。参数nItem指定了列表项的索引,参数nSubItem指定了列表子项的索引。 

       BOOL SetItemText(int nItem,int nSubItem,LPCTSTR lpszText); 

       设置指定列表项或列表子项的显示文本。参数nItemnSubItemGetItemText。参数lpszText为要设置的显示文本字符串。如果设置成功则返回TRUE,否则返回FALSE

       DWORD_PTR GetItemData(int nItem) const; 

       该函数用于获取指定列表项的附加32位数据。参数nItem为列表项的索引。返回值就是由nItem指定列表项的附加32位数据。

       BOOL SetItemData(int nItem,DWORD_PTR dwData); 

       该函数用于为指定列表项设置附加32位是数据。参数nItem为列表项的索引,参数dwData为列表项的附加32位数据。

       CListCtrl类应用实例 

       最后鸡啄米还是给大家写一个简单的实例,说明CListCtrl类的几个成员函数及通知消息等的使用方法。因为在开发中最常用的要属报表风格的List Control了,所以鸡啄米给大家写的是一个报表List Control的例子。

       此实例实现的功能:在单选列表视图控件中显示一个简单的编程语言排行榜,然后在用鼠标左键选择某列表项时,将选中列表项的文本显示到编辑框中。下面是具体实现步骤:

       1. 创建一个基于对话框的MFC工程,名称设置为“Example29”。

       2. 在自动生成的对话框模板IDD_EXAMPLE29_DIALOG中,删除“TODO: Place dialog controls here.”静态文本控件、“OK”按钮和“Cancel”按钮。添加一个List Control控件,ID设置为IDC_PROGRAM_LANG_LISTView属性设为Report,即为报表风格,Single Selection属性设为True。再添加一个静态文本控件和一个编辑框,静态文本控件的Caption属性设为“选择的语言:”,编辑框的ID设为IDC_LANG_SEL_EDITRead Only属性设为True。此时的对话框模板如下图:

 

       3. 为列表视图控件IDC_PROGRAM_LANG_LIST 添加CListCtrl类型的控件变量 m_programLangList 

       4. 在对话框初始化时,我们将编程语言排行榜加入到列表视图控件中,那么需要修改CExample29Dlg::OnInitDialog()函数为:

C++代码
1.BOOL  CExample29Dlg::OnInitDialog()    
2.{    
3.    CDialogEx::OnInitDialog();    
4.   
5.     // Add "About..." menu item to system menu.    
6.   
7.     // IDM_ABOUTBOX must be in the system command range.    
8.    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);    
9.    ASSERT(IDM_ABOUTBOX < 0xF000);    
10.   
11.    CMenu* pSysMenu = GetSystemMenu(FALSE);    
12.     if  (pSysMenu != NULL)    
13.    {    
14.         BOOL  bNameValid;    
15.        CString strAboutMenu;    
16.        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);    
17.        ASSERT(bNameValid);    
18.         if  (!strAboutMenu.IsEmpty())    
19.        {    
20.            pSysMenu->AppendMenu(MF_SEPARATOR);    
21.            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);    
22.        }    
23.    }    
24.   
25.     // Set the icon for this dialog.  The framework does this automatically    
26.     //  when the application's main window is not a dialog    
27.    SetIcon(m_hIcon, TRUE);          // Set big icon    
28.    SetIcon(m_hIcon, FALSE);         // Set small icon    
29.   
30.     // TODO: Add extra initialization here    
31.    CRect rect;    
32.   
33.     // 获取编程语言列表视图控件的位置和大小    
34.    m_programLangList.GetClientRect(&rect);    
35.   
36.     // 为列表视图控件添加全行选中和栅格风格    
37.    m_programLangList.SetExtendedStyle(m_programLangList.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);    
38.   
39.     // 为列表视图控件添加三列    
40.    m_programLangList.InsertColumn(0, _T( "语言" ), LVCFMT_CENTER, rect.Width()/3, 0);    
41.    m_programLangList.InsertColumn(1, _T( "2012.02排名" ), LVCFMT_CENTER, rect.Width()/3, 1);    
42.    m_programLangList.InsertColumn(2, _T( "2011.02排名" ), LVCFMT_CENTER, rect.Width()/3, 2);    
43.   
44.     // 在列表视图控件中插入列表项,并设置列表子项文本    
45.    m_programLangList.InsertItem(0, _T( "Java" ));    
46.    m_programLangList.SetItemText(0, 1, _T( "1" ));    
47.    m_programLangList.SetItemText(0, 2, _T( "1" ));    
48.    m_programLangList.InsertItem(1, _T( "C" ));    
49.    m_programLangList.SetItemText(1, 1, _T( "2" ));    
50.    m_programLangList.SetItemText(1, 2, _T( "2" ));    
51.    m_programLangList.InsertItem(2, _T( "C#" ));    
52.    m_programLangList.SetItemText(2, 1, _T( "3" ));    
53.    m_programLangList.SetItemText(2, 2, _T( "6" ));    
54.    m_programLangList.InsertItem(3, _T( "C++" ));    
55.    m_programLangList.SetItemText(3, 1, _T( "4" ));    
56.    m_programLangList.SetItemText(3, 2, _T( "3" ));    
57.   
58.     return  TRUE;   // return TRUE  unless you set the focus to a control    
59.}   
       5. 我们希望在选中列表项改变时,将最新的选择项实时显示到编辑框中,那么可以使用NM_CLICK通知消息。为列表框IDC_PROGRAM_LANG_LIST的通知消息NM_CLICK 添加消息处理函数 CExample29Dlg::OnNMClickProgramLangList,并修改如下: 

C++代码
1.void  CExample29Dlg::OnNMClickProgramLangList(NMHDR *pNMHDR,  LRESULT  *pResult)    
2.{    
3.    LPNMITEMACTIVATE pNMItemActivate =  reinterpret_cast <LPNMITEMACTIVATE>(pNMHDR);    
4.     // TODO: Add your control notification handler code here    
5.    *pResult = 0;    
6.   
7.    CString strLangName;     // 选择语言的名称字符串    
8.    NMLISTVIEW *pNMListView = (NMLISTVIEW*)pNMHDR;    
9.   
10.     if  (-1 != pNMListView->iItem)         // 如果iItem不是-1,就说明有列表项被选择    
11.    {    
12.         // 获取被选择列表项第一个子项的文本    
13.        strLangName = m_programLangList.GetItemText(pNMListView->iItem, 0);    
14.         // 将选择的语言显示与编辑框中    
15.        SetDlgItemText(IDC_LANG_SEL_EDIT, strLangName);    
16.    }    
17.}   
       6. 运行程序,弹出结果对话框,在对话框的列表框中用鼠标改变选中项时,编辑框中的显示会相应改变。效果图如下:

 

       关于列表视图控件List Control的内容总算讲完了,内容不少,但实际上这些还只是一部分,在实际开发中会遇到各种问题,需要大家去查阅MSDN或上网找资料等来解决。最后鸡啄米仍然感谢大家对本VS2010/MFC教程的关注。