想在CLISTBOX中实现鼠标拖动某项? 就是在鼠标左键选中某项然后鼠标左键不放,将某项拖动到指定位置呢?

kiddy1010 2006-09-28 05:18:02
想在CLISTBOX中实现鼠标拖动多项项? 就是在鼠标左键选中某些项然后鼠标左键不放,将某项拖动到指定位置呢?现在已经可以是EXTENDED了 可以选择多项 就是不知道如何实现拖动?
望各位朋友指教
我这里有支持单项拖动的代码 但是就是不能支持多项拖动?
先附上:

#pragma once

// CDragAndDropListBox

class 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);
};












...全文
277 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
kiddy1010 2006-09-29
  • 打赏
  • 举报
回复
我试了试 谢谢楼上的朋友 在我以上的代码中 MOUSE_MOVE不知道 为什么我用 GetSelItems();
得不到所选的几项 只能得到 第一个选中 和最后一个选中的ITEM 我以上的代码能不能修改一下 贴出来 多谢...
折腾_苏州 2006-09-29
  • 打赏
  • 举报
回复
MOUSE_MOVE的时候记录当前被选中的几项索引,待MOUSE_UP时CListBox::ItemFromPoint得到插入点, 将记录的几项索引依次插入,这里在MOUSE_MOVE 绘制 Rectangle 随你了,用GDI来画
kiddy1010 2006-09-29
  • 打赏
  • 举报
回复
不好意思 你们说的都是只有单项拖动功能 ,以上代码就是我下的
压宝散人 2006-09-29
  • 打赏
  • 举报
回复
顺路关注
liumang9527 2006-09-29
  • 打赏
  • 举报
回复
mark
littlepboy 2006-09-29
  • 打赏
  • 举报
回复
你的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
pioneer_public 2006-09-29
  • 打赏
  • 举报
回复
只需要将用户选择的列标识为被选中

然后插入时,当是你插入前面的一列移动不也可以吗?
yjgx007 2006-09-28
  • 打赏
  • 举报
回复
像这样问题以后先到msdn, codeproject或codeguru搜下,看有没有示例代码
lixiaosan 2006-09-28
  • 打赏
  • 举报
回复
http://www.codeguru.com/cpp/controls/listbox/

Drag & Drop
kiddy1010 2006-09-28
  • 打赏
  • 举报
回复


// DragAndDropListBox.cpp : implementation file
//

#include "stdafx.h"
#include "DragAndDropListBox.h"

#define TID_SCROLLDOWN 100
#define TID_SCROLLUP 101

// CDragAndDropListBox

IMPLEMENT_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);
}
先在这说声谢谢了

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧