localfilelistctrl.cpp

来自「一个支持FTP,SFTP的客户端程序」· C++ 代码 · 共 2,497 行 · 第 1/5 页

CPP
2,497
字号
			CString type=GetType(m_FileData[m_IndexMapping[pItem->iItem]].lName, m_FileData[m_IndexMapping[pItem->iItem]].bIsDir);
			lstrcpy(pItem->pszText,type);
		}
		else if (m_Columns[pItem->iSubItem]==1)
		{
			__int64 size=m_FileData[m_IndexMapping[pItem->iItem]].nSize;
			if (size!=-1)
			{
				int nFormat=COptions::GetOptionVal(OPTION_LOCALFILESIZEFORMAT);
				if (!nFormat)
					if (size<1024)
						nFormat=1;
					else if (size<(1024*1024))
						nFormat=2;
					else
						nFormat=3;
				
				CString tmp, sizestr;
				switch (nFormat)
				{
				case 1:
					sizestr.Format(_T("%I64d"), size);
					break;
				case 2:
					tmp.LoadString(IDS_SIZE_KBS);
					sizestr.Format(_T("%I64d %s"), size/1024, tmp);
					break;
				case 3:
					tmp.LoadString(IDS_SIZE_MBS);
					sizestr.Format(_T("%I64d %s"), size/1024/1024, tmp);
					break;
				default:
					ASSERT(FALSE);
				}
				lstrcpy(pItem->pszText,sizestr);
			}
		}
		else if (m_Columns[pItem->iSubItem]==3 && m_Fullpath!=_T("") && pItem->iItem && m_FileData[m_IndexMapping[pItem->iItem]].hasTime)
		{
			CTime time=m_FileData[m_IndexMapping[pItem->iItem]].Time;
			SYSTEMTIME timeDest;
			time.GetAsSystemTime( timeDest ) ;
		
			TCHAR text[512];
			if (!GetDateFormat(
				LOCALE_USER_DEFAULT,               // locale for which date is to be formatted
				DATE_SHORTDATE,             // flags specifying function options
				&timeDest,  // date to be formatted
				0,          // date format string
				text,          // buffer for storing formatted string
				512                // size of buffer
				))
				return;
			CString text2=text;
			
			if (!GetTimeFormat(
				LOCALE_USER_DEFAULT,               // locale for which date is to be formatted
				TIME_NOSECONDS|TIME_FORCE24HOURFORMAT,             // flags specifying function options
				&timeDest,  // date to be formatted
				0,          // date format string
				text,          // buffer for storing formatted string
				512                // size of buffer
				))
				return;
			text2+=" ";
			text2+=text;
			_tcscpy(pItem->pszText, text2);
		}
	}
	*pResult = 0;
}

void CLocalFileListCtrl::DisplayDrives()
{
	m_Fullpath = _T("");
	TCHAR  szDrives[128];
	LPTSTR pDrive;

	GetLogicalDriveStrings( sizeof(szDrives), szDrives );
	
	pDrive = szDrives;
	int count=0;
	while( *pDrive )
	{
		CString path=pDrive;
		t_FileData FileData;
		path.TrimRight('\\');
		FileData.Name=path;
		path.MakeLower();
		FileData.lName=path;
		FileData.nSize=-1;
		FileData.bIsDir=TRUE;
		m_FileData.push_back(FileData);
		m_IndexMapping.push_back(count);
		pDrive += _tcslen(pDrive) + 1;
		count++;
	}
	SetItemCount(count);
	SortList(m_sortcolumn,m_sortdir);

	for (int i = 1; i < GetItemCount(); i++)
	{
		if (m_selectionBuffer.empty())
			break;
		const CString& name = m_FileData[m_IndexMapping[i]].lName;
		std::set<CString>::iterator iter = m_selectionBuffer.find(name);
		if (iter != m_selectionBuffer.end())
		{
			SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
			m_selectionBuffer.erase(iter);
		}
	}

	UpdateStatusBar();
}

BOOL CLocalFileListCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) 
{
	if (message==WM_NOTIFY)
	{
		LPNMHDR  lpnmh = (LPNMHDR) lParam;
		
		if (lpnmh->code==LVN_ODFINDITEM)
		{
			NMLVFINDITEM* pFindItem = (NMLVFINDITEM*)lParam;
			LVFINDINFO pFindInfo=pFindItem->lvfi;
		
			CString part=pFindInfo.psz;
			part.MakeLower();
			int start=pFindItem->iStart;
			
			for (int i=start;i<(GetItemCount()+start);i++)
			{
				CString fn=m_FileData[m_IndexMapping[i%GetItemCount()]].Name.Left(part.GetLength());
				fn.MakeLower();
				if (fn==part)
				{
					*pLResult=i%GetItemCount();
					return TRUE;
				}
			}
			*pLResult=-1;
			return TRUE;
		}
	}
	return CListCtrl::OnChildNotify(message, wParam, lParam, pLResult);
}

void CLocalFileListCtrl::OnLocalcontextUploadas() 
{
	CTransferAsDlg dlg;
	if (dlg.DoModal()==IDOK)
	{
		m_transferuser=dlg.m_User;
		m_transferpass=dlg.m_Pass;
		if (dlg.m_bTransferNow)
			OnLocalcontextUpload();
		else
			OnLocalcontextAddtoqueue();
	}
	m_transferuser = m_transferpass = _T("");
}

void CLocalFileListCtrl::SetListStyle(int nStyle)
{
	if (!nStyle)
		nStyle = LVS_REPORT;
	else if (nStyle == 1)
		nStyle = LVS_LIST;
	else if (nStyle == 2)
		nStyle = LVS_ICON;
	else if (nStyle == 3)
		nStyle = LVS_SMALLICON;
	
	if (m_nStyle == nStyle)
		return;

	m_nStyle = nStyle;

	int remove = ~m_nStyle & (LVS_REPORT | LVS_ICON | LVS_SMALLICON | LVS_LIST);
	ModifyStyle(remove, m_nStyle, SWP_NOZORDER);
	
	GetSysImgList();
	CHeaderCtrl *header=GetHeaderCtrl( );
	if (header)
		header->SetImageList(&m_SortImg);
	Arrange(LVA_DEFAULT);
	if (m_nStyle!=LVS_REPORT)
		SortList(0,1);
	SetItemCount(GetItemCount());
}

void CLocalFileListCtrl::UpdateColumns(int nHideColumns)
{
	CString str;
	if (nHideColumns&1 && !(m_nHideColumns&1))
	{
		m_Columns[1]=m_Columns[2];
		m_Columns[2]=m_Columns[3];
		DeleteColumn(1);
		if (m_sortcolumn==1)
			SortList(0,1);
		if (m_sortcolumn>1)
			m_sortcolumn--;
	}
	if (m_nHideColumns&1 && !(nHideColumns&1))
	{
		m_Columns[3]=m_Columns[2];
		m_Columns[2]=m_Columns[1];
		m_Columns[1]=1;
		str.LoadString(IDS_HEADER_FILESIZE);
		InsertColumn(1,str,LVCFMT_RIGHT,66);
		if (m_sortcolumn>=1)
			m_sortcolumn++;
	}
	if (nHideColumns&2 && !(m_nHideColumns&2))
	{
		for (int i=1;i<3;i++)
		{
			if (m_Columns[i]==2)
			{
				int j=i;
				while (j<3)
				{
					m_Columns[j]=m_Columns[j+1];
					j++;
				}
				DeleteColumn(i);		
				if (m_sortcolumn==i)
					SortList(0,1);
				if (m_sortcolumn>i)
					m_sortcolumn--;
				break;
			}
		}
	}
	if (m_nHideColumns&2 && !(nHideColumns&2))
	{
		for (int i=1;i<3;i++)
		{
			if (m_Columns[i]==3)
			{
				int j=3;
				while (j!=i)
				{
					m_Columns[j]=m_Columns[j-1];
					j--;
				}
				m_Columns[i]=2;
				str.LoadString(IDS_HEADER_FILETYPE);
				InsertColumn(i,str,LVCFMT_LEFT,100);
				if (m_sortcolumn>=i)
					m_sortcolumn++;
				break;
			}
		}
	}
	if (nHideColumns&4 && !(m_nHideColumns&4))
	{
		for (int i=1;i<4;i++)
		{
			if (m_Columns[i]==3)
			{
				m_Columns[i]=3;
				DeleteColumn(i);		
				if (m_sortcolumn==i)
					SortList(0,1);
				if (m_sortcolumn>i)
					m_sortcolumn--;
				break;
			}
		}
	}
	if (m_nHideColumns&4 && !(nHideColumns&4))
	{
		for (int i=1;i<4;i++)
		{
			if (m_Columns[i]==3)
			{
				m_Columns[i]=3;
				str.LoadString(IDS_HEADER_LASTMODIFIED);
				InsertColumn(i,str,LVCFMT_LEFT,99);
				if (m_sortcolumn>=i)
					m_sortcolumn++;
				break;
			}
		}
	}
	m_nHideColumns=nHideColumns;
}

void CLocalFileListCtrl::OnLocalcontextProperties() 
{
	POSITION selpos=GetFirstSelectedItemPosition();
	if (!selpos)
		return;
	
	int nItem = GetNextSelectedItem(selpos);
	if (!nItem && m_Fullpath!="")
		return;
	int index=m_IndexMapping[nItem];

	//Show the "properties" for the selected file
    CString sFile = m_Fullpath+m_FileData[index].Name;
    SHELLEXECUTEINFO sei;
    ZeroMemory(&sei,sizeof(sei));
    sei.cbSize = sizeof(sei);
    sei.hwnd = AfxGetMainWnd()->GetSafeHwnd();
    sei.nShow = SW_SHOW;
    sei.lpFile = sFile.GetBuffer(sFile.GetLength()+1);
    sei.lpVerb = _T("properties");
    sei.fMask  = SEE_MASK_INVOKEIDLIST;
	sei.lpParameters = 0;//_T("An example: \"\"\"quoted text\"\"\""9;
    BOOL bSuccess = ShellExecuteEx(&sei);
    sFile.ReleaseBuffer(0);	
}

void CLocalFileListCtrl::SaveColumnSizes()
{
	int nSize[4];
	nSize[0]=GetColumnWidth(0);
	int index=1;
	nSize[1]=60;
	nSize[2]=100;
	nSize[3]=99;

	if (!(m_nHideColumns&1))
	{
		nSize[1]=GetColumnWidth(index);
		index++;
	}
	
	if (!(m_nHideColumns&2))
	{
		nSize[2]=GetColumnWidth(index);
		index++;
	}
	
	if (!(m_nHideColumns&4))
	{
		nSize[3]=GetColumnWidth(index);
		index++;
	}

	CString str;
	str.Format(_T("%d %d %d %d"), nSize[0], nSize[1], nSize[2], nSize[3]);
	COptions::SetOption(OPTION_LOCALCOLUMNWIDTHS, str);
}

void CLocalFileListCtrl::OnDestroy() 
{
	if (COptions::GetOptionVal(OPTION_REMEMBERLOCALCOLUMNWIDTHS))
		SaveColumnSizes();

	if (COptions::GetOptionVal(OPTION_LOCALCOLUMNSORT))
	{
		int nSort = 1;
		nSort |= m_Columns[m_sortcolumn] << 1;
		nSort |= m_sortdir << 4;
		COptions::SetOption(OPTION_LOCALCOLUMNSORT, nSort);
	}

	CListCtrl::OnDestroy();	
}

LRESULT CLocalFileListCtrl::OnUpdateContinue(WPARAM wParam, LPARAM lParam)
{
	if (!m_bUpdating)
		return 0;

	if (m_NewDir != _T(""))
	{
		SetFolder(m_NewDir);
		return 0;
	}
	
	ASSERT(lParam);

	int nOldItemCount = m_FileData.size();
	int nItemCount = nOldItemCount;
	HANDLE hFind = (HANDLE)lParam;

	WIN32_FIND_DATA find;
	if (!FindNextFile(hFind, &find))
	{
		FindClose(hFind);
		hFind=0;
	}
	
	while ( hFind )
	{
		if (!(find.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY && (!_tcscmp(find.cFileName, _T("..")) || !_tcscmp(find.cFileName, _T(".")))))
		{
			t_FileData FileData;
			FileData.Name=find.cFileName;
			FileData.lName=find.cFileName;
			FileData.lName.MakeLower();

			TRY
			{
				FileData.Time = find.ftLastWriteTime;
				FileData.hasTime = true;
			}
			CATCH_ALL(e)
			{
				FileData.hasTime = false;
			}
			END_CATCH_ALL;

			if ( find.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
			{
				FileData.bIsDir=TRUE;
				FileData.nSize=-1;
			}
			else
			{
				FileData.bIsDir=FALSE;
				FileData.nSize=(_int64)find.nFileSizeLow + ((_int64)find.nFileSizeHigh<<32);
			}
			
			m_FileData.push_back(FileData);
			m_IndexMapping.push_back(nItemCount);
			
			nItemCount++;
		}
		if ((nItemCount-nOldItemCount)==100)
		{
			VERIFY(PostMessage(WM_APP + 1, wParam, (LPARAM)hFind));
			return 0;
		}		
		if (!FindNextFile(hFind, &find))
		{
			FindClose(hFind);
			hFind=0;
		}
	
	}

	m_bUpdating=FALSE;

	SetItemCount(nItemCount);
	
	SortList(m_sortcolumn,m_sortdir);

	EnableWindow(TRUE);
	
	SetRedraw( TRUE );

	if (wParam)
		SetFocus();

	for (int i = 1; i < GetItemCount(); i++)
	{
		if (m_selectionBuffer.empty())
			break;
		const CString& name = m_FileData[m_IndexMapping[i]].lName;
		std::set<CString>::iterator iter = m_selectionBuffer.find(name);
		if (iter != m_selectionBuffer.end())
		{
			SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
			m_selectionBuffer.erase(iter);
		}
	}

	UpdateStatusBar();

	return 0;
}

void CLocalFileListCtrl::RefreshFile(CString file)
{
	// Refreshes a single file in a list

	// Do not refresh while updating
	if (m_bUpdating)
		return;

	int i;
	int pos = file.ReverseFind('\\');
	if ( pos==-1 || pos==(file.GetLength()-1) )
		return;

	WIN32_FIND_DATA find;
	HANDLE hFind;
	CString name;
	BOOL bDir=FALSE;
	if (file.Left(pos+1).CollateNoCase(m_Fullpath))
	{
		if (m_Fullpath.CollateNoCase(file.Left(m_Fullpath.GetLength())))
			return;
		
		file=file.Mid(m_Fullpath.GetLength());
		int pos=file.Find('\\');
		if ( pos==-1 || pos==(file.GetLength()-1) || !pos)
			return;
		file=file.Left(pos);
		
		hFind = FindFirstFile( m_Fullpath+file+"\\.", &find);
		
		name=file;

⌨️ 快捷键说明

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