Drag and drop in CTreeCtrl
B Chandra Sekhar -- int@pacific.net.sg Monday, July 01, 1996 Hi everybody ! I have a CTreeCtrl object in one of my dialogs. I have implemented dragging and dropping of items within the tree control. I am stuck with a problem now. How do I scroll the items in the tree when an item is being dragged (e.g when the dragged item goes beyond the tree control) ? I have seen Explorer etc. do this. Using MFC 4.0, developing for Win 95. Any help will be appreciated. Thanks Srini
GoroKhM1 -- gorokhm1@SMTP.ATG-NET.COM Friday, July 05, 1996 [Mini-digest: 2 responses] Trace the mouse position. If it is crossing the bottom border, scroll TreeView slowly up. If it is crossing the top border, scroll TreeView slowly down. Mark Gorokhov Allied Technology Group Rockville, MD GorokhM1@atg-net.com ______________________________ Reply Separator _________________________________ Subject: Drag and drop in CTreeCtrl Author: mfc-l@netcom.com at INTERNET Date: 7/4/96 5:30 PM Hi everybody ! I have a CTreeCtrl object in one of my dialogs. I have implemented dragging and dropping of items within the tree control. I am stuck with a problem now. How do I scroll the items in the tree when an item is being dragged (e.g when the dragged item goes beyond the tree control) ? I have seen Explorer etc. do this. Using MFC 4.0, developing for Win 95. Any help will be appreciated. Thanks Srini -----From: "Kenneth Reed"Srini, I just did this Friday. Here is what you need to do: Somewhere early on you'll need to get the windows scroll delay value. I did it in my control view contructor using the following: // Get the scroll delay time m_uScrollDelay = ::GetProfileInt(_T("windows"), _T("DragScrollDelay"), DD_DEFSCROLLDELAY); Then, in OnDragOver: find the item that's being dragged using SelectDropTarget: UINT flags; HTREEITEM hItem= m_rTreeCtrl.SelectDropTarget(m_rTreeCtrl.HitTest(point,&flags)); hItem = m_rTreeCtrl.GetDropHilightItem(); (Note that contrary to the documentation the first call above does NOT return an HTREEITEM! If successful, it returns a 1. You need to call GetDropHighlightItem if you want the HTREEITEM for the selected item.) Check for keys which modify the drag: // Set the default state based on keys if ((dwKeyState & MK_CONTROL) == MK_CONTROL) dropEffect = DROPEFFECT_COPY; if ((dwKeyState & MK_ALT) == MK_ALT) dropEffect = DROPEFFECT_MOVE; Now switch on the flags value from SelectDropTarget to catch the locations close to the edges of the control. The code below contains timer code (thanks to Kraig Brockschmidt's "Inside OLE") that delays the intial scroll and "pulses" the scrolling once it starts. m_dwLastTime is a DWORD member variable and m_uLastTest is a UINT member variable. Finally, if we're in the drop source code, pDoc->m_hDraggingItem contains the HTREEITEM for the item being dragged, otherwise it is NULL. // Decide if this is a normal operation, a preparation to scroll, // or finally time to scroll. switch (flags) { case TVHT_ABOVE: case TVHT_BELOW: case TVHT_TOLEFT: case TVHT_TORIGHT: // Turn on the scroll effect, even if we won't // actually scroll. dropEffect |= DROPEFFECT_SCROLL; // First time through? if (m_dwLastTime == 0 || m_uLastTest != flags) { TRACE("Start scroll wait..."); m_dwLastTime = GetTickCount(); m_uLastTest = flags; } else { // We've been here before. See if it's time to // scroll yet. if (GetTickCount() - m_dwLastTime > m_uScrollDelay) { // do scroll TRACE("Did scroll...\n"); if (flags == TVHT_ABOVE || flags == TVHT_BELOW) { m_rTreeCtrl.SendMessage(WM_VSCROLL, flags == TVHT_ABOVE ? SB_LINEUP : SB_LINEDOWN, 0); } else { m_rTreeCtrl.SendMessage( WM_HSCROLL, flags == TVHT_TOLEFT ? SB_LINELEFT : SB_LINERIGHT, 0); } // Set up for next iteration m_dwLastTime = GetTickCount(); } else { TRACE("Wait some more...\n"); } } break; default: // The cursor wasn't on a scroll area, so reset timer and // scroll test. m_dwLastTime = 0; m_uLastTest = 0; // we're not on the edge // If we weren't scrolling or getting ready to and there is no // valid item, we can't allow drop. if (hItem == NULL || hItem == pDoc->m_hDraggingItem) { dropEffect = DROPEFFECT_NONE; } break; } Now you can return the dropEffect and you're done! Good luck! Ken
| Вернуться в корень Архива |