>>-aMessageExtensions~DefTreeDragHandler-----------------------><
A tree view control cannot handle a drag-and-drop operation within the tree view. Therefore, you can connect the DefTreeDragHandler method with the BEGINDRAG or BEGINRDRAG notification message (see ConnectTreeNotify) to allow the moving of an item or a node with all its subitems from one parent node to another within a tree view. The cursor shape is changed to a crosshair during the drag operation. If the cursor is moved over the item dragged, the cursor shape is changed to a slashed circle. You can cancel the drag operation by clicking the other mouse button while holding the button that started the drag operation.
The DefTreeDragHandler is implemented as follows:
::method DefTreeDragHandler use arg id, item, pt tc = self~GetTreeControl(id) hc = tc~Cursor_Cross /* change cursor and store current */ parse value tc~GetRect with left top right bottom oldItem = 0 nocurs = 0 lmb = self~IsMouseButtonDown("LEFT") rmb = self~IsMouseButtonDown("RIGHT") call time "R" do while (lmb \= 0 | rmb \= 0) & \(lmb \= 0 & rmb \= 0) pos = self~CursorPos parse var pos x y parse value tc~ScreenToClient(x, y) with newx newy ht = tc~HitTest(newx, newy) if ht \= 0 & ht~wordpos("ONITEM") > 0 then do parse var ht newParent where /* check if droptarget is the current parent or one of the dragged item's children */ if newParent \= Item & newParent \= tc~Parent(Item) & tc~IsAncestor, (Item,newParent) = 0 then do is. = tc~ItemInfo(newParent) if is.!State~Wordpos("INDROP") = 0 then do call time "R" tc~DropHighlight(newParent) if nocurs \= 0 then do tc~RestoreCursorShape(nocurs) /*restore old cursor (cross)*/ nocurs = 0 end end else if time("E") > 1 then do /* expand node after 1 second */ if is.!Children \= 0 & is.!State~Wordpos("EXPANDED") = 0 then tc~expand(newParent) end end else do if nocurs = 0 then do nocurs = tc~Cursor_No /* set no cursor and retrieve current cursor (cross) */ tc~DropHighlight /* remove drop highlight */ end end end else do if newParent \= 0 then do /* necessary to redraw cursor when moving on a valid item again */ tc~DropHighlight /* remove drop highlight */ newParent = 0 end if nocurs = 0 then nocurs = tc~Cursor_No /* set no cursor and retrieve current cursor (cross) */ /* handle scrolling */ fvItem = tc~FirstVisible if (ybottom) & (tc~NextVisible(fvItem) \= 0) then do tc~MakeFirstVisible(tc~NextVisible(fvItem)) if y-bottom < 200 then call sleepms 200-(y-bottom) end end lmb = self~IsMouseButtonDown("LEFT") rmb = self~IsMouseButtonDown("RIGHT") end if ht~wordpos("ONITEM") > 0 & lmb = 0 & rmb = 0 then do /* if mouse on item and both mouse buttons up */ item = tc~MoveItem(Item, newParent, 1) /* move item under newParent */ end tc~DropHighlight(0) /* remove drop highlight */ tc~select(item) /* select item */ tc~EnsureVisible(item) tc~RestoreCursorShape(hc) /* restore old cursor */ pos = self~CursorPos parse var pos x y self~SetCursorPos(x+1, y+1) /* move cursor to force redraw */