首页 > 其他分享 >3_3、MFC常用控件用法:列表视图、树型控件和标签

3_3、MFC常用控件用法:列表视图、树型控件和标签

时间:2024-06-22 19:27:47浏览次数:13  
标签:控件 MFC int 标签 视图 列表 节点

列表视图、树型和标签

1、列表视图控件

1.1 简介

列表视图控件List Contro比较常见,它能够把任何字符串内容以列表的方式显示出来,这种显示方式的特点是整洁、直观,在实际应用中能为用户带来方便。
列表视图控件是对前面讲到的列表框控件List Box的改进和延伸。列表视图控件的列表项一般有图标(Icon)和标签(Label)两部分。图标是对列表项的图形描述,标签是文字描述。当然列表项可以只包含图标也可以只包含标签。
列表视图控件有4种风格:Icon、Small Icon、List和Report。

  1. Icon大图标风格:列表项的图标通常为32×32像素,在图标的下面显示标签。
  2. Small Icon小图标风格:列表项的图标通常为16×16像素,在图标的右面显示标签。
  3. List列表风格:与小图标风格类似,图标和文字的对齐方式不同。
  4. Report报表风格:列表视图控件可以包含一个列表头来描述各列的含义。每行显示一个列表项,通常可以包含多个列表子项。最左边的列表子项的标签左边可以添加一个图标,而它右边的所有子项则只能显示文字。这种风格的列表视图控件很适合做各种报表。

通知消息

  1. NM_CLICK的通知消息,点击列表视图
    消息映射入口:ON_NOTIFY(NM_CLICK, IDC_PROGRAM_LANG_LIST, &CExample29Dlg::OnNMClickProgramLangList)
    消息处理函数自动生成时的形式:
void CExample29Dlg::OnNMClickProgramLangList(NMHDR *pNMHDR, LRESULT *pResult)   
{   
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR);   
    // TODO: Add your control notification handler code here   
    *pResult = 0;   
}
  • 将NMHDR指针类型的pNMHDR强制转换为LPNMITEMACTIVATE类型的pNMItemActivate,那么我们就可以在函数中通过pNMHDR来访问NMHDR结构,也可以通过pNMItemActive指针变量来访问第一个元素为NMHDR结构体变量的扩充结构。
  1. LVN_ITEMCHANGING 和LVN_ITEMCHANGED:当列表视图的状态发生变化时,会发送这两个通知消息。例如,当用户选择了新的列表项时,程序就会收到这两个消息。
    消息会附带一个指向NMLISTVIEW 结构的指针,消息处理函数可从该结构中获得状态信息。两个消息的不同之处在于,前者的消息处理函数如果返回TRUE,那么就阻
    止选择的改变,如果返回FALSE,则允许改变。
  2. LVN_KEYDOWN:该消息表明了一个键盘事件。消息会附带一个指向NMLVKEYDOWN结构的指针,通过该结构程序可以获得按键的信息。
  3. LVN_BEGINLABELEDIT 和LVN_ENDLABELEDIT:分别在用户开始编辑和结束编辑标题时发送。消息会附带一个指向NMLVDISPINFO结构的指针。在前者的消息处理函数中,可以调用GetEditControl成员函数返回一个指向用于编辑标题的编辑框的指针,如果处理函数返回FALSE,则允许编辑,如果返回TRUE,则禁止编辑。在后者的消息处理函数中,NMLVDISPINFO结构中的item.pszText指向编辑后的新标题,如果pszText 为NULL,那么说明用户放弃了编辑,否则,程序应负责更新表项的标题,这可以由SetItem或SetItemText函数来完成。

列表视图控件相关结构体

  1. NMHDR结构体
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;
  1. 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同左列表项或列表子项被选中
  1. 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;
  1. NMLISTVIEW结构体
    该结构体存放了列表视图控件通知消息的相关信息。列表视图控件的大部分通知消息都会附带指向该结构体的指针。
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;

1.2 创建

MFC同样为列表视图控件的操作提供了CListCtrl类。创建列表视图有两种方式:

  1. 在对话框模板中直接拖入List Control来使用列表视图控件;
  2. 动态创建,用到CListCtrl类的成员函数Create函数,原型如下:
virtual BOOL Create(
   DWORD dwStyle,
   const RECT& rect,
   CWnd* pParentWnd,
   UINT nID 
);
  • 参数rect为列表视图控件的位置和尺寸,pParentWnd为指向父窗口的指针,nID指定列表视图控件的ID,最复杂的一个参数同样还是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按降序排列列表项
  • 与前面的控件一样,除了以上风格一般我们还要为列表视图控件设置WS_CHILD和WS_VISIBLE风格。对于直接在对话框模板中创建的列表视图控件,其属性页中的属性与上述风格是对应的,例如,属性Alignment默认为Left,也就等价于指定了LVS_ALIGNLEFT风格。

CListCtrl类的主要成员函数

  1. UINT GetSelectedCount( ) const;
    该函数返回列表视图控件中被选择列表项的数量。
  2. POSITION GetFirstSelectedItemPosition( ) const;
    获取列表视图控件中第一个被选择项的位置。返回的POSITION值可以用来迭代来获取其他选择项,可以当作参数传入下面的GetNextSelectedItem函数来获得选择项的索引。如果没有被选择项则返回NULL。
  3. int GetNextSelectedItem(POSITION& pos) const;
    该函数获取由pos指定的列表项的索引,然后将pos设置为下一个位置的POSITION值。参数pos为之前调用GetNextSelectedItem或GetFirstSelectedItemPosition得到的POSITION值的引用。返回值就是pos指定列表项的索引。
  4. int GetItemCount( ) const;
  5. 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结构,其中包含了插入列的属性。第二个函数中,nCol参数也是插入列的索引,lpszColumnHeading参数为列标题字符串,nFormat参数为列中文本的对齐方式,可以是LVCFMT_LEFT、LVCFMT_RIGHT或LVCFMT_CENTER,nWidth参数为列宽,nSubItem为插入列对应列表子项的索引。两个函数在成功时都返回新列的索引,失败都返回-1。
  6. BOOL DeleteColumn(int nCol);
    该函数用于删除列表视图控件中的某列。参数nCol为删除列的索引。删除成功则返回TRUE,失败返回FALSE。
  7. int InsertItem(int nItem,LPCTSTR lpszItem);
    向列表视图控件中插入新的列表项。参数nItem为要插入项的索引,参数lpszItem为要插入项的标签字符串。如果插入成功则返回新列表项的索引,否则返回-1。
  8. BOOL DeleteItem(int nItem);
    从列表视图控件中删除某个列表项。参数nItem指定了要删除的列表项的索引。删除成功则返回TRUE,否则返回FALSE。
  9. CString GetItemText(int nItem,int nSubItem) const;
    获取指定列表项或列表子项的显示文本。参数nItem指定了列表项的索引,参数nSubItem指定了列表子项的索引。
  10. BOOL SetItemText(int nItem,int nSubItem,LPCTSTR lpszText);
    设置指定列表项或列表子项的显示文本。参数nItem和nSubItem同GetItemText。参数lpszText为要设置的显示文本字符串。如果设置成功则返回TRUE,否则返回FALSE。
  11. DWORD_PTR GetItemData(int nItem) const;
    该函数用于获取指定列表项的附加32位数据。参数nItem为列表项的索引。返回值就是由nItem指定列表项的附加32位数据。
  12. BOOL SetItemData(int nItem,DWORD_PTR dwData);
    该函数用于为指定列表项设置附加32位是数据。参数nItem为列表项的索引,参数dwData为列表项的附加32位数据。

1.3 实例

  1. 创建控件资源,设置控件属性,添加控件变量;
  2. 初始化控件内部数据;在对话框的初始化函数中设置
// 获取编程语言列表视图控件的位置和大小   
    m_lstReport.GetClientRect(&rect);
    // 为列表视图控件添加全行选中和栅格风格   
    m_lstReport.SetExtendedStyle(m_lstReport.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
    // 为列表视图控件添加三列   
    m_lstReport.InsertColumn(0, _T("语言"), LVCFMT_CENTER, rect.Width() / 3, 0);
    m_lstReport.InsertColumn(1, _T("2012.02排名"), LVCFMT_CENTER, rect.Width() / 3, 1);
    m_lstReport.InsertColumn(2, _T("2011.02排名"), LVCFMT_CENTER, rect.Width() / 3, 2);

    // 在列表视图控件中插入列表项,并设置列表子项文本   
    m_lstReport.InsertItem(0, _T("Java"));
    m_lstReport.SetItemText(0, 1, _T("1"));
    m_lstReport.SetItemText(0, 2, _T("1"));
    m_lstReport.InsertItem(1, _T("C"));
    m_lstReport.SetItemText(1, 1, _T("2"));
    m_lstReport.SetItemText(1, 2, _T("2"));
    m_lstReport.InsertItem(2, _T("C#"));
    m_lstReport.SetItemText(2, 1, _T("3"));
    m_lstReport.SetItemText(2, 2, _T("6"));
    m_lstReport.InsertItem(3, _T("C++"));
    m_lstReport.SetItemText(3, 1, _T("4"));
    m_lstReport.SetItemText(3, 2, _T("3"));
  1. 添加控件消息相应函数:
	CString strLangName;    // 选择语言的名称字符串   
    NMLISTVIEW* pNMListView = (NMLISTVIEW*)pNMHDR;
    if (-1 != pNMListView->iItem)        // 如果iItem不是-1,就说明有列表项被选择   
    {
        // 获取被选择列表项第一个子项的文本   
        strLangName = m_lstReport.GetItemText(pNMListView->iItem, 0);
        // 将选择的语言显示与编辑框中   
        SetDlgItemText(IDC_EDT_REPORT, strLangName);
    }

在这里插入图片描述

2、树型控件

2.1 简介

树形控件在Windows系统中是很常见的,例如资源管理器左侧的窗口中就有用来显示目录的树形视图。树形视图中以分层结构显示数据,每层的缩进不同,层次越低缩进越多。树形控件的节点一般都由标签和图标两部分组成,图标用来抽象的描述数据,能够使树形控件的层次关系更加清晰。
树形控件在插入新的树节点时会稍麻烦些,回顾之前的列表框,插入新列表项时调用AddString成员函数就可以了,而对于树形控件则需要指定新节点与已有节点的关系。另外,树形控件与列表视图控件一样,可以在每一个节点的左边加入图标。这些都使得树形控件给人一种复杂的感觉,但我们在使用它一两次后会发现其实树形控件用起来还是很方便的。

通知信息

  1. TVN_SELCHANGING和TVN_SELCHANGED:在用户改变了对树节点的选择时,控件会发送这两个消息。消息会附带一个指向NMTREEVIEW结构的指针,程序可从该结构中获得必要的信息。两个消息都会在该结构的itemOld成员中包含原来的选择项信息,在itemNew成员中包含新选择项的信息,在action成员中表明是用户的什么行为触发了该通知消息(若是TVC_BYKEYBOARD则表明是键盘,若是TVC_BYMOUSE则表明是鼠标,若是TVC_UNKNOWN则表示未知)。两个消息的不同之处在于,如果TVN_SELCHANGING的消息处理函数返回TRUE,那么就阻止选择的改变,如果返回FALSE,则允许改变。
  2. TVN_KEYDOWN:该消息表明了一个键盘事件。消息会附带一个指向NMTVKEYDOWN结构的指针,通过该结构程序可以获得按键的信息。
  3. TVN_BEGINLABELEDIT和TVN_ENDLABELEDIT:分别在用户开始编辑和结束编辑节点的标签时发送。消息会附带一个指向NMTVDISPINFO结构的指针,程序可从该结构中获得必要的信息。在前者的消息处理函数中,可以调用GetEditControl()成员函数返回一个指向用于编辑标题的编辑框的指针。如果处理函数返回FALSE,则允许编辑,如果返回TRUE,则禁止编辑。在后者的消息处理函数中,NMTVDISPINFO结构中的item.pszText指向编辑后的新标题,如果pszText为NULL,那么说明用户放弃了编辑,否则,程序应负责更新节点的标签,这可以由SetItem()或SetItemText()函数来完成。

相关数据结构

  1. HTREEITEM句柄:树形控件中的每个节点都可以由一个HTREEITEM类型的句柄表示。我们通过CTreeCtrl类的成员函数对树进行访问和操作时,很多时候都要用到HTREEITEM句柄。
  2. TVITEM结构体
    TVITEM结构体描述了树形控件节点的属性,定义如下:
typedef struct tagTVITEM {   
    UINT mask;       // 包含一些掩码位(下面的括号中列出)的组合,用来表明结构的哪些成员是有效的   
    HTREEITEM hItem; // 树节点的句柄(TVIF_HANDLE)   
    UINT state;      // 树节点的状态(TVIF_STATE)   
    UINT stateMask;  // 状态的掩码组合(TVIF_STATE)   
    LPTSTR pszText;  // 树节点的标签文本(TVIF_TEXT)   
    int cchTextMax;  // 标签文本缓冲区的大小(TVIF_TEXT)   
    int iImage;      // 树节点的图像索引(TVIF_IMAGE)   
    int iSelectedImage;  // 选中项的图像索引(TVIF_SELECTEDIMAGE)   
    int cChildren;   // 表明节点是否有子节点,为1则有,为0则没有(TVIF_CHILDREN)   
    LPARAM lParam;   // 一个32 位的附加数据(TVIF_PARAM)   
} TVITEM, *LPTVITEM;
  • 树形控件节点需要显示图标时,就要为树形控件关联一个图像序列,上面的iImage成员就代表了该结构体对应的树节点的图标在图像序列中的索引,iSelectedImage则代表该树节点被选中时显示的图标在图像序列中的索引。
    stateMask用来说明要获取或设置树节点的哪些状态。下面是state和stateMask的一些常用值及含义:
state对应的stateMask含义
TVIS_CUTTVIS_CUT节点被选择用来进行剪切和粘贴操作
TVIS_DROPHILITEDTVIS_DROPHILITED节点成为拖动操作的目标
TVIS_EXPANDEDTVIS_EXPANDED节点的子节点被展开
TVIS_EXPANDEDONCETVIS_EXPANDEDONCE节点的子节点曾经被展开过
TVIS_SELECTEDTVIS_SELECTED节点被选中

lParam在实际开发中常用来存放与树节点有关的附加数据。

  1. NMTREEVIEW结构体
    NMTREEVIEW结构体中包含了树形控件通知消息的相关信息。树形控件的大多数通知消息都会带有指向该结构体的指针。NMTREEVIEW结构体的定义如下:
typedef struct tagNMTREEVIEW {   
    NMHDR hdr;      // 标准的NMHDR结构   
    UINT action;    // 表明是用户的什么行为触发了该通知消息   
    TVITEM itemOld; // 原节点的属性   
    TVITEM itemNew; // 新节点的属性   
    POINT ptDrag;   // 事件发生时鼠标的客户区坐标   
} NMTREEVIEW, *LPNMTREEVIEW;
  1. VINSERTSTRUCT结构体
    向树形控件中插入新节点时需要用到TVINSERTSTRUCT结构体,它常与TVM_INSERTITEM消息一起使用。定义如下:
typedef struct tagTVINSERTSTRUCT {   
    HTREEITEM hParent;      // 父节点的句柄   
    HTREEITEM hInsertAfter; // 指明插入到同层中哪一项的后面   
#if (_WIN32_IE >= 0x0400)   
    union  
    {   
        TVITEMEX itemex;   
        TVITEM item;   
    } DUMMYUNIONNAME;   
#else   
    TVITEM item;            // 要添加的新节点的属性   
#endif   
} TVINSERTSTRUCT, *LPTVINSERTSTRUCT;
  • 若hParent成员为TVI_ROOT或NULL,那么新节点将被作为树的根节点插入。hInsertAfter除了可以是某个节点的句柄,还可以有四种取值:TVI_FIRST(插入到树形控件的最前面)、TVI_LAST(插入到树形控件的最后面)、TVI_ROOT(作为根节点插入)和TVI_SORT(按字母顺序插入)。
  1. NMTVDISPINFO结构体
    NMTVDISPINFO结构体中包含了与树节点的显示有关的信息。定义如下:
typedef struct tagNMTVDISPINFO {   
    NMHDR hdr;   
    TVITEM item;   
} NMTVDISPINFO, *LPNMTVDISPINFO;

2.2 创建

MFC为树形控件提供了CTreeCtrl类,它封装了树形控件的所有操作。
树型控件创建有两种形式:

  1. 在对话框模板中直接拖入Tree Control控件创建;
  2. 通过CTreeCtrl类的Create成员函数创建。
virtual BOOL Create(
        DWORD dwStyle,
        const RECT& rect,
        CWnd* pParentWnd,
        UINT nID 
);
  • dwStyle指定树形控件风格的组合,rect指定树形控件窗口的位置和大小,pParentWnd为指向树形控件父窗口的指针,nID指定树形控件的ID。
  • 树形控件的主要风格以及含义:
设计风格含义
TVS_DISABLEDRAGDROP禁止树形控件发送TVN_BEGINDRAG通知消息,即不支持拖动操作
TVS_EDITLABELS用户可以编辑节点的标签文本
TVS_HASBUTTONS显示带有"+"或"-"的小方框来表示某项能否被展开或已展开
TVS_HASLINES在父节点与子节点间连线以更清晰地显示树的结构
TVS_LINESATROOT在根节点处连线
TVS_SHOWSELALWAYS即使控件失去输入焦点,仍显示出项的选择状态
  • 在对话框模板中直接拖入Tree Control创建树形控件时,可以在树形控件的属性页中设置其风格,与上面的风格是对应的,例如,属性Has Lines对应的就是TVS_HASLINES风格。

CTreeCtrl类的主要成员函数

  1. CImageList* SetImageList(CImageList * pImageList,int nImageListType);
    如果树节点需要显示图标时,则必须先创建一个CImageList类的对象,并为其添加多个图像组成一个图像序列,然后调用SetImageList函数为树形控件设置图像序列,在用InsertItem插入节点时传入所需图像在图像序列中的索引即可。后面的例子中会演示。参数pImageList为指向图像序列类CImageList的对象的指针,若为NULL则删除树形控件的所有图像。参数nImageListType指定图像序列的类型,可以是TVSIL_NORMAL(普通图像序列)或TVSIL_STATE(状态图像序列,用图像表示节点的状态)。
  2. UINT GetCount( ) const;
    获取树形控件中节点的数量。
  3. DWORD_PTR GetItemData(HTREEITEM hItem) const;
    获取树形控件中某个指定节点的附加32位数据。参数hItem为指定的树节点的句柄。
  4. BOOL SetItemData(HTREEITEM hItem,DWORD_PTR dwData);
    为树形控件中某个指定节点设置附加的32位数据。参数hItem同上,dwData为要设置的32位数据。
  5. CString GetItemText(HTREEITEM hItem) const;
    获取树形控件中某个指定节点的标签文本。参数hItem同上。返回值是包含标签文本的字符串。
  6. BOOL SetItemText(HTREEITEM hItem,LPCTSTR lpszItem);
    为树形控件中某个指定节点设置标签文本。参数hItem同上,lpszItem为包含标签文本的字符串的指针。
  7. HTREEITEM GetNextSiblingItem(HTREEITEM hItem) const;
    获取树形控件中某个指定节点的下一个兄弟节点。参数hItem同上。返回值是下一个兄弟节点的句柄。
  8. HTREEITEM GetPrevSiblingItem(HTREEITEM hItem) const;
    获取树形控件中某个指定节点的上一个兄弟节点。参数hItem同上。返回值是上一个兄弟节点的句柄。
  9. HTREEITEM GetParentItem(HTREEITEM hItem) const;
    获取树形控件中某个指定节点的父节点。参数hItem同上。返回值是父节点的句柄。
  10. HTREEITEM GetRootItem( ) const;
    获取树形控件根节点的句柄。
  11. HTREEITEM GetSelectedItem( ) const;
    获取树形控件当前选中节点的句柄。
  12. BOOL DeleteAllItems( );
    删除树形控件中的所有节点。删除成功则返回TRUE,否则返回FALSE。
  13. BOOL DeleteItem(HTREEITEM hItem);
    删除树形控件中的某个节点。参数hItem为要删除的节点的句柄。删除成功则返回TRUE,否则返回FALSE。
  14. HTREEITEM InsertItem(LPCTSTR lpszItem,int nImage,int nSelectedImage,HTREEITEM hParent = TVI_ROOT,HTREEITEM hInsertAfter = TVI_LAST);
    在树形控件中插入一个新节点。参数lpszItem为新节点的标签文本字符串的指针,参数nImage为新节点的图标在树形控件图像序列中的索引,参数nSelectedImage为新节点被选中时的图标在图像序列中的索引,参数hParent为插入节点的父节点的句柄,参数hInsertAfter为新节点的前一个节点的句柄,即新节点将被插入到hInsertAfter节点之后。
  15. BOOL SelectItem(HTREEITEM hItem);
    选中指定的树节点。参数hItem为要选择的节点的句柄。若成功则返回TRUE,否则返回FALSE。

2.3 实例

  1. 创建树型控件资源,并设置属性Has Buttons、Has Lines和Lines At Root,为了在鼠标划过某个节点时显示提示信息还需要将Info Tip属性设为True。
  2. 设置树型控件的图标.ico文件,在线转换即可。
  3. 创建树型控件的控件变量。
  4. 初始化树型空间的显示状态,在对话框初始化函数中:
	HICON hIcon[3];      // 图标句柄数组   
	HTREEITEM hRoot;     // 树的根节点的句柄   
	HTREEITEM hCataItem; // 可表示任一分类节点的句柄   
	HTREEITEM hArtItem;  // 可表示任一文章节点的句柄   

	// 加载三个图标,并将它们的句柄保存到数组   
	hIcon[0] = theApp.LoadIcon(IDI_ICON1);
	hIcon[1] = theApp.LoadIcon(IDI_ICON2);
	hIcon[2] = theApp.LoadIcon(IDI_ICON3);
	// 创建图像序列CImageList对象   
	m_imageList.Create(32, 32, ILC_COLOR32, 3, 3);
	// 将三个图标添加到图像序列   
	for (int i = 0; i < 3; i++)
	{
		m_imageList.Add(hIcon[i]);
	}

	// 为树形控件设置图像序列   
	m_treeTest.SetImageList(&m_imageList, TVSIL_NORMAL);
    // 插入根节点   
    hRoot = m_treeTest.InsertItem(_T("目录"), 0, 0);
    // 在根节点下插入子节点   
    hCataItem = m_treeTest.InsertItem(_T("IT互联网"), 1, 1, hRoot, TVI_LAST);
    // 为“IT互联网”节点添加附加的编号数据,在鼠标划过该节点时显示   
    m_treeTest.SetItemData(hCataItem, 1);
    // 在“IT互联网”节点下插入子节点   
    hArtItem = m_treeTest.InsertItem(_T("百度文章1"), 2, 2, hCataItem, TVI_LAST);
    // 为“百度文章1”节点添加附加的编号数据,在鼠标划过该节点时显示   
    m_treeTest.SetItemData(hArtItem, 2);
    // 在“IT互联网”节点下插入另一子节点   
    hArtItem = m_treeTest.InsertItem(_T("谷歌文章2"), 2, 2, hCataItem, TVI_LAST);
    // 为“谷歌文章2”节点添加附加的编号数据,在鼠标划过该节点时显示   
	m_treeTest.SetItemData(hArtItem, 3);
  1. 添加消息处理函数
ON_NOTIFY(TVN_SELCHANGED, IDC_TRE_TEST, &CDlgTree::OnTvnSelchangedTreTest)

void CDlgTree::OnTvnSelchangedTreTest(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
    // TODO: 在此添加控件通知处理程序代码
    *pResult = 0;
    CString strText; // 树节点的标签文本字符串   

    // 获取当前选中节点的句柄   
    HTREEITEM hItem = m_treeTest.GetSelectedItem();
    // 获取选中节点的标签文本字符串   
    strText = m_treeTest.GetItemText(hItem);
    // 将字符串显示到编辑框中   
    SetDlgItemText(IDC_EDT_TREE, strText);
}

在这里插入图片描述

3、标签控件

3.1 简介

标签控件也比较常见。它可以把多个页面集成到一个窗口中,每个页面对应一个标签,用户点击某个标签时,它对应的页面就会显示。如系统属性页:
在这里插入图片描述
使用标签控件我们可以同时加载多个有关联的页面,用户只需点击标签即可实现页面切换,方便灵活的进行操作。每个标签除了可以显示标签文本,还可以显示图标。
标签控件相当于是一个页面的容器,可以容纳多个对话框,而且一般也只容纳对话框,所以我们不能直接在标签控件上添加其他控件,必须先将其他控件放到对话框中,再将对话框添加到标签控件中。最终我们点击标签切换页面时,切换的不是控件的组合,而是对话框。

标签页的通知信息

在对标签控件进行一些操作,比如点击标签时,标签控件也会向父窗口发送一些通知消息。我们可以为这些通知消息添加处理函数,实现各种功能。 ON_NOTIFY():针对控件的通知消息进行消息响应对应关系

通知消息含义
TCN_SELCHANGE通知父窗口控件的标签选择项已经改变
TCN_SELCHANGING通知父窗口控件的标签选择项正在改变
TCN_KEYDOWN通知父窗口在控件范围内键盘被按下
TCN_GETOBJECT具有TCS_EX_REGISTERDROP扩展特性并且对象被拖动时的通知消息
TCN_FOCUSCHANGE通知父窗口控件的按钮聚焦已经改变
NM_CLICK通知父窗口用户在控件区域范围内点击了鼠标左键
NM_RCLICK通知父窗口用户在控件区域范围内点击了鼠标右键
NM_RELEASEDCAPTURE通知父窗口在控件区域范围内释放鼠标捕获消息

标签控件的相关结构体

  1. TCITEMHEADER结构体
    该结构体用来指定或获取标签控件本身的属性。用在TCM_INSERTITEM、TCM_GETITEM和TCM_SETITEM消息中。
typedef struct tagTCITEMHEADER {      
    UINT mask;   // 掩码,可以为TCIF_IMAGE(iImage成员有效)、TCIF_RTLREADING、TCIF_TEXT(pszText成员有效)   
    UINT lpReserved1;   // 预留   
    UINT lpReserved2;   // 预留   
    LPTSTR pszText;     // 标签文本字符串   
    int cchTextMax;      
    int iImage;         // 图标在标签控件图像序列中的索引   
} TCITEMHEADER, *LPTCITEMHEADER;
  1. TCITEM结构体
    该结构体用来指定或获取标签页的属性。用在TCM_INSERTITEM、TCM_GETITEM和TCM_SETITEM消息中。
typedef struct tagTCITEM {     
    UINT mask;  // 掩码,可以是TCIF_IMAGE(iImage成员有效)、TCIF_PARAM(lParam成员有效)、TCIF_RTLREADING、TCIF_STATE、TCIF_TEXT(pszText成员有效)   
#if (_WIN32_IE >= 0x0300)   
    DWORD dwState;   
    DWORD dwStateMask;   
#else   
    UINT lpReserved1;   
    UINT lpReserved2;   
#endif   
    LPTSTR pszText;   
    int cchTextMax;   
    int iImage;   
    LPARAM lParam;     // 与标签页关联的32位数据   
} TCITEM, *LPTCITEM;
  1. TCHITTESTINFO结构体
    该结构体包含了鼠标单击测试的信息。
typedef struct tagTCHITTESTINFO {   
    POINT pt;  // 鼠标点击测试的客户区坐标   
    UINT flags; // 接收点击测试的结果。有以下几种:TCHT_NOWHERE(坐标点不在标签上)、TCHT_ONITEM(坐标点在标签上但不在标签文本或图标上)、TCHT_ONITEMICON(坐标点在标签图标上)、TCHT_ONITEMLABEL(坐标点在标签文本上)   
} TCHITTESTINFO, *LPTCHITTESTINFO;
  1. NMTCKEYDOWN结构体
    该结构体包含了标签控件中键盘按下的相关信息。主要用在TCN_KEYDOWN通知消息中。
typedef struct tagNMTCKEYDOWN {   
    NMHDR hdr;   
    WORD wVKey;   
    UINT flags;   
} NMTCKEYDOWN;

3.2 创建

MFC为标签控件的操作提供了CTabCtrl类。
创建方式两种:

  1. 在对话框模板中直接拖入Tab Control;
  2. 使用CTabCtrl类的Create成员函数创建。Create函数的原型如下:
virtual BOOL Create(
  DWORD dwStyle,
  const RECT& rect,
  CWnd* pParentWnd,
  UINT nID 
);
  • 参数dwStyle为标签控件的风格,rect为标签控件的位置和大小,pParentWnd为指向标签控件父窗口的指针,nID指定标签控件的ID。

TCS_BUTTONS:标签(控件上部用来选择标签页的位置)外观为按钮风格,且整个控件周围没有边框。

控件风格含义
TCS_FIXEDWIDTH所有标签具有相同的宽度。
TCS_MULTILINE标签以多行显示,如果需要,可以显示所有标签。
TCS_SINGLELINE只显示一行标签,用户可以滚动着看其他标签。
TCS_TABS标签以普通标签样式显示,且整个控件周围有边框。

CTabCtrl类的主要成员函数

  1. int GetCurSel( ) const;
    获取标签控件中当前选择标签的索引。如果成功则返回选择标签的索引,否则返回-1。
  2. BOOL GetItem(int nItem,TCITEM* pTabCtrlItem) const;
    获取标签控件中某个标签的信息。参数nItem为标签索引,pTabCtrlItem为指向TCITEM结构体的指针,用来接收标签信息。若获取成功返回TRUE,否则返回FALSE。
  3. int GetItemCount( ) const;
    获取标签控件中标签的数量。
  4. int SetCurSel(int nItem);
    在标签控件中选择某标签。参数nItem为要选择的标签的索引。如果成功则返回之前选择标签的索引,否则返回-1。
  5. BOOL SetItem(int nItem,TCITEM* pTabCtrlItem);
    设置某标签的所有或部分属性。参数nItem为标签的索引,pTabCtrlItem为指向TCITEM结构体的指针,包含了新的标签属性。成功则返回TRUE,否则返回FALSE。
  6. BOOL DeleteAllItems( );
    删除标签控件中所有标签。
  7. BOOL DeleteItem(int nItem);
    删除标签控件中的某个标签。参数nItem为要删除标签的索引。
  8. LONG InsertItem(int nItem,LPCTSTR lpszItem);
    在标签控件中插入新的标签。参数nItem为新标签的索引,lpszItem为标签文本字符串。如果插入成功则返回新标签的索引,否则返回-1。

3.3 实例

  1. 创建标签控件并创建控件变量;
  2. 创建标签页的对话框,并设置属性为边框none,样式child,创建对话框类;
  3. 建立对话框类和标签控件的联系性。在父窗口中建立对话框类的对象,在父窗口对话框类的初始化函数中对控件进行设置:
	CRect tabRect;   // 标签控件客户区的位置和大小   

    m_tabTest.InsertItem(0, _T("标签1"));         // 插入第一个标签“鸡啄米”  
    m_tabTest.InsertItem(1, _T("标签2"));  // 插入第二个标签“Android开发网”   
    m_tabA.Create(IDD_DLG_TAB1, &m_tabTest);    // 创建第一个标签页   
    m_tabB.Create(IDD_DLG_TAB2, &m_tabTest); // 创建第二个标签页  

    m_tabTest.GetClientRect(&tabRect);    // 获取标签控件客户区Rect 
    tabRect.left += 1;
    tabRect.right -= 1;
    tabRect.top += 25;
    tabRect.bottom -= 1;

    // 根据调整好的tabRect放置m_jzmDlg子对话框,并设置为显示   
    m_tabA.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_SHOWWINDOW);
    // 根据调整好的tabRect放置m_androidDlg子对话框,并设置为隐藏   
    m_tabB.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_HIDEWINDOW);
  1. 建立消息响应函数处理通知消息:
void CDlgTree::OnTcnSelchangeTabTest(NMHDR* pNMHDR, LRESULT* pResult)
{
    // TODO: 在此添加控件通知处理程序代码
    *pResult = 0;

    CRect tabRect;    // 标签控件客户区的Rect   

    // 获取标签控件客户区Rect,并对其调整,以适合放置标签页   
    m_tabTest.GetClientRect(&tabRect);
    tabRect.left += 1;
    tabRect.right -= 1;
    tabRect.top += 25;
    tabRect.bottom -= 1;

    switch (m_tabTest.GetCurSel())
    {
        // 如果标签控件当前选择标签为“鸡啄米”,则显示m_jzmDlg对话框,隐藏m_androidDlg对话框   
    case 0:
        m_tabA.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_SHOWWINDOW);
        m_tabB.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_HIDEWINDOW);
        break;
        // 如果标签控件当前选择标签为“Android开发网”,则隐藏m_jzmDlg对话框,显示m_androidDlg对话框   
    case 1:
        m_tabA.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_HIDEWINDOW);
        m_tabB.SetWindowPos(NULL, tabRect.left, tabRect.top, tabRect.Width(), tabRect.Height(), SWP_SHOWWINDOW);
        break;
    default:
        break;
    }
}

在这里插入图片描述

标签:控件,MFC,int,标签,视图,列表,节点
From: https://blog.csdn.net/qingttqing/article/details/139826615

相关文章

  • Django框架之视图层,form表单文件上传下载,FBV与CBV引入,CBV源码剖析
    ⅠDjango框架之视图层【一】Django的三板斧fromdjango.shortcutsimportHttpResponse,render,redirect,reverse【1】HttpResponse能返回字符串形式的数据HttpResponse是Django中用于创建HTTP响应对象的类,它允许你构建并返回服务器对客户端请求的数据和状态当需......
  • 文本类型控件
    usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;namespaceWindowsFormsApplication2{publicpartialclassForm1:......
  • 第二讲 常见布局及控件
    第二讲常见布局及控件一.RelativeLayout格式:android:layout_二.线性布局 layout_width不要设置wrap_content没有用layout_weight是每个控件占权重线性布局默认水平显示选择题:1.在下列选项中,用于给Activity指定主题的属性是(C)A、iconB、labelC、themeD、style分......
  • Qt QTableView插入控件,qss设计
    环境Qt5.4.2功能QtQTableView插入控件,qss设计源码1.mainwindow.hclassMyComboBox;classMyDoubleSpinBox;classMainWindow:publicQMainWindow{Q_OBJECTpublic:explicitMainWindow(QWidget*parent=0);~MainWindow();private:Ui:......
  • 向 splitContainer1 控件中添加子窗体
    先上效果图: 方法已经封装好了,可以直接用: publicvoidFormControl(Formform){//首先判断容器中是否有其他窗体,如果有,则先关闭foreach(Controliteminthis.splitContainer1.Panel2.Controls){if(itemisForm){((Form......
  • 【C++】【MFC】CView和CDocument关联以及COMMAND消息走向
    MFC编程中,CView类负责显示,CDocument负责数据管理,所以其之间的联系十分重要,包括COMMAND消息的流向CView中的m_pDocument成员将存储和其关联的唯一的CDocument地址,而CDocument中的m_viewList链表将存储和其关联的所有CView地址,即一个CDocument可以有多个CView,但一个CView只能有一个......
  • webman admin 控件的使用 如何修改富文本控件的高度
    如何修改富文本控件的高度把控件类型为富文本的控件参数设置为height:300,则会生成一个300高度的tinymcetinymce.init({selector:'textarea',//changethisvalueaccordingtoyourHTMLheight:300});你也可以将其他的tinymce设置添加进这个控件参数当中,......
  • WPF控件库 https://wpfui.lepo.co/
    wpfui:一个开源免费具有现代化设计趋势的WPF控件库 https://wpfui.lepo.co/合集-C#(46) 1.使用C#将几个Excel文件合并去重分类2023-11-152.C#使用SqlSugar操作MySQL数据库实现简单的增删改查2023-11-163.C#中的类和继承2023-11-174.C#中的virtual和override关键字2023-......
  • 基于语音信号MFCC特征提取和GRNN神经网络的人员身份检测算法matlab仿真
    1.算法运行效果图预览    2.算法运行软件版本MATLAB2022a 3.部分核心程序P=[Dat1_wav1;Dat1_wav2;Dat2_wav1;Dat2_wav2;Dat3_wav1;Dat3_wav2;Dat4_wav1;Dat4_wav2];T=[ones(800,1);2*ones(800,1);3*ones(800,1);4*ones(800,1)];%GRNN训练net=newgrnn(......
  • MySQL进阶知识之视图、触发器、事务
    【一】MySQL进阶知识之视图【1】视图介绍(1)什么是视图视图就是通过查询得到一张虚拟表,然后保存下来,下次可以直接使用视图也是一张表在计算机科学中,视图(View)是一种虚拟表,其内容是一个或多个基本表的查询结果。视图基于数据库中的数据,通过定义查询语句来构建,并在需要时动......