当用户开始拖动CTreeCtrl中的一个节点时,将发送消息TVN_BEGINDRAG(左键拖动)或TVN_BEGINRDRAG(右键拖动)到父窗口,然后是响应WM_MOVE消息,最后当松开鼠标时,停止拖动操作,整个过程就是这样。主要涉及到以下几个消息:TVN_BEGINDRAG或TVN_BEGINRDRAG,WM_MOUSEMOVE,WM_LBUTTONUP或WM_RBUTTONUP,分别对应处理函数如下:
void CLayerMgrTreeCtrl::OnDrag(NMHDR *pNMHDR, LRESULT *pResult) { //hBeforeDrag为开始拖动时鼠标拖动的节点句柄 hBeforeDrag = ((LPNMTREEVIEW)pNMHDR)->itemOld.hItem; Main_OnBeginDrag(m_hWnd, (LPNMTREEVIEW)pNMHDR); } void CLayerMgrTreeCtrl::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 Main_OnMouseMove(::GetParent(m_hWnd), m_hWnd, point.x, point.y); CTreeCtrl::OnMouseMove(nFlags, point); } void CLayerMgrTreeCtrl::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (g_fDragging) { //拖放结束 ImageList_EndDrag(); ShowCursor(TRUE); g_fDragging = FALSE; } return; } // Main_OnBeginDrag - begins dragging an item in a tree-view control. // hwndTV - handle to the image list. // lpnmtv - address of information about the item being dragged. void CLayerMgrTreeCtrl::Main_OnBeginDrag(HWND hwndTV, LPNMTREEVIEW lpnmtv) { HIMAGELIST himl; // handle to image list RECT rcItem; // bounding rectangle of item DWORD dwLevel; // heading level of item DWORD dwIndent; // amount that child items are indented TVHITTESTINFO tvht; tvht.pt.x = lpnmtv->ptDrag.x; tvht.pt.y = lpnmtv->ptDrag.y; hBeforeDrag = TreeView_HitTest(hwndTV, &tvht); // Tell the tree-view control to create an image to use // for dragging. himl = TreeView_CreateDragImage(hwndTV, lpnmtv->itemNew.hItem); // Get the bounding rectangle of the item being dragged. TreeView_GetItemRect(hwndTV, lpnmtv->itemNew.hItem, &rcItem, TRUE); // Get the heading level and the amount that the child items are // indented. dwLevel = lpnmtv->itemNew.lParam; dwIndent = (DWORD)::SendMessage(hwndTV, TVM_GETINDENT, 0, 0); // Start the drag operation. ImageList_BeginDrag(himl, 0, 0, 0); ImageList_DragEnter(hwndTV, 50, 50); // Hide the mouse pointer, and direct mouse input to the // parent window. ShowCursor(FALSE); g_fDragging = TRUE; return; } // Main_OnMouseMove - drags an item in a tree-view control, // highlighting the item that is the target. // hwndParent - handle to the parent window. // hwndTV - handle to the tree-view control. // xCur and yCur - x- and y-coordinates of the mouse pointer. void CLayerMgrTreeCtrl::Main_OnMouseMove(HWND hwndParent, HWND hwndTV, LONG xCur, LONG yCur) { HTREEITEM htiTarget; // handle to target item TVHITTESTINFO tvht; // hit test information if (g_fDragging) { // Drag the item to the current position of the mouse pointer. ImageList_DragMove(xCur, yCur); // Find out if the pointer is on the item. If it is, // highlight the item as a drop target. tvht.pt.x = xCur; tvht.pt.y = yCur; CPoint pt ; pt.x = xCur; pt.y = yCur; CImageList::DragMove( pt ); //鼠标经过时高亮显示 CImageList::DragShowNolock( false ); //避免鼠标经过时留下难看的痕迹 if ((htiTarget = TreeView_HitTest(hwndTV, &tvht)) != NULL) { //hAfterDrag为拖动时鼠标所在的节点句柄,即拖动结束后的节点句柄 hAfterDrag = htiTarget; TreeView_SelectItem(hwndTV, htiTarget); /* 我这里之前用了下面这个函数,是从其他地方看到的,拖动时正常,但拖动后会产生选中某项时 * 不高亮显示了,让我检查了好久,郁闷,大家用的时候也注意点 */ //TreeView_SelectDropTarget(hwndTV, htiTarget); } CImageList::DragShowNolock( true ); } return; }