前面一節(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í)的形式:

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. }  

       我們看到,上面的代碼中將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)體

C++代碼
  1. typedef struct tagNMHDR {   
  2.     HWND hwndFrom;     // 控件窗口的句柄   
  3.      UINT_PTR idFrom;   // 控件ID   
  4.     UINT code;         // 控件的通知消息碼   
  5. } NMHDR;  

        此結(jié)構(gòu)體在很多情況下都是其他擴(kuò)充結(jié)構(gòu)體的第一個(gè)元素,比如上面的NMITEMACTIVATE結(jié)構(gòu)體:

C++代碼
  1. typedef struct tagNMITEMACTIVATE {   
  2.     NMHDR hdr;   
  3.     int iItem;   
  4.     int iSubItem;   
  5.     UINT uNewState;   
  6.     UINT uOldState;   
  7.     UINT uChanged;   
  8.     POINT ptAction;   
  9.     LPARAM lParam;   
  10.     UINT uKeyFlags;   
  11. } NMITEMACTIVATE, *LPNMITEMACTIVATE;  

       2. LVITEM 結(jié)構(gòu)體

       該結(jié)構(gòu)體包含了列表視圖控件中列表項(xiàng)或列表子項(xiàng)的各種屬性。

C++代碼
  1. typedef struct _LVITEM {    
  2.     UINT mask;           // 掩碼位的組合(下面有對(duì)應(yīng)掩碼的元素都已在括號(hào)中標(biāo)出掩碼),表明哪些元素是有效的   
  3.     int iItem;           // 列表項(xiàng)的索引   
  4.     int iSubItem;        // 列表子項(xiàng)的索引   
  5.     UINT state;          // 狀態(tài),下面會(huì)列出。(LVIF_STATE)   
  6.     UINT stateMask;      // 狀態(tài)掩碼,用來(lái)說(shuō)明要獲取或設(shè)置哪些狀態(tài)。下面會(huì)列出   
  7.     LPTSTR pszText;      // 指向列表項(xiàng)或列表子項(xiàng)的標(biāo)簽字符串。(LVIF_TEXT)   
  8.     int cchTextMax;      // pszText指向緩沖區(qū)的字符的個(gè)數(shù),包括字符串結(jié)束符。(LVIF_TEXT)   
  9.     int iImage;          // 圖標(biāo)的索引。(LVIF_IMAGE)   
  10.     LPARAM lParam;       // 32位的附加數(shù)據(jù)。(LVIF_PARAM)   
  11. #if (_WIN32_IE >= 0x0300)   
  12.     int iIndent;   
  13. #endif   
  14. #if (_WIN32_WINNT >= 0x501)   
  15.     int iGroupId;   
  16.     UINT cColumns; // tile view columns   
  17.     PUINT puColumns;   
  18. #endif   
  19. #if (_WIN32_WINNT >= 0x0600)   
  20.     int* piColFmt;   
  21.     int iGroup;   
  22. #endif   
  23. } 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)體。它包含了列表控件某列的各種屬性。

C++代碼
  1. typedef struct _LVCOLUMN {    
  2.     UINT mask;              // 掩碼位的組合(下面有對(duì)應(yīng)掩碼的元素都已在括號(hào)中標(biāo)出掩碼),表明哪些元素是有效的   
  3.     int fmt;                    // 該列的表頭和列表子項(xiàng)的標(biāo)簽正文顯示格式,可以是LVCFMT_CENTER、LVCFMT_LEFT或LVCFMT_RIGHT。(LVCF_FMT)   
  4.     int cx;                     // 以像素為單位的列的寬度。(LVCF_FMT)   
  5.     LPTSTR pszText;    // 指向列表頭標(biāo)題正文的字符串。(LVCF_TEXT)   
  6.     int cchTextMax;     // pszText指向緩沖區(qū)的字符的個(gè)數(shù),包括字符串結(jié)束符。(LVCF_TEXT)   
  7.     int iSubItem;          // 該列的索引。(LVCF_SUBITEM)   
  8. #if (_WIN32_IE >= 0x0300)   
  9.     int iImage;   
  10.     int iOrder;   
  11. #endif   
  12. #if (_WIN32_WINNT >= 0x0600)   
  13.     int cxMin;   
  14.     int cxDefault;   
  15.     int cxIdeal;   
  16. #endif   
  17. } LVCOLUMN, *LPLVCOLUMN;  

       4. NMLISTVIEW結(jié)構(gòu)體

       該結(jié)構(gòu)體存放了列表視圖控件通知消息的相關(guān)信息。列表視圖控件的大部分通知消息都會(huì)附帶指向該結(jié)構(gòu)體的指針。

C++代碼
  1. typedef struct tagNMLISTVIEW {   
  2.     NMHDR hdr;       // 標(biāo)準(zhǔn)的NMHDR 結(jié)構(gòu)   
  3.      int iItem;       // 列表項(xiàng)的索引   
  4.      int iSubItem;    // 列表子項(xiàng)的索引   
  5.      UINT uNewState;  // 列表項(xiàng)或列表子項(xiàng)的新?tīng)顟B(tài)   
  6.      UINT uOldState;  // 列表項(xiàng)或列表子項(xiàng)原來(lái)的狀態(tài)   
  7.      UINT uChanged;   // 取值與LVITEM的mask成員相同,用來(lái)表明哪些狀態(tài)發(fā)生了變化   
  8.      POINT ptAction;  // 事件發(fā)生時(shí)鼠標(biāo)的客戶區(qū)坐標(biāo)   
  9.      LPARAM lParam;   //32位的附加數(shù)據(jù)   
  10. } NMLISTVIEW, *LPNMLISTVIEW;  

       有關(guān)列表視圖控件的內(nèi)容本節(jié)先講這些,下節(jié)繼續(xù)講列表控件類CListCtrl的一些成員函數(shù)和應(yīng)用實(shí)例,歡迎繼續(xù)關(guān)注雞啄米的VS2010/MFC教程。