82上位机VC MFC树视图节点拖拽功能
82上位机VC MFC树视图节点拖拽功能 功能展示 树状视图用于描述一些具有层次关系的数据,但有时候,没于一些原因,这此层次关系会发生改变,我们就得重新更改树状视图节点的的位置,如果能够利用鼠标拖动节点来进行修改,将会极大的简化操作,给用户节省时间我们当前例程就实现这一功能,效果如图 要点提示 当用户用鼠标拖拽树状视图节点进,会触发一个TVN_BEGINDRAG消息,我们只要处理这消息的响应函数,再结合鼠标移动及放开消息,就能够方便的实现节点的拖拽功能; 实现功能 1.新建基于对话框的应用程序 2.从CTreeCtrl类派生一个自己的定义的类class CDragTree : public CTreeCtrl;先设置派生类CDragTree的属性ModifyStyle(0,TVS_EDITLABELS|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_HASLINES,0);添加几个变量 CImageList* m_pDragImages; //拖动的图像列表 BOOL m_bDrag; //是否进行拖动 HTREEITEM m_hBeginDrag; //拖动的起点并初始化 m_pDragImages = NULL; m_bDrag = FALSE;m_hBeginDrag = NULL; 3.依次添加复制节点的自定义消息CopyNodes(), TVN_BEGINDRAG消息的响应消息OnBegindrag(),鼠标放开及移动消息OnLButtonUp(), OnMouseMove() - void CDragTree::OnMouseMove(UINT nFlags, CPoint point)
- {
- if (m_bDrag) //处于拖动状态
- {
- HTREEITEM hItem;
- UINT nHitFlags;
- CRect clientRC;
- GetClientRect(&clientRC); //获取客户区域
- m_pDragImages->DragMove(point); //设置拖动的图像位置
- //鼠标经过时高亮显示
- if( (hItem = HitTest(point, &nHitFlags)) != NULL )
- {
复制代码- CImageList::DragShowNolock(FALSE); //隐藏拖动的图像
- SelectDropTarget(hItem); //设置选中的项目
- CImageList::DragShowNolock(TRUE); //显示拖动的图像
- }
- }
- else
- CTreeCtrl::OnMouseMove(nFlags, point);
- }
- void CDragTree::OnLButtonUp(UINT nFlags, CPoint point)
- {
- if (m_bDrag) //处于拖动状态
- {
- m_bDrag = FALSE;
- CImageList::DragLeave(this); //
- CImageList::EndDrag(); //结束图像拖动
- ReleaseCapture(); //释放鼠标捕捉
- delete m_pDragImages; //释放图像列表
- m_pDragImages = NULL;
- CRect winRC;
- GetWindowRect(&winRC); //获取窗口区域
- HTREEITEM hItem;
- if((hItem = HitTest(point, &nFlags)) != NULL)
- {
- //进行拖动处理
- //如果目标项目与开始拖动的项目相同或者目标项目仍是开始项目的父节点,不进行处理
- if (m_hBeginDrag != hItem && hItem != GetParentItem(m_hBeginDrag))
- {
- CopyNodes(hItem, m_hBeginDrag); //进行节点的复制
- DeleteItem(m_hBeginDrag); //删除源节点
- }
- Invalidate();
- SelectDropTarget(NULL);
- m_hBeginDrag = NULL;
- }
- }
- }
复制代码- void CDragTree::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
- {
- NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
- HTREEITEM hItem = pNMTreeView->itemNew.hItem; //获取开始拖动的节点
- if (hItem==GetRootItem()) //不允许拖动根节点
- {
- *pResult = 0;
- return;
- }
- m_hBeginDrag = hItem; //记录开始拖动的项目
- m_pDragImages = CreateDragImage(hItem); //创建拖动的图像列表
- CPoint dragPT; //记录起始点
- dragPT.x = pNMTreeView->ptDrag.x;
- dragPT.y = pNMTreeView->ptDrag.y;
- if (m_pDragImages != NULL)
- {
- m_pDragImages->BeginDrag(0, CPoint(8, 8)); //开始拖动图像
- ClientToScreen(&dragPT); //转换客户坐标到屏幕坐标
- m_pDragImages->DragEnter(this, dragPT); //锁定窗口更新,在拖动的过程中显示拖动的图像
- SetCapture(); //开始鼠标捕捉
- m_bDrag = TRUE;
- }
- *pResult = 0;
- }
- //复制节点,将hSrcItem及其子项目复制到下hDesItem节点下
- void CDragTree::CopyNodes(HTREEITEM hDesItem, HTREEITEM hSrcItem)
- {
- if (hDesItem==NULL || hSrcItem==NULL) //验证参数
- {
- return;
- }
- TVITEM tvItem; //定义项目信息
- tvItem.mask = TVIF_TEXT|TVIF_IMAGE; //设置返回标记
- tvItem.hItem = hSrcItem;
- char chText[MAX_PATH] = {0};
- tvItem.pszText = chText;
- tvItem.cchTextMax = MAX_PATH;
-
复制代码- GetItem(&tvItem); //获取项目信息
- TVINSERTSTRUCT tvInsert; //定义插入操作的数据结构
- tvInsert.hParent = hDesItem;
- tvInsert.item = tvItem;
- HTREEITEM hInsert = InsertItem(&tvInsert); //插入项目
- HTREEITEM hChild = GetChildItem(hSrcItem); //获取子节点
- while (hChild != NULL) //遍历子节点
- {
- tvItem.mask = TVIF_TEXT|TVIF_IMAGE;
- tvItem.hItem = hChild;
- tvItem.pszText = chText;
- tvItem.cchTextMax = MAX_PATH;
- GetItem(&tvItem);
- tvInsert.hParent = hInsert;
- tvInsert.item = tvItem;
- CopyNodes(hInsert, hChild); //递归调用
- hChild = GetNextSiblingItem(hChild); //查找下一个兄弟节点
- }}
复制代码4.最后是我们自定义的类的使用:添加树状视图控件关联变量CDragTree m_Tree;添加用于设置树状控件图标的变量CImageList m_ImageList;初始化这两个变量 - m_ImageList.Create(22, 22,ILC_COLOR24|ILC_MASK, 3, 1);
- CBitmapbmp,bmp1,bmp2; bmp.LoadBitmap(IDB_BITMAP1); bmp1.LoadBitmap(IDB_BITMAP2);
- bmp2.LoadBitmap(IDB_BITMAP3);m_ImageList.Add(&bmp, RGB(255, 255, 255));
- m_ImageList.Add(&bmp1,RGB(255, 255, 255)); m_ImageList.Add(&bmp2, RGB(255, 255, 255));
- m_Tree.SetImageList(&m_ImageList,TVSIL_NORMAL);
- HTREEITEM hRoot =m_Tree.InsertItem("PLC自学编程", 0, 0);
- m_Tree.InsertItem("松下PLC", 1, 1, hRoot);
- m_Tree.InsertItem("三菱PLC", 1, 1, hRoot);
- m_Tree.InsertItem("西门子PLC", 1, 1, hRoot);
- HTREEITEM hChild= m_Tree.InsertItem("欧姆龙", 1, 1, hRoot);
- m_Tree.InsertItem("CP1H",2, 2, hChild);
- m_Tree.InsertItem("CP1E",2, 2, hChild);
- m_Tree.InsertItem("CJ1H",2, 2, hChild);
复制代码
记得添加用到的位图 我们来演示实现树状视图拖拽功能的过程
|