localfilelistctrl.cpp
来自「一个FTP下载的源代码。代码质量非常高」· C++ 代码 · 共 2,497 行 · 第 1/5 页
CPP
2,497 行
{
while (greaterbytime(m_FileData[m_IndexMapping[l]].Time, ref, m_FileData[m_IndexMapping[l]].bIsDir, bRefIsDir, m_FileData[m_IndexMapping[l]].lName, refname) && (l<ende)) l++;
while (lesserbytime (m_FileData[m_IndexMapping[r]].Time, ref, m_FileData[m_IndexMapping[r]].bIsDir, bRefIsDir, m_FileData[m_IndexMapping[r]].lName, refname) && (r>anf)) r--;
}
if (l<=r)
{
int tmp=m_IndexMapping[l];
m_IndexMapping[l]=m_IndexMapping[r];
m_IndexMapping[r]=tmp;
l++;
r--;
}
}
while (l<=r);
if (anf<r) quicksortbytime(direction, anf, r);
if (l<ende) quicksortbytime(direction, l, ende);
}
void CLocalFileListCtrl::SortList(int item, int direction)
{
UINT nID[4]={IDS_HEADER_FILENAME,IDS_HEADER_FILESIZE,IDS_HEADER_FILETYPE,IDS_HEADER_LASTMODIFIED};
if (!direction)
{
if (item!=m_sortcolumn)
m_sortdir=1;
else
{
m_sortdir=(++m_sortdir%3);
if (!m_sortdir)
m_sortdir++;
}
}
else if (direction != -1)
m_sortdir = direction;
if (item == -1)
item = m_sortcolumn;
CHeaderCtrl *header=GetHeaderCtrl();
if (header)
{
CString headertext;
headertext.LoadString(nID[m_Columns[m_sortcolumn]]);
HDITEM *hdi=new HDITEM;
hdi->pszText=headertext.GetBuffer(0);
hdi->cchTextMax=0;
hdi->mask= HDI_TEXT | HDI_FORMAT;
hdi->fmt=((m_Columns[m_sortcolumn]!=1)?HDF_LEFT:HDF_RIGHT) | HDF_STRING;
hdi->mask= HDI_TEXT | HDI_IMAGE | HDI_FORMAT;
hdi->iImage=0; // My ascending image list index
header->SetItem( m_sortcolumn, hdi );
headertext.ReleaseBuffer();
headertext.LoadString(nID[m_Columns[item]]);
hdi->pszText=headertext.GetBuffer(0);
hdi->mask= HDI_TEXT | HDI_IMAGE | HDI_FORMAT;
hdi->iImage= m_sortdir; // My ascending image list index
hdi->fmt=((m_Columns[item]!=1)?HDF_LEFT:HDF_RIGHT) | HDF_IMAGE | HDF_STRING | HDF_BITMAP_ON_RIGHT;
header->SetItem( item, hdi );
delete hdi;
headertext.ReleaseBuffer();
}
m_sortcolumn = item;
if (GetItemCount()<=1)
return;
std::list<int> SelectedItemsList;
int i;
for (i=1; i<GetItemCount(); i++)
{
if (GetItemState( i, LVIS_SELECTED))
{
SelectedItemsList.push_back(m_IndexMapping[i]);
SetItemState( i, 0, LVIS_SELECTED);
}
}
if (!m_Columns[item])
{ //Sort by filename
BOOL dir=m_sortdir==1;
quicksortbyname(dir, 1, GetItemCount()-1);
}
if (m_Columns[item]==2)
{ //Sort by filetype
//Since this is a column that is filled while displaying,
//we have to load the filetypes for every file
std::vector<CString> array;
array.resize(GetItemCount()+1);
array[0]=_T("");
for (int i=1; i<GetItemCount(); i++)
{
array[i]=GetType(m_FileData[i].lName, m_FileData[i].bIsDir);
array[i].MakeLower();
}
BOOL dir=m_sortdir==1;
quicksortbytype(array, dir, 1, GetItemCount()-1);
}
else if (m_Columns[m_sortcolumn]==1)
{
BOOL dir=m_sortdir==1;
quicksortbysize(dir, 1, GetItemCount()-1);
}
else if (m_Columns[m_sortcolumn]==3)
{
BOOL dir=m_sortdir==1;
quicksortbytime(dir, 1, GetItemCount()-1);
}
for (i=1; i<GetItemCount(); i++)
{
int nIndex=m_IndexMapping[i];
if (SelectedItemsList.empty())
break;
for (std::list<int>::iterator iter=SelectedItemsList.begin(); iter!=SelectedItemsList.end(); iter++)
if (*iter==nIndex)
{
SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
SelectedItemsList.erase(iter);
break;
}
}
RedrawItems(0,GetItemCount());
}
void CLocalFileListCtrl::OnContextMenu(CWnd* pWnd, CPoint point)
{
m_transferuser=m_transferpass="";
if (!GetItemCount())
return;
CMenu menu;
menu.LoadMenu(IDR_LOCALCONTEXTMENU);
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;
//while (pWndPopupOwner->GetStyle() & WS_CHILD)
// pWndPopupOwner = pWndPopupOwner->GetParent();
POSITION selpos=GetFirstSelectedItemPosition();
if (!selpos)
{
pPopup->EnableMenuItem(ID_LOCALCONTEXT_UPLOAD, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_UPLOADAS, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_ADDTOQUEUE, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_DELETE, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_RENAME, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_OPEN, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_PROPERTIES, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_VIEWEDIT, MF_GRAYED);
if (point.x==-1 || point.y==-1)
{
point.x=5;
point.y=5;
ClientToScreen(&point);
}
}
else
{
int nItem = GetNextSelectedItem(selpos);
if (point.x==-1 || point.y==-1)
{
CRect rect;
GetItemRect(nItem,&rect,LVIR_LABEL);
point.x=rect.left+5;
point.y=rect.top+5;
ClientToScreen(&point);
}
int index=m_IndexMapping[nItem];
if (m_Fullpath=="")
{
pPopup->EnableMenuItem(ID_LOCALCONTEXT_CREATEDIRECTORY, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_RENAME, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_DELETE, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_UPLOAD, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_UPLOADAS, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_ADDTOQUEUE, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_VIEWEDIT, MF_GRAYED);
}
else if (!nItem)
{
pPopup->EnableMenuItem(ID_LOCALCONTEXT_UPLOAD, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_UPLOADAS, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_ADDTOQUEUE, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_DELETE, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_RENAME, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_PROPERTIES, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_VIEWEDIT, MF_GRAYED);
}
if (m_FileData[index].bIsDir)
pPopup->EnableMenuItem(ID_LOCALCONTEXT_VIEWEDIT, MF_GRAYED);
nItem = GetNextSelectedItem(selpos);
while (nItem!=-1)
{
pPopup->EnableMenuItem(ID_LOCALCONTEXT_PROPERTIES, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_RENAME, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_OPEN, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_VIEWEDIT, MF_GRAYED);
int index=m_IndexMapping[nItem];
if (!nItem)
{
pPopup->EnableMenuItem(ID_LOCALCONTEXT_UPLOAD,MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_UPLOADAS,MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALCONTEXT_ADDTOQUEUE,MF_GRAYED);
}
nItem = GetNextSelectedItem(selpos);
}
}
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
pWndPopupOwner);
}
void CLocalFileListCtrl::OnLocalcontextOpen()
{
POSITION selpos=GetFirstSelectedItemPosition();
if (!selpos)
return;
int nItem = GetNextSelectedItem(selpos);
int index=m_IndexMapping[nItem];
if (m_FileData[index].bIsDir)
{
CString newpath;
CString text=GetItemText(nItem,0);
if (text=="..")
{
newpath=m_Fullpath;
newpath.TrimRight('\\');
int pos=newpath.ReverseFind('\\');
ASSERT(pos!=-1);
newpath=newpath.Left(pos+1);
}
else
newpath=m_Fullpath+m_FileData[index].Name+"\\";
m_pOwner->SetLocalFolder(newpath);
m_pOwner->SetLocalFolderOut(newpath);
}
else
{
CString file=m_Fullpath+m_FileData[index].Name;
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.lpFile = file;
sei.nShow = SW_SHOWNORMAL;
BOOL b = ShellExecuteEx(&sei);
}
}
void CLocalFileListCtrl::OnLocalcontextUpload()
{
POSITION selpos=GetFirstSelectedItemPosition();
CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
while (selpos)
{
int nItem = GetNextSelectedItem(selpos);
if (!nItem || m_Fullpath=="")
continue;
int index=m_IndexMapping[nItem];
if (m_FileData[index].bIsDir)
UploadDir(m_Fullpath+m_FileData[index].Name+"\\*.*", m_FileData[index].Name+"\\", TRUE);
else
pMainFrame->AddQueueItem(FALSE, m_FileData[index].Name, "", m_Fullpath, CServerPath(), TRUE, m_transferuser, m_transferpass);
}
pMainFrame->TransferQueue(2);
}
void CLocalFileListCtrl::OnLocalcontextAddtoqueue()
{
POSITION selpos=GetFirstSelectedItemPosition();
CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
while (selpos)
{
int nItem = GetNextSelectedItem(selpos);
if (!nItem || m_Fullpath=="")
continue;
int index=m_IndexMapping[nItem];
if (m_FileData[index].bIsDir)
UploadDir(m_Fullpath+m_FileData[index].Name+"\\*.*", m_FileData[index].Name+"\\", FALSE);
else
pMainFrame->AddQueueItem(FALSE, GetItemText(nItem,0), "", m_Fullpath, CServerPath(), FALSE, m_transferuser, m_transferpass);
}
}
void CLocalFileListCtrl::OnLocalcontextDelete()
{
POSITION selpos=GetFirstSelectedItemPosition();
CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
if (!selpos)
return;
int len=1;
while (selpos)
{
int nItem = GetNextSelectedItem(selpos);
if (!nItem || m_Fullpath=="")
continue;
int index=m_IndexMapping[nItem];
len+=m_Fullpath.GetLength()+m_FileData[index].Name.GetLength()+1;
}
LPTSTR buffer = new TCHAR[len];
memset(buffer, 0, len*sizeof(TCHAR));
selpos=GetFirstSelectedItemPosition();
ASSERT(selpos);
int bufpos=0;
std::list<CString> FileList;
BOOL bDirDeleted=FALSE;
while (selpos)
{
int nItem = GetNextSelectedItem(selpos);
if (!nItem || m_Fullpath=="")
continue;
int index=m_IndexMapping[nItem];
FileList.push_back(m_FileData[index].lName);
if (m_FileData[index].bIsDir)
bDirDeleted=TRUE;
_tcscpy(buffer+bufpos, m_Fullpath+m_FileData[index].Name);
bufpos+=m_Fullpath.GetLength()+m_FileData[index].Name.GetLength()+1;
}
SHFILEOPSTRUCT op;
memset(&op,0,sizeof(op));
op.hwnd=m_hWnd;
op.wFunc=FO_DELETE;
op.fFlags=(GetKeyState(VK_SHIFT)&128)?0:FOF_ALLOWUNDO;
op.pFrom=buffer;
SHFileOperation(&op);
delete buffer;
if (bDirDeleted)
pMainFrame->RefreshViews(1);
else
{
m_bUpdating = TRUE;
for (std::list<CString>::const_iterator iter=FileList.begin(); iter!=FileList.end(); iter++)
RefreshFile(m_Fullpath+*iter);
m_bUpdating = FALSE;
UpdateStatusBar();
}
}
void CLocalFileListCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar==46)
OnLocalcontextDelete();
else if (nChar==VK_F2)
{
// To Use F2 as hot Key to get EditCtrl on the ListView it must have
// the Style LVS_EDITLABELS
ASSERT( GetStyle() & LVS_EDITLABELS );
// don't do an Edit Label when the multiple Items are selected
if( GetSelectedCount( ) == 1 )
{
UINT nListSelectedItem = GetSelectedItem();
VERIFY( EditLabel( nListSelectedItem ) != NULL );
}
else
CListCtrl::OnKeyDown( nChar, nRepCnt, nFlags );
}
else if (nChar==VK_BACK)
{
if (GetItemCount() && m_IndexMapping.size())
{
int nIndex=m_IndexMapping[0];
if (m_FileData[nIndex].bIsDir)
{
if (m_Fullpath!="")
{
CString newpath;
newpath=m_Fullpath;
newpath.TrimRight('\\');
int pos=newpath.ReverseFind('\\');
newpath=newpath.Left(pos+1);
m_pOwner->SetLocalFolder(newpath);
m_pOwner->SetLocalFolderOut(newpath);
}
}
}
}
CListCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CLocalFileListCtrl::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
{
//Start of a Drag&Drop operation
*pResult = 0;
if (m_Fullpath == _T("") || m_Fullpath == _T("\\"))
return;
POSITION selpos=GetFirstSelectedItemPosition();
while (selpos)
{
int nItem = GetNextSelectedItem(selpos);
if (!nItem)
return;
}
EnsureVisible(((LPNMLISTVIEW)pNMHDR)->iItem, FALSE);
//Let the main window handle the rest
CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
pMainFrame->OnBegindrag(this, ((LPNMLISTVIEW)pNMHDR)->ptAction);
}
void CLocalFileListCtrl::OnDropFiles(HDROP hDropInfo)
{
if (!GetItemCount())
{
DragFinish(hDropInfo);
return;
}
int dropcount=DragQueryFile(hDropInfo,0xFFFFFFFF,0,0);
LPTSTR fullnames=0;
int fulllen=0;
for (int i=0;i<dropcount;i++)
{
int len=DragQueryFile(hDropInfo,i,0,0)+1;
fullnames=(LPTSTR)realloc(fullnames,(fulllen+len+1)*sizeof(TCHAR));
DragQueryFile(hDropInfo,i,&fullnames[fulllen],len);
fulllen+=len;
}
fullnames[fulllen]=0;
CString path=m_Fullpath;
SHFILEOPSTRUCT opstruct;
opstruct.hwnd=m_hWnd;
opstruct.wFunc=FO_COPY;
opstruct.pFrom=fullnames;
opstruct.pTo=path;
opstruct.fFlags=FOF_ALLOWUNDO;
SHFileOperation(&opstruct);
DragFinish(hDropInfo);
free(fullnames);
CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
pMainFrame->RefreshViews(1);
}
void CLocalFileListCtrl::UploadDir(CString dir, CString subdir, BOOL upload)
{
while (dir.Replace(_T("\\\\"), _T("\\")));
CMainFrame *pMainFrame = DYNAMIC_DOWNCAST(CMainFrame, GetParentFrame());
CFileFind find;
BOOL res = find.FindFile(dir);
while (res)
{
BOOL bDirIsEmpty = TRUE;
res = find.FindNextFile();
if (find.IsDirectory())
{
if (!find.IsDots())
{
bDirIsEmpty = FALSE;
UploadDir(find.GetFilePath()+"\\*.*", subdir+find.GetFileName()+"\\", upload);
}
}
else
{
bDirIsEmpty = FALSE;
CString sdir="";
CString path=subdir;
path.TrimLeft( _T("\\") );
path.TrimRight(_T("\\") );
while (path!=_T("") )
{
CString tmp;
int pos=path.Find( _T("\\") );
if (pos==-1)
{
tmp.Format(_T(" %d %s"), path.GetLength(), path);
path="";
}
else
{
tmp.Format(_T(" %d %s"), path.Left(pos).GetLength(), path.Left(pos));
path=path.Mid(pos+1);
}
sdir+=tmp;
}
sdir.TrimLeft( _T(" ") );
CString lPath=find.GetFilePath();
int pos=lPath.ReverseFind('\\');
ASSERT(pos!=-1);
lPath=lPath.Left(pos+1);
pMainFrame->AddQueueItem(FALSE, find.GetFileName(), sdir, lPath, CServerPath(), upload, m_transferuser, m_transferpass);
}
if (bDirIsEmpty)
{
CServerPath serverpath = reinterpret_cast<CFtpListCtrl *>(pMainFrame->GetFtpPane()->GetListCtrl())->GetCurrentDirectory();
if (!serverpath.IsEmpty())
{
CString sdir;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?