A Drag and Drop List Control

There are already several articles on CodeGuru that describe aspects of drag and drop in list and tree controls, particularly Dragging Items to Rearrange Rows by Wayne Berthin, and CreateDragImage for multiple selected items in CListCtrl by Frank Kobs. Unfortunately, none of these articles present a complete solution with working code, which is thus the purpose of this contribution.

This article includes a demo project, a CListCtrl derived class, and a release build EXE for a quick demonstration of the capabilities of the class. I don't intend the class to be all singing and dancing, but it is good enough for me to use in my current project. No doubt there are further enhancements that could be made it, so please be my guest.

The new class, CDragDropListCtrl, has the following features:

  • Supports dragging of single and multiple selections.
  • Potential drag targets are highlighted (selected) as the mouse moves over them.
  • The list control will scroll when you try to drag out of the top or bottom.
  • Horizontal mouse movement is ignored; if the mouse is to the left or right of the list control, dragging still occurs as though the mouse is over the control.
  • Works with LVS_EX_FULLROWSELECT style on or off.
  • Preserves the checked state of dragged items.
  • All code is encapsulated in the control—no changes are required to the parent class.

The class grew out of the original article by Wayne Berthin, but I've rewritten most of the code, and added a heap more. The CreateDragImageEx method is almost the same as that given by Frank Kobs, with a minor bug fix so that it works correctly when the LVS_EX_FULLROWSELECT style is not set.

To use the new class, first add the DragDropListCtrl.cpp and DragDropListCtrl.h files to your project. Then, add a list control to your dialog resource, and set the View style to Report. Use ClassWizard to add a variable for the list control. The Category for the variable should be Control, and the Variable type should be CDragDropListCtrl. Finally, add this line to the top of your dialog header file:

#include "DragDropListCtrl.h"

That's all there is to it!



  • Not getting LButtonUp on single clicks

    Posted by yooper on 07/27/2009 10:56am

    I've implemented this control in one of my projects, and I'm seeing some slightly strange behavior. When I click my left mouse button on any item and release without dragging, I don't get the WM_ON_LBUTTONUP message. However, if I double-click on any item, I do get the WM_ON_LBUTTONUP message. Could this have something to do with the SetCapture()? Or is there something else I'm missing? Thanks!

  • Problems with common controls v6 (XP and Vista style appearance)

    Posted by rjones on 01/07/2008 06:31pm

    There are several problems using this control with the new-style XP and Vista controls (common controls v6), including excessive flickering, autoscroll not working, and the drag image having an incorrect appearance. See the following thread for more details: http://www.codeguru.com/forum/showthread.php?t=442854 At present the thread describes a fix for the flickering and autoscroll problems, but there's still no fix for the odd-looking drag image. Can anyone find a fix for that?

  • This is the fix for dragging to upper items

    Posted by jastek on 06/22/2005 01:07am

    All you have to do is change line #361 ---
    356: void CDragDropListCtrl::DropItem()
    357: {
    358: RestorePrevDropItemState();
    360: // Drop after currently selected item.
    361: m_nDropIndex++;
    356: void CDragDropListCtrl::DropItem()
    357: {
    358: RestorePrevDropItemState();
    360: // Drop after currently selected item.
    361: if (m_nDropIndex > m_anDragIndexes[0]) m_nDropIndex++;

  • Fix for using with itemdata for each item

    Posted by mecug on 03/16/2004 01:32am

    Before deleting drag item you must change value for lParam to NULL to prevent memory leak on droping item.
    void CDragDropListCtrl::DropItem()
      // Change lParam data to NULL to prevent memory leak after DropItem
      // Delete the original item.
    Other fix: delete dcMem:
    CImageList* CDragDropListCtrl::CreateDragImageEx(LPPOINT lpPoint)
     // created with CreateCompatibleDC and you must be delete it 

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

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date