前面一節(jié)中,雞啄米講了圖片控件Picture Control,本節(jié)為大家詳解列表視圖控件List Control的使用。
列表視圖控件簡(jiǎn)介
列表視圖控件List Control同樣比較常見(jiàn),它能夠把任何字符串內(nèi)容以列表的方式顯示出來(lái),這種顯示方式的特點(diǎn)是整潔、直觀,在實(shí)際應(yīng)用中能為用戶帶來(lái)方便。
列表視圖控件是對(duì)前面講到的列表框控件List Box的改進(jìn)和延伸。列表視圖控件的列表項(xiàng)一般有圖標(biāo)(Icon)和標(biāo)簽(Label)兩部分。圖標(biāo)是對(duì)列表項(xiàng)的圖形描述,標(biāo)簽是文字描述。當(dāng)然列表項(xiàng)可以只包含圖標(biāo)也可以只包含標(biāo)簽。
列表視圖控件有4種風(fēng)格:Icon、Small Icon、List和Report。下面簡(jiǎn)單說(shuō)下4種風(fēng)格各自的特點(diǎn):
Icon大圖標(biāo)風(fēng)格:列表項(xiàng)的圖標(biāo)通常為32×32像素,在圖標(biāo)的下面顯示標(biāo)簽。
Small Icon小圖標(biāo)風(fēng)格:列表項(xiàng)的圖標(biāo)通常為16×16像素,在圖標(biāo)的右面顯示標(biāo)簽。
List列表風(fēng)格:與小圖標(biāo)風(fēng)格類似,圖標(biāo)和文字的對(duì)齊方式不同。
Report報(bào)表風(fēng)格:列表視圖控件可以包含一個(gè)列表頭來(lái)描述各列的含義。每行顯示一個(gè)列表項(xiàng),通??梢园鄠€(gè)列表子項(xiàng)。最左邊的列表子項(xiàng)的標(biāo)簽左邊可以添加一個(gè)圖標(biāo),而它右邊的所有子項(xiàng)則只能顯示文字。這種風(fēng)格的列表視圖控件很適合做各種報(bào)表。
列表視圖控件的通知消息
雞啄米在VS2010/MFC編程入門(mén)之五(MFC消息映射機(jī)制概述)中的“各種Windows消息的消息處理函數(shù)”部分,就曾以列表視圖控件為例簡(jiǎn)單講了WM_NOTIFY通知消息及其消息映射入口和消息處理函數(shù)的形式。如果你忘記了可以回到第五節(jié)看一看,回憶一下。
雞啄米這里給出下一節(jié)中將要演示的列表視圖控件實(shí)例中,通知碼為NM_CLICK的通知消息的消息映射入口:
ON_NOTIFY(NM_CLICK, IDC_PROGRAM_LANG_LIST, &CExample29Dlg::OnNMClickProgramLangList)
還有消息處理函數(shù)自動(dòng)生成時(shí)的形式:
- void CExample29Dlg::OnNMClickProgramLangList(NMHDR *pNMHDR, LRESULT *pResult)
- {
- LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
- // TODO: Add your control notification handler code here
- *pResult = 0;
- }
我們看到,上面的代碼中將NMHDR指針類型的pNMHDR強(qiáng)制轉(zhuǎn)換為L(zhǎng)PNMITEMACTIVATE類型的pNMItemActivate,那么我們就可以在函數(shù)中通過(guò)pNMHDR來(lái)訪問(wèn)NMHDR結(jié)構(gòu),也可以通過(guò)pNMItemActive指針變量來(lái)訪問(wèn)第一個(gè)元素為NMHDR結(jié)構(gòu)體變量的擴(kuò)充結(jié)構(gòu)。
當(dāng)然列表視圖控件還有一些自己特有的通知消息,下面就介紹幾個(gè)其中比較常用的。
LVN_ITEMCHANGING 和LVN_ITEMCHANGED:當(dāng)列表視圖的狀態(tài)發(fā)生變化時(shí),會(huì)發(fā)送這兩個(gè)通知消息。例如,當(dāng)用戶選擇了新的列表項(xiàng)時(shí),程序就會(huì)收到這兩個(gè)消息。
消息會(huì)附帶一個(gè)指向NMLISTVIEW 結(jié)構(gòu)的指針,消息處理函數(shù)可從該結(jié)構(gòu)中獲得狀態(tài)信息。兩個(gè)消息的不同之處在于,前者的消息處理函數(shù)如果返回TRUE,那么就阻
止選擇的改變,如果返回FALSE,則允許改變。
LVN_KEYDOWN:該消息表明了一個(gè)鍵盤(pán)事件。消息會(huì)附帶一個(gè)指向NMLVKEYDOWN結(jié)構(gòu)的指針,通過(guò)該結(jié)構(gòu)程序可以獲得按鍵的信息。
LVN_BEGINLABELEDIT 和LVN_ENDLABELEDIT:分別在用戶開(kāi)始編輯和結(jié)束編輯標(biāo)題時(shí)發(fā)送。消息會(huì)附帶一個(gè)指向NMLVDISPINFO結(jié)構(gòu)的指針。在前者的消息處理函數(shù)中,可以調(diào)用GetEditControl成員函數(shù)返回一個(gè)指向用于編輯標(biāo)題的編輯框的指針,如果處理函數(shù)返回FALSE,則允許編輯,如果返回TRUE,則禁止編輯。在后者的消息處理函數(shù)中,NMLVDISPINFO結(jié)構(gòu)中的item.pszText指向編輯后的新標(biāo)題,如果pszText 為NULL,那么說(shuō)明用戶放棄了編輯,否則,程序應(yīng)負(fù)責(zé)更新表項(xiàng)的標(biāo)題,這可以由SetItem或SetItemText函數(shù)來(lái)完成。

列表視圖控件的相關(guān)結(jié)構(gòu)體
下面我們來(lái)介紹一下與列表視圖控件有關(guān)的一些結(jié)構(gòu)體。
1. NMHDR結(jié)構(gòu)體
- typedef struct tagNMHDR {
- HWND hwndFrom; // 控件窗口的句柄
- UINT_PTR idFrom; // 控件ID
- UINT code; // 控件的通知消息碼
- } NMHDR;
此結(jié)構(gòu)體在很多情況下都是其他擴(kuò)充結(jié)構(gòu)體的第一個(gè)元素,比如上面的NMITEMACTIVATE結(jié)構(gòu)體:
- typedef struct tagNMITEMACTIVATE {
- NMHDR hdr;
- int iItem;
- int iSubItem;
- UINT uNewState;
- UINT uOldState;
- UINT uChanged;
- POINT ptAction;
- LPARAM lParam;
- UINT uKeyFlags;
- } NMITEMACTIVATE, *LPNMITEMACTIVATE;
2. LVITEM 結(jié)構(gòu)體
該結(jié)構(gòu)體包含了列表視圖控件中列表項(xiàng)或列表子項(xiàng)的各種屬性。
- typedef struct _LVITEM {
- UINT mask; // 掩碼位的組合(下面有對(duì)應(yīng)掩碼的元素都已在括號(hào)中標(biāo)出掩碼),表明哪些元素是有效的
- int iItem; // 列表項(xiàng)的索引
- int iSubItem; // 列表子項(xiàng)的索引
- UINT state; // 狀態(tài),下面會(huì)列出。(LVIF_STATE)
- UINT stateMask; // 狀態(tài)掩碼,用來(lái)說(shuō)明要獲取或設(shè)置哪些狀態(tài)。下面會(huì)列出
- LPTSTR pszText; // 指向列表項(xiàng)或列表子項(xiàng)的標(biāo)簽字符串。(LVIF_TEXT)
- int cchTextMax; // pszText指向緩沖區(qū)的字符的個(gè)數(shù),包括字符串結(jié)束符。(LVIF_TEXT)
- int iImage; // 圖標(biāo)的索引。(LVIF_IMAGE)
- LPARAM lParam; // 32位的附加數(shù)據(jù)。(LVIF_PARAM)
- #if (_WIN32_IE >= 0x0300)
- int iIndent;
- #endif
- #if (_WIN32_WINNT >= 0x501)
- int iGroupId;
- UINT cColumns; // tile view columns
- PUINT puColumns;
- #endif
- #if (_WIN32_WINNT >= 0x0600)
- int* piColFmt;
- int iGroup;
- #endif
- } LVITEM, *LPLVITEM;
下面是state和stateMask的取值及含義:
狀態(tài) 對(duì)應(yīng)的狀態(tài)掩碼 含義
LVIS_CUT 同左 列表項(xiàng)或列表子項(xiàng)被選擇用來(lái)進(jìn)行剪切和粘貼操作
LVIS_DROPHILITED 同左 列表項(xiàng)或列表子項(xiàng)成為拖動(dòng)操作的目標(biāo)
LVIS_FOCUSED 同左 列表項(xiàng)或列表子項(xiàng)具有輸入焦點(diǎn)
LVIS_SELECTED 同左 列表項(xiàng)或列表子項(xiàng)被選中
3. LVCOLUMN結(jié)構(gòu)體
該結(jié)構(gòu)體僅適用于Report報(bào)表式列表視圖控件。在向列表控件中插入一列時(shí)需要用到此結(jié)構(gòu)體。它包含了列表控件某列的各種屬性。
- typedef struct _LVCOLUMN {
- UINT mask; // 掩碼位的組合(下面有對(duì)應(yīng)掩碼的元素都已在括號(hào)中標(biāo)出掩碼),表明哪些元素是有效的
- int fmt; // 該列的表頭和列表子項(xiàng)的標(biāo)簽正文顯示格式,可以是LVCFMT_CENTER、LVCFMT_LEFT或LVCFMT_RIGHT。(LVCF_FMT)
- int cx; // 以像素為單位的列的寬度。(LVCF_FMT)
- LPTSTR pszText; // 指向列表頭標(biāo)題正文的字符串。(LVCF_TEXT)
- int cchTextMax; // pszText指向緩沖區(qū)的字符的個(gè)數(shù),包括字符串結(jié)束符。(LVCF_TEXT)
- int iSubItem; // 該列的索引。(LVCF_SUBITEM)
- #if (_WIN32_IE >= 0x0300)
- int iImage;
- int iOrder;
- #endif
- #if (_WIN32_WINNT >= 0x0600)
- int cxMin;
- int cxDefault;
- int cxIdeal;
- #endif
- } LVCOLUMN, *LPLVCOLUMN;
4. NMLISTVIEW結(jié)構(gòu)體
該結(jié)構(gòu)體存放了列表視圖控件通知消息的相關(guān)信息。列表視圖控件的大部分通知消息都會(huì)附帶指向該結(jié)構(gòu)體的指針。
- typedef struct tagNMLISTVIEW {
- NMHDR hdr; // 標(biāo)準(zhǔn)的NMHDR 結(jié)構(gòu)
- int iItem; // 列表項(xiàng)的索引
- int iSubItem; // 列表子項(xiàng)的索引
- UINT uNewState; // 列表項(xiàng)或列表子項(xiàng)的新?tīng)顟B(tài)
- UINT uOldState; // 列表項(xiàng)或列表子項(xiàng)原來(lái)的狀態(tài)
- UINT uChanged; // 取值與LVITEM的mask成員相同,用來(lái)表明哪些狀態(tài)發(fā)生了變化
- POINT ptAction; // 事件發(fā)生時(shí)鼠標(biāo)的客戶區(qū)坐標(biāo)
- LPARAM lParam; //32位的附加數(shù)據(jù)
- } NMLISTVIEW, *LPNMLISTVIEW;
有關(guān)列表視圖控件的內(nèi)容本節(jié)先講這些,下節(jié)繼續(xù)講列表控件類CListCtrl的一些成員函數(shù)和應(yīng)用實(shí)例,歡迎繼續(xù)關(guān)注雞啄米的VS2010/MFC教程。