MFC常用控件之列表視圖控件(List Control)


近期學習了雞啄米大神的博客,對其中的一些知識點做了一些自己的總結。不過,博客內容大部分來自雞啄米。因此,這個博客算是轉載博客,只是加了一些我自己的理解而已。若想學習雞啄米大神的博客總結,請點擊連接:http://www.jizhuomi.com/software/257.html

1.List Control控件:列表視圖控件的列表項一般有圖標(Icon)和標簽(Label)兩部分。圖標是對列表項的圖形描述,標簽是文字描述。當然列表項可以只包含圖標也可以只包含標簽。

2.列表視圖控件有4種風格:Icon、Small Icon、List和Report。下面簡單說下4種風格各自的特點:
    Icon大圖標風格:列表項的圖標通常為32×32像素,在圖標的下面顯示標簽。
    Small Icon小圖標風格:列表項的圖標通常為16×16像素,在圖標的右面顯示標簽。
    List列表風格:與小圖標風格類似,圖標和文字的對齊方式不同。
    Report報表風格:列表視圖控件可以包含一個列表頭來描述各列的含義。每行顯示一個列表項,通常可以包含多個列表子項。最左邊的列表子項的標簽左邊可以添加一個圖標,而它右邊的所有子項則只能顯示文字。這種風格的列表視圖控件很適合做各種報表。

3.相關消息:
(1)NM_CLICK的通知消息:在該消息的消息處理函數中的第一句有這樣一句系統為我們加上的代碼:     
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
通過這句代碼我們可以看出:上面的代碼中將NMHDR指針類型的pNMHDR強制轉換為LPNMITEMACTIVATE類型的pNMItemActivate,那么我們就可以在函數中通過pNMHDR來訪問NMHDR結構,也可以通過pNMItemActive指針變量來訪問第一個元素為NMHDR結構體變量的擴充結構。
(2)LVN_ITEMCHANGING 和LVN_ITEMCHANGED:當列表視圖的狀態發生變化時,會發送這兩個通知消息。例如,當用戶選擇了新的列表項時,程序就會收到這兩個消息。消息會附帶一個指向NMLISTVIEW 結構的指針,消息處理函數可從該結構中獲得狀態信息。兩個消息的不同之處在於,前者的消息處理函數如果返回TRUE,那么就阻止選擇的改變,如果返回FALSE,則允許改變。
(3)LVN_KEYDOWN:該消息表明了一個鍵盤事件。消息會附帶一個指向NMLVKEYDOWN結構的指針,通過該結構程序可以獲得按鍵的信息。
(4)LVN_BEGINLABELEDIT 和LVN_ENDLABELEDIT:分別在用戶開始編輯和結束編輯標題時發送。消息會附帶一個指向NMLVDISPINFO結構的指針。在前者的消息處理函數中,可以調用GetEditControl成員函數返回一個指向用於編輯標題的編輯框的指針,如果處理函數返回FALSE,則允許編輯,如果返回TRUE,則禁止編輯。在后者的消息處理函數中,NMLVDISPINFO結構中的item.pszText指向編輯后的新標題,如果pszText 為NULL,那么說明用戶放棄了編輯,否則,程序應負責更新表項的標題,這可以由SetItem或SetItemText函數來完成。

4.列表視圖控件相關結構體:
.列表視圖控件相關結構體:

typedef struct tagNMHDR {   
    HWND hwndFrom;     // 控件窗口的句柄   
     UINT_PTR idFrom;   // 控件ID   
    UINT code;         // 控件的通知消息碼   
} NMHDR;

 此結構體在很多情況下都是其他擴充結構體的第一個元素,比如上面的NMITEMACTIVATE結構體:

typedef struct tagNMITEMACTIVATE {   
    NMHDR hdr;   
    int iItem;   
    int iSubItem;   
    UINT uNewState;   
    UINT uOldState;   
    UINT uChanged;   
    POINT ptAction;   
    LPARAM lParam;   
    UINT uKeyFlags;   
} NMITEMACTIVATE, *LPNMITEMACTIVATE;

 LVITEM結構體:該結構體包含了列表視圖控件中列表項或列表子項的各種屬性。

    typedef struct _LVITEM {    
        UINT mask;           // 掩碼位的組合(下面有對應掩碼的元素都已在括號中標出掩碼),表明哪些元素是有效的   
        int iItem;           // 列表項的索引   
        int iSubItem;        // 列表子項的索引   
        UINT state;          // 狀態,下面會列出。(LVIF_STATE)   
        UINT stateMask;      // 狀態掩碼,用來說明要獲取或設置哪些狀態。下面會列出   
        LPTSTR pszText;      // 指向列表項或列表子項的標簽字符串。(LVIF_TEXT)   
        int cchTextMax;      // pszText指向緩沖區的字符的個數,包括字符串結束符。(LVIF_TEXT)   
        int iImage;          // 圖標的索引。(LVIF_IMAGE)   
        LPARAM lParam;       // 32位的附加數據。(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的取值及含義:

 狀態                     對應的狀態掩碼                   含義
        LVIS_CUT                     同左                 列表項或列表子項被選擇用來進行剪切和粘貼操作
        LVIS_DROPHILITED      同左                 列表項或列表子項成為拖動操作的目標
        LVIS_FOCUSED            同左                 列表項或列表子項具有輸入焦點
        LVIS_SELECTED           同左                 列表項或列表子項被選中

LVCOLUMN結構體:該結構體僅適用於Report報表式列表視圖控件。在向列表控件中插入一列時需要用到此結構體。它包含了列表控件某列的各種屬性

    typedef struct _LVCOLUMN {    
        UINT mask;              // 掩碼位的組合(下面有對應掩碼的元素都已在括號中標出掩碼),表明哪些元素是有效的   
        int fmt;                    // 該列的表頭和列表子項的標簽正文顯示格式,可以是LVCFMT_CENTER、LVCFMT_LEFT或LVCFMT_RIGHT。(LVCF_FMT)   
        int cx;                     // 以像素為單位的列的寬度。(LVCF_FMT)   
        LPTSTR pszText;    // 指向列表頭標題正文的字符串。(LVCF_TEXT)   
        int cchTextMax;     // pszText指向緩沖區的字符的個數,包括字符串結束符。(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;  

 NMLISTITEM結構體:該結構體存放了列表視圖控件通知消息的相關信息。列表視圖控件的大部分通知消息都會附帶指向該結構體的指針。

    typedef struct tagNMLISTVIEW {   
        NMHDR hdr;       // 標准的NMHDR 結構   
         int iItem;       // 列表項的索引   
         int iSubItem;    // 列表子項的索引   
         UINT uNewState;  // 列表項或列表子項的新狀態   
         UINT uOldState;  // 列表項或列表子項原來的狀態   
         UINT uChanged;   // 取值與LVITEM的mask成員相同,用來表明哪些狀態發生了變化   
         POINT ptAction;  // 事件發生時鼠標的客戶區坐標   
         LPARAM lParam;   //32位的附加數據   
    } NMLISTVIEW, *LPNMLISTVIEW;  

5.列表視圖控件類:CListCtrl類:

6.創建列表視圖控件:
virtual BOOL Create(
   DWORD dwStyle,
   const RECT& rect,
   CWnd* pParentWnd,
   UINT nID
);
針對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            按降序排列列表項

7.獲取被選擇列表項行數: UINT GetSelectedCount( ) const;

8.獲取第一個被選擇項的位置:POSITION GetFirstSelectedItemPosition( ) const;
返回的POSITION值可以用來迭代來獲取其他選擇項,可以當作參數傳入下面的GetNextSelectedItem函數來獲得選擇項的索引。如果沒有被選擇項則返回NULL。

9.int GetNextSelectedItem(POSITION& pos) const;
該函數獲取由pos指定的列表項的索引,然后將pos設置為下一個位置的POSITION值。返回值就是pos指定列表項的索引。

10.獲取列表項數量:int GetItemCount( ) const;

11.插入列:
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結構,其中包含了插入列的屬性。第二個函數中,lpszColumnHeading參數為列標題字符串,nFormat參數為列中文本的對齊方式,可以是LVCFMT_LEFT、LVCFMT_RIGHT或LVCFMT_CENTER,nWidth參數為列寬,nSubItem為插入列對應列表子項的索引。兩個函數在成功時都返回新列的索引,失敗都返回-1。

12.刪除某列:BOOL DeleteColumn(int nCol);

13.插入新的列表項:int InsertItem(int nItem,LPCTSTR lpszItem);

14.刪除某行:BOOL DeleteItem(int row);nItem指定了要刪除的行的索引

15.獲取指定列表項或列表子項的顯示文本。
    CString GetItemText(int row,int colomn) const;

16.設置指定列表項或列表子項的顯示文本:
BOOL SetItemText(int row,int column,LPCTSTR lpszText);

17.獲取指定列表項的附加32位數據:
DWORD_PTR GetItemData(int nItem) const;

18.設置指定列表項的附加32位數據:
 BOOL SetItemData(int nItem,DWORD_PTR dwData)

示例代碼:

 1 插入數據,設置屬性:
 2 //列表視圖控件
 3     CRect rect;
 4     m_listCtrl.GetClientRect(&rect);
 5     m_listCtrl.SetExtendedStyle(m_listCtrl.GetExtendedStyle()|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
 6 
 7     m_listCtrl.InsertColumn(0,"語言",LVCFMT_CENTER,rect.Width()/3,0);
 8     m_listCtrl.InsertColumn(1,"2016排名",LVCFMT_CENTER,rect.Width()/3,1);
 9     m_listCtrl.InsertColumn(2,"2017排名",LVCFMT_CENTER,rect.Width()/3,2);
10 
11     m_listCtrl.InsertItem(0,"java");
12     m_listCtrl.SetItemText(0,1,"1");
13     m_listCtrl.SetItemText(0,2,"1");
14 
15     m_listCtrl.InsertItem(1,"c++");
16     m_listCtrl.SetItemText(1,1,"2");
17     m_listCtrl.SetItemText(1,2,"2");
18 
19     m_listCtrl.InsertItem(2,"c#");
20     m_listCtrl.SetItemText(2,1,"5");
21     m_listCtrl.SetItemText(2,2,"3");
22 
23 消息處理函數:
24 void CMFC_NoramlControlDlg::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)
25 {
26 //    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<NMITEMACTIVATE>(pNMHDR);
27     // TODO: Add your control notification handler code here
28     *pResult = 0;
29 
30     CString strLanguageName;
31     NMLISTVIEW* pNmListView=(NMLISTVIEW*)pNMHDR;
32     if (pNmListView->iItem!=-1)
33     {
34         strLanguageName=m_listCtrl.GetItemText(pNmListView->iItem,0);
35         AfxMessageBox(strLanguageName);
36     }
37 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM