localfilelistctrl.cpp

来自「一个FTP下载的源代码。代码质量非常高」· C++ 代码 · 共 2,497 行 · 第 1/5 页

CPP
2,497
字号
			m_FileData[nIndex].lName=find.cFileName;
			m_FileData[nIndex].lName.MakeLower();
			m_FileData[nIndex].nSize=bDir ? -1 : ((_int64)find.nFileSizeLow + ((_int64)find.nFileSizeHigh<<32));
			m_FileData[nIndex].Time=find.ftLastWriteTime;
			FileData=m_FileData[nIndex];
			unsigned int j;
			for (j=0; j<static_cast<int>(m_IndexMapping.size()); j++)
			{
				if (m_IndexMapping[j]==nIndex)
					break;
			}
			ASSERT(j!=m_IndexMapping.size());
			m_IndexMapping.erase(m_IndexMapping.begin()+j);
			if (GetItemState( j, LVIS_SELECTED))
				bSelected=TRUE;
			SetItemState( j, 0, LVIS_SELECTED);
			for (int nItem=j+1;nItem<GetItemCount();nItem++)
			{
				if (GetItemState( nItem, LVIS_SELECTED))
				{
					SetItemState( nItem, 0, LVIS_SELECTED);
					SetItemState( nItem-1, LVIS_SELECTED, LVIS_SELECTED);
				}
			}
			datapos=nIndex;
			count--;
		}
		else
		{
			FileData.Name=find.cFileName;
			FileData.lName=find.cFileName;
			FileData.lName.MakeLower();
			FileData.bIsDir=bDir;
			FileData.nSize=bDir ? -1 : ((_int64)find.nFileSizeLow + ((_int64)find.nFileSizeHigh<<32));
			FileData.Time=find.ftLastWriteTime;
			m_FileData.push_back(FileData);
			datapos=count;
			SetItemCount(GetItemCount()+1);
		}
		CString filetype;
		if (m_Columns[m_sortcolumn]==2)
		{
			filetype=GetType(FileData.lName, FileData.bIsDir);
			filetype.MakeLower();
		}
		
		if (count>1)
		{ //Binary search for optimal position to insert file sorted.
			int anf=1;
			int ende=count-1;
			
			int mitte;
			while(anf<=ende)
			{
				mitte=(anf+ende)/2;
				
				t_FileData CompareData=m_FileData[m_IndexMapping[mitte]];
				BOOL res;
				if (!m_Columns[m_sortcolumn]) //Chose compare function based on column and direction
					if (m_sortdir==1)
						res=lesser(CompareData.lName, FileData.lName, CompareData.bIsDir, FileData.bIsDir);
					else
						res=greater(CompareData.lName, FileData.lName, CompareData.bIsDir, FileData.bIsDir);
					else if (m_Columns[m_sortcolumn]==1)
						if (m_sortdir==1)
							res=lesserbysize(CompareData.nSize, FileData.nSize, CompareData.bIsDir, FileData.bIsDir, CompareData.lName, FileData.lName);
						else
							res=greaterbysize(CompareData.nSize, FileData.nSize, CompareData.bIsDir, FileData.bIsDir, CompareData.lName, FileData.lName);
						else if (m_Columns[m_sortcolumn]==2)
						{
							CString typecompare=GetType(CompareData.lName, CompareData.bIsDir);
							typecompare.MakeLower();
							if (m_sortdir==1)
								res=lesserbytype(typecompare, filetype, CompareData.bIsDir, FileData.bIsDir, CompareData.lName, FileData.lName);
							else
								res=greaterbytype(typecompare, filetype, CompareData.bIsDir, FileData.bIsDir, CompareData.lName, FileData.lName);
						}
						else if (m_Columns[m_sortcolumn]==3)
							if (m_sortdir==1)
								res=lesserbytime(CompareData.Time, FileData.Time, CompareData.bIsDir, FileData.bIsDir, CompareData.lName, FileData.lName);
							else
								res=greaterbytime(CompareData.Time, FileData.Time, CompareData.bIsDir, FileData.bIsDir, CompareData.lName, FileData.lName);
							
							if (res)
								anf=mitte+1;
							else
							{
								ende=mitte-1;
								mitte--;
							}
			}
			m_IndexMapping.insert(m_IndexMapping.begin()+mitte+1, datapos);
			for (int nItem=GetItemCount()-1; nItem>(mitte+1); nItem--)
			{
				if (GetItemState( nItem-1, LVIS_SELECTED))
				{
					SetItemState( nItem-1, 0, LVIS_SELECTED);
					SetItemState( nItem, LVIS_SELECTED, LVIS_SELECTED);
				}
			}
			if (bSelected)
				SetItemState( mitte+1, LVIS_SELECTED, LVIS_SELECTED);
		}
		else
			m_IndexMapping.push_back(count);
	}
	if (hFind && hFind!=INVALID_HANDLE_VALUE)
		FindClose(hFind);
	RedrawItems(0, GetItemCount());
}

CString CLocalFileListCtrl::GetType(CString lName, BOOL bIsDir)
{
	CString type;
	std::map<CString, CString>::iterator typeIter=m_TypeCache.find(m_Fullpath+lName);
	if (typeIter==m_TypeCache.end())
	{
		CString str=PathFindExtension(lName);
		str.MakeLower();
		std::map<CString, CString>::iterator permTypeIter=m_permanentTypeCache.find(str);
		if (permTypeIter!=m_permanentTypeCache.end())
		{
			m_TypeCache[m_Fullpath+lName]=permTypeIter->second;
			type=permTypeIter->second;
		}
		else
		{
			SHFILEINFO shFinfo;
			CString path;
			path=m_Fullpath+lName;
			if (m_Fullpath=="")
				path+="\\";
			memset(&shFinfo,0,sizeof(SHFILEINFO));
			if (SHGetFileInfo(path,
				bIsDir?FILE_ATTRIBUTE_DIRECTORY:FILE_ATTRIBUTE_NORMAL,
				&shFinfo,
				sizeof( shFinfo ),
				SHGFI_TYPENAME))
			{
				type=shFinfo.szTypeName;
				if (type=="")
				{
					type=PathFindExtension(lName);
					if (type!="") 
						type=type.Mid(1);
					type.MakeUpper();
					if (type!="")
						type+="-file";
					else
						type="File";
				}
				else
				{
					CString str2=PathFindExtension(lName);
					if (!bIsDir && str2!="")
					{
						str2.MakeLower();
						m_permanentTypeCache[str2]=type;
					}
				}
			}
			else
			{
				type=PathFindExtension(lName);
				if (type!="") 
					type=type.Mid(1);
				type.MakeUpper();
				if (type!="")
					type+="-file";
				else
					type="File";
			}
			m_TypeCache[m_Fullpath+lName]=type;		
		}
	}
	else
		type=typeIter->second;
	return type;
}

void CLocalFileListCtrl::OnLocalcontextViewEdit()
{
	if (m_Fullpath=="")
		return;

	POSITION selpos=GetFirstSelectedItemPosition();
	if (!selpos)
		return;
	
	int nItem = GetNextSelectedItem(selpos);
	if (!nItem)
		return;
	
	int index=m_IndexMapping[nItem];

	if (m_FileData[index].bIsDir)
		return;

	CString file=m_FileData[index].lName;

	int pos=file.ReverseFind('.');
	if (pos!=-1)
	{
		CString fext=file.Mid(pos+1);
		fext.MakeLower();
		//Parse the file associations
		CString CustomAssociations=COptions::GetOption(OPTION_VIEWEDITCUSTOM);
		
		CString ext;
		CString prog;
		BOOL bDoExt=TRUE;
		while (CustomAssociations!="")
		{
			int pos=CustomAssociations.Find( _T(";") );
			if (bDoExt)
			{
				if (!pos || pos==-1 || pos==CustomAssociations.GetLength()-1)
					break;
				ext+=CustomAssociations.Left(pos);
				CustomAssociations=CustomAssociations.Mid(pos+1);
				if (CustomAssociations.Left(1)== _T(" "))
				{
					ext+=_T(";");
					CustomAssociations=CustomAssociations.Mid(1);
				}
				else
					bDoExt=FALSE;
			}
			else
			{
				if (!pos || pos==CustomAssociations.GetLength()-1)
					break;
				if (pos!=-1)
				{
					prog+=CustomAssociations.Left(pos);
					CustomAssociations=CustomAssociations.Mid(pos+1);
				}
				else
				{
					prog=CustomAssociations;
					CustomAssociations="";
				}
				if (CustomAssociations.Left(1)== _T(" "))
				{
					prog+=_T(";");
					CustomAssociations=CustomAssociations.Mid(1);
					if (CustomAssociations!="")
						continue;
				}
				
				ext.MakeLower();
				if (fext==ext)
				{ //We've found a file aassociation for this extension
					CString cmdLine;
					file=m_Fullpath+file;
					if (file.Find( _T(" ") )!=-1)
						file=_T("\"") + file + _T("\"");
					cmdLine=prog + _T(" ") + file;
					PROCESS_INFORMATION ProcessInformation;  
					STARTUPINFO startupinfo={0};
					startupinfo.cb=sizeof(startupinfo);
					LPTSTR str=new TCHAR[cmdLine.GetLength()+1];
					_tcscpy(str, cmdLine);
					if (CreateProcess(0, str, 0, 0, 0, 0, 0, 0, &startupinfo, &ProcessInformation))
					{
						CloseHandle(ProcessInformation.hThread);
						CloseHandle(ProcessInformation.hProcess);
					}
					delete [] str;
					return;;
				}
				ext="";
				prog="";
				bDoExt=TRUE;
			}
		}
	}
	//File has no extension or custom file association could not be found
	CString defprog=COptions::GetOption(OPTION_VIEWEDITDEFAULT);
	if (defprog=="")
	{
		AfxMessageBox(IDS_ERRORMSG_VIEWEDIT_NODEFPROG, MB_ICONEXCLAMATION);
		return;
	}
	CString cmdLine;
	file=m_Fullpath+file;
	if (file.Find( _T(" ") )!=-1)
		file=_T("\"") + file + _T("\"");
	cmdLine=defprog + _T(" ") + file;
	PROCESS_INFORMATION ProcessInformation;  
	STARTUPINFO startupinfo={0};
	startupinfo.cb=sizeof(startupinfo);
	LPTSTR str=new TCHAR[cmdLine.GetLength()+1];
	_tcscpy(str, cmdLine);
	if (CreateProcess(0, str, 0, 0, 0, 0, 0, 0, &startupinfo, &ProcessInformation))
	{
		CloseHandle(ProcessInformation.hThread);
		CloseHandle(ProcessInformation.hProcess);
	}
	delete [] str;
}

BOOL CLocalFileListCtrl::UpdateStatusBar()
{
	if (m_bUpdating)
		return FALSE;

	CString str;
	POSITION selpos = GetFirstSelectedItemPosition();
	
	int dircount = 0;
	int filecount = 0;
	_int64 size = 0;

	while (selpos)
	{
		int nItem = GetNextSelectedItem(selpos);
		if (!nItem)
			continue;

		int nIndex = m_IndexMapping[nItem];
		if (m_FileData[nIndex].bIsDir)
				dircount++;
			else
			{
				filecount++;
				size += m_FileData[nIndex].nSize;
			}
	}

	if (dircount || filecount)
	{
		if (!dircount)
			if (filecount == 1)
				str.Format(IDS_DIRINFO_SELECTED_FILE, size);
			else
				str.Format(IDS_DIRINFO_SELECTED_FILES, filecount, size);
		else if (!filecount)
			if (dircount == 1)
				str.LoadString(IDS_DIRINFO_SELECTED_DIR);
			else
				str.Format(IDS_DIRINFO_SELECTED_DIRS, dircount);
		else if (dircount == 1)
			if (filecount == 1)
				str.Format(IDS_DIRINFO_SELECTED_DIRANDFILE, size);
			else
				str.Format(IDS_DIRINFO_SELECTED_DIRANDFILES, filecount, size);
		else
			if (filecount == 1)
				str.Format(IDS_DIRINFO_SELECTED_DIRSANDFILE, dircount, size);
			else
				str.Format(IDS_DIRINFO_SELECTED_DIRSANDFILES, dircount, filecount, size);
		return m_pOwner->SetStatusBarText(str);
	}

	if (m_FileData.size() <= 1)
		str.LoadString(IDS_DIRINFO_EMPTY);
	else
	{
		for (unsigned int i=1; i<m_FileData.size(); i++)
			if (m_FileData[i].bIsDir)
				dircount++;
			else
			{
				filecount++;
				size += m_FileData[i].nSize;
			}
		if (!dircount)
			if (filecount == 1)
				str.Format(IDS_DIRINFO_FILE, size);
			else
				str.Format(IDS_DIRINFO_FILES, filecount, size);
		else if (!filecount)
			if (dircount == 1)
				str.LoadString(IDS_DIRINFO_DIR);
			else
				str.Format(IDS_DIRINFO_DIRS, dircount);
		else if (dircount == 1)
			if (filecount == 1)
				str.Format(IDS_DIRINFO_DIRANDFILE, size);
			else
				str.Format(IDS_DIRINFO_DIRANDFILES, filecount, size);
		else
			if (filecount == 1)
				str.Format(IDS_DIRINFO_DIRSANDFILE, dircount, size);
			else
				str.Format(IDS_DIRINFO_DIRSANDFILES, dircount, filecount, size);			
	}
	
	return m_pOwner->SetStatusBarText(str);
}

void CLocalFileListCtrl::OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	// TODO: Code f黵 die Behandlungsroutine der Steuerelement-Benachrichtigung hier einf黦en
	
	*pResult = 0;

	UpdateStatusBar();
}

void CLocalFileListCtrl::GetSortInfo(int &column, int &direction) const
{
	column = m_sortcolumn;
	direction = m_sortdir;
}

BOOL CLocalFileListCtrl::DragPosition(CImageList *pImageList, CWnd* pDragWnd, CPoint point)
{
	ScreenToClient(&point);
	int nItem = HitTest(point);

	int nIndex = -1;
	
	if (nItem != -1)
	{
		nIndex = m_IndexMapping[nItem];
		if (!m_FileData[nIndex].bIsDir)
			nIndex = -1;
	}
	if (pDragWnd == this)
	{
		POSITION selpos = GetFirstSelectedItemPosition();
		while (selpos)
		{
			int nSelectedItem = GetNextSelectedItem(selpos);
			if (nSelectedItem == nItem)
			{
				DragLeave(pImageList);
				return FALSE;
			}
		}
	}
	if (nIndex != -1)
	{
		if (nItem != m_nDragHilited)
		{
			pImageList->DragShowNolock(false);
			if (m_nDragHilited != -1)
			{
				SetItemState(m_nDragHilited, 0, LVIS_DROPHILITED);
				RedrawItems(m_nDragHilited, m_nDragHilited);
			}
			m_nDragHilited = nItem;
			SetItemState(nItem, LVIS_DROPHILITED, LVIS_DROPHILITED);
			RedrawItems(nItem, nIndex);
			UpdateWindow();
			pImageList->DragShowNolock(true);
		}
	}
	else
		DragLeave(pImageList);

	return TRUE;
}

void CLocalFileListCtrl::DragLeave(CImageList *pImageList)
{
	if (m_nDragHilited != -1)
	{
		if (pImageList)
			pImageList->DragShowNolock(false);
		SetItemState(m_nDragHilited, 0, LVIS_DROPHILITED);
		RedrawItems(m_nDragHilited, m_nDragHilited);
		UpdateWindow();
		if (pImageList)
			pImageList->DragShowNolock(true);
		m_nDragHilited = -1;
	}
}

void CLocalFileListCtrl::OnDragEnd(int target, CPoint point)
{
	m_transferuser = m_transferpass = "";
	if (target == 1)
		OnLocalcontextAddtoqueue();
	else if (!target)
		OnLocalcontextUpload();
	else if (target == 2 || target == 3)
	{
		if (m_Fullpath == _T("") ||
			m_Fullpath == _T("\\"))
			return;

		CString to;
		if (target == 2)
		{
			// Check if drag target is valid
			if (m_nDragHilited == -1)
			return;

			POSITION selpos = GetFirstSelectedItemPosition();
			while (selpos)
			{
				int nItem = GetNextSelectedItem(selpos);
				if (nIte

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?