列表視圖控件的創建
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_LIST或LVS_REPORT組合使用
LVS_NOSORTHEADER 報表格式的列表視圖控件的表頭不能作爲排序按鈕使用
LVS_OWNERDRAWFIXED 由控件的擁有者負責繪製表項
LVS_REPORT 指定報表顯示格式
LVS_SHAREIMAGELISTS 使列表視圖共享圖像序列
LVS_SHOWSELALWAYS 即使控件失去輸入焦點,仍顯示出項的選擇狀態
LVS_SINGLESEL 指定只能有一個列表項被選中。默認時可以多項選擇
LVS_SMALLICON 指定小圖標顯示格式
LVS_SORTASCENDING 按升序排列列表項
LVS_SORTDESCENDING 按降序排列列表項
與前面的控件一樣,除了以上風格一般我們還要爲列表視圖控件設置WS_CHILD和WS_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爲之前調用GetNextSelectedItem或GetFirstSelectedItemPosition得到的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_LEFT、LVCFMT_RIGHT或LVCFMT_CENTER,nWidth參數爲列寬,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);
設置指定列表項或列表子項的顯示文本。參數nItem和nSubItem同GetItemText。參數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_LIST,View屬性設爲Report,即爲報表風格,Single Selection屬性設爲True。再添加一個靜態文本控件和一個編輯框,靜態文本控件的Caption屬性設爲“選擇的語言:”,編輯框的ID設爲IDC_LANG_SEL_EDIT,Read Only屬性設爲True。此時的對話框模板如下圖:
3. 爲列表視圖控件IDC_PROGRAM_LANG_LIST添加CListCtrl類型的控件變量m_programLangList。
4. 在對話框初始化時,我們將編程語言排行榜加入到列表視圖控件中,那麼需要修改CExample29Dlg::OnInitDialog()函數爲:
- BOOL CExample29Dlg::OnInitDialog()
- {
- CDialogEx::OnInitDialog();
- // Add "About..." menu item to system menu.
- // IDM_ABOUTBOX must be in the system command range.
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- BOOL bNameValid;
- CString strAboutMenu;
- bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
- ASSERT(bNameValid);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
- // TODO: Add extra initialization here
- CRect rect;
- // 獲取編程語言列表視圖控件的位置和大小
- m_programLangList.GetClientRect(&rect);
- // 爲列表視圖控件添加全行選中和柵格風格
- m_programLangList.SetExtendedStyle(m_programLangList.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
- // 爲列表視圖控件添加三列
- m_programLangList.InsertColumn(0, _T("語言"), LVCFMT_CENTER, rect.Width()/3, 0);
- m_programLangList.InsertColumn(1, _T("2012.02排名"), LVCFMT_CENTER, rect.Width()/3, 1);
- m_programLangList.InsertColumn(2, _T("2011.02排名"), LVCFMT_CENTER, rect.Width()/3, 2);
- // 在列表視圖控件中插入列表項,並設置列表子項文本
- m_programLangList.InsertItem(0, _T("Java"));
- m_programLangList.SetItemText(0, 1, _T("1"));
- m_programLangList.SetItemText(0, 2, _T("1"));
- m_programLangList.InsertItem(1, _T("C"));
- m_programLangList.SetItemText(1, 1, _T("2"));
- m_programLangList.SetItemText(1, 2, _T("2"));
- m_programLangList.InsertItem(2, _T("C#"));
- m_programLangList.SetItemText(2, 1, _T("3"));
- m_programLangList.SetItemText(2, 2, _T("6"));
- m_programLangList.InsertItem(3, _T("C++"));
- m_programLangList.SetItemText(3, 1, _T("4"));
- m_programLangList.SetItemText(3, 2, _T("3"));
- return TRUE; // return TRUE unless you set the focus to a control
- }
5. 我們希望在選中列表項改變時,將最新的選擇項實時顯示到編輯框中,那麼可以使用NM_CLICK通知消息。爲列表框IDC_PROGRAM_LANG_LIST的通知消息NM_CLICK添加消息處理函數CExample29Dlg::OnNMClickProgramLangList,並修改如下:
- void CExample29Dlg::OnNMClickProgramLangList(NMHDR *pNMHDR, LRESULT *pResult)
- {
- LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
- // TODO: Add your control notification handler code here
- *pResult = 0;
- CString strLangName; // 選擇語言的名稱字符串
- NMLISTVIEW *pNMListView = (NMLISTVIEW*)pNMHDR;
- if (-1 != pNMListView->iItem) // 如果iItem不是-1,就說明有列表項被選擇
- {
- // 獲取被選擇列表項第一個子項的文本
- strLangName = m_programLangList.GetItemText(pNMListView->iItem, 0);
- // 將選擇的語言顯示與編輯框中
- SetDlgItemText(IDC_LANG_SEL_EDIT, strLangName);
- }
- }
6. 運行程序,彈出結果對話框,在對話框的列表框中用鼠標改變選中項時,編輯框中的顯示會相應改變。效果圖如下: