CTreeCtrl---树控件自绘
来源:互联网 发布:mac迅雷自带播放器 编辑:程序博客网 时间:2024/06/05 11:22
效果:
1、原理:在CTreeCtrl的派生类CMyTreeCtrl的OnPaint()函数中逐行进行绘制。
2、要点:
1)创建CTreeCtrl的派生类CMyTreeCtrl;
2)为树型控件绑定一个控件类型变量CMyTreeCtrl m_Tree;
3)设置属性has buttons、Lines at Root、border、horizontal scroll 都为TRUE;
4)导入一些必要的图标。
3、实现:
1)在主对话框的OnInitDialog()函数中:
BOOL CCTreeCtrl自绘Dlg::OnInitDialog(){CDialogEx::OnInitDialog();// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动// 执行此操作SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标m_IconList.Create(16,16,ILC_COLOR32|ILC_MASK,4,4);m_IconList.Add(AfxGetApp()->LoadIcon(IDI_DOG));m_IconList.Add(AfxGetApp()->LoadIcon(IDI_QIE));m_IconList.Add(AfxGetApp()->LoadIcon(IDI_ADD));m_IconList.Add(AfxGetApp()->LoadIcon(IDI_SUB));m_Tree.GetIconList(&m_IconList);//插入一些测试项HTREEITEM hRoot = m_Tree.InsertItemEx("第1项",0);m_Tree.InsertItemEx("第1.1项",1,hRoot);m_Tree.InsertItemEx("第1.2项",1,hRoot);HTREEITEM hItem = m_Tree.InsertItemEx("第1.3项",0,hRoot);m_Tree.InsertItemEx("第1.3.1项",1,hItem);m_Tree.InsertItemEx("第1.3.2项",1,hItem);hRoot = m_Tree.InsertItemEx("第2项",0);m_Tree.InsertItemEx("第2.1项",1,hRoot);m_Tree.InsertItemEx("第2.2项",1,hRoot);m_Tree.InsertItemEx("第2.3项",1,hRoot);m_Tree.InsertItemEx("第2.4项",1,hRoot);m_Tree.InsertItemEx("第2.5项",1,hRoot);m_Tree.InsertItemEx("第2.6项",1,hRoot);return TRUE; // 除非将焦点设置到控件,否则返回 TRUE}
2)派生类中的实现(已有详细注释)
.h文件:
#pragma once#include "map"using namespace std;// CMyTreeCtrlstruct ITEM_DATA //存放每一项的文本和Icon索引{CString strText;int nIconIndex;ITEM_DATA(){strText.Empty();nIconIndex = 0;}};class CMyTreeCtrl : public CTreeCtrl{DECLARE_DYNAMIC(CMyTreeCtrl)public:CFont m_RootFont; //根节点的字体 CFont m_ChildFont; //子结点的字体CPoint m_mouseOldPoint; //上一次鼠标所在的位置HTREEITEM m_CurMouseItem; //当前鼠标移动到的节点句柄map<HTREEITEM,ITEM_DATA*> m_mapItemData; //某一项的句柄<--->某一项对应的文本和Iconmap<HTREEITEM,ITEM_DATA*>::iterator m_iter; //对应类型的迭代器CRect m_ClientRect; //树控件客户端大小CImageList* m_pBmpList; //存放bitmapCImageList* m_pIconList; //存放ICONCImageList* GetBmpList(CImageList* pBmpList); //没用到CImageList* GetIconList(CImageList* pIconList); //得到Iconafx_msg void OnPaint();afx_msg void OnMouseMove(UINT nFlags, CPoint point);void DrawBackGround(CDC* pDC); //绘制背景void DrawItem(CDC* pDC); //绘制树控件中的每一项HTREEITEM InsertItemEx(CString strText,int nIconIndex, //插入一项数据 HTREEITEM lparent= TVI_ROOT,HTREEITEM lpFont = TVI_LAST); void DrawItemText(CDC * pDC,HTREEITEM pItem,CRect Rect);//绘制每一项的文本public:CMyTreeCtrl();virtual ~CMyTreeCtrl();protected:DECLARE_MESSAGE_MAP()public:afx_msg void OnLButtonDown(UINT nFlags, CPoint point);};
.cpp:
// MyTreeCtrl.cpp : 实现文件//#include "stdafx.h"#include "CTreeCtrl自绘.h"#include "MyTreeCtrl.h"// CMyTreeCtrlIMPLEMENT_DYNAMIC(CMyTreeCtrl, CTreeCtrl)CMyTreeCtrl::CMyTreeCtrl(){m_pBmpList = NULL;m_pIconList = NULL;m_RootFont.CreateFont(13, // nHeight0, // nWidth0, // nEscapement0, // nOrientationFW_BOLD, // nWeightFALSE, // bItalicFALSE, // bUnderline0, // cStrikeOutANSI_CHARSET, // nCharSetOUT_DEFAULT_PRECIS, // nOutPrecisionCLIP_DEFAULT_PRECIS, // nClipPrecisionPROOF_QUALITY, // nQualityDEFAULT_PITCH | FF_SWISS, // nPitchAndFamily_T("宋体") ); // lpszFacenamem_ChildFont.CreateFont(12, // nHeight0, // nWidth0, // nEscapement0, // nOrientationFW_NORMAL, // nWeightFALSE, // bItalicFALSE, // bUnderline0, // cStrikeOutANSI_CHARSET, // nCharSetOUT_DEFAULT_PRECIS, // nOutPrecisionCLIP_DEFAULT_PRECIS, // nClipPrecisionPROOF_QUALITY, // nQualityDEFAULT_PITCH | FF_SWISS, // nPitchAndFamily_T("宋体") ); // lpszFacename}CMyTreeCtrl::~CMyTreeCtrl()//释放申请的内存{m_iter = m_mapItemData.begin();while (m_iter != m_mapItemData.end()){if (m_iter->second != NULL){delete m_iter->second;m_iter->second = NULL;}++m_iter;}}BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl)ON_WM_PAINT()ON_WM_MOUSEMOVE()ON_WM_LBUTTONDOWN()END_MESSAGE_MAP()// CMyTreeCtrl 消息处理程序CImageList* CMyTreeCtrl::GetBmpList(CImageList* pBmpList){CImageList* pOldBmpList = m_pBmpList;m_pBmpList = pBmpList;return pOldBmpList;}CImageList* CMyTreeCtrl::GetIconList(CImageList* pIconList){CImageList* pOldIconList = m_pIconList;m_pIconList = pIconList;return pOldIconList;}void CMyTreeCtrl::OnPaint(){CPaintDC dc(this); // device context for paintingGetClientRect(&m_ClientRect);//创建兼容的内存DC和位图,并将位图选入到内存DCCBitmap bitmap;CDC MemeDc;MemeDc.CreateCompatibleDC(&dc);bitmap.CreateCompatibleBitmap(&dc,m_ClientRect.Width(),m_ClientRect.Height());CBitmap* pOldBmp = MemeDc.SelectObject(&bitmap);DrawBackGround(&MemeDc);//向兼容的内存DC中绘制背景DrawItem(&MemeDc); //将每一项逐个绘制到树控件上dc.BitBlt( m_ClientRect.left, m_ClientRect.top, m_ClientRect.Width(), m_ClientRect.Height(), &MemeDc, 0, 0,SRCCOPY);MemeDc.SelectObject(pOldBmp);MemeDc.DeleteDC();}void CMyTreeCtrl::DrawBackGround(CDC* pDC){pDC->FillSolidRect(m_ClientRect,RGB(143,175,156));}void CMyTreeCtrl::DrawItem(CDC* pDC){HTREEITEM hCurrentItem,hParentItem;//绘制的当前项句柄和其父句柄DWORD dTreeStyle;//树控件的类型CRect CurItemRect;//当前项的区域int CurItemState;//当前项的状态dTreeStyle =:: GetWindowLong( m_hWnd, GWL_STYLE );//获取树的类型stylehCurrentItem = GetFirstVisibleItem();//获取第一个可见的项,返回它的句柄值do { //Nonzero if the item is visible, with the bounding rectangle contained in lpRect.//Otherwise, 0 with lpRect uninitialized.if (GetItemRect(hCurrentItem,CurItemRect,1)){CurItemRect.left = CurItemRect.left-20;CRect fillRect(0,CurItemRect.top,m_ClientRect.right,CurItemRect.bottom);//Returns the state of the item specified by hItem.CurItemState = GetItemState(hCurrentItem,TVIF_STATE);//当前正绘制的项已超出窗口的边界,所以不绘制,并退出绘制if (CurItemRect.top > m_ClientRect.bottom) {break;}//当前节点没有孩子节点,才为其绘制鼠标热点if (hCurrentItem == m_CurMouseItem && ItemHasChildren(hCurrentItem) == NULL){pDC->FillSolidRect(&fillRect,GetSysColor(COLOR_HIGHLIGHTTEXT));}if(CurItemState & TVIS_SELECTED)//当前项的状态有被选中这个状态{pDC->FillSolidRect(&fillRect,GetSysColor(COLOR_HIGHLIGHT));fillRect.DeflateRect(-1,-1);pDC->DrawFocusRect(&fillRect);}//绘制展开图标if (ItemHasChildren(hCurrentItem)){CPoint point;point.x = CurItemRect.left;//x值最左point.y = CurItemRect.top+(CurItemRect.Height()-16)/2;//y值居中if (CurItemState & TVIS_EXPANDED)//当前项展开m_pIconList->Draw(pDC,3,point,ILD_TRANSPARENT);else//当前项没展开m_pIconList->Draw(pDC,2,point,ILD_TRANSPARENT);}//绘制文字前面的图标CurItemRect.left += 16+2;//返回值是map的迭代器m_iter = m_mapItemData.find(hCurrentItem);int nIconIndex = m_iter->second->nIconIndex;m_pIconList->Draw(pDC,nIconIndex,CurItemRect.TopLeft(),ILD_NORMAL);//绘制文字CurItemRect.left += 16+2;CurItemRect.right = m_ClientRect.right;DrawItemText(pDC,hCurrentItem,CurItemRect);}} while ((hCurrentItem = GetNextVisibleItem(hCurrentItem)) != NULL);}HTREEITEM CMyTreeCtrl::InsertItemEx(CString strText,int nIconIndex,HTREEITEM lparent,HTREEITEM lpFont){HTREEITEM hTempTreeItem;hTempTreeItem = InsertItem(strText,lparent,lpFont);ITEM_DATA* pItemData = new ITEM_DATA;pItemData->strText = strText;pItemData->nIconIndex = nIconIndex;//m_mapItemData.insert(make_pair(hTempTreeItem,pItemData));m_mapItemData.insert(pair<HTREEITEM,ITEM_DATA*>(hTempTreeItem,pItemData));return hTempTreeItem;}void CMyTreeCtrl::OnMouseMove(UINT nFlags, CPoint point){m_mouseOldPoint = point;HTREEITEM hItem = HitTest(point);//判断鼠标在控件的哪一项上面if (hItem != NULL && m_CurMouseItem != hItem){m_CurMouseItem = hItem;Invalidate(FALSE);}CTreeCtrl::OnMouseMove(nFlags, point);}void CMyTreeCtrl::DrawItemText(CDC * pDC,HTREEITEM pItem,CRect Rect){if (GetParentItem(pItem) == NULL)//如果是最顶级节点{pDC->SelectObject(&m_RootFont);pDC->SetTextColor(0x000000);}else{if (ItemHasChildren(pItem))//有孩子节点{pDC->SelectObject(&m_RootFont);}else//没孩子节点{pDC->SelectObject(&m_ChildFont);}pDC->SetTextColor(0x000066);}CString ItemText = GetItemText(pItem);CSize fontSize;fontSize= pDC->GetTextExtent(ItemText);//返回字体的尺寸//让文字显示在矩形垂直的中间位置int middPos;middPos=(Rect.Height()-fontSize.cy)/2;Rect.top += middPos;pDC->SetBkMode(TRANSPARENT);pDC->DrawText(ItemText,Rect,DT_LEFT|DT_TOP);//显示项文本}void CMyTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point){/*HTREEITEM hItem = HitTest(point);int nItemState = GetItemState(hItem,TVIF_STATE);if (hItem != NULL && ItemHasChildren(hItem) != 0){if (nItemState & TVIS_EXPANDED){SetItemState(hItem,GetItemState(hItem,TVIF_STATE) & ~TVIS_EXPANDED,TVIF_STATE);} else{SetItemState(hItem,GetItemState(hItem,TVIF_STATE) || TVIS_EXPANDED,TVIF_STATE);}}*///Invalidate(FALSE);CTreeCtrl::OnLButtonDown(nFlags, point);}
阅读全文
0 0
- CTreeCtrl---树控件自绘
- 【MFC】控件自绘之CTreeCtrl
- 自绘CTreeCtrl控件,添加按钮功能,模仿360界面
- MFC常用控件CListCtrl 、CSliderCtrl、CToolTipCtrl、CTreeCtrl的自绘
- MFC常用控件CListCtrl 、CSliderCtrl、CToolTipCtrl、CTreeCtrl的自绘
- MFC常用控件CListCtrl、CSliderCtrl、CToolTipCtrl、CTreeCtrl的自绘
- CTreeCtrl 自绘
- CTreeCtrl自绘
- "-"树视图(CTreeCtrl)控件
- CTreeCtrl 树控件使用方法总结
- CTreeCtrl控件
- CTreeCtrl控件
- MFC控件之树型控件CTreeCtrl
- 一步一步教你实现CTreeCtrl 自绘
- 一步一步教你实现CTreeCtrl 自绘
- 一步一步教你实现CTreeCtrl 自绘
- 一步一步教你实现CTreeCtrl 自绘
- 一步一步教你实现CTreeCtrl 自绘
- 国际产品经理资格认证NPDP 2017
- 研究 PHP opcode 是如何优化的
- 关于chrome主页被捆绑问题
- 矩阵的各种乘积
- 前端性能优化:客户端从输入到展示讲解
- CTreeCtrl---树控件自绘
- windows下C++中相对路径与绝对路径 文件路径
- impala 不可轻易更换列类型
- 清华大学C++程序设计基础课程学习笔记
- 利用python库在局域网内传输文件
- 异步调度quartz
- springmvc配置MappingJackson2HttpMessageConverter实现属性驼峰和下划线的转换
- python 列表、字典、集合解析
- QT4.8