zoukankan      html  css  js  c++  java
  • (转载)VS2010/MFC编程入门之三十一(常用控件:树形控件Tree Control 下)

     前面一节讲了树形控件Tree Control的简介、通知消息以及相关数据结构,本节继续讲下半部分,包括树形控件的创建、CTreeCtrl类的主要成员函数和应用实例。

           树形控件的创建

           MFC为树形控件提供了CTreeCtrl类,它封装了树形控件的所有操作。

           树形控件的创建也是有两种方式,一种是在对话框模板中直接拖入Tree Control控件创建,另一种就是通过CTreeCtrl类的Create成员函数创建。下面主要讲后者。

           CTreeCtrl类的Create成员函数的原型如下:

           virtual BOOL Create(
                  DWORD dwStyle,
                  const RECT& rect,
                  CWnd* pParentWnd,
                  UINT nID 
           );

           此函数的原型与前面讲到的所有控件类的Create函数都类似。dwStyle指定树形控件风格的组合,rect指定树形控件窗口的位置和大小,pParentWnd为指向树形控件父窗口的指针,nID指定树形控件的ID。下面还是主要讲讲树形控件的主要风格以及含义。

           TVS_DISABLEDRAGDROP:禁止树形控件发送TVN_BEGINDRAG通知消息,即不支持拖动操作
           TVS_EDITLABELS:用户可以编辑节点的标签文本
           TVS_HASBUTTONS:显示带有"+"或"-"的小方框来表示某项能否被展开或已展开
           TVS_HASLINES:在父节点与子节点间连线以更清晰地显示树的结构
           TVS_LINESATROOT:在根节点处连线
           TVS_SHOWSELALWAYS:即使控件失去输入焦点,仍显示出项的选择状态

           同样,动态创建树形控件时,除了能够指定上述风格的组合外,一般还要指定WS_CHILD和WS_VISIBLE风格。

           在对话框模板中直接拖入Tree Control创建树形控件时,可以在树形控件的属性页中设置其风格,与上面的风格是对应的,例如,属性Has Lines对应的就是TVS_HASLINES风格。

           CTreeCtrl类的主要成员函数

           CImageList* SetImageList(CImageList * pImageList,int nImageListType);

           如果树节点需要显示图标时,则必须先创建一个CImageList类的对象,并为其添加多个图像组成一个图像序列,然后调用SetImageList函数为树形控件设置图像序列,在用InsertItem插入节点时传入所需图像在图像序列中的索引即可。后面的例子中会演示。参数pImageList为指向图像序列类CImageList的对象的指针,若为NULL则删除树形控件的所有图像。参数nImageListType指定图像序列的类型,可以是TVSIL_NORMAL(普通图像序列)或TVSIL_STATE(状态图像序列,用图像表示节点的状态)。

           UINT GetCount( ) const;

           获取树形控件中节点的数量。

           DWORD_PTR GetItemData(HTREEITEM hItem) const;

           获取树形控件中某个指定节点的附加32位数据。参数hItem为指定的树节点的句柄。

           BOOL SetItemData(HTREEITEM hItem,DWORD_PTR dwData);

           为树形控件中某个指定节点设置附加的32位数据。参数hItem同上,dwData为要设置的32位数据。

           CString GetItemText(HTREEITEM hItem) const;

           获取树形控件中某个指定节点的标签文本。参数hItem同上。返回值是包含标签文本的字符串。

           BOOL SetItemText(HTREEITEM hItem,LPCTSTR lpszItem);

           为树形控件中某个指定节点设置标签文本。参数hItem同上,lpszItem为包含标签文本的字符串的指针。

           HTREEITEM GetNextSiblingItem(HTREEITEM hItem) const;

           获取树形控件中某个指定节点的下一个兄弟节点。参数hItem同上。返回值是下一个兄弟节点的句柄。

           HTREEITEM GetPrevSiblingItem(HTREEITEM hItem) const;

           获取树形控件中某个指定节点的上一个兄弟节点。参数hItem同上。返回值是上一个兄弟节点的句柄。

           HTREEITEM GetParentItem(HTREEITEM hItem) const;

           获取树形控件中某个指定节点的父节点。参数hItem同上。返回值是父节点的句柄。

           HTREEITEM GetRootItem( ) const;

           获取树形控件根节点的句柄。

           HTREEITEM GetSelectedItem( ) const;

           获取树形控件当前选中节点的句柄。

           BOOL DeleteAllItems( );

           删除树形控件中的所有节点。删除成功则返回TRUE,否则返回FALSE。

           BOOL DeleteItem(HTREEITEM hItem);

           删除树形控件中的某个节点。参数hItem为要删除的节点的句柄。删除成功则返回TRUE,否则返回FALSE。

           HTREEITEM InsertItem(LPCTSTR lpszItem,int nImage,int nSelectedImage,HTREEITEM hParent = TVI_ROOT,HTREEITEM hInsertAfter = TVI_LAST);

           在树形控件中插入一个新节点。参数lpszItem为新节点的标签文本字符串的指针,参数nImage为新节点的图标在树形控件图像序列中的索引,参数nSelectedImage为新节点被选中时的图标在图像序列中的索引,参数hParent为插入节点的父节点的句柄,参数hInsertAfter为新节点的前一个节点的句柄,即新节点将被插入到hInsertAfter节点之后。

           BOOL SelectItem(HTREEITEM hItem);

           选中指定的树节点。参数hItem为要选择的节点的句柄。若成功则返回TRUE,否则返回FALSE。

           树形控件的应用实例

           最后鸡啄米还是给大家写一个简单的实例,说明CListCtrl类的几个成员函数及树形控件通知消息等的使用方法。

           此实例实现的功能:在一个树形控件中显示鸡啄米网站的简单结构分层,共有三层,分别为鸡啄米网站、各个分类和文章。用鼠标左键单击改变选中节点后,将选中节点的文本显示到编辑框中。另外,还要实现一个常见的效果,就是鼠标划过除根节点外的某个树节点时,显示相应的Tip提示信息。下面是具体实现步骤:

           1. 创建一个基于对话框的MFC工程,名称设置为“Example31”。

           2. 在自动生成的对话框模板IDD_EXAMPLE31_DIALOG中,删除“TODO: Place dialog controls here.”静态文本框、“OK”按钮和“Cancel”按钮。添加一个Tree Control控件,ID设置为IDC_WEB_TREE,属性Has Buttons、Has Lines和Lines At Root都设为True,为了在鼠标划过某个节点时显示提示信息还需要将Info Tip属性设为True。再添加一个静态文本框和一个编辑框,静态文本框的Caption属性设为“您选择的节点:”,编辑框的ID设为IDC_ITEM_SEL_EDIT,Read Only属性设为True。此时的对话框模板如下图:

    树形控件对话框模板

           3. 导入需要为树形控件的节点添加的图标。鸡啄米在这里找了三个32x32的Icon图标,保存到工程的res目录下。然后在Resource View资源视图中,右键点击Icon节点,在右键菜单中选择“Add Resource...”,弹出“Add Resource”对话框,再从左边“Resource type”列表中选择“Icon”,点击右边的“Import...”按钮,就可以选择三个图标文件进行导入了。导入成功后,分别修改它们ID为IDI_WEB_ICON、IDI_CATALOG_ICON和IDI_ARTICLE_ICON。

           4. 为树形控件IDC_WEB_TREE添加CTreeCtrl类型的控件变量m_webTree。并在Example31Dlg.h文件中为CExample31Dlg类添加成员对象:CImageList m_imageList;。

           5. 在对话框初始化时,我们在树形控件中添加鸡啄米网站的树形结构,那么需要修改CExample31Dlg::OnInitDialog()函数为:

    C++代码
    1. BOOL CExample31Dlg::OnInitDialog()   
    2. {   
    3.     CDialogEx::OnInitDialog();   
    4.          ......略   
    5.   
    6.     // TODO: Add extra initialization here   
    7.     HICON hIcon[3];      // 图标句柄数组   
    8.     HTREEITEM hRoot;     // 树的根节点的句柄   
    9.     HTREEITEM hCataItem; // 可表示任一分类节点的句柄   
    10.     HTREEITEM hArtItem;  // 可表示任一文章节点的句柄   
    11.   
    12.     // 加载三个图标,并将它们的句柄保存到数组   
    13.     hIcon[0] = theApp.LoadIcon(IDI_WEB_ICON);   
    14.     hIcon[1] = theApp.LoadIcon(IDI_CATALOG_ICON);   
    15.     hIcon[2] = theApp.LoadIcon(IDI_ARTICLE_ICON);   
    16.   
    17.     // 创建图像序列CImageList对象   
    18.     m_imageList.Create(32, 32, ILC_COLOR32, 3, 3);   
    19.     // 将三个图标添加到图像序列   
    20.     for (int i=0; i<3; i++)   
    21.     {   
    22.         m_imageList.Add(hIcon[i]);   
    23.     }   
    24.   
    25.     // 为树形控件设置图像序列   
    26.     m_webTree.SetImageList(&m_imageList, TVSIL_NORMAL);   
    27.   
    28.     // 插入根节点   
    29.     hRoot = m_webTree.InsertItem(_T("鸡啄米"), 0, 0);   
    30.     // 在根节点下插入子节点   
    31.     hCataItem = m_webTree.InsertItem(_T("IT互联网"), 1, 1, hRoot, TVI_LAST);   
    32.     // 为“IT互联网”节点添加附加的编号数据,在鼠标划过该节点时显示   
    33.     m_webTree.SetItemData(hCataItem, 1);   
    34.     // 在“IT互联网”节点下插入子节点   
    35.     hArtItem = m_webTree.InsertItem(_T("百度文章1"), 2, 2, hCataItem, TVI_LAST);   
    36.     // 为“百度文章1”节点添加附加的编号数据,在鼠标划过该节点时显示   
    37.     m_webTree.SetItemData(hArtItem, 2);   
    38.     // 在“IT互联网”节点下插入另一子节点   
    39.     hArtItem = m_webTree.InsertItem(_T("谷歌文章2"), 2, 2, hCataItem, TVI_LAST);   
    40.     // 为“谷歌文章2”节点添加附加的编号数据,在鼠标划过该节点时显示   
    41.     m_webTree.SetItemData(hArtItem, 3);   
    42.     // 在根节点下插入第二个子节点   
    43.     hCataItem = m_webTree.InsertItem(_T("数码生活"), 1, 1, hRoot, TVI_LAST);   
    44.     // 为“数码生活”节点添加附加的编号数据,在鼠标划过该节点时显示   
    45.     m_webTree.SetItemData(hCataItem, 4);   
    46.     // 在“数码生活”节点下插入子节点   
    47.     hArtItem = m_webTree.InsertItem(_T("智能手机文章1"), 2, 2, hCataItem, TVI_LAST);   
    48.     // 为“智能手机文章1”节点添加附加的编号数据,在鼠标划过该节点时显示   
    49.     m_webTree.SetItemData(hArtItem, 5);   
    50.     // 在“数码生活”节点下插入另一子节点   
    51.     hArtItem = m_webTree.InsertItem(_T("平板电脑文章2"), 2, 2, hCataItem, TVI_LAST);   
    52.     // 为“平板电脑文章2”节点添加附加的编号数据,在鼠标划过该节点时显示   
    53.     m_webTree.SetItemData(hArtItem, 6);   
    54.     // 在根节点下插入第三个子节点   
    55.     hCataItem = m_webTree.InsertItem(_T("软件开发"), 1, 1, hRoot, TVI_LAST);   
    56.     // 为“软件开发”节点添加附加的编号数据,在鼠标划过该节点时显示   
    57.     m_webTree.SetItemData(hCataItem, 7);   
    58.     // 在“软件开发”节点下插入子节点   
    59.     hArtItem = m_webTree.InsertItem(_T("C++编程入门系列1"), 2, 2, hCataItem, TVI_LAST);   
    60.     // 为“C++编程入门系列1”节点添加附加的编号数据,在鼠标划过该节点时显示   
    61.     m_webTree.SetItemData(hArtItem, 8);   
    62.     // 在“软件开发”节点下插入另一子节点   
    63.     hArtItem = m_webTree.InsertItem(_T("VS2010/MFC编程入门2"), 2, 2, hCataItem, TVI_LAST);   
    64.     // 为“VS2010/MFC编程入门2”节点添加附加的编号数据,在鼠标划过该节点时显示   
    65.     m_webTree.SetItemData(hArtItem, 9);   
    66.     // 在根节点下插入第四个子节点   
    67.     hCataItem = m_webTree.InsertItem(_T("娱乐休闲"), 1, 1, hRoot, TVI_LAST);   
    68.     // 为“娱乐休闲”节点添加附加的编号数据,在鼠标划过该节点时显示   
    69.     m_webTree.SetItemData(hCataItem, 10);   
    70.     // 在“娱乐休闲”节点下插入子节点   
    71.     hArtItem = m_webTree.InsertItem(_T("玛雅文明文章1"), 2, 2, hCataItem, TVI_LAST);   
    72.     // 为“玛雅文明文章1”节点添加附加的编号数据,在鼠标划过该节点时显示   
    73.     m_webTree.SetItemData(hArtItem, 11);   
    74.     // 在“娱乐休闲”节点下插入另一子节点   
    75.     hArtItem = m_webTree.InsertItem(_T("IT笑话2"), 2, 2, hCataItem, TVI_LAST);   
    76.     // 为“IT笑话2”节点添加附加的编号数据,在鼠标划过该节点时显示   
    77.     m_webTree.SetItemData(hArtItem, 12);   
    78.   
    79.     return TRUE;  // return TRUE  unless you set the focus to a control   
    80. }  

           6. 我们希望在选中节点改变时,将最新的选择项实时显示到编辑框中,那么可以响应TVN_SELCHANGED通知消息。为树形控件IDC_WEB_TREE的通知消息TVN_SELCHANGED添加消息处理函数CExample31Dlg::OnTvnSelchangedWebTree,并修改函数体如下:

    C++代码
    1. void CExample31Dlg::OnTvnSelchangedWebTree(NMHDR *pNMHDR, LRESULT *pResult)   
    2. {   
    3.     LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);   
    4.     // TODO: Add your control notification handler code here   
    5.     *pResult = 0;   
    6.   
    7.     CString strText; // 树节点的标签文本字符串   
    8.        
    9.     // 获取当前选中节点的句柄   
    10.     HTREEITEM hItem = m_webTree.GetSelectedItem();   
    11.     // 获取选中节点的标签文本字符串   
    12.     strText = m_webTree.GetItemText(hItem);   
    13.     // 将字符串显示到编辑框中   
    14.     SetDlgItemText(IDC_ITEM_SEL_EDIT, strText);   
    15. }  

           7. 还有一个功能需要实现,那就是鼠标划过除根节点外的某个树节点时,显示相应的Tip提示信息,本实例中提示信息为节点的编号。这需要响应TVN_GETINFOTIP通知消息。为树形控件IDC_WEB_TREE的通知消息TVN_GETINFOTIP添加消息处理函数CExample31Dlg::OnTvnGetInfoTipWebTree,并修改函数体如下:

    C++代码
    1. void CExample31Dlg::OnTvnGetInfoTipWebTree(NMHDR *pNMHDR, LRESULT *pResult)   
    2. {   
    3.     LPNMTVGETINFOTIP pGetInfoTip = reinterpret_cast<LPNMTVGETINFOTIP>(pNMHDR);   
    4.     // TODO: Add your control notification handler code here   
    5.     *pResult = 0;   
    6.     NMTVGETINFOTIP* pTVTipInfo = (NMTVGETINFOTIP*)pNMHDR;   // 将传入的pNMHDR转换为NMTVGETINFOTIP指针类型   
    7.     HTREEITEM hRoot = m_webTree.GetRootItem();      // 获取树的根节点  
    8.     CString strText;     // 每个树节点的提示信息   
    9.   
    10.     if (pTVTipInfo->hItem == hRoot)   
    11.     {   
    12.         // 如果鼠标划过的节点是根节点,则提示信息为空   
    13.         strText = _T("");   
    14.     }   
    15.     else  
    16.     {   
    17.         // 如果鼠标划过的节点不是根节点,则将该节点的附加32位数据格式化为字符串  
    18.         strText.Format(_T("%d"), pTVTipInfo->lParam);   
    19.     }   
    20.   
    21.     // 将strText字符串拷贝到pTVTipInfo结构体变量的pszText成员中,这样就能显示内容为strText的提示信息   
    22.     wcscpy(pTVTipInfo->pszText, strText);   
    23. }  

           8. 运行程序,弹出结果对话框。效果如下图:

    树形控件效果图

           树形控件的知识就讲到这里了,相比之前的控件可能稍有复杂。不过用的多了,就会觉得得心应手了。鸡啄米欢迎大家继续关注后面的VS2010/MFC编程入门教程。

    原文地址:http://www.jizhuomi.com/software/203.html

  • 相关阅读:
    Educational Codeforces Round 85 D. Minimum Euler Cycle(模拟/数学/图)
    Educational Codeforces Round 85 C. Circle of Monsters(贪心)
    NOIP 2017 提高组 DAY1 T1小凯的疑惑(二元一次不定方程)
    Educational Codeforces Round 85 B. Middle Class(排序/贪心/水题)
    Educational Codeforces Round 85 A. Level Statistics(水题)
    IOS中的三大事件
    用Quartz 2D画小黄人
    strong、weak、copy、assign 在命名属性时候怎么用
    用代码生成UINavigationController 与UITabBarController相结合的简单QQ框架(部分)
    Attempting to badge the application icon but haven't received permission from the user to badge the application错误解决办法
  • 原文地址:https://www.cnblogs.com/wodehao0808/p/6758514.html
Copyright © 2011-2022 走看看