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

  • 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 …

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds