📄 sclistctrl.cpp
字号:
// ScListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "agsm2.h"
#include "ScListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CScListCtrl
CScListCtrl::CScListCtrl()
{
m_bDragging = FALSE;
m_pimagelist = NULL;
m_bSortAscending = TRUE;
}
CScListCtrl::~CScListCtrl()
{
}
BEGIN_MESSAGE_MAP(CScListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CScListCtrl)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBegindrag)
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteitem)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CScListCtrl message handlers
void CScListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
int iColumn = pNMListView->iSubItem;
TRACE("%d Column click.\n",iColumn);
if(iColumn == 0)
return;
if(iColumn == m_iSortColumn)
m_bSortAscending = !m_bSortAscending;
else
m_bSortAscending = TRUE;
m_iSortColumn = iColumn;
SortItems(ScCompareProc,reinterpret_cast<DWORD>(this));
char buf[8];
for(int i=0; i<GetItemCount(); i++)
{
sprintf(buf,"%d",i+1);
SetItemText(i,0,buf);
SCLIST_ITEMDATA *ItemData = (SCLIST_ITEMDATA *)GetItemData(i);
ItemData->nItem = i;
}
if(GetSelectedCount())
EnsureVisible((int)GetFirstSelectedItemPosition()-1,FALSE);
*pResult = 0;
}
BOOL CScListCtrl::AddItem(int nItem, int nSubItem, LPCTSTR strItem, int nImageIndex)
{
LV_ITEM lvItem;
lvItem.mask = LVIF_TEXT;
lvItem.iItem = nItem;
lvItem.iSubItem = nSubItem;
lvItem.pszText = (LPTSTR) strItem;
if(nImageIndex != -1){
lvItem.mask |= LVIF_IMAGE;
lvItem.iImage |= LVIF_IMAGE;
}
SCLIST_ITEMDATA *pItemData;
if(nSubItem == 0)
{
BOOL ret = InsertItem(&lvItem);
//sort function use the ItemData.
pItemData = (SCLIST_ITEMDATA *)this->GetItemData(nItem);
if(pItemData)
{
if(pItemData->ItemData)
free((void *)pItemData->ItemData);
}else
pItemData = (SCLIST_ITEMDATA *)malloc(sizeof(SCLIST_ITEMDATA));
pItemData->nItem = nItem;
pItemData->ItemData = 0;
pItemData->dirty = FALSE;
SetItemData(nItem,(DWORD)pItemData);
return ret;
}
pItemData = (SCLIST_ITEMDATA *)this->GetItemData(nItem);
pItemData->dirty = TRUE;
return SetItem(&lvItem);
}
void CScListCtrl::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
TRACE("OnBegindrag\n");
CPoint ptAction;
UINT nFlags;
GetCursorPos(&ptAction);
ScreenToClient(&ptAction);
ASSERT(!m_bDragging);
m_bDragging = TRUE;
m_nitemDrag = HitTest(ptAction, &nFlags);
m_nitemDrop = NULL;
TRACE("nItemDrag=%d\n",m_nitemDrag);
ASSERT(m_pimagelist == NULL);
m_pimagelist = CreateDragImage(m_nitemDrag,&ptAction); // get the image list for dragging
m_pimagelist->DragShowNolock(TRUE);
m_pimagelist->SetDragCursorImage(0, CPoint(0, 0));
m_pimagelist->BeginDrag(0, CPoint(0,0));
m_pimagelist->DragMove(ptAction);
m_pimagelist->DragEnter(this, ptAction);
SetCapture();
*pResult = 0;
}
void CScListCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
TRACE("OnEndlabeledit\n");
*pResult = 0;
}
void CScListCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
int nitem;
UINT flags;
if (m_bDragging)
{
ASSERT(m_pimagelist != NULL);
m_pimagelist->DragMove(point);
if ((nitem = HitTest(point, &flags)) >= 0)
{
m_nitemDrop = nitem;
}
}
CListCtrl::OnMouseMove(nFlags, point);
}
void CScListCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (m_bDragging)
{
ASSERT(m_pimagelist != NULL);
m_pimagelist->DragLeave(this);
m_pimagelist->EndDrag();
delete m_pimagelist;
m_pimagelist = NULL;
if (m_nitemDrag != m_nitemDrop)
{
//change m_nitemDrag and m_nitemDrop
int cc = GetColumnCount();
CString str1,str2;
for(int i=1; i<cc; i++)
{
str1 = GetItemText(m_nitemDrag,i);
str2 = GetItemText(m_nitemDrop,i);
AddItem(m_nitemDrag,i,str2);
AddItem(m_nitemDrop,i,str1);
}
}
else
MessageBeep(0);
ReleaseCapture();
m_bDragging = FALSE;
}
CListCtrl::OnLButtonUp(nFlags, point);
}
int CScListCtrl::GetColumnCount()
{
int i = 0;
LVCOLUMN col;
col.mask = LVCF_WIDTH;
do{
if(GetColumn(i, &col))
i++;
else
break;
}while(1);
return i;
}
void CScListCtrl::MoveUp()
{
POSITION pos = GetFirstSelectedItemPosition();
if((int)pos > 1)
{
int cc = GetColumnCount();
CString str1,str2;
for(int i=1; i<cc; i++)
{
str1 = GetItemText((int)pos-1,i);
str2 = GetItemText((int)pos-2,i);
AddItem((int)pos-1,i,str2);
AddItem((int)pos-2,i,str1);
}
SetItem((int)pos-1, 0, LVIF_STATE, NULL, 0, ~LVIS_SELECTED,
LVIS_SELECTED, 0);
SetItem((int)pos-2, 0, LVIF_STATE, NULL, 0, LVIS_SELECTED,
LVIS_SELECTED, 0);
EnsureVisible((int)pos-2, FALSE);
}
}
void CScListCtrl::MoveDown()
{
POSITION pos = GetFirstSelectedItemPosition();
if(pos && (int)pos < GetItemCount())
{
int cc = GetColumnCount();
CString str1,str2;
for(int i=1; i<cc; i++)
{
str1 = GetItemText((int)pos-1,i);
str2 = GetItemText((int)pos,i);
AddItem((int)pos-1,i,str2);
AddItem((int)pos,i,str1);
}
SetItem((int)pos-1, 0, LVIF_STATE, NULL, 0, ~LVIS_SELECTED,
LVIS_SELECTED, 0);
SetItem((int)pos, 0, LVIF_STATE, NULL, 0, LVIS_SELECTED,
LVIS_SELECTED, 0);
EnsureVisible((int)pos, FALSE);
}
}
int CALLBACK CScListCtrl::ScCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
// lParamSort contains a pointer to the list view control.
// The lParam of an item is just its index.
CScListCtrl* pListCtrl = (CScListCtrl*) lParamSort;
int nItem1 = ((SCLIST_ITEMDATA *)lParam1)->nItem;
int nItem2 = ((SCLIST_ITEMDATA *)lParam2)->nItem;
CString strItem1 = pListCtrl->GetItemText(nItem1, pListCtrl->m_iSortColumn);
CString strItem2 = pListCtrl->GetItemText(nItem2, pListCtrl->m_iSortColumn);
if(pListCtrl->m_bSortAscending)
{
if(*strItem2 == 0)
return -1;
else
return strcmp(strItem1, strItem2);
}else{
// Sort the item in reverse alphabetical order
return strcmp(strItem2, strItem1);
}
}
BOOL CScListCtrl::Find(CString what, CString replace, BOOL mcase, int dir/*0 up 1 down*/,BOOL ReplaceAll)
{
BOOL ret = FALSE;
POSITION pos = GetFirstSelectedItemPosition();
if(dir)//down
{
int from = 0,to = 0;
if(pos)
from = (int)pos;
to = GetItemCount();
int i;
if((i = FindItemString(from,to,what,replace,mcase,ReplaceAll)) > -1)
{
SetItem(((int)pos == GetItemCount()) ? (GetItemCount() - 1) : from-1,
0, LVIF_STATE, NULL, 0, ~LVIS_SELECTED,
LVIS_SELECTED, 0);
if(!ReplaceAll)
return TRUE;
else
ret = TRUE;
}
if(from != 0)
{
if((i = FindItemString(0,from,what,replace,mcase,ReplaceAll)) > -1)
{
SetItem(((int)pos == GetItemCount()) ? (GetItemCount() - 1) : from-1,
0, LVIF_STATE, NULL, 0, ~LVIS_SELECTED,
LVIS_SELECTED, 0);
if(!ReplaceAll)
return TRUE;
else
ret = TRUE;
}
}
}else{
int from = this->GetItemCount()-1;
int to = -1;
if((int)pos > 1)
from = (int)pos-2;
int i;
int cc = GetColumnCount();
if((i = FindItemString(from,to,what,replace,mcase,ReplaceAll)) > -1)
{
SetItem(((int)pos == 1) ? 0 : from+1,
0, LVIF_STATE, NULL, 0, ~LVIS_SELECTED,
LVIS_SELECTED, 0);
if(!ReplaceAll)
return TRUE;
else
ret = TRUE;
}
if(from != GetItemCount()-1)
{
if((i = FindItemString(GetItemCount()-1,from,what,replace,mcase,ReplaceAll)) > -1)
{
SetItem(((int)pos == 1) ? 0 : from+1,
0, LVIF_STATE, NULL, 0, ~LVIS_SELECTED,
LVIS_SELECTED, 0);
if(!ReplaceAll)
return TRUE;
else
ret = TRUE;
}
}
}
return ret;
}
BOOL CScListCtrl::FindItemString(int from, int to, CString what, CString replace, BOOL mcase,BOOL ReplaceAll)
{
int rret = -1;
int cc = GetColumnCount();
if(from < to)
{
for(int i=from; i<to; i++)
{
CString str;
for(int j=1; j<cc; j++)
{
str = GetItemText(i,j);
if(!mcase)
{
str.MakeLower();
what.MakeLower();
}
int ret = -1;
if(replace == _T(""))
ret = str.Find(what);
else
{
ret = str.Replace(what,replace);
if(ret == 0)
ret = -1;
else{
AddItem(i,j,str);
}
}
if(ret > -1)
{
SetItem(i, 0, LVIF_STATE, NULL, 0, LVIS_SELECTED,
LVIS_SELECTED, 0);
EnsureVisible(i, FALSE);
if(!ReplaceAll)
return i;
else
rret = i;
}
}
}
}else{
for(int i=from; i>to; i--)
{
CString str;
for(int j=1; j<cc; j++)
{
str = GetItemText(i,j);
if(!mcase)
{
str.MakeLower();
what.MakeLower();
}
int ret = -1;
if(replace == _T(""))
ret = str.Find(what);
else
{
ret = str.Replace(what,replace);
if(ret == 0)
ret = -1;
else{
AddItem(i,j,str);
}
}
if(ret > -1)
{
SetItem(i, 0, LVIF_STATE, NULL, 0, LVIS_SELECTED,
LVIS_SELECTED, 0);
EnsureVisible(i, FALSE);
if(!ReplaceAll)
return i;
else
rret = i;
}
}
}
}
return rret;
}
void CScListCtrl::Delete()
{
ULONG uSelectedCount = GetSelectedCount();
int cc = GetColumnCount();
ULONG i;
int nItem = -1;
if (uSelectedCount > 0)
{
for (i=0;i < uSelectedCount;i++)
{
nItem = GetNextItem(nItem, LVNI_SELECTED);
ASSERT(nItem != -1);
for(int j=1; j<cc; j++)
AddItem(nItem,j,"");
}
}
}
void CScListCtrl::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
//TRACE("Delete Item %d\n",pNMListView->iItem);
SCLIST_ITEMDATA *pItemData = (SCLIST_ITEMDATA *)GetItemData(pNMListView->iItem);
if(pItemData)
{
if(pItemData->ItemData)
free((void *)pItemData->ItemData);
free(pItemData);
}
*pResult = 0;
}
void CScListCtrl::CopySelectedItems()
{
ULONG uSelectedCount = GetSelectedCount();
if(uSelectedCount)
{
if ( !OpenClipboard() )
{
AfxMessageBox( "Cannot open the Clipboard" );
return;
}
// Remove the current Clipboard contents
if( !EmptyClipboard() )
{
AfxMessageBox( "Cannot empty the Clipboard" );
return;
}
// Get the currently selected data
HANDLE hData;
LPVOID lpData;
if (!(hData = ::GlobalAlloc(GMEM_DDESHARE, 1024*uSelectedCount))) {
AfxMessageBox( "Out of memory" );
return;
}
if (!(lpData = GlobalLock(hData)))
{
AfxMessageBox( "Out of memory" );
return;
}
char *buf_base = (char *)malloc(1024*uSelectedCount);
char *buf = buf_base;
ULONG i;
int nItem = -1;
// Update all of the selected items.
if (uSelectedCount > 0)
{
for (i=0;i < uSelectedCount;i++)
{
nItem = GetNextItem(nItem, LVNI_SELECTED);
ASSERT(nItem != -1);
int cc = GetColumnCount();
for(int j=0; j<cc; j++)
{
CString str = GetItemText(nItem,j);
//CSV encoding...
if(str.FindOneOf(",\r\n\"") != -1)
{
str.Replace("\"","\"\"");//Microsot's 通讯簿 don't do this
str.Insert(0,'\"');
str.Insert(str.GetLength(),'\"');
TRACE("new CSV String %s\n",str);
}
buf += sprintf(buf,"%s,",str);
}
if(j)
buf -= 1; //remove the last ","
buf += sprintf(buf,"%s","\r\n");
}
}
memcpy(lpData,buf_base,strlen(buf_base)+1);
GlobalUnlock(hData);
free(buf_base);
// For the appropriate data formats...
if ( ::SetClipboardData(CF_TEXT, hData ) == NULL )
{
AfxMessageBox( "Unable to set Clipboard data" );
CloseClipboard();
return;
}
// ...
CloseClipboard();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -