localfilelistctrl.cpp
来自「一个支持FTP,SFTP的客户端程序」· C++ 代码 · 共 2,497 行 · 第 1/5 页
CPP
2,497 行
name.MakeLower();
for (i=0;i<static_cast<int>(m_FileData.size());i++)
{
if (name==m_FileData[i].lName)
break;
}
bDir=TRUE;
}
else
{
name=file.Mid(pos+1);
name.MakeLower();
for (i=0;i<static_cast<int>(m_FileData.size());i++)
{
if (name==m_FileData[i].lName)
break;
}
hFind = FindFirstFile( file, &find);
}
unsigned int nIndex=i;
if (!hFind || hFind==INVALID_HANDLE_VALUE)
{
//File does not exist
if (nIndex!=m_FileData.size())
{ //But file is still visible in list
if (!bDir && m_FileData[nIndex].bIsDir)
{
FindClose(hFind);
return;
}
if (bDir && !m_FileData[nIndex].bIsDir)
{
FindClose(hFind);
return;
}
m_FileData.erase(m_FileData.begin()+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);
for (i=1;i<static_cast<int>(m_IndexMapping.size());i++)
{
if (m_IndexMapping[i]>nIndex)
m_IndexMapping[i]--;
}
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);
}
}
SetItemCount(GetItemCount()-1);
}
}
else
{
if (!bDir)
{
if (find.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY || !_tcscmp(find.cFileName, _T(".")) || !_tcscmp(find.cFileName, _T("..")) )
{
FindClose(hFind);
return;
}
}
else if (!(find.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
{
FindClose(hFind);
return;
}
t_FileData FileData;
int count=GetItemCount();
int datapos;
BOOL bSelected=FALSE;
if (nIndex!=m_FileData.size())
{ //File is already visible in list
if (!bDir && m_FileData[nIndex].bIsDir)
{
FindClose(hFind);
return;
}
else if (bDir && !m_FileData[nIndex].bIsDir)
{
FindClose(hFind);
return;
}
m_FileData[nIndex].Name=find.cFileName;
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());
UpdateStatusBar();
}
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-Benachr
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?