localfilelistctrl.cpp

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

CPP
2,497
字号
// this Function Returns the first Selected Item in the List
UINT CLocalFileListCtrl::GetSelectedItem()
{
	// this Function Valid Only when a Single Item is Selected
	ASSERT( GetSelectedCount( ) == 1 );
	UINT nNoOfItems = GetItemCount( );
	UINT nListItem;
	for (nListItem = 0; nListItem < nNoOfItems; nListItem++)
		if (GetItemState( nListItem, LVIS_SELECTED )  )
			break;
	ASSERT(nListItem < nNoOfItems);
	return nListItem;
}

#define VK_A		65
BOOL CLocalFileListCtrl::PreTranslateMessage(MSG* pMsg) 
{
	// If edit control is visible in tree view control, sending a
	// WM_KEYDOWN message to the edit control will dismiss the edit
	// control.  When ENTER key was sent to the edit control, the parent
	// window of the tree view control is responsible for updating the
	// item's label in TVN_ENDLABELEDIT notification code.
	if ( pMsg->message == WM_KEYDOWN )
	{
		CEdit* edit = GetEditControl();
		if (edit)
		{
			if( GetKeyState( VK_CONTROL )&128 && pMsg->wParam == VK_A )
			{
				edit->SetSel(0, -1);
				return TRUE;
			}
			else if( pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_CONTROL || pMsg->wParam == VK_INSERT || pMsg->wParam == VK_SHIFT )
			{
				edit->SendMessage(WM_KEYDOWN, pMsg->wParam, pMsg->lParam);
				return TRUE;
			}
		}
		else
		{
			if( GetKeyState( VK_CONTROL )&128 && pMsg->wParam == VK_A )
			{
				m_bUpdating = TRUE;
				if (GetItemCount())
					SetItemState(0, GetItemCount()==1 || m_Fullpath==""?LVIS_SELECTED:0,LVIS_SELECTED);
				for (int i=1;i<GetItemCount();i++)
					SetItemState(i, LVIS_SELECTED,LVIS_SELECTED);
			
				m_bUpdating = FALSE;
				UpdateStatusBar();
				return TRUE;
			}
			//Handle the enter key
			else if (pMsg->wParam==VK_RETURN)
			{
				CMainFrame *pMainFrame = DYNAMIC_DOWNCAST(CMainFrame, GetParentFrame());
				POSITION selpos=GetFirstSelectedItemPosition();
				BOOL bOpen=TRUE;
				int openindex=-1;
				int openitem=-1;
				if (selpos)
				{
					int nItem = openitem = GetNextSelectedItem(selpos);
					int index=openindex=m_IndexMapping[nItem];
					if (m_FileData[index].bIsDir)
					{
					
					}
					else
					{
						bOpen=FALSE;
						pMainFrame->AddQueueItem(FALSE,GetItemText(nItem,0),"",m_Fullpath,CServerPath(),TRUE);
						openindex=-1;
						openitem=-1;
					}
				}
				else
					return TRUE;
				while (selpos)
				{
					if (!openindex)
						return TRUE;
					bOpen=FALSE;
					int nItem = GetNextSelectedItem(selpos);
					if(!nItem || m_Fullpath=="")
						return TRUE;
					int index=m_IndexMapping[nItem];
					if (m_FileData[index].bIsDir)
						pMainFrame->UploadDir(m_Fullpath+m_FileData[index].Name+"\\*.*", m_FileData[index].Name+"\\", TRUE, m_transferuser, m_transferpass);
					else
						pMainFrame->AddQueueItem(FALSE, m_FileData[index].Name, "", m_Fullpath, CServerPath(), TRUE, m_transferuser, m_transferpass);
				}
				if (bOpen)
				{
					CString newpath;
					if (!openitem && m_Fullpath!="")
					{
						m_Fullpath.TrimRight('\\');
						int pos=m_Fullpath.ReverseFind('\\');
						if (pos!=-1)
							m_Fullpath=m_Fullpath.Left(pos+1);
						else
							m_Fullpath="";
						newpath=m_Fullpath;
					}
					else
						newpath=m_Fullpath+m_FileData[openindex].Name+"\\";
					m_pOwner->SetLocalFolder(newpath);
					m_pOwner->SetLocalFolderOut(newpath);
				}
				else
				{
					ASSERT(m_Fullpath!="");
					if (openindex>=0)
						pMainFrame->UploadDir(m_Fullpath+m_FileData[openindex].Name+"\\*.*", m_FileData[openindex].Name+"\\", TRUE, m_transferuser, m_transferpass);
					pMainFrame->TransferQueue(2);					
				}

				return TRUE;
			}
		}
	}
	else if ( pMsg->message == WM_CHAR )
	{
		CEdit* edit = GetEditControl();
		if (edit)
		{
			if (pMsg->wParam=='/' ||
				pMsg->wParam=='\\' ||
				pMsg->wParam==':' ||
				pMsg->wParam=='*' ||
				pMsg->wParam=='?' ||
				pMsg->wParam=='"' ||
				pMsg->wParam=='<' ||
				pMsg->wParam=='>' ||
				pMsg->wParam=='|')
			{
				MessageBeep(0xFFFFFFFF);
				return TRUE;
			}
		}
	}
	return CListCtrl::PreTranslateMessage(pMsg);
}

void CLocalFileListCtrl::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
	// This is the Limit the size of the Tag Name to 255
	if (!pDispInfo->item.iItem || m_Fullpath=="")
	{
		*pResult=TRUE;
		return;
	}
	
	m_EditDir = m_Fullpath;
	*pResult = 0;
	CEdit *pEdit=GetEditControl();
	if (pEdit)
		pEdit->LimitText( 255 );	
}

void CLocalFileListCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	*pResult = FALSE;

	if (m_EditDir != m_Fullpath)
	{
		m_EditDir = _T("");
		return;
	}
	m_EditDir = _T("");

	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
	if (!pDispInfo->item.pszText)
	{
		if (m_NewDir != _T(""))
			SetFolder(m_NewDir);
		return;
	}

	unsigned int item = pDispInfo->item.iItem;
	if (!item || item >= m_IndexMapping.size())
	{
		if (m_NewDir != _T(""))
			SetFolder(m_NewDir);
		return;
	}

	int index = m_IndexMapping[item];

	t_FileData& fileData = m_FileData[index];

	CString newname = pDispInfo->item.pszText;
	newname = newname.Left(255);
	if ((newname.Find('/') != -1) || (newname.Find('\\') != -1) ||
		(newname.Find(':') != -1) || (newname.Find('*') != -1) ||
		(newname.Find('?') != -1) || (newname.Find('"') != -1) ||
		(newname.Find('<') != -1) || (newname.Find('>') != -1) ||
		(newname.Find('|') != -1))
	{
		AfxMessageBox(IDS_ERRORMSG_FILENAMEINVALID, MB_ICONEXCLAMATION);
		if (m_NewDir != _T(""))
			SetFolder(m_NewDir);
		return;
	}
	SHFILEOPSTRUCT op;
	memset(&op, 0, sizeof(op));
	CString from = m_Fullpath + fileData.Name + " ";
	from.SetAt(from.GetLength() - 1, '\0');
	op.pFrom = from;
	CString to = m_Fullpath + pDispInfo->item.pszText + " ";
	to.SetAt(to.GetLength() - 1, '\0');
	op.pTo = to;
	op.hwnd = AfxGetMainWnd()->m_hWnd;
	op.wFunc = FO_RENAME;
	op.fFlags = FOF_ALLOWUNDO;
	if (!SHFileOperation(&op))
	{
		*pResult = TRUE;
		fileData.Name = pDispInfo->item.pszText;
		fileData.lName = pDispInfo->item.pszText;
		fileData.lName.MakeLower();
	}
	if (m_NewDir != _T(""))
		SetFolder(m_NewDir);
}

void CLocalFileListCtrl::OnLocalcontextRename() 
{
	ASSERT(GetSelectedCount()==1);
	POSITION selpos=GetFirstSelectedItemPosition();
	int index=GetNextSelectedItem(selpos);
	EditLabel(index);
}

void CLocalFileListCtrl::OnLocalcontextCreatedirectory() 
{
	if (m_Fullpath=="")
		return;
	CEnterSomething dlg(IDS_INPUTDIALOGTITLE_CREATEDIR,IDS_INPUTDIALOGTEXT_CREATEDIR);
	if (dlg.DoModal()==IDOK)
	{
		CreateDirectory(m_Fullpath+dlg.m_String, 0);
		CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
		pMainFrame->RefreshViews(1);
	}		
}

void CLocalFileListCtrl::ReloadHeader()
{
	ReloadHeaderItem(0,IDS_HEADER_FILENAME);
	int i=1;
	if (!(m_nHideColumns&1))
	{
		ReloadHeaderItem(i,IDS_HEADER_FILESIZE);
		i++;
	}
	if (!(m_nHideColumns&2))
	{
		ReloadHeaderItem(i,IDS_HEADER_FILETYPE);
		i++;
	}
	if (!(m_nHideColumns&4))
		ReloadHeaderItem(i,IDS_HEADER_LASTMODIFIED);
}

void CLocalFileListCtrl::ReloadHeaderItem(int nIndex, UINT nID)
{
	CHeaderCtrl *header=GetHeaderCtrl();
	TCHAR text[100];
	HDITEM item;
	memset(&item,0,sizeof(HDITEM));
	item.cchTextMax=100;
	item.mask=HDI_TEXT;
	item.pszText=text;
	header->GetItem(nIndex,&item);
	CString str;
	str.LoadString(nID);
	_tcscpy(text,str);
	header->SetItem(nIndex,&item);
}

void CLocalFileListCtrl::SetFolder(CString folder)
{
	if (m_bUpdating)
	{
		m_NewDir = folder;
		return;
	}
	else if (GetEditControl() && folder == m_Fullpath)
	{
		m_NewDir = folder;
		return;
	}
	else
		m_NewDir = _T("");

	BOOL bDidHaveFocus = GetFocus() == this;
	
	folder.TrimRight(_T("\\")); 
	folder += _T("\\");

	if (folder == m_Fullpath || (folder == _T("\\") && m_Fullpath == _T("")))
	{
		for (int i = 1; i < GetItemCount(); i++)
		{
			if (GetItemState( i, LVIS_SELECTED))
			{
				m_selectionBuffer.insert(m_FileData[m_IndexMapping[i]].lName);
				SetItemState(i, 0, LVIS_SELECTED);
			}
		}
	}
	else
		m_selectionBuffer.clear();

	m_FileData.clear();
	m_IndexMapping.clear();
	m_Fullpath = folder;
	if (m_Fullpath == _T("\\"))
	{
		m_Fullpath="";
		DisplayDrives();
		return;
	}
	m_bUpdating=TRUE;

	SetRedraw(FALSE);
	EnableWindow(FALSE);
	
	
	CString strPathFiles = m_Fullpath;
	
	if ( strPathFiles.Right(1) != "\\" )
		strPathFiles += "\\";
	strPathFiles += "*.*";

	WIN32_FIND_DATA find;
	HANDLE hFind = FindFirstFile( strPathFiles, &find);

	CString folder2=m_Fullpath;
	folder2.TrimRight('\\');
	
	int pos=folder2.ReverseFind('\\');
	folder2=folder2.Left(pos+1);

	t_FileData FileData;

	FileData.Name="..";
	FileData.lName="..";
	FileData.bIsDir=TRUE;
	m_IndexMapping.push_back(0);
	FileData.nSize=-1;
	FileData.hasTime = false;
	m_FileData.push_back(FileData);
	int nItemCount=1;
			
	while (hFind != INVALID_HANDLE_VALUE)
	{
		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++;
		}
//#define SPEEDTEST 20000
#ifndef SPEEDTEST
		if (nItemCount==100)
		{
			VERIFY(PostMessage(WM_APP + 1, bDidHaveFocus, (LPARAM)hFind));
			return;
		}
#endif //SPEEDTEST
		if (!FindNextFile(hFind, &find))
		{
			FindClose(hFind);
			hFind=0;
#ifdef SPEEDTEST
			//Speed test code with SPEEDTEST files
			if (nItemCount>1 && nItemCount<SPEEDTEST) 
				hFind = FindFirstFile( strPathFiles, &find);
			else
				break;
#else
			break;
#endif //SPEEDTEST
		}
	}

	m_bUpdating = FALSE;

	SetItemCount(nItemCount);
	
	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);
		}
	}

	EnableWindow(TRUE);
	
	SetRedraw( TRUE );

	if (bDidHaveFocus)
		SetFocus();

	UpdateStatusBar();
}

void CLocalFileListCtrl::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
	LV_ITEM* pItem= &(pDispInfo)->item;

	if (static_cast<int>(m_IndexMapping.size())<=pItem->iItem)
		return;
	if (static_cast<int>(m_FileData.size())<=m_IndexMapping[pItem->iItem])
		return;
	
	if (pItem->mask & LVIF_IMAGE && !pItem->iSubItem)
	{
		if (m_FileData[m_IndexMapping[pItem->iItem]].iIcon!=-1)
			pItem->iImage=m_FileData[m_IndexMapping[pItem->iItem]].iIcon;
		else
		{
			CString path;
			if (m_FileData[m_IndexMapping[pItem->iItem]].lName=="..")
				path="alkjhgfdfghjjhgfdghuztxvbhzt";
			else
			{
				path=m_Fullpath+m_FileData[m_IndexMapping[pItem->iItem]].Name;
				if (m_Fullpath=="")
					path+="\\";			
			}
			
			int iIcon=-1;
			SHFILEINFO shFinfo;
			memset(&shFinfo,0,sizeof(SHFILEINFO));
			if (SHGetFileInfo( path,
				m_FileData[m_IndexMapping[pItem->iItem]].bIsDir?FILE_ATTRIBUTE_DIRECTORY:FILE_ATTRIBUTE_NORMAL,
					&shFinfo,
					sizeof( SHFILEINFO ),
					SHGFI_ICON | ((m_FileData[m_IndexMapping[pItem->iItem]].lName=="..")?SHGFI_USEFILEATTRIBUTES:0) ) )
			{
				iIcon = shFinfo.iIcon;
				// we only need the index from the system image ctrl
				DestroyIcon( shFinfo.hIcon );
				m_FileData[m_IndexMapping[pItem->iItem]].iIcon=iIcon;
			}
			pItem->iImage=iIcon;
		}
	}
	if (pItem->mask & LVIF_TEXT)
	{
		if (!pItem->pszText)
			return;
		if (!m_Columns[pItem->iSubItem])
		{
			lstrcpy(pItem->pszText, m_FileData[m_IndexMapping[pItem->iItem]].Name);
		}
		else if (m_Columns[pItem->iSubItem]==2 && (pItem->iItem||(m_Fullpath=="")))
		{

⌨️ 快捷键说明

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