想在CLISTBOX中实现鼠标拖动多项项? 就是在鼠标左键选中某些项然后鼠标左键不放,将某项拖动到指定位置呢?现在已经可以是EXTENDED了 可以选择多项 就是不知道如何实现拖动? 
 望各位朋友指教 
我这里有支持单项拖动的代码 但是就是不能支持多项拖动?
 先附上:#pragma once// CDragAndDropListBoxclass CDragAndDropListBox : public CListBox
{
DECLARE_DYNAMIC(CDragAndDropListBox)public:
CDragAndDropListBox();
virtual ~CDragAndDropListBox();
   int m_Oldposition;
   int m_ifmove;
protected:
   afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
   afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
   afx_msg void OnMouseMove(UINT nFlags, CPoint point);
   afx_msg void OnTimer(UINT nIDEvent);
DECLARE_MESSAGE_MAP()private:
   int   m_MovingIndex;
   int   m_MoveToIndex;
   BOOL  m_Captured;
   DWORD m_Interval;    //scroll speed when an item is dragged above or below the window   void InsertDraggedItem();
   void DoTheScrolling(CPoint Point,CRect ClientRect);
   void DrawTheLines(int Index);
};

解决方案 »

  1.   

    // DragAndDropListBox.cpp : implementation file
    //#include "stdafx.h"
    #include "DragAndDropListBox.h"#define TID_SCROLLDOWN  100
    #define TID_SCROLLUP    101// CDragAndDropListBoxIMPLEMENT_DYNAMIC(CDragAndDropListBox, CListBox)
    CDragAndDropListBox::CDragAndDropListBox()
    : m_MovingIndex(-1)
    , m_MoveToIndex(-1)
    , m_Captured(FALSE)
    , m_Interval(0),
    m_Oldposition(-1),
    m_ifmove(0)
    {
    }CDragAndDropListBox::~CDragAndDropListBox()
    {
    }
    BEGIN_MESSAGE_MAP(CDragAndDropListBox, CListBox)
       ON_WM_LBUTTONDOWN()
       ON_WM_LBUTTONUP()
       ON_WM_MOUSEMOVE()
       ON_WM_TIMER()
    END_MESSAGE_MAP()// CDragAndDropListBox message handlers
    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);   
       m_Oldposition=GetCurSel();
       if (Index != LB_ERR && !Outside)
       {
          m_MovingIndex = Index;
          SetSel(Index);
       }}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);
    }
    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, then
             //simply select the last item as the drop point
             //else if they are outside the window then scroll the items
             if (ClientRect.PtInRect(point))
             {
                KillTimer(TID_SCROLLDOWN);
                KillTimer(TID_SCROLLUP);
                m_Interval = 0;
                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);
          }
       }
    }void CDragAndDropListBox::DrawTheLines(int Index)
    {
       CRect ClientRect;
       GetClientRect(&ClientRect);   CDC *pDC = GetDC();   CRect Rect;
       int Width = 2;
       if (m_MoveToIndex != m_MovingIndex)
       {
          CPen Pen(PS_SOLID,Width,RGB(255,255,255));
          CPen *pOldPen = pDC->SelectObject(&Pen);
          if (m_MoveToIndex != LB_ERR)
          {
             GetItemRect(m_MoveToIndex,&Rect);
             if (ClientRect.PtInRect(Rect.TopLeft()))
             {
                pDC->MoveTo(Rect.left,Rect.top+1);
                pDC->LineTo(Rect.right-(Width/2),Rect.top+1);
             }
          }
          else
          {
             GetItemRect(GetCount()-1,&Rect);
             if (ClientRect.PtInRect(CPoint(0,Rect.bottom)))
             {
                pDC->MoveTo(Rect.left,Rect.bottom);
                pDC->LineTo(Rect.right-(Width/2),Rect.bottom);
             }
          }
          pDC->SelectObject(pOldPen);
       }
       m_MoveToIndex = Index;
       if (m_MoveToIndex != m_MovingIndex)
       {
          CPen Pen(PS_SOLID,Width,RGB(0,0,0));
          CPen *pOldPen = pDC->SelectObject(&Pen);
          if (m_MoveToIndex != LB_ERR)
          {
             GetItemRect(Index,&Rect);
             if (ClientRect.PtInRect(Rect.TopLeft()))
             {
                pDC->MoveTo(Rect.left,Rect.top+1);
                pDC->LineTo(Rect.right-(Width/2),Rect.top+1);
             }
          }
          else
          {
             GetItemRect(GetCount()-1,&Rect);
             if (ClientRect.PtInRect(CPoint(0,Rect.bottom)))
             {
                pDC->MoveTo(Rect.left,Rect.bottom);
                pDC->LineTo(Rect.right-(Width/2),Rect.bottom);
             }
          }
          pDC->SelectObject(pOldPen);
       }
       ReleaseDC(pDC);
    }void CDragAndDropListBox::InsertDraggedItem()
    {
       CString Text;
       DWORD ItemData;//_PTR
       GetText(m_MovingIndex,Text);
       ItemData = GetItemData(m_MovingIndex);
       if (m_MovingIndex < m_MoveToIndex)
       {
          SetRedraw(FALSE);
          int TopIndex = GetTopIndex();
          int NewIndex = InsertString(m_MoveToIndex,Text);
          SetItemData(NewIndex,ItemData);
          DeleteString(m_MovingIndex);
          SetSel(NewIndex-1);
          SetTopIndex(TopIndex);
          SetRedraw(TRUE);
      m_ifmove=1;
          //we have to redraw the window since we are deleting a string
          //after we set the current selection. DeleteString causes a 
          //focus rect to show up under the current selection
          Invalidate();
          UpdateWindow();
       }
       else if (m_MovingIndex > m_MoveToIndex)
       {
          SetRedraw(FALSE);
          int TopIndex = GetTopIndex();
          DeleteString(m_MovingIndex);
          int NewIndex = InsertString(m_MoveToIndex,Text);
          SetItemData(NewIndex,ItemData);
          SetSel(NewIndex);
          SetTopIndex(TopIndex);
          SetRedraw(TRUE);
       m_ifmove=1;
          //we have to redraw the window since we are deleting a string
          //after we set the current selection. DeleteString causes a 
          //focus rect to show up under the current selection
          Invalidate();
          UpdateWindow();
       }
       GetParent()->SendMessage(WM_COMMAND,MAKEWPARAM(GetDlgCtrlID(),LBN_SELCHANGE),(LPARAM)m_hWnd);
    }void CDragAndDropListBox::DoTheScrolling(CPoint Point,CRect ClientRect)
    {
       if (Point.y > ClientRect.Height())
       {
          DWORD Interval = 250 / (1+ ((Point.y-ClientRect.Height())/GetItemHeight(0)));
          if (Interval != m_Interval)
          {
             m_Interval = Interval;
             SetTimer(TID_SCROLLDOWN,Interval,NULL);
             OnTimer(TID_SCROLLDOWN);
          }
       }
       else if (Point.y < 0)
       {
          DWORD Interval = 250 / (1+(abs(Point.y)/GetItemHeight(1)));
          if (Interval != m_Interval)
          {
             m_Interval = Interval;
             SetTimer(TID_SCROLLUP,Interval,NULL);
             OnTimer(TID_SCROLLUP);
          }
       }
       else
       {
          KillTimer(TID_SCROLLDOWN);
          KillTimer(TID_SCROLLUP);
          m_Interval = 0;
       }
    }void CDragAndDropListBox::OnTimer(UINT nIDEvent)
    {
       if (nIDEvent == TID_SCROLLDOWN)
       {
          DrawTheLines(m_MoveToIndex+1);
          SetTopIndex(GetTopIndex()+1);
       }
       else if (nIDEvent == TID_SCROLLUP)
       {
          DrawTheLines(m_MoveToIndex-1);
          SetTopIndex(GetTopIndex()-1);
       }   CListBox::OnTimer(nIDEvent);
    }
    先在这说声谢谢了
      

  2.   

    http://www.codeguru.com/cpp/controls/listbox/Drag & Drop
      

  3.   

    像这样问题以后先到msdn, codeproject或codeguru搜下,看有没有示例代码
      

  4.   

    MOUSE_MOVE的时候记录当前被选中的几项索引,待MOUSE_UP时CListBox::ItemFromPoint得到插入点, 将记录的几项索引依次插入,这里在MOUSE_MOVE 绘制 Rectangle 随你了,用GDI来画
      

  5.   

    我试了试 谢谢楼上的朋友  在我以上的代码中 MOUSE_MOVE不知道 为什么我用 GetSelItems();
    得不到所选的几项  只能得到 第一个选中 和最后一个选中的ITEM 我以上的代码能不能修改一下 贴出来  多谢...
      

  6.   

    你的GetSelItems用法对么?// The pointer to my list box.
    extern CListBox* pmyListBox;// Get the indexes of all the selected items.
    int nCount = pmyListBox->GetSelCount();
    CArray<int,int> aryListBoxSel;aryListBoxSel.SetSize(nCount);
    pmyListBox->GetSelItems(nCount, aryListBoxSel.GetData()); // Dump the selection array.
    #ifdef _DEBUG
       afxDump << aryListBoxSel;
    #endif