261 lines
6.6 KiB
C++
261 lines
6.6 KiB
C++
// SortList1.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "SortList.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSortList
|
|
|
|
CSortList::CSortList()
|
|
{
|
|
m_bDragging = FALSE;
|
|
m_bReSort = false; //每次拖动后不需要重排
|
|
m_lCheck1 = -1;
|
|
m_lCheck2 = -1;
|
|
m_lCheck3 = -1;
|
|
}
|
|
|
|
CSortList::~CSortList()
|
|
{
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CSortList, CListCtrl)
|
|
//{{AFX_MSG_MAP(CSortList)
|
|
ON_WM_LBUTTONUP()
|
|
ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBegindrag)
|
|
ON_WM_MOUSEMOVE()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSortList message handlers
|
|
|
|
void CSortList::Init(BOOL bReSort , long lCheck1 , long lCheck2 , long lCheck3)
|
|
{
|
|
//ListView_SetExtendedListViewStyle(m_hWnd, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP|LVS_EX_CHECKBOXES);
|
|
this->SetExtendedStyle(LVS_EX_TRACKSELECT|LVS_EX_ONECLICKACTIVATE|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP|LVS_EX_CHECKBOXES);
|
|
m_bReSort = bReSort; //每次拖动后是否需要重排
|
|
m_lCheck1 = lCheck1; //每次必选的项目
|
|
m_lCheck2 = lCheck2; //每次必选的项目
|
|
m_lCheck3 = lCheck3; //每次必选的项目
|
|
}
|
|
|
|
|
|
void CSortList::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
if( m_bDragging )
|
|
{
|
|
//RELEASE THE MOUSE CAPTURE AND END THE DRAGGING
|
|
::ReleaseCapture();
|
|
m_bDragging = FALSE;
|
|
m_pDragImage->DragLeave(GetDesktopWindow());
|
|
m_pDragImage->EndDrag();
|
|
delete m_pDragImage;
|
|
|
|
//GET THE WINDOW UNDER THE DROP POINT
|
|
CPoint pt(point);
|
|
ClientToScreen(&pt);
|
|
m_pDropWnd = WindowFromPoint(pt);
|
|
|
|
//DROP THE ITEM ON THE LIST
|
|
if( m_pDropWnd->IsKindOf(RUNTIME_CLASS(CListCtrl)) )
|
|
DropItemOnList();
|
|
CListCtrl::OnLButtonUp(nFlags, point);
|
|
return ;
|
|
}
|
|
|
|
if ( m_lCheck1 >=0 ) //每次必选
|
|
{
|
|
NoverCheck(); //永远必须的一个。
|
|
}
|
|
if ( m_bReSort ) //重排
|
|
{
|
|
ReShowSort();
|
|
}
|
|
|
|
CListCtrl::OnLButtonUp(nFlags, point);
|
|
}
|
|
|
|
void CSortList::DropItemOnList()
|
|
{
|
|
//GET THE DROP INDEX
|
|
m_ptDropPoint.y += 10;
|
|
m_ptDropPoint.x = 0;//allows dropping to right of last column
|
|
m_nDropIndex = this->HitTest(m_ptDropPoint);
|
|
|
|
//GET INFORMATION ON THE DRAGGED ITEM BY SETTING AN LV_ITEM STRUCTURE
|
|
//AND THEN CALLING GetItem TO FILL IT IN
|
|
TCHAR szLabel[256];
|
|
LV_ITEM lvi;
|
|
ZeroMemory(&lvi, sizeof(LV_ITEM));
|
|
//lvi.mask = LVIF_TEXT | LVIF_IMAGE;
|
|
lvi.mask = LVIF_TEXT;
|
|
lvi.stateMask = LVIS_DROPHILITED | LVIS_FOCUSED | LVIS_SELECTED;
|
|
lvi.pszText = szLabel;
|
|
lvi.iItem = m_nDragIndex;
|
|
lvi.cchTextMax = 255;
|
|
this->GetItem(&lvi);
|
|
|
|
//INSERT THE DROPPED ITEM
|
|
if(m_nDropIndex < 0) m_nDropIndex = this->GetItemCount();
|
|
lvi.iItem = m_nDropIndex;
|
|
this->InsertItem(&lvi);
|
|
|
|
//FILL IN ALL OF THE COLUMNS
|
|
CHeaderCtrl* pHeader = (CHeaderCtrl*)this->GetDlgItem(0);
|
|
int nColumnCount = pHeader->GetItemCount();
|
|
lvi.mask = LVIF_TEXT;
|
|
lvi.iItem = m_nDropIndex;
|
|
//INDEX OF DRAGGED ITEM WILL CHANGE IF ITEM IS DROPPED ABOVE ITSELF
|
|
if(m_nDragIndex > m_nDropIndex) m_nDragIndex++;
|
|
for(int col=1; col < nColumnCount; col++)
|
|
{
|
|
_tcscpy(lvi.pszText, (LPCTSTR)(this->GetItemText(m_nDragIndex,
|
|
col)));
|
|
lvi.iSubItem = col;
|
|
this->SetItem(&lvi);
|
|
}
|
|
BOOL b = this->GetCheck(m_nDragIndex);
|
|
this->SetCheck( m_nDropIndex , b );
|
|
DWORD dw = this->GetItemData(m_nDragIndex);
|
|
this->SetItemData( m_nDropIndex , dw );
|
|
|
|
|
|
//DELETE THE ITEM THAT WAS DRAGGED FROM ITS ORIGINAL LOCATION
|
|
this->DeleteItem(m_nDragIndex);
|
|
|
|
if ( m_bReSort ) //重排
|
|
{
|
|
ReShowSort();
|
|
}
|
|
|
|
//FIX HEADER - it disappears if item was scrolled & dropped;
|
|
pHeader->RedrawWindow();
|
|
}
|
|
|
|
void CSortList::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
//NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
|
|
|
|
|
*pResult = 0;
|
|
|
|
m_nDragIndex = ((NM_LISTVIEW *)pNMHDR)->iItem;
|
|
|
|
//CREATE A DRAG IMAGE FROM THE CENTER POINT OF THE ITEM IMAGE
|
|
POINT pt;
|
|
pt.x = 8;
|
|
pt.y = 8;
|
|
m_pDragImage = this->CreateDragImage(m_nDragIndex, &pt);
|
|
m_pDragImage->BeginDrag(0, CPoint (8, 8));
|
|
m_pDragImage->DragEnter(
|
|
GetDesktopWindow(), ((NM_LISTVIEW *)pNMHDR)->ptAction);
|
|
|
|
//SET THE FLAGS INDICATING A DRAG IN PROGRESS
|
|
m_bDragging = TRUE;
|
|
m_nDropIndex = -1;
|
|
m_pDropWnd = this;
|
|
|
|
//CAPTURE ALL MOUSE MESSAGES IN CASE THE USER DRAGS OUTSIDE OF THE VIEW
|
|
SetCapture();
|
|
}
|
|
|
|
void CSortList::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
if( m_bDragging )
|
|
{
|
|
m_ptDropPoint = point;
|
|
ClientToScreen(&m_ptDropPoint);
|
|
|
|
//MOVE THE DRAG IMAGE
|
|
m_pDragImage->DragMove(m_ptDropPoint);
|
|
|
|
//TEMPORARILY UNLOCK WINDOW UPDATES
|
|
m_pDragImage->DragShowNolock(FALSE);
|
|
|
|
//CONVERT THE DROP POINT TO CLIENT CO-ORDIANTES
|
|
m_pDropWnd = WindowFromPoint(m_ptDropPoint);
|
|
m_pDropWnd->ScreenToClient(&m_ptDropPoint);
|
|
|
|
//SCROLL VIEW IF NECESSARY
|
|
int iOverItem = this->HitTest(m_ptDropPoint);
|
|
int iTopItem = this->GetTopIndex();
|
|
int iBottomItem = iTopItem + this->GetCountPerPage() - 1;
|
|
if (iOverItem == iTopItem && iTopItem != 0)
|
|
{
|
|
this->EnsureVisible(iOverItem - 1, false);
|
|
::UpdateWindow(this->m_hWnd);
|
|
}
|
|
else if (iOverItem == iBottomItem && iBottomItem != (this->GetItemCount() - 1))
|
|
{
|
|
this->EnsureVisible(iOverItem + 1, false);
|
|
::UpdateWindow(this->m_hWnd);
|
|
}
|
|
|
|
//LOCK WINDOW UPDATES
|
|
m_pDragImage->DragShowNolock(TRUE);
|
|
}
|
|
|
|
CListCtrl::OnMouseMove(nFlags, point);
|
|
}
|
|
|
|
void CSortList::ReShowSort()
|
|
{
|
|
long lCount = this->GetItemCount();
|
|
TCHAR Buf[32];
|
|
long lIndex = 1;
|
|
for ( int i=0 ; i< lCount ; i++ )
|
|
{
|
|
if ( this->GetCheck(i) )
|
|
{
|
|
_stprintf(Buf , _T("%d") , lIndex );
|
|
this->SetItemText( i , 0 , Buf );
|
|
lIndex ++;
|
|
}
|
|
else
|
|
this->SetItemText( i , 0 , _T(" ") );
|
|
}
|
|
}
|
|
|
|
void CSortList::NoverCheck()
|
|
{
|
|
if ( m_lCheck1 >=0 ) //每次必选
|
|
{
|
|
long lCount=this->GetItemCount();
|
|
for (int i = 0 ; i<lCount ; i++ )
|
|
{
|
|
if ( GetItemData(i) == m_lCheck1 )
|
|
SetCheck(i , true );
|
|
if ( GetItemData(i) == m_lCheck2 )
|
|
SetCheck(i , true );
|
|
if ( GetItemData(i) == m_lCheck3 )
|
|
SetCheck(i , true );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CSortList::CheckAll()
|
|
{
|
|
long lCount = GetItemCount();
|
|
for ( int i = 0 ; i<lCount;i++ )
|
|
SetCheck(i,true);
|
|
ReShowSort();
|
|
}
|
|
|
|
void CSortList::ClearAll()
|
|
{
|
|
long lCount = GetItemCount();
|
|
for ( int i = 0 ; i<lCount;i++ )
|
|
SetCheck(i,false);
|
|
NoverCheck();
|
|
ReShowSort();
|
|
}
|