15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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




| Вернуться в корень Архива |