首    页 界面/窗口 网络/通讯 数据库 组件开发 图像/多媒体 NET/Web 其它技术 源码下载 资料下载 软件共享 软件外包 曲艺杂谈
栏目导航:  首    页  |  界面/窗口  |  树型控件   


TreeCtrl的使用和一个CTreeCtrl的派生类


原作者:SammyLan    源出处:CSDN    发布者:施昌权    发布类型:转载    发布日期:2008-10-13

                     

    1.树视图风格:

    TVS_HASBUTTONS;  //在父项旁边显示(+)(-)

    TVS_HASLINES;   //使用线条显示各项之间的层次

    TVS_LINESATROOT;//使用线条链接树视图控件根部各项

    2.处理单击事件:TVN_SELCHANGED

    void CTreeCtrlDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)

    {

        LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

        // TODO: 在此添加控件通知处理程序代码

        HTREEITEM ht=m_treeCtrl.GetSelectedItem();

        CString strSelect=m_treeCtrl.GetItemText(ht);

        m_strTreeVal=strSelect;

        UpdateData(FALSE);

        *pResult = 0;

    }

    3.同时让自己派生的CMyTreeCtrl类和对话框处理TVN_SELCHANGED消息:

    只须在CMyTreeCtrl中处理以下消息,并返回FALSEOKON_NOTIFY_REFLECT_EX(TVN_SELCHANGED, OnTvnSelchanged) OnTvnSelchanged的签名如下

    BOOL CMyTreeCtrl::OnTvnSelchanged(NMHDR *pNMHDR,LRESULT *pResult)

 

    4.编辑标签:要允许编辑树视图控件中的文本,可以设置以下三个步骤

        1.设置树视图的TVS_EDITLABELS风格

        TVS_EDITLABE可以通过资源编辑框内部修改(Edit labels),也可以用代码的方式修改,如下

        long lStyle=::GetWindowLong(m_treeCtrl.GetSafeHwnd(),GWL_STYLE);

        lStyle|=TVS_EDITLABELS;

        ::SetWindowLong(m_treeCtrl.GetSafeHwnd(),GWL_STYLE,lStyle)

        2.处理TVN_BEGINLABELEDIT通知消息

         //设置相关限制,如限制编辑框字符串长度

        CEdit*pEdit=GetEditControl();   //获取当前选中结点编辑框

        ASSERT(pEdit);

        if (pEdit)

        {

            pEdit->LimitText(15);//设置编辑框文本长度为15个字符串

            *pResult = 0;      

        }

        3.处理TVN_ENDLABLEEDIT通知消息

        HTREEITEM hParent=GetParentItem(pTVDispInfo->item.hItem); //获取父结点 

        HTREEITEM hChild=GetChildItem(hParent?hParent:TVI_ROOT); //获取第一个根结点

        hChild=GetNextSiblingItem(hChild);          //获取下一个兄弟节点

        if (pTVDispInfo->item.hItem!=hChild)        //判断是否与当前节点相同

            pTVDispInfo->item.pszText                   //获取当前节点的字符串

        CString strText=GetItemText(hChild);        //获取节点的字符串

 

    3.让树视图处理EscEnter

    重载PreTranslateMessage函数

    BOOL bHandleMsg=FALSE;

    switch(pMsg->message) {

        case VK_ESCAPE:

        case VK_RETURN:

            if (::GetKeyState(VK_CONTROL)&0x8000)

            {

                break;

            }

            if (GetEditControl())

            {

                ::TranslateMessage(pMsg);

                ::DispatchMessage(pMsg);

                bHandleMsg=TRUE;

            }

            break;

        }

    4.实现上下文菜单

    在WM_RBUTTONDOWN消息处理函数上实现上下文菜单

    5.展开和收起树视图结点:

    HTREEITEM hItem=GetRootItem();              //获取根结点,可能会有多个根结点

    ItemHasChildren(hParent)                    //判断结点是否有孩子结点

    hItem=GetChildItem(hParent);                //获取第一个子结点

    hItem=GetNextSiblingItem(hItem));           //获取下一个兄弟结点结点

    Expand(hItem,bExpand?TVE_EXPAND:TVE_COLLAPSE);//展开/叠起结点

    Select(hItem,TVGN_FIRSTVISIBLE);                //设置选中结点

    CString str=GetItemText(hChild);            //获取结点字符串信息

    HTREEITEM hCurrSel = GetSelectedItem();     //获取当前选中结点

    SelectItem(hNewSel);

    HTREEITEM hNewSel = HitTest(pt, &nFlags);       //判断坐标是否在当前结点范围内

    HTREEITEM hItem=InsertItem(dlg.m_strItemText,hItemParent);  //插入结点

    #pragma once 

    //定义文件MyTreeCtrl.h

    // CMyTreeCtrl 

    class CMyTreeCtrl : public CTreeCtrl

    {

        DECLARE_DYNAMIC(CMyTreeCtrl)

    public:

        CMyTreeCtrl();

        virtual ~CMyTreeCtrl();

    protected:

        DECLARE_MESSAGE_MAP()

        void ExpandBranch(HTREEITEM hItem,BOOL bExpand =TRUE);

    public:

        void ExpandAllBranches(BOOL bExpand =TRUE);

        BOOL DoesItemExist(HTREEITEM hItemParent, CString const& strItem);

        afx_msg void OnRButtonDown(UINT nFlags, CPoint point);

        afx_msg void OnAddItem();

        virtual BOOL PreTranslateMessage(MSG* pMsg);

        afx_msg void OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult);

        afx_msg void OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult);  

        afx_msg BOOL OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult);

    }; 

    // MyTreeCtrl.cpp : 实现文件

    // 

    #include "stdafx.h"

    #include "TreeCtrl.h"

    #include "MyTreeCtrl.h"

    #include ".\mytreectrl.h"

    #include "AddItemDlg.h"  

    // CMyTreeCtrl 

    IMPLEMENT_DYNAMIC(CMyTreeCtrl, CTreeCtrl)

    CMyTreeCtrl::CMyTreeCtrl()

    {

    } 

    CMyTreeCtrl::~CMyTreeCtrl()

    {

    } 

    BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl)

        ON_WM_RBUTTONDOWN()

        ON_COMMAND(IDR_ADD_ITEM, OnAddItem)

        ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnTvnEndlabeledit)

        ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnTvnBeginlabeledit)

        ON_NOTIFY_REFLECT_EX(TVN_SELCHANGED, OnTvnSelchanged)

    END_MESSAGE_MAP()

    // CMyTreeCtrl 消息处理程序

    void CMyTreeCtrl::ExpandBranch(HTREEITEM hItem,BOOL bExpand /* =TRUE */)

    //展开

    {

        if (ItemHasChildren(hItem))  //判断是否有孩子结点

        {

            Expand(hItem,bExpand?TVE_EXPAND:TVE_COLLAPSE);

            //展开/叠起结点

            hItem=GetChildItem(hItem);//获取第一个子结点

            do {

                ExpandBranch(hItem);

            } while(hItem=GetNextSiblingItem(hItem));//获取兄弟结点

        }

    }

    void CMyTreeCtrl::ExpandAllBranches(BOOL bExpand /* =TRUE */)

    {

        HTREEITEM hItem=GetRootItem();//获取根结点,可能会有多个根结点

        do {

            ExpandBranch(hItem,bExpand);

        } while(hItem=GetNextSiblingItem(hItem));

        Select(hItem,TVGN_FIRSTVISIBLE);//设置选中结点

    } 

    BOOL CMyTreeCtrl::DoesItemExist(HTREEITEM hItemParent,CString const& strItem)

    {

        BOOL bDoesItemExist=FALSE;

        ASSERT(strItem.GetLength()); 

        HTREEITEM hChild=GetChildItem(hItemParent?hItemParent:TVI_ROOT);

        while (NULL!=hChild&&!bDoesItemExist)

        {

            CString str=GetItemText(hChild);//获取结点字符串信息

            if (0==str.CompareNoCase(strItem))

            {

                bDoesItemExist=TRUE;

            }

            else

            {

                hChild=GetNextSiblingItem(hChild);

            }

        }

        return bDoesItemExist;

    } 

    void CMyTreeCtrl::OnRButtonDown(UINT nFlags, CPoint point)

    {

        // TODO: 在此添加消息处理程序代码和/或调用默认值   

        // set focus to the tree control

        SetFocus(); 

        // map the point that is passed to the

        // function from client coordinates

        // to screen coordinates

        ClientToScreen(&point); 

        // Get the currently selected item

        HTREEITEM hCurrSel = GetSelectedItem();//获取当前选中结点

        // Figure out which item was right clicked

        CPoint pt(0, 0);

        ::GetCursorPos(&pt);

        ScreenToClient (&pt);

        HTREEITEM hNewSel = HitTest(pt, &nFlags);

        // Set the selection to the item that the

        // mouse was over when the user right

        // clicked

        if (NULL == hNewSel)

        {

            SelectItem(NULL);

        }

        else if (hCurrSel != hNewSel)

        {

           SelectItem(hNewSel);

            SetFocus();

        } 

        // Load the context menu

       CMenu Menu;

        if (Menu.LoadMenu(IDM_CONTEXT_MENU))

       {

            CMenu* pSubMenu = Menu.GetSubMenu(0);

            if (pSubMenu!=NULL)

            {

                // Display the context menu

               pSubMenu->TrackPopupMenu(

                    TPM_LEFTALIGN | TPM_RIGHTBUTTON,

                    point.x, point.y, this);

            }

        }  

    } 

    void CMyTreeCtrl::OnAddItem()

    //添加上下文菜单

    {

        // TODO: 在此添加命令处理程序代码

        HTREEITEM hItemParent=GetSelectedItem();

        //获取当前选中结点 

        CAddItemDlg dlg;

       if (dlg.DoModal()==IDOK)

        {

            if (!DoesItemExist(hItemParent,dlg.m_strItemText))

            {

                HTREEITEM hItem=InsertItem(dlg.m_strItemText,hItemParent);

                //插入结点

                SelectItem(hItem);

            }

            else

            {

                AfxMessageBox("已存在相同结点");

            }

        }   

    } 

    BOOL CMyTreeCtrl::PreTranslateMessage(MSG* pMsg)

    {

        // TODO: 在此添加专用代码和/或调用基类

        BOOL bHandledMsg = FALSE;

        switch (pMsg->message)

        {

            case WM_KEYDOWN:

            {

                switch (pMsg->wParam)

                {

                    case VK_ESCAPE:

                    case VK_RETURN:   

                    if (::GetKeyState(VK_CONTROL) & 0x8000)

                    {

                        break;

                    } 

                    if (GetEditControl())

                    {

                        ::TranslateMessage(pMsg);

                        ::DispatchMessage(pMsg);

                        bHandledMsg = TRUE;

                    } 

                    break;

                    default:
                       break;

                } // switch (pMsg->wParam)

        } // WM_KEYDOWN

        break;

       default: break;

        } // switch (pMsg->message)                   

        // continue normal translation and dispatching             

        return (bHandledMsg ?TRUE : CTreeCtrl::PreTranslateMessage(pMsg)); 

    }

    void CMyTreeCtrl::OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult)

    {

        LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);

        // TODO: 在此添加控件通知处理程序代码

       *pResult=1;

        CEdit*pEdit=GetEditControl();

        ASSERT(pEdit);

        if (pEdit)

        {

            pEdit->LimitText(15);

            *pResult=0;

        }  

    }

    void CMyTreeCtrl::OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult)

    {

        LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);

        // TODO: 在此添加控件通知处理程序代码

        BOOL bValidItem=FALSE; 

        CString strItem=pTVDispInfo->item.pszText;

        if (0<strItem.GetLength())

        {

            HTREEITEM hParent=GetParentItem(pTVDispInfo->item.hItem);

            bValidItem=!DoesItemExist(hParent,strItem);    

        }

        *pResult = bValidItem;

    }

    BOOL CMyTreeCtrl::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)

    {

        LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

       // TODO: 在此添加控件通知处理程序代码

        TRACE(GetItemText(pNMTreeView->itemNew.hItem));

        TRACE("\n");

        *pResult = 0;

        return FALSE;       //返回FALSE可以让父窗口进行进一步的处理

    }

 

关于我们 版权声明 广告服务 联系我们 友情链接 加入收藏
站长:施昌权    Email:scq2099yt@163.com    MSN:scq2099yt@live.cn    QQ:14046300    本站QQ群:67202409
Copyright © 2008     卓为VC(www.joyvc.cn)    All Rights Reserved    建议分辨率 1024×768
本站由施昌权制作维护
京ICP备09012297号