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
| Вернуться в корень Архива
|