Files
coco df489d5640 a
2026-07-03 16:05:30 +08:00

234 lines
6.4 KiB
C++

#include "stdafx.h"
#include "DragList.h"
vector <RECT> CDragList::ItemRect;
int CDragList::m_ActiveItem = SELECT_NONE;
bool CDragList::m_IsOut = true;
int CDragList::m_SelectItem = SELECT_NONE;
bool CDragList::m_IsInFilstPart = false;
bool CDragList::m_IsInSecondPart = false;
POINT CDragList::MouseDownPoint = { -10, -10 };
void CDragList::BeginDrag(HWND ListWnd, POINT point)
{
::SetCapture(ListWnd);
//设置焦点
if (::GetFocus() != ListWnd)
::SetFocus(ListWnd);
//enum to find out if select one
int count = (int)::SendMessage(ListWnd, LVM_GETITEMCOUNT, 0, 0);
int state;
CString strLog;
for (int i = 0; i < count; i++)
{
state = (int)::SendMessage(ListWnd, LVM_GETITEMSTATE, i, (LPARAM)LVIS_SELECTED);
if (state | LVIS_SELECTED == 1)
{
m_SelectItem = i;
m_ActiveItem = i;
m_IsOut = true;
MouseDownPoint = point;
strLog.Format(_T("遍历当前选中%d行"), i);
OutputDebugString(strLog);
}
}
}
void CDragList::EndDrag(HWND ListWnd, POINT point)
{
if (m_ActiveItem != SELECT_NONE)
{
::InvalidateRect(ListWnd, &ItemRect[m_ActiveItem], false);
if (m_ActiveItem != m_SelectItem && m_SelectItem != SELECT_NONE)
{
//最后的Item的处理
//if (m_IsInSecondPart == true)
// m_ActiveItem += 1;
::PostMessage(::GetParent(ListWnd), WM_MOVEITEM, m_SelectItem, m_ActiveItem);
}
}
::ReleaseCapture();
m_SelectItem = SELECT_NONE;
}
void CDragList::Dragging(HWND ListWnd, POINT point)
{
//当鼠标按下后没有移动就弹起时,ClistCtrl会发送一个click消息,
//并且会有一个WM_MOUSEMOVE的消息(却没有WM_LBUTTONDUP的消息)
//我们这里简单的返回
if (point.x == MouseDownPoint.x && point.y == MouseDownPoint.y)
{
::ReleaseCapture();
m_SelectItem = SELECT_NONE;
return;
}
//get the rect of ListCtrl
RECT rect;
::GetWindowRect(ListWnd, &rect);
rect.top += 24; //去掉头表的高度
POINT MousePoint;
::GetCursorPos(&MousePoint);
//mouse is not in the ListCtrl
if (!::PtInRect(&rect, MousePoint))
{
m_IsOut = true;
if (m_ActiveItem != SELECT_NONE)
{
::InvalidateRect(ListWnd, &ItemRect[m_ActiveItem], false);
m_ActiveItem = SELECT_NONE;
}
//::SetCursor(LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURSOR2)));
//超过窗体上边,向上滚动
if (MousePoint.y<rect.top)
{
::SendMessage(ListWnd, WM_KEYDOWN, VK_UP, 0);
::SendMessage(ListWnd, WM_KEYUP, VK_UP, 0);
}
//超过窗体下边,向下滚动
else if (MousePoint.y>rect.bottom)
{
::SendMessage(ListWnd, WM_KEYDOWN, VK_DOWN, 0);
::SendMessage(ListWnd, WM_KEYUP, VK_DOWN, 0);
}
return;
}
//if is outside the widnow,re receive all the item rect again
if (m_IsOut)
{
m_IsOut = false;
m_IsInFilstPart = false;
m_IsInSecondPart = false;
//get the count of listctrl
int count = (int)::SendMessage(ListWnd, LVM_GETITEMCOUNT, 0, 0);
//initial data
ItemRect.clear();
ItemRect.resize(count);
for (int i = 0; i < count; i++)
{
//save item rect
ItemRect[i].left = LVIR_SELECTBOUNDS;
::SendMessage(ListWnd, LVM_GETITEMRECT, i, (LPARAM)&ItemRect[i]);
}
}
//begin find item
int i;
for (i = 0; i < ItemRect.size() && !::PtInRect(&ItemRect[i], point); i++); //注意这行的分号
CString strLog;
strLog.Format(_T("CDragList::Dragging() 查找当前的点在哪一行,%d行,点x=%d,y=%d , ItemRect[i] left=%d,top=%d,right=%d,bottom=%d\n"), i, point.x, point.y, ItemRect[i].left, ItemRect[i].top, ItemRect[i].right, ItemRect[i].bottom);
OutputDebugString(strLog);
//if found item(即鼠标在List里面)
if (i != ItemRect.size())
{
//改变鼠标形状
//::SetCursor(LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_MOVEITEMCUR)));
//在最后一项移动
if (i == ItemRect.size() - 1)
{
//是否第一次移入此Item
if (m_ActiveItem != i)
{
//假如需要,更新原来的ItemRect
if (m_ActiveItem != SELECT_NONE)
::InvalidateRect(ListWnd, &ItemRect[m_ActiveItem], false);
//保存当前焦点的按钮索引
m_ActiveItem = i;
}
//在最后一个item的上半部分上移动
if (point.y < (ItemRect[m_ActiveItem].top + ItemRect[m_ActiveItem].bottom) / 2)
{
//第一次进入最后一个item的前半部分
if (m_IsInFilstPart == false)
{
m_IsInFilstPart = true;
m_IsInSecondPart = false;
::InvalidateRect(ListWnd, &ItemRect[m_ActiveItem], false);
::UpdateWindow(ListWnd);
//DrawLine(ListWnd, ItemRect[m_ActiveItem].left + 2, ItemRect[m_ActiveItem].top + 2,
// ItemRect[m_ActiveItem].right - 2, ItemRect[m_ActiveItem].top + 2);
}
}
//在最后一个item的后半部分上移动
else
{
//第一次进入最后一个item的后半部分
if (m_IsInSecondPart == false)
{
m_IsInSecondPart = true;
m_IsInFilstPart = false;
::InvalidateRect(ListWnd, &ItemRect[m_ActiveItem], false);
::UpdateWindow(ListWnd);
//DrawLine(ListWnd, ItemRect[m_ActiveItem].left + 2, ItemRect[m_ActiveItem].bottom - 2,
// ItemRect[m_ActiveItem].right - 2, ItemRect[m_ActiveItem].bottom - 2);
}
}
return;
}
//是否第一次移入此Item
if (m_ActiveItem != i)
{
m_IsInFilstPart = false;
//假如需要,更新原来的ItemRect
if (m_ActiveItem != SELECT_NONE)
::InvalidateRect(ListWnd, &ItemRect[m_ActiveItem], false);
//保存当前焦点的按钮索引
m_ActiveItem = i;
//DrawLine(ListWnd, ItemRect[m_ActiveItem].left + 4, ItemRect[m_ActiveItem].top + 2,
// ItemRect[m_ActiveItem].right - 4, ItemRect[m_ActiveItem].top + 2);
return;
}
}
//if not found item(鼠标不在List里面)
else
{
//假如第一次移出List
if (m_ActiveItem != SELECT_NONE)
{
//重绘原来的按钮
::InvalidateRect(ListWnd, &ItemRect[m_ActiveItem], false);
//表示鼠标在List外
m_ActiveItem = SELECT_NONE;
}
m_IsInFilstPart = false;
m_IsInSecondPart = false;
//改变鼠标形状
//::SetCursor(LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURSOR2)));
}
}
/* void CDragList::DrawLine(HWND hWnd, int BeginX, int BeginY, int EndX, int EndY)
{
HDC hdc = ::GetDC(hWnd);
HPEN Pen = ::CreatePen(PS_SOLID, 4, RGB(0, 0, 0));
HPEN OldPen = (HPEN)SelectObject(hdc, Pen);
HBRUSH OldBrush = (HBRUSH)::SelectObject(hdc, (HBRUSH)GetStockObject(NULL_BRUSH));
MoveToEx(hdc, BeginX, BeginY, NULL);
LineTo(hdc, EndX, EndY);
::SelectObject(hdc, OldBrush);
::SelectObject(hdc, OldPen);
::DeleteObject(Pen);
::ReleaseDC(hWnd, hdc);
}*/