CTreeCtrl 和 CListCtrl 控件(VC_MFC)

来源:http://www.cnblogs.com/kzloser/archive/2012/11/23/2783305.html

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.资源视图如下:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

为这个控件添加子节点,节点结构为如下所示:

+--- 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);
复制代码

运行结果:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

若将控件 Tree Control 的 Has Buttons , Has Lines 和 Lines At Root 设置为 true,则控件效果为如下所示:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

插入有带图标的节点

先在主对话框中拖入一个 Tree Control 控件,然后为这个控件添加控制变量其变量类型为 CTreeCtrl 类和名为 m_tc.和两个图标资源(IDI_ICON1 和 IDI_ICON2)资源视图如下:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)  CTreeCtrl 和 CListCtrl 控件(VC_MFC)

然后将控件 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);
复制代码

运行结果:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

相关文章:

树形图的使用详解

在MFC中应用CTreeCtrl控件的技巧


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):

代码样例:

[插入行][插入带图标的行][在 View 值为 Report 下设置多列样式][设置控件样式][使控件在失去焦点时候依旧高亮显示]

插入行

先在主对话框中拖入一个 List Control 控件(View 属性为 Icon),然后为这个控件添加控制变量其变量类型为 CListCtrl 类和名为 m_lc.资源视图如下:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

然后,在对话框初始化函数(即函数 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");
复制代码

运行结果:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

若将控件的 View 属性设置 Small Icon,List 或 Report 时的效果如下:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

插入有带图标的行

先在主对话框中拖入一个 List Control 控件(View 属性为 Icon,若为其他图标则显示不出来),然后为这个控件添加控制变量其变量类型为 CListCtrl 类和名为 m_lc.和两个图标资源(IDI_ICON1 和 IDI_ICON2)资源视图如下:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)CTreeCtrl 和 CListCtrl 控件(VC_MFC)

然后为在对话框初始化函数(即函数 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);
复制代码

运行结果:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

在 View 值为 Report 下设置多列样式 

在插入数据前大致步骤如上,只需把对话框的 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");
复制代码

运行结果:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

设置控件样式

利用 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");
复制代码

运行结果(为最右图,前两个图只是为了比较在添加了对应属性的和为添加的区别):

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

使控件在失去焦点时候依旧高亮显示

方法一:

为 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);
复制代码

运行结果:

CTreeCtrl 和 CListCtrl 控件(VC_MFC)

相关文章:

CListCtrl 如何在失去焦点后行仍高亮显示

如何让 ListCtrl 控件失去焦点后还高亮

MFC 中 List Control 控件的使用

你可能感兴趣的:(list)