Drag and Drop Listbox Items Without OLE

This listbox class demonstrates how to rearrange listbox items using Drag and Drop without the overhead of OLE. (If you are trying to drag items from one ListBox to another, refer to the OLE verion of this article.)

MFC has a CDragListBox that virtually does the same thing. The advantage of this class over MFC's CDragListBox is that it allows the user to insert the item at the end of the list, whereas CDragListBox does not. The concept is very simple: Keep track of the item that is being dragged, indicate where the drop will be when the user is dragging the item around, and finally, insert the item in its new location once the user releases the mouse button.

To accomplish this task, you will need to catch three messages for your listbox window: WM_LBUTTONDOWN, WM_MOUSEMOVE, and WM_LBUTTONUP. The WM_LBUTTONDOWN handler method simply initializes the drag and drop process by finding the item that the user clicked on.

void CDragAndDropListBox::OnLButtonDown(UINT nFlags, CPoint point)
{
   CListBox::OnLButtonDown(nFlags, point);

   //clear all the flags
   m_MovingIndex = LB_ERR;
   m_MoveToIndex = LB_ERR;
   m_Captured = FALSE;
   m_Interval = 0;
   
   BOOL Outside;
   //Find the item that they want to drag and keep track of it.
   //Later in the mouse move, we will capture the mouse if this
   //value is set.
   int Index = ItemFromPoint(point,Outside);
   if (Index != LB_ERR && !Outside)
   {
      m_MovingIndex = Index;
      SetCurSel(Index);
   }
}

The WM_WMMOUSEMOVE handler method does three things:

  1. Capture the mouse if it hasn't done so.
  2. Scroll the listbox if the user has dragged the mouse above or below the listbox window (it does this with the help of timers).
  3. Draw a line above the item where the dragged item will be dropped, it also keeps track of the item's index value so that WM_LBUTTONUP does not have to find the information again.
void CDragAndDropListBox::OnMouseMove(UINT nFlags, CPoint point)
{
   CListBox::OnMouseMove(nFlags, point);
   if (nFlags & MK_LBUTTON)
   {
      if (m_MovingIndex != LB_ERR && !m_Captured)
      {
         SetCapture();
         m_Captured = TRUE;
      }
      BOOL Outside;
      int Index = ItemFromPoint(point,Outside);
      //if they our not on a particular item
      if (Outside)
      {
         CRect ClientRect;
         GetClientRect(&ClientRect);

         //If they are still within the listbox window, simply
         //select the last item as the drop point; else, if
         //they are outside the window, scroll the items.
         if (ClientRect.PtInRect(point))
         {
            KillTimer(TID_SCROLLDOWN);
            KillTimer(TID_SCROLLUP);
            m_Interval = 0;
            //indicates that the user wants to drop the item
            //at the end of the list
            Index = LB_ERR;
            Outside = FALSE;
         }
         else
         {
            DoTheScrolling(point,ClientRect);
         }
      }
      else
      {
         KillTimer(TID_SCROLLDOWN);
         KillTimer(TID_SCROLLUP);
         m_Interval = 0;
      }
      
      if (Index != m_MoveToIndex && !Outside)
      {
         DrawTheLines(Index);
      }
   }
}

Next, the WM_LBUTTONUP message handler will do the actual drop operation. It first checks to make sure that there was a item being dragged to begin with. Next, it checks to make sure that the button was released within the listbox window. If it wasn't, there is nothing to do. If, on the other hand, it was released within the window, simply insert the item into the listbox at the index indicated by the WM_MOUSEMOVE handler.

void CDragAndDropListBox::OnLButtonUp(UINT nFlags, CPoint point)
{
   if (m_MovingIndex != LB_ERR && m_Captured)
   {
      KillTimer(TID_SCROLLDOWN);
      KillTimer(TID_SCROLLUP);
      m_Interval = 0;
      m_Captured = FALSE;
      ReleaseCapture();

      CRect Rect;
      GetClientRect(&Rect);
      //if they are still within the listbox window
      if (Rect.PtInRect(point))
      {
         InsertDraggedItem();
      }
      else
      {
         Invalidate();
         UpdateWindow();
      }
      m_MovingIndex = LB_ERR;
      m_MoveToIndex = LB_ERR;
   }

   CListBox::OnLButtonUp(nFlags, point);
}

Using the Code

To use this class, simply attach a variable (subclass) to the listbox control on your window, and then change the variable from CListBox to CDragAndDropListBox. That's all.

// CDragDropListBoxSampleDlg dialog
class CDragDropListBoxSampleDlg : public CDialog
{
......

// Implementation
protected:
   CDragAndDropListBox  m_ListBox;
   
......
};


About the Author

Ali Rafiee

Ali Rafiee has been developing windows applications for the past 14 years using Visual C++, and he hasn't looked back since. Ali has been a software development consultant for must of his career, but he has finally settled down and has been working for an educational software company for the past 7 years. While he is not working, he is either learning C#, flying airplanes, playing with his daughter, or answering peoples question on newsgroups, he finds that to be a great learning tool for him (He is always trying to learn something new).

Downloads

Comments

  • Lisseur GHD détaillants de plus en plus préoccupés par la Norvège

    Posted by ysniob448 on 07/16/2013 12:48pm

    Récemment a eu le GHD rose, édition limitée pur / sombre sous le nom de GHD MK4 (IV) établir GHD au pouvoir se rapproche uangripelig posisjon au-dessus av portée marché opp-et-vient à défrisants professionnels avec plusieurs funksjoner utile, entre autres choses, un câble sterk supplémentaire , quelque chose qui muliggjør plus frihet lorsque vous stockez ces cils et les boucles et les dernières plaines de la technologie chauffage infra-rouge signifie que hastigheten sur gjennomføring chaleur av et garder au chaud le temps lengre dans le MK4 céramique Plater, ytterligere aidera à veiller à y serrure en minéraux, cheveux ferries et l'humidité dans le ditt de cheveux pour lengre période, un gi cheveux ditt silkemykt, éclat de style et sans électricité statique. Les nouvelles plaines de maintien rondes signifient y Skape styles complexes comme les boucles et les cils sont plus faciles y do.Another avantage le client obtient avec cette nouvelle GHD MK4 (IV) Styler & Horizontal Tang est un DVD qui donne instruksjoner et spesielle conseils pour y obtenir le beste visant à cheveux. Vous pouvez accéder à expérimenter et forskjellig style de cheveux pour la deuxième journée. [url=http://bbeatsinorge.cabanova.com/]lisseur ghd[/url] Maintenant, avec tension universelle pour une performance optimale partout dans le monde que vous êtes deg.Hvilemodus est une configuration de sécurité intégré qui vous donne la tranquillité d'esprit, car il s'éteint automatiquement technologie numérique av.Unik signifie que la température est contrôlée automatiquement encore plus rapide pour un meilleur style. New rounder baril de sorte qu'il est facile de créer des boucles parfaites, vagues ou chiquenaudes, ainsi que les supprimer. [url=http://ghdpascherfer.hpage.com/]ghd pas cher lisseur[/url] Cadeaux de Noël enveloppés dans du papier coloré de Noël, marqué par des tags de nom et distribué avant Noël. Les colis sont généralement ouvertes à la maison en Scandinavie habituellement pendant une fête de famille le réveillon de Noël au Royaume-Uni et aux États-Unis le jour de Noël. Dans les familles avec de petits enfants norvégiens, bon nombre des cadeaux distribués par un Père Noël habillé venir à eux dans son sac. Sinon, il est fréquent de recueillir des cadeaux de Noël dans une pile sous l'arbre de Noël et les ouvrir lorsque la famille est samlet.Trodde Noël lors de l'envoi GHD?

    Reply
  • Hoofdtelefoon isnot slechts een hoofdtelefoon, is een venster op de wereld te zien

    Posted by mrswanzi on 06/06/2013 07:03am

    [url=http://koptelefoon-monsterbeats.manifo.com/]Beats by dre Goedkope[/url] Met de Beats by Dr. Dre Wireless geniet je van volledige muzikale vrijheid. De draadloze hoofdtelefoon, in het design van de populaire Solo HD, beschikt over Bluetooth waarmee je hem eenvoudig koppelt aan je smartphone (of mp3-speler met Bluetooth). Alle benodigde bedieningsknoppen voor volume, het skippen van nummers of het aannemen of beindigen van een telefoongesprek zijn geplaatst op de rechteroorschelp en dus altijd binnen handbereik. [url=http://koptelefoon-monsterbeats.manifo.com/]Beats by dre Goedkope[/url] Zo is Lady GaGa in de clip van Pokerface uit 2008 te zien met een Beats by Dr. Dre. Het is slechts een paar tellen, maar na de introductie van de muziekvideo stellen vele fans diezelfde twee vragen: van welk merk is toch die hoofdtelefoon met die rode B en hoe kom ik daaraan Steeds meer artiesten volgden het voorbeeld van LeBron James en Lady GaGa. Niet omdat de hoofdtelefoons significant beter waren dan andere merken, maar puur vanwege de uitstraling: mode. [url=http://monsterbeats.webgarden.es/]beats by dre[/url] Met de Beats by Dr. Dre Wireless geniet je van volledige muzikale vrijheid. De draadloze hoofdtelefoon, in het design van de populaire Solo HD, beschikt over Bluetooth waarmee je hem eenvoudig koppelt aan je smartphone (of mp3-speler met Bluetooth). Alle benodigde bedieningsknoppen voor volume, het skippen van nummers of het aannemen of beindigen van een telefoongesprek zijn geplaatst op de rechteroorschelp en dus altijd binnen handbereik.

    Reply
  • Nike Display Max 1 FB release, father a fervent color grain, the new shoes

    Posted by Geozyoceada on 04/24/2013 07:51pm

    In the summer in a pane backing bowels the imperturbable sprite seems to be a decorous fitting, but if the sprite "feet"? Inclination also fork out you a trip, take a invigorating! This summer, Nike and Sprite [url=http://northernroofing.co.uk/roofins.cfm]nike free run uk[/url] and his sneakers to a graduate of exemplary snow spread of unripened, drained and downcast color blueprint in the definitive Nike Superciliousness Max 1 shoes reveal a refreshing chill scent.[url=http://markwarren.org.uk/property-waet.cfm]air max 90 uk[/url] Summer is the yet to choice a cleanly shoe, shoes should be a good choice. Qualifying series Nike Publicize Max HomeTurf metropolis recently lastly comes up, this series in the first-rate Melody Max shoes to London, Paris and Milan the three paid glorification to the iconic city of Europe, combined with the characteristics of the three cities, Feeling Max 1 HYP,Allied Max 90 HYP,Superciliousness Max 1 and shoes such as Air Max 95, combined [url=http://fossilsdirect.co.uk/glossarey.cfm]nike huarache free[/url] with the Hyperfuse, as kindly as a variety of materials, such as suede, Whether you crave functional or retro-everything.

    Reply
  • drag and drop listbox items

    Posted by uday on 01/16/2013 10:35pm

    don't we have any other option like without creating extra class for this.

    Reply
  • Fatal error

    Posted by satishmanohar on 01/23/2008 02:02am

    fatal error C1083: Cannot open include file: 'stdafx.h': No such file or directory Error executing cl.exe. DragAndDropListBox.exe - 1 error(s), 0 warning(s) I compiled using visual studio 6.0.. can u suggest a remedy for that???

    • Re: Fatal error

      Posted by AliRafiee on 01/23/2008 02:40am

      Stdafx.h is the header file used for precompiled headers. My sample project is a visual c++ 2003 project. If you want to port it to 6.0 the easiest thing would be to create a new MFC project, and then add .cpp .h and .rc files from my project to that project. It is a little tricky with the rc file. You might want to simply copy and paste the code for the dialog box from the sample projects rc file to your rc file instead of copying the entire file.

      Reply
    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Packaged application development teams frequently operate with limited testing environments due to time and labor constraints. By virtualizing the entire application stack, packaged application development teams can deliver business results faster, at higher quality, and with lower risk.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds