📄 ftplistctrl.cpp
字号:
// 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.
// FtpListCtrl.cpp: Implementierungsdatei
//
#include "stdafx.h"
#include "FileZilla.h"
#include "FtpListCtrl.h"
#include "mainfrm.h"
#include "queueview.h"
#include "entersomething.h"
#include "FileAttributes.h"
#include "TransferAsDlg.h"
#include "commandqueue.h"
#include "FtpView.h"
#include "LocalView2.h"
#include "PathFunctions.h"
#include "FtpTreeView.h"
#include "FtpTreeCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CFtpListCtrl
static CString dateformat;
BOOL CALLBACK EnumDateFormatsProc(LPTSTR lpDateFormatString)
{
dateformat=lpDateFormatString;
return FALSE;
}
CFtpListCtrl::CFtpListCtrl(CFtpView *pOwner)
{
ASSERT(pOwner);
m_pOwner = pOwner;
m_nStyle=0;
m_pDirectory=0;
m_nHideColumns=0;
for (int i=0; i<7; i++)
m_Columns[i] = i;
dateformat = _T("");
EnumDateFormats(EnumDateFormatsProc, LOCALE_USER_DEFAULT, DATE_SHORTDATE);
m_bUpdating = FALSE;
m_nBatchAction = 0;
m_nDragHilited = -1;
}
CFtpListCtrl::~CFtpListCtrl()
{
if (m_pDirectory)
{
delete m_pDirectory;
m_pDirectory=0;
}
}
BEGIN_MESSAGE_MAP(CFtpListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CFtpListCtrl)
ON_WM_CREATE()
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_DROPFILES()
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
ON_COMMAND(ID_FTPCONTEXT_ADDTOQUEUE, OnFtpcontextAddtoqueue)
ON_COMMAND(ID_FTPCONTEXT_ATTRIBUTES, OnFtpcontextAttributes)
ON_COMMAND(ID_FTPCONTEXT_CREATEDIR, OnFtpcontextCreatedir)
ON_COMMAND(ID_FTPCONTEXT_DELETE, OnFtpcontextDelete)
ON_COMMAND(ID_FTPCONTEXT_DOWNLOAD, OnFtpcontextDownload)
ON_COMMAND(ID_FTPCONTEXT_DOWNLOADAS, OnFtpcontextDownloadas)
ON_COMMAND(ID_FTPCONTEXT_OPEN, OnFtpcontextOpen)
ON_COMMAND(ID_FTPCONTEXT_RENAME, OnFtpcontextRename)
ON_COMMAND(ID_FTPCONTEXT_VIEWEDIT, OnFtpcontextViewEdit)
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
ON_WM_KEYDOWN()
ON_WM_PAINT()
ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemchanged)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Behandlungsroutinen f黵 Nachrichten CFtpListCtrl
extern CFileZillaApp theApp;
/////////////////////////////////////////////////
BOOL CFtpListCtrl::GetSysImgList()
/////////////////////////////////////////////////
{
USES_CONVERSION;
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();
/*
Do a version check first because you only need to use this code on
Windows NT version 4.0 or newer (2000/XP)
*/
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
GetVersionEx(&vi);
if (VER_PLATFORM_WIN32_WINDOWS == vi.dwPlatformId)
return TRUE;
/*
You need to create a temporary, empty .lnk file that you can use to
pass to IShellIconOverlay::GetOverlayIndex. You could just enumerate
down from the Start Menu folder to find an existing .lnk file, but
there is a very remote chance that you will not find one. By creating
your own, you know this code will always work.
*/
HRESULT hr;
IShellFolder *psfDesktop = NULL;
IShellFolder *psfTempDir = NULL;
IMalloc *pMalloc = NULL;
LPITEMIDLIST pidlTempDir = NULL;
LPITEMIDLIST pidlTempFile = NULL;
TCHAR szTempDir[MAX_PATH];
TCHAR szTempFile[MAX_PATH] = TEXT("");
TCHAR szFile[MAX_PATH];
HANDLE hFile;
int i;
OLECHAR szOle[MAX_PATH];
DWORD dwAttributes;
DWORD dwEaten;
IShellIconOverlay *psio = NULL;
int nIndex;
// Get the desktop folder.
hr = SHGetDesktopFolder(&psfDesktop);
if(FAILED(hr))
goto exit;
// Get the shell's allocator.
hr = SHGetMalloc(&pMalloc);
if(FAILED(hr))
goto exit;
// Get the TEMP directory.
if(!GetTempPath(MAX_PATH, szTempDir))
{
/*
There might not be a TEMP directory. If this is the case, use the
Windows directory.
*/
if(!GetWindowsDirectory(szTempDir, MAX_PATH))
{
hr = E_FAIL;
goto exit;
}
}
// Create a temporary .lnk file.
if(szTempDir[lstrlen(szTempDir) - 1] != '\\')
lstrcat(szTempDir, TEXT("\\"));
for(i = 0, hFile = INVALID_HANDLE_VALUE;
INVALID_HANDLE_VALUE == hFile;
i++)
{
lstrcpy(szTempFile, szTempDir);
wsprintf(szFile, TEXT("temp%d.lnk"), i);
lstrcat(szTempFile, szFile);
hFile = CreateFile( szTempFile,
GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Do not try this more than 100 times.
if(i > 100)
{
hr = E_FAIL;
goto exit;
}
}
// Close the file you just created.
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
// Get the PIDL for the directory.
//LocalToWideChar(szOle, szTempDir, MAX_PATH);
wcscpy(szOle, T2OLE(szTempDir));
hr = psfDesktop->ParseDisplayName( NULL,
NULL,
szOle,
&dwEaten,
&pidlTempDir,
&dwAttributes);
if(FAILED(hr))
goto exit;
// Get the IShellFolder for the TEMP directory.
hr = psfDesktop->BindToObject( pidlTempDir,
NULL,
IID_IShellFolder,
(LPVOID*)&psfTempDir);
if(FAILED(hr))
goto exit;
/*
Get the IShellIconOverlay interface for this folder. If this fails,
it could indicate that you are running on a pre-Internet Explorer 4.0
shell, which doesn't support this interface. If this is the case, the
overlay icons are already in the system image list.
*/
hr = psfTempDir->QueryInterface(IID_IShellIconOverlay, (LPVOID*)&psio);
if(FAILED(hr))
goto exit;
// Get the PIDL for the temporary .lnk file.
//LocalToWideChar(szOle, szFile, MAX_PATH);
wcscpy(szOle, T2OLE(szFile));
hr = psfTempDir->ParseDisplayName( NULL,
NULL,
szOle,
&dwEaten,
&pidlTempFile,
&dwAttributes);
if(FAILED(hr))
goto exit;
/*
Get the overlay icon for the .lnk file. This causes the shell
to put all of the standard overlay icons into your copy of the system
image list.
*/
hr = psio->GetOverlayIndex(pidlTempFile, &nIndex);
exit:
// Delete the temporary file.
DeleteFile(szTempFile);
if(psio)
psio->Release();
if(INVALID_HANDLE_VALUE != hFile)
CloseHandle(hFile);
if(psfTempDir)
psfTempDir->Release();
if(pMalloc)
{
if(pidlTempFile)
pMalloc->Free(pidlTempFile);
if(pidlTempDir)
pMalloc->Free(pidlTempDir);
pMalloc->Release();
}
if(psfDesktop)
psfDesktop->Release();
return TRUE;
}
int CFtpListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
int widths[7]={150, 70, 80, 68, 54, 90, 90};
if (COptions::GetOptionVal(OPTION_REMEMBERREMOTECOLUMNWIDTHS))
{
CString tmp=COptions::GetOption(OPTION_REMOTECOLUMNWIDTHS);
int pos=-1;
int i;
for (i=0; i<6; 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 == 6)
{
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_DATE);
InsertColumn(3, str, LVCFMT_LEFT, widths[3]);
str.LoadString(IDS_HEADER_TIME);
InsertColumn(4, str, LVCFMT_LEFT, widths[4]);
str.LoadString(IDS_HEADER_PERMISSIONS);
InsertColumn(5, str, LVCFMT_LEFT, widths[5]);
str.LoadString(IDS_HEADER_OWNERGROUP);
InsertColumn(6, str, LVCFMT_LEFT, widths[6]);
SetListStyle(0);
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);
CHeaderCtrl *header=GetHeaderCtrl( );
if (header)
header->SetImageList(&m_SortImg);
int nSort = COptions::GetOptionVal(OPTION_REMOTECOLUMNSORT);
m_sortdir = (nSort >> 4) % 3;
if (!m_sortdir)
m_sortdir = 1;
m_sortcolumn = (nSort >> 1) & 0x07;
if (m_sortcolumn > 6)
m_sortcolumn = 0;
DragAcceptFiles(TRUE);
m_nFolderDownloadStart = FALSE;
SetExtendedStyle(LVS_EX_INFOTIP);
SetCallbackMask(GetCallbackMask() | LVIS_OVERLAYMASK);
return 0;
}
void CFtpListCtrl::List(t_directory *list)
{
//Don't update the statusbar until finished
m_bUpdating = TRUE;
CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
std::list<CString> SelectedList;
BOOL bDotsSelected=FALSE;
CServerPath OldPath;
if (m_pDirectory)
{
//Previous directory visible
OldPath=m_pDirectory->path;
BOOL bStoreSelectedFiles=0;
//If the new and the old directory have the same path, remember the selected items
if (list && list->path==m_pDirectory->path)
bStoreSelectedFiles=TRUE;
UINT nNoOfItems = GetItemCount( );
for( UINT nListItem = 0; nListItem < nNoOfItems; nListItem++ )
{
//Unselect all selected items
if( GetItemState( nListItem, LVIS_SELECTED ) )
{
SetItemState( nListItem, 0, LVIS_SELECTED);
if (bStoreSelectedFiles && nListItem) //and remember them if nessesary
SelectedList.push_back(m_pDirectory->direntry[m_IndexMapping[nListItem]].lName);
else if (bStoreSelectedFiles && !nListItem)
bDotsSelected=TRUE;
}
}
delete m_pDirectory;
}
//Set new directory
m_pDirectory=list;
m_IndexMapping.clear();
m_IconCache.clear();
if (!list)
{
m_PendingDirs.clear();
pMainFrame->m_pCommandQueue->SetLock(FALSE);
SetItemCount(0);
m_nBatchAction = 0;
m_PathsToVisit.clear();
m_PathsVisited.clear();
m_bUpdating = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -