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 + -
显示快捷键?