目錄
Tree Control 控件
List Control 控件
(本章節中例子都是用 VS2005 編譯調試的)
Tree Control 控件(MSDN 鏈接)
說明:
樹形控件是用於構造樹形的結構,其中有一個根接點(Root)然后下面有許多子結點,而每個子結點上有允許有一個或多個或沒有子結點.在樹形控件中每一個結點都有一個句柄(HTREEITEM),同時添加結點時必須提供該結點的父結點句柄(其中根Root結點只有一個,既不可以添加也不可以刪除), MFC 中使用 CTreeCtrl 類來封裝樹形控件的各種操作.樹形控件的消息映射使用 ON_NOTIFY 宏.
三個重要結構:
TVINSERTSTRUCT(MSDN 鏈接)
作用: 這個結構體包含了在樹形圖控件添加子節點時需要的相關信息
結構體定義:

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 鏈接)
作用: 記錄着被添加的數的節點的信息
結構體定義:

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 鏈接)
作用: 包含關於樹形視通知消息的信息
結構體定義:

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):
- 創建樹形結構控件窗口: Create
在 Create 中 dwStyle 中可以使用以下一些樹形控件的專用風格:
TVS_HASLINES 在父/子結點之間繪制連線
TVS_LINESATROOT 在根/子結點之間繪制連線
TVS_HASBUTTONS 在每一個結點前添加一個按鈕,用於表示當前結點是否已被展開
TVS_EDITLABELS 結點的顯示字符可以被編輯
TVS_SHOWSELALWAYS 在失去焦點時也顯示當前選中的結點
TVS_DISABLEDRAGDROP 不允許Drag/Drop
TVS_NOTOOLTIPS 不使用ToolTip顯示結點的顯示字符 - 插入字節點: InsertItem
- 獲得 / 設置節點圖標: GetImageList / SetImageList
- 獲得 / 設置選中結點: GetSelectedItem / SelectItem
- 獲得 / 修改索引結點圖標: GetItemImage / SetItemImage
- 獲得 / 修改結點的顯示字符: GetItemText / SetItemText
- 刪除結點: DeleteItem
- 將刪除所有結點: DeleteAllItems
- 獲得根結點: GetRootItem
- 獲得節點父 / 子結點: GetParentItem / GetChildItem
- 獲得結點的上 / 下一個兄弟結點: GetPrevSiblingItem / GetNextSiblingItem
- 獲得 / 設置控件背景色: GetBkColor / SetBkColor
- 獲得 / 設置節點屬性: GetItem / SetItem
- 獲得 / 設置控件字體顏色: GetTextColor / SetTextColor
- 獲得節點矩形區: GetItemRect
代碼示例:
先在主對話框中拖入一個 Tree Control 控件,,然后為這個控件添加控制變量其變量類型為 CTreeCtrl 類和名為 m_tc.資源視圖如下:
為這個控件添加子節點,節點結構為如下所示:
+--- Parent1
+--- Child1_1
+--- Child1_2
+--- Parent2
+--- Child2_1
在對話框的初始化函數(即 OnInitDialog 函數)添加相關的實現代碼,如下:

//聲明指向節點的句柄 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 函數)添加相關的實現代碼,如下:

//載入圖標 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);
運行結果:
相關文章:
List Control 控件(MSDN 鏈接)
兩個重要結構:
LVCOLUMN(MSDN 鏈接)
作用: 這個結構體記錄了列的相關信息
結構體定義:

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 鏈接)
作用: 這個結構體記錄了行的相關信息
結構體定義:

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):
- 插入 / 刪除列: InsertColumn / DeleteItem
- 插入 / 刪除行: InsertItem / DeleteColumn
- 刪除所有行: DeleteAllItems
- 獲得 / 設置行圖標: GetImageList / SetImageList
- 獲得 / 更改行位置: GetItemPosition / SetItemPosition
- 獲得 / 設置行文本: GetItemText / SetItemText
- 獲得 / 設置列寬度: GetColumnWidth / SetColumnWidth
- 獲得 / 設置控件擴展風格: GetExtendedStyle / SetExtendedStyle
- 獲得 / 設置列屬性: GetColumn / SetColumn
- 獲得 / 設置控件背景圖片: GetBkImage / SetBkImage
- 獲得 / 設置控件背景顏色: GetBkColor / SetBkColor
- 獲得 / 設置文本顏色: GetTextColor / SetTextColor
- 獲得 / 設置文本背景色: GetTextBkColor / SetTextBkColor
- 獲得字符串寬度: GetStringWidth
- 獲得 / 設置行屬性: GetItem / SetItem
- 獲得某行矩形區域: GetItemRect
- 獲得 / 設置行狀態: GetItemState / SetItemState (在 SetItemState 中的兩個參數取值說明 nState , nMask )
- 獲得控件行總數: GetItemCount
- 獲得選中行索引(當時索引不是基於 0 而是基於 1): GetFirstSelectedItemPosition
代碼樣例:
[插入行][插入帶圖標的行][在 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 屬性值為 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行帶有圖標的數據,具體代碼如下:

//載入圖標 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 然后,先添對列進行添加操作(即插入列)后等列都設置好了后,再進行行插入,實現代碼依舊是在初始對話框的函數中(即函數 OnInitDialog 中),具體代碼如下:

//插入列,列屬性只對 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 中).具體實現代碼如下:

//獲得控件擴展屬性 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> 點擊其參看詳細說名)

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; } }
這里也可以實現行顏色和選中行顏色的自定義.即對上面中的一下代碼顏色值進行調整即可:

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 相關說明參看上面)

/* 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);
運行結果:
相關文章: