localfilelistctrl.cpp
来自「一个支持FTP,SFTP的客户端程序」· C++ 代码 · 共 2,497 行 · 第 1/5 页
CPP
2,497 行
// FileZilla - a Windows ftp client
// Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// LocalFileListCtrl.cpp: Implementierungsdatei
//
#include "stdafx.h"
#include "FileZilla.h"
#include "LocalFileListCtrl.h"
#include "LocalView2.h"
#include "process.h"
#include "mainfrm.h"
#include "direct.h"
#include "EnterSomething.h"
#include "TransferAsDlg.h"
#include "PathFunctions.h"
#include "CommandQueue.h"
#include "FtpListCtrl.h"
#include "DirTreeCtrl.h"
#include "LocalView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CLocalFileListCtrl
CLocalFileListCtrl::CLocalFileListCtrl(CLocalView2 *pOwner)
{
ASSERT(pOwner);
m_pOwner = pOwner;
m_Fullpath = ".."; //Just anything invalid
m_nStyle = -1;
for (int i = 0; i < 4; i++)
m_Columns[i] = i;
m_nHideColumns = 0;
m_bUpdating = FALSE;
m_nDragHilited = -1;
}
CLocalFileListCtrl::~CLocalFileListCtrl()
{
}
BEGIN_MESSAGE_MAP(CLocalFileListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CLocalFileListCtrl)
ON_WM_CREATE()
ON_MESSAGE(WM_APP+1, OnUpdateContinue)
ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBegindrag)
ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnBeginlabeledit)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
ON_WM_CONTEXTMENU()
ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
ON_WM_DESTROY()
ON_WM_DROPFILES()
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
ON_WM_KEYDOWN()
ON_COMMAND(ID_LOCALCONTEXT_ADDTOQUEUE, OnLocalcontextAddtoqueue)
ON_COMMAND(ID_LOCALCONTEXT_CREATEDIRECTORY, OnLocalcontextCreatedirectory)
ON_COMMAND(ID_LOCALCONTEXT_DELETE, OnLocalcontextDelete)
ON_COMMAND(ID_LOCALCONTEXT_OPEN, OnLocalcontextOpen)
ON_COMMAND(ID_LOCALCONTEXT_PROPERTIES, OnLocalcontextProperties)
ON_COMMAND(ID_LOCALCONTEXT_RENAME, OnLocalcontextRename)
ON_COMMAND(ID_LOCALCONTEXT_UPLOAD, OnLocalcontextUpload)
ON_COMMAND(ID_LOCALCONTEXT_UPLOADAS, OnLocalcontextUploadas)
ON_COMMAND(ID_LOCALCONTEXT_VIEWEDIT, OnLocalcontextViewEdit)
ON_WM_VSCROLL()
ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemchanged)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Behandlungsroutinen f黵 Nachrichten CLocalFileListCtrl
void CLocalFileListCtrl::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
POSITION selpos = GetFirstSelectedItemPosition();
if (selpos)
{
int nItem = GetNextSelectedItem(selpos);
int nIndex = m_IndexMapping[nItem];
if (m_FileData[nIndex].bIsDir)
{
CString newpath;
if (!nItem && m_Fullpath!="")
{
newpath=m_Fullpath;
newpath.TrimRight('\\');
int pos=newpath.ReverseFind('\\');
newpath=newpath.Left(pos+1);
}
else
newpath=m_Fullpath+m_FileData[nIndex].Name + "\\";
m_pOwner->SetLocalFolder(newpath);
m_pOwner->SetLocalFolderOut(newpath);
}
else
{
int nAction = COptions::GetOptionVal(OPTION_LOCAL_DOUBLECLICK_ACTION);
if (nAction == 1)
{
CString file = m_Fullpath+m_FileData[nIndex].Name;
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.lpFile = file;
sei.nShow = SW_SHOWNORMAL;
BOOL b = ShellExecuteEx(&sei);
}
else
{
CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
pMainFrame->AddQueueItem(FALSE, GetItemText(nItem,0), "", m_Fullpath, CServerPath(), !nAction);
if (!nAction)
pMainFrame->TransferQueue(2);
}
}
}
*pResult = 0;
}
void CLocalFileListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}
CString CLocalFileListCtrl::GetFolder() const
{
return m_Fullpath;
}
int CLocalFileListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
int widths[5]={150, 66, 100, 99};
if (COptions::GetOptionVal(OPTION_REMEMBERLOCALCOLUMNWIDTHS))
{
CString tmp = COptions::GetOption(OPTION_LOCALCOLUMNWIDTHS);
int pos = -1;
int i;
for (i = 0; i<3; i++)
{
int oldpos = pos + 1;
pos = tmp.Find(_T(" "), oldpos);
if (pos == -1)
break;
tmp.SetAt(pos, 0);
int size=_ttoi(tmp.Mid(oldpos));
if (size>0)
widths[i]=size;
}
if (i==3)
{
int size=_ttoi(tmp.Mid(pos+1));
if (size>0)
widths[i]=size;
}
}
CString str;
str.LoadString(IDS_HEADER_FILENAME);
InsertColumn(0,str,LVCFMT_LEFT, widths[0]);
str.LoadString(IDS_HEADER_FILESIZE);
InsertColumn(1,str,LVCFMT_RIGHT, widths[1]);
str.LoadString(IDS_HEADER_FILETYPE);
InsertColumn(2,str,LVCFMT_LEFT, widths[2]);
str.LoadString(IDS_HEADER_LASTMODIFIED);
InsertColumn(3,str,LVCFMT_LEFT, widths[3]);
m_SortImg.Create( 8, 8, ILC_MASK, 3, 3 );
HICON Icon;
Icon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_EMPTY));
m_SortImg.Add(Icon);
Icon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_UP));
m_SortImg.Add(Icon);
Icon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_DOWN));
m_SortImg.Add(Icon);
m_SortImg.SetBkColor(CLR_NONE);
SetListStyle(0);
int nSort = COptions::GetOptionVal(OPTION_LOCALCOLUMNSORT);
m_sortdir = (nSort >> 4) % 3;
if (!m_sortdir)
m_sortdir = 1;
m_sortcolumn = (nSort >> 1) & 0x07;
if (m_sortcolumn > 3)
m_sortcolumn = 0;
DragAcceptFiles(TRUE);
SetExtendedStyle(LVS_EX_INFOTIP);
return 0;
}
/////////////////////////////////////////////////
BOOL CLocalFileListCtrl::GetSysImgList()
/////////////////////////////////////////////////
{
CImageList sysImgList;
SHFILEINFO shFinfo;
HIMAGELIST hImageList = 0;
CString errorMessage;
TCHAR filename[MAX_PATH + 10];
if (GetModuleFileName(0, filename, MAX_PATH + 10))
{
hImageList = (HIMAGELIST)SHGetFileInfo(filename,
0,
&shFinfo,
sizeof( shFinfo ),
SHGFI_SYSICONINDEX |
((m_nStyle == LVS_ICON)?SHGFI_ICON:SHGFI_SMALLICON) );
if (!hImageList)
{
int errorCode = GetLastError();
TCHAR buffer[1000];
memset(buffer, 0, 1000);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, buffer, 999, 0);
CString str;
str.Format(_T("SHGetFileInfo failed with error %d: %s"), errorCode, buffer);
errorMessage += str;
}
}
else
{
int errorCode = GetLastError();
TCHAR buffer[1000];
memset(buffer, 0, 1000);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, buffer, 999, 0);
CString str;
str.Format(_T("GetModuleFileName failed with error %d: %s"), errorCode, buffer);
errorMessage += str;
}
if (!hImageList)
{
/*
* Fall back to C:\\
* Not bullerproof, but better than nothing
*/
hImageList = (HIMAGELIST)SHGetFileInfo(_T("C:\\"),
0,
&shFinfo,
sizeof( shFinfo ),
SHGFI_SYSICONINDEX |
((m_nStyle == LVS_ICON)?SHGFI_ICON:SHGFI_SMALLICON) );
if (!hImageList)
{
int errorCode = GetLastError();
TCHAR buffer[1000];
memset(buffer, 0, 1000);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, buffer, 999, 0);
CString str;
str.Format(_T("SHGetFileInfo failed with error %d: %s"), errorCode, buffer);
if (errorMessage != _T(""))
errorMessage += _T("\n");
errorMessage += str;
}
}
if (!hImageList)
{
AfxMessageBox(errorMessage);
return FALSE;
}
sysImgList.Attach(hImageList);
SetImageList( &sysImgList, (m_nStyle == LVS_ICON)?LVSIL_NORMAL:LVSIL_SMALL);
sysImgList.Detach();
return TRUE;
}
void CLocalFileListCtrl::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
SortList(pNMListView->iSubItem);
*pResult = 0;
}
BOOL greater(const CString &str1, const CString &str2, BOOL isdir1, BOOL isdir2)
{
if (isdir1 && !isdir2)
return FALSE;
if (!isdir1 && isdir2)
return TRUE;
if (str1.CollateNoCase(str2) > 0)
return TRUE;
return FALSE;
}
BOOL lesser(const CString &str1, const CString &str2, BOOL isdir1, BOOL isdir2)
{
if (isdir1 && !isdir2)
return TRUE;
if (!isdir1 && isdir2)
return FALSE;
if (str2.CollateNoCase(str1) > 0)
return TRUE;
return FALSE;
}
BOOL greaterbytype(const CString &str1, const CString &str2, const BOOL isdir1, const BOOL isdir2, const CString &fn1, const CString &fn2)
{
if (isdir1 && !isdir2)
return FALSE;
if (!isdir1 && isdir2)
return TRUE;
if (str1>str2)
return TRUE;
if (str1==str2)
{
if (fn1.CollateNoCase(fn2) > 0)
return TRUE;
}
return FALSE;
}
BOOL lesserbytype(const CString &str1, const CString &str2, const BOOL isdir1, const BOOL isdir2, const CString &fn1, const CString &fn2)
{
if (isdir1 && !isdir2)
return TRUE;
if (!isdir1 && isdir2)
return FALSE;
if (str1<str2)
return TRUE;
if (str1==str2)
{
if (fn1.CollateNoCase(fn2) < 0)
return TRUE;
}
return FALSE;
}
BOOL greaterbytime(const CTime &time1, const CTime &time2, const BOOL &isdir1, const BOOL &isdir2, const CString &fn1, const CString &fn2)
{
if (isdir1 && !isdir2)
return FALSE;
if (!isdir1 && isdir2)
return TRUE;
if (time1>time2)
return TRUE;
if (time1==time2)
{
if (fn1.CollateNoCase(fn2) > 0)
return TRUE;
}
return FALSE;
}
BOOL lesserbytime(const CTime &time1, const CTime &time2, const BOOL &isdir1, const BOOL &isdir2, const CString &fn1, const CString &fn2)
{
if (isdir1 && !isdir2)
return TRUE;
if (!isdir1 && isdir2)
return FALSE;
if (time1<time2)
return TRUE;
if (time1==time2)
{
if (fn1.CollateNoCase(fn2) < 0)
return TRUE;
}
return FALSE;
}
BOOL greaterbysize(const __int64 &size1, const __int64 &size2, BOOL isdir1, BOOL isdir2, const CString &fn1, const CString &fn2)
{
if (isdir1 && !isdir2)
return FALSE;
if (!isdir1 && isdir2)
return TRUE;
if (size1>size2)
return TRUE;
if (size1==size2)
{
if (fn1.CollateNoCase(fn2) > 0)
return TRUE;
}
return FALSE;
}
BOOL lesserbysize(const __int64 &size1, const __int64 &size2, BOOL isdir1, BOOL isdir2, const CString &fn1, const CString &fn2)
{
if (isdir1 && !isdir2)
return TRUE;
if (!isdir1 && isdir2)
return FALSE;
if (size1<size2)
return TRUE;
if (size1==size2)
{
if (fn1.CollateNoCase(fn2) < 0)
return TRUE;
}
return FALSE;
}
void CLocalFileListCtrl::quicksortbyname(const BOOL &direction, int anf, int ende)
{
int l=anf;
int r=ende;
CString tmp;
CString ref=m_FileData[m_IndexMapping[(l+r)/2]].lName;
BOOL bRefIsDir=m_FileData[m_IndexMapping[(l+r)/2]].bIsDir;
do
{
if (direction)
{
while (lesser (m_FileData[m_IndexMapping[l]].lName, ref, m_FileData[m_IndexMapping[l]].bIsDir, bRefIsDir) && (l<ende)) l++;
while (greater(m_FileData[m_IndexMapping[r]].lName, ref, m_FileData[m_IndexMapping[r]].bIsDir, bRefIsDir) && (r>anf)) r--;
}
else
{
while (greater(m_FileData[m_IndexMapping[l]].lName, ref, m_FileData[m_IndexMapping[l]].bIsDir, bRefIsDir) && (l<ende)) l++;
while (lesser (m_FileData[m_IndexMapping[r]].lName, ref, m_FileData[m_IndexMapping[r]].bIsDir, bRefIsDir) && (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) quicksortbyname(direction, anf, r);
if (l<ende) quicksortbyname(direction, l, ende);
}
void CLocalFileListCtrl::quicksortbytype(const std::vector<CString> &array, const BOOL &direction, int anf, int ende)
{
int l=anf;
int r=ende;
CString tmp;
CString ref=array[m_IndexMapping[(l+r)/2]];
CString refname=m_FileData[m_IndexMapping[(l+r)/2]].lName;
BOOL bRefIsDir=m_FileData[m_IndexMapping[(l+r)/2]].bIsDir;
do
{
if (direction)
{
while (lesserbytype (array[m_IndexMapping[l]], ref, m_FileData[m_IndexMapping[l]].bIsDir, bRefIsDir, m_FileData[m_IndexMapping[l]].lName, refname) && (l<ende)) l++;
while (greaterbytype(array[m_IndexMapping[r]], ref, m_FileData[m_IndexMapping[r]].bIsDir, bRefIsDir, m_FileData[m_IndexMapping[r]].lName, refname) && (r>anf)) r--;
}
else
{
while (greaterbytype(array[m_IndexMapping[l]], ref, m_FileData[m_IndexMapping[l]].bIsDir, bRefIsDir, m_FileData[m_IndexMapping[l]].lName, refname) && (l<ende)) l++;
while (lesserbytype (array[m_IndexMapping[r]], 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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?