#include "stdafx.h" #include "DragList.h" vector 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.yrect.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); }*/