CTreeCtrl 和 CListCtrl 控件(VC_MFC)


目錄

Tree Control 控件
List Control 控件

(本章節中例子都是用 VS2005 編譯調試的)


Tree Control 控件(MSDN 鏈接)

說明:

樹形控件是用於構造樹形的結構,其中有一個根接點(Root)然后下面有許多子結點,而每個子結點上有允許有一個或多個或沒有子結點.在樹形控件中每一個結點都有一個句柄(HTREEITEM),同時添加結點時必須提供該結點的父結點句柄(其中根Root結點只有一個,既不可以添加也不可以刪除), MFC 中使用 CTreeCtrl 類來封裝樹形控件的各種操作.樹形控件的消息映射使用 ON_NOTIFY 宏.

三個重要結構:

TVINSERTSTRUCT(MSDN 鏈接)

作用:  這個結構體包含了在樹形圖控件添加子節點時需要的相關信息

結構體定義:

View Code
typedef struct _TV_INSERTSTRUCT { 
HTREEITEM hParent; // Handle to the parent item
HTREEITEM hInsertAfter; // Handle to the item after which the new item is to be inserted
TV_ITEM item; // TV_ITEM structure that contains information about the item to add
} TV_INSERTSTRUCT, FAR *LPTV_INSERTSTRUCT;

TVITEM(MSDN 鏈接)

作用:  記錄着被添加的數的節點的信息

結構體定義:

View Code
typedef struct _TV_ITEM { //tvi
UINT mask; // ndicates which of the other structure members contain valid data
HTREEITEM hItem; // Handle to the item to which this structure refers
UINT state; // Set of bit flags and image list indexes that indicate the item's state
UINT stateMask; // Bits of the state member that are valid
LPSTR pszText; // Pointer to a null-terminated string that contains the item text
int cchTextMax; // Size of the buffer pointed to by the pszText member
int iImage; // Index in the tree view control's image list of the icon image to use when the item is in the nonselected state
int iSelectedImage; //Index in the tree view control's image list of the icon image to use when the item is in the selected state.
int cChildren; // Indicates whether the item has associated child items
LPARAM lParam;  // Specifies a 32-bit value to associate with the item.
}TV_ITEM, FAR *LPTV_ITEM;

NMTREEVIEW(MSDN 鏈接)

作用:  包含關於樹形視通知消息的信息

結構體定義:

View Code
typedef struct _NM_TREEVIEW { 
  NMHDR hdr; // NMHDR structure that contains information about this message
  UINT action; // Notification-specific action flag
  TV_ITEM itemOld; // TV_ITEM structure that contains information about the old item state
  TV_ITEM itemNew; // TV_ITEM structure that contains information about the new item state.
  POINT ptDrag; // POINTstructure that contains the client coordinates of the mouse at the time the event occurred that caused the message to be sent
} NM_TREEVIEW;
typedef NM_TREEVIEW FAR* LPNM_TREEVIEW;

CTreeCtrl 常用函數(單擊函數鏈接至MSDN):

代碼示例:

[插入節點][插入帶圖標的節點]

插入節點

先在主對話框中拖入一個 Tree Control 控件,,然后為這個控件添加控制變量其變量類型為 CTreeCtrl 類和名為 m_tc.資源視圖如下:

為這個控件添加子節點,節點結構為如下所示:

+--- Parent1
  +--- Child1_1
  +--- Child1_2
+--- Parent2
  +--- Child2_1

在對話框的初始化函數(即 OnInitDialog 函數)添加相關的實現代碼,如下:

View Code
//聲明指向節點的句柄
HTREEITEM hItem,hSubItem;

//插入節點
//在根結點上添加 Parent1
hItem = m_tc.InsertItem(L"Parent1",TVI_ROOT);
//在 Parent1 上添加一個子結點 Child1_1
hSubItem = m_tc.InsertItem(L"Child1_1",hItem);
// 在 Parent1 上添加一個子結點Child1_2,排在 Child1_1 后面
hSubItem = m_tc.InsertItem(L"Child1_2",hItem,hSubItem);
//在根結點上添加 Parent2
hItem = m_tc.InsertItem(L"Parent2",TVI_ROOT,hItem);
//在 Parent2 上添加一個子結點 Child2_1
m_tc.InsertItem(L"Child2_1",hItem);

運行結果:

若將控件 Tree Control 的 Has Buttons , Has Lines 和 Lines At Root 設置為 true,則控件效果為如下所示:

插入有帶圖標的節點

先在主對話框中拖入一個 Tree Control 控件,然后為這個控件添加控制變量其變量類型為 CTreeCtrl 類和名為 m_tc.和兩個圖標資源(IDI_ICON1 和 IDI_ICON2)資源視圖如下:

  

然后將控件 Tree Control 的 Has Buttons , Has Lines 和 Lines At Root 設置為 true. 並為這個控件添加子節點,節點結構為如下所示:

+--- Parent1
  +--- Child1_1
  +--- Child1_2
+--- Parent2
  +--- Child2_1

在對話框的初始化函數(即 OnInitDialog 函數)添加相關的實現代碼,如下:

View Code
//載入圖標
HICON icon[2];
icon[0]=AfxGetApp()->LoadIcon (IDI_ICON1); 
icon[1]=AfxGetApp()->LoadIcon (IDI_ICON2);

//創建圖像列表控件
CImageList *imagelist=new CImageList; 
imagelist->Create(16,16,0,7,7); 
imagelist->SetBkColor (RGB(255,255,255));
for(int n=0;n<2;n++)
{
    //把圖標載入圖像列表控件
    imagelist->Add(icon[n]); 
}
//為 m_tc 設置一個圖像列表,使 Tree Control 控件的節點顯示不同的圖標
m_tc.SetImageList(imagelist,TVSIL_NORMAL);  

//聲明指向節點的句柄
HTREEITEM hItem,hSubItem;

//插入節點
//在根結點上添加 Parent1
hItem = m_tc.InsertItem(L"Parent1",TVI_ROOT);
//在 Parent1 上添加一個子結點 Child1_1
hSubItem = m_tc.InsertItem(L"Child1_1",hItem);
// 在 Parent1 上添加一個子結點Child1_2,排在 Child1_1 后面
hSubItem = m_tc.InsertItem(L"Child1_2",hItem,hSubItem);
//在根結點上添加 Parent2
hItem = m_tc.InsertItem(L"Parent2",TVI_ROOT,hItem);
//在 Parent2 上添加一個子結點 Child2_1
m_tc.InsertItem(L"Child2_1",hItem);

運行結果:

相關文章:

樹形圖的使用詳解

在MFC中應用CTreeCtrl控件的技巧


List Control 控件(MSDN 鏈接)

兩個重要結構:

LVCOLUMN(MSDN 鏈接)

作用:  這個結構體記錄了列的相關信息

結構體定義:

View Code
typedef struct _LVCOLUMN {
  UINT   mask; // Variable specifying which members contain valid information
  int    fmt; // Alignment of the column header and the subitem text in the column
  int    cx; // Width of the column, in pixels
  LPTSTR pszText; // contains the column header text.
  int    cchTextMax; // Size in TCHARs of the buffer pointed to by the pszText member
  int    iSubItem; // Index of subitem associated with the column.
#if (_WIN32_IE >= 0x0300)
  int    iImage; // Zero-based index of an image within the image list. The specified image will appear within the column.
  int    iOrder; // Zero-based column offset. Column offset is in left-to-right order. For example, zero indicates the leftmost column.
#endif 
#if (_WIN32_WINNT >= 0x0600)
  int    cxMin; // Minimum width of the column in pixels.
  int    cxDefault; // Application-defined value typically used to store the default width of the column. This member is ignored by the list-view control.
  int    cxIdeal; // Read-only. The ideal width of the column in pixels, as the column may currently be autosized to a lesser width.
#endif 
} LVCOLUMN, *LPLVCOLUMN;

LVITEM(MSDN 鏈接)

作用:  這個結構體記錄了行的相關信息

結構體定義:

View Code
typedef struct {
  UINT   mask; // Set of flags that specify which members of this structure contain data to be set or which members are being requested
  int    iItem; // Zero-based index of the item to which this structure refers
  int    iSubItem; // One-based index of the subitem to which this structure refers, or zero if this structure refers to an item rather than a subitem
  UINT   state; // Indicates the item's state, state image, and overlay image
  UINT   stateMask; // Value specifying which bits of the state member will be retrieved or modified
  LPTSTR pszText; // containing the item text
  int    cchTextMax; // Number of TCHARs in the buffer pointed to by pszText, including the terminating NULL.
  int    iImage; // Index of the item's icon in the control's image list.
  LPARAM lParam; // Value specific to the item. If you use the LVM_SORTITEMS message, the list-view control passes this value to the application-defined comparison function.
#if (_WIN32_IE >= 0x0300)
  int    iIndent; // Number of image widths to indent the item. A single indentation equals the width of an item image
#endif 
#if (_WIN32_WINNT >= 0x0501)
  int    iGroupId; //  Identifier of the group that the item belongs to, or one of the following values.
  UINT   cColumns; // Number of data columns (subitems) to display for this item in tile view.
  UINT   puColumns; // A pointer to an array of column indices, specifying which columns are displayed for this item, and the order of those columns.
#endif 
#if (_WIN32_WINNT >= 0x0600)
  int    piColFmt; // A pointer to an array of the following flags (alone or in combination), specifying the format of each subitem in extended tile view.
  int    iGroup; // Group index of the item.
#endif 
} LVITEM, *LPLVITEM;

CListCtrl 常用函數(單擊函數鏈接至MSDN):

代碼樣例:

[插入行][插入帶圖標的行][在 View 值為 Report 下設置多列樣式][設置控件樣式][使控件在失去焦點時候依舊高亮顯示]

插入行

先在主對話框中拖入一個 List Control 控件(View 屬性為 Icon),然后為這個控件添加控制變量其變量類型為 CListCtrl 類和名為 m_lc.資源視圖如下:

然后,在對話框初始化函數(即函數 OnInitDialog 中)向控件中插入"T_1","T_2","T_3","T_4","T_5","T_6","T_7","T_8","T_9","T_0" 10 行數據,具體代碼如下:

View Code
//插入列,列屬性只對 View 屬性值為 Report 時才起作用
//並且在 Report 下不能不插入列,不然顯示不出任何東西 
m_lc.InsertColumn(0, L"ColumnName",LVCFMT_LEFT,100);
//插入行
 m_lc.InsertItem(0, L"T_1");
 m_lc.InsertItem(1, L"T_2");
 m_lc.InsertItem(2, L"T_3");
 m_lc.InsertItem(3, L"T_4");
 m_lc.InsertItem(4, L"T_5");
 m_lc.InsertItem(5, L"T_6");
 m_lc.InsertItem(6, L"T_7");
 m_lc.InsertItem(7, L"T_8");
 m_lc.InsertItem(8, L"T_9");
 m_lc.InsertItem(9, L"T_0");

運行結果:

若將控件的 View 屬性設置 Small Icon,List 或 Report 時的效果如下:

插入有帶圖標的行

先在主對話框中拖入一個 List Control 控件(View 屬性為 Icon,若為其他圖標則顯示不出來),然后為這個控件添加控制變量其變量類型為 CListCtrl 類和名為 m_lc.和兩個圖標資源(IDI_ICON1 和 IDI_ICON2)資源視圖如下:

然后為在對話框初始化函數(即函數 OnInitDialog 中)向控件中插入"T_1","T_2" 2行帶有圖標的數據,具體代碼如下:

View Code
//載入圖標
HICON icon[2];
icon[0]=AfxGetApp()->LoadIcon (IDI_ICON1); 
icon[1]=AfxGetApp()->LoadIcon (IDI_ICON2);

//創建圖像列表控件
CImageList *imagelist=new CImageList; 
imagelist->Create(16,16,0,7,7); 
imagelist->SetBkColor (RGB(255,255,255));
for(int n=0;n<2;n++)
{
    //把圖標載入圖像列表控件
    imagelist->Add(icon[n]); 
}

//為 m_lc 置一個圖像列表,使 List Control 的行顯示不同的圖標
m_lc.SetImageList(imagelist,TVSIL_NORMAL);

// 插入行
m_lc.InsertItem(0, L"T_1",0);
m_lc.InsertItem(1, L"T_2",1);

運行結果:

在 View 值為 Report 下設置多列樣式 

在插入數據前大致步驟如上,只需把對話框的 View 屬性設置為 Report 然后,先添對列進行添加操作(即插入列)后等列都設置好了后,再進行行插入,實現代碼依舊是在初始對話框的函數中(即函數 OnInitDialog 中),具體代碼如下:

View Code
//插入列,列屬性只對 View 屬性值為 Report 時才起作用
//並且在 Report 下不能不插入列,不然顯示不出任何東西 
m_lc.InsertColumn(0, L"ColumnName",LVCFMT_LEFT,100);
m_lc.InsertColumn(1,L"ColumnValue",LVCFMT_LEFT,100);
/* 插入行 **************************************************/
int i = m_lc.InsertItem(0, L"T_1");
//在非 Report 下這個文本數據是不顯示的
//設置第二列數據
m_lc.SetItemText(i,1,L"One");

i = m_lc.InsertItem(1, L"T_2");
m_lc.SetItemText(i,1,L"Two");

i = m_lc.InsertItem(2, L"T_3");
m_lc.SetItemText(i,1,L"Three");

i = m_lc.InsertItem(3, L"T_4");
m_lc.SetItemText(i,1,L"Four");

i = m_lc.InsertItem(4, L"T_5");
m_lc.SetItemText(i,1,L"Five");

i = m_lc.InsertItem(5, L"T_6");
m_lc.SetItemText(i,1,L"Six");

i = m_lc.InsertItem(6, L"T_7");
m_lc.SetItemText(i,1,L"Seven");

i = m_lc.InsertItem(7, L"T_8");
m_lc.SetItemText(i,1,L"Eight");

i = m_lc.InsertItem(8, L"T_9");
m_lc.SetItemText(i,1,L"Nine");

i = m_lc.InsertItem(9, L"T_0");
m_lc.SetItemText(i,1,L"Zero");

運行結果:

設置控件樣式

利用 SetExtendedStyle 來設置控件的擴展樣式.List Control 具體的擴展樣式(MSDN 鏈接)

我們來將控件設置一個具有整行高亮的屬性且具有網格線並把實現添加至初始對話框的函數中(即函數 OnInitDialog 中).具體實現代碼如下:

View Code
//獲得控件擴展屬性
DWORD dwStyle = m_lc.GetExtendedStyle();

//選中某行使整行高亮(只適用與report風格的listctrl)
dwStyle |= LVS_EX_FULLROWSELECT;
//網格線(只適用與report風格的listctrl)
dwStyle |= LVS_EX_GRIDLINES;    

//設置控件擴展屬性  
m_lc.SetExtendedStyle(dwStyle); 

//插入列,列屬性只對 View 屬性值為 Report 時才起作用
//並且在 Report 下不能不插入列,不然顯示不出任何東西 
m_lc.InsertColumn(0, L"ColumnName",LVCFMT_LEFT,100);
m_lc.InsertColumn(1,L"ColumnValue",LVCFMT_LEFT,100);
/* 插入行 **************************************************/
int i = m_lc.InsertItem(0, L"T_1");
//在非 Report 下這個文本數據是不顯示的
//設置第二列數據
m_lc.SetItemText(i,1,L"One");

i = m_lc.InsertItem(1, L"T_2");
m_lc.SetItemText(i,1,L"Two");

運行結果(為最右圖,前兩個圖只是為了比較在添加了對應屬性的和為添加的區別):

使控件在失去焦點時候依舊高亮顯示

方法一:

為 List Control 控件添加 NM_CUSTOMDRAW 事件,並為事件添加如下代碼:(其中有兩個關鍵的結構體< NMHDR 和 NMLVCUSTOMDRAW> 點擊其參看詳細說名)

View Code
void CtestDlg::OnNMCustomdrawProtocol(NMHDR *pNMHDR, LRESULT *pResult)
{
    //LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
    // TODO: 在此添加控件通知處理程序代碼
    //*pResult = 0;

    //將 pLVCD 指向參數 pNMHDR 轉換為 NMLVCUSTOMDRAW 類型的對象
    NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
    *pResult = CDRF_DODEFAULT;

    if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
        *pResult = CDRF_NOTIFYITEMDRAW;
    else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
        *pResult = CDRF_NOTIFYSUBITEMDRAW;
    //當行被重繪時候
    else if ( (CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage )
    {
        COLORREF clrNewTextColor, clrNewBkColor;
        
        //獲得要重繪的行的索引
        int nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec );
        
        BOOL bSelect = FALSE;
        
        //獲得選擇行的位置
        POSITION pos =m_lc.GetFirstSelectedItemPosition()-1;  
  
        //若為重繪的該項為選中項 bSelect 為 true
        if((int)pos==nItem)   
            bSelect = TRUE;  

        //判斷要重繪的項是否為選中項
        if(bSelect)
        {
            //為選中的行文本的背景色和前景初始化
            clrNewTextColor = RGB(255,255,255);
            clrNewBkColor = RGB(53,153,251);
        }
        else
        {
            //為未選中的行文本的背景色和前景初始化
            clrNewTextColor = RGB(0,0,0);
            clrNewBkColor = RGB(255,255,255);
        }
        //設置控件文本和文本背景色
        pLVCD->clrText = clrNewTextColor;
        pLVCD->clrTextBk = clrNewBkColor;

        *pResult = CDRF_DODEFAULT;
    }
}

這里也可以實現行顏色和選中行顏色的自定義.即對上面中的一下代碼顏色值進行調整即可:

View Code
if(bSelect)
{
    //通過調整下面兩個變量的 RGB 值實現自定義選中的行文本的背景色和前景色
    clrNewTextColor = RGB(255,255,255);
    clrNewBkColor = RGB(53,153,251);
}
else
{
    //通過調整下面兩個變量的 RGB 值實現自定義未選中的行文本的背景色和前景色
    clrNewTextColor = RGB(0,0,0);
    clrNewBkColor = RGB(255,255,255);
}

運行結果與方法二一樣

方法二:

為 List Control 控件添加 NM_KILLFOCUS 和 NM_SETFOCUS 事件,然后在對話框框中添加一個整形變量 m_SecCount.

接着在 NM_KILLFOCUS 和 NM_SETFOCUS 事件響應函數中添加如下代碼:( SetItemState 相關說明參看上面)

View Code
/* NM_KILLFOCUS 事件響應函數中添加代碼 *******************************************/    
//獲得選中行的索引
m_SecCount = (int)m_lc.GetFirstSelectedItemPosition()-1;

//設置選中行一直高亮顯示
m_lc.SetItemState(m_SecCount,LVIS_DROPHILITED,LVIF_STATE);



/* NM_SETFOCUS 事件響應函數中添加代碼 *******************************************/    
//取消在失去高亮時候選中行的高亮顯示
m_lc.SetItemState(m_SecCount,FALSE,LVIF_STATE);

運行結果:

相關文章:

CListCtrl 如何在失去焦點后行仍高亮顯示

如何讓 ListCtrl 控件失去焦點后還高亮

MFC 中 List Control 控件的使用


免責聲明!

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



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