⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftplistctrl.cpp

📁 一个支持FTP,SFTP的客户端程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// 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 + -