dirtreectrl.cpp
来自「一个支持FTP,SFTP的客户端程序」· C++ 代码 · 共 1,174 行 · 第 1/2 页
CPP
1,174 行
hChild = GetNextItem( hChild, TVGN_NEXT );
}
if ( !bFound )
return FALSE;*/
strTempPath += "\\nul";
if ( find.FindFile( strTempPath ) )
return TRUE;
return FALSE;
}
void CDirTreeCtrl::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
if (!m_dont_notify)
{
m_pOwner->SetLocalFolderOut(GetFullPath(pNMTreeView->itemNew.hItem));
}
*pResult = 0;
}
void CDirTreeCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CTreeCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}
int CDirTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
GetSysImgList() ;
return 0;
}
void CDirTreeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar==VK_F2)
{
// To Use F2 as hot Key to get EditCtrl on the ListView it must have
// the Style TVS_EDITLABELS
ASSERT( GetStyle() & TVS_EDITLABELS );
// don't do an Edit Label when the multiple Items are selected
//Don't allow to rename "My Computer"
if (GetRootItem()==GetSelectedItem())
return;
//Don't allow to rename the drives
if (GetRootItem()==GetParentItem(GetSelectedItem()))
return;
VERIFY( EditLabel( GetSelectedItem() ) != NULL );
}
CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
#define VK_A 65
BOOL CDirTreeCtrl::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;
}
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;
}
}
}
if (pMsg->message == WM_RBUTTONDOWN)
{
if (pMsg->hwnd!=GetSafeHwnd())
return FALSE;
/*CEdit* edit = GetEditControl();
if (edit)
return FALSE;*/
HTREEITEM olditem=GetSelectedItem();
CPoint point=pMsg->pt;
ScreenToClient(&point);
HTREEITEM item=HitTest(point,0);
if (item)
{
if (item!=olditem)
{
SelectItem(item);
ExpandItem(item,TVE_EXPAND);
m_pOwner->SetLocalFolderOut(GetFullPath(item));
SetFocus();
}
}
return TRUE;
}
return CTreeCtrl::PreTranslateMessage(pMsg);
}
void CDirTreeCtrl::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
GetEditControl()->LimitText( 255 );
*pResult = 0;
}
void CDirTreeCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
if (pTVDispInfo->item.pszText)
{
CString newname=pTVDispInfo->item.pszText;
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);
*pResult=FALSE;
return;
}
if (newname=="")
{
*pResult=FALSE;
return;
}
SHFILEOPSTRUCT op;
memset(&op,0,sizeof(op));
CString from=GetFullPath(pTVDispInfo->item.hItem);
from.TrimRight(_T("\\"));
op.pFrom=from;
CString to=from.Left(from.ReverseFind('\\')+1)+pTVDispInfo->item.pszText;
op.pTo=to;
op.hwnd=AfxGetMainWnd()->m_hWnd;
op.wFunc=FO_RENAME;
op.fFlags=FOF_ALLOWUNDO;
if (!SHFileOperation(&op))
{
*pResult = TRUE;
to.TrimRight(_T("\\"));
to+=_T("\\");
m_pOwner->SetLocalFolderOut(to);
return;
}
}
*pResult = FALSE;
}
void CDirTreeCtrl::OnContextMenu(CWnd* pWnd, CPoint point)
{
if (!GetCount())
return;
CMenu menu;
menu.LoadMenu(IDR_LOCALTREECONTEXTMENU);
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;
//while (pWndPopupOwner->GetStyle() & WS_CHILD)
// pWndPopupOwner = pWndPopupOwner->GetParent();
HTREEITEM hTreeItem=GetSelectedItem();
if (!hTreeItem)
{
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_UPLOAD,MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_UPLOADAS,MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_ADDTOQUEUE,MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_DELETE,MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_RENAME,MF_GRAYED);
}
else
{
if (point.x==-1 || point.y==-1)
{
CRect rect;
GetItemRect(hTreeItem,&rect,TRUE);
point.x=rect.left+5;
point.y=rect.top+5;
ClientToScreen(&point);
}
if (!GetParentItem(hTreeItem) || !GetParentItem(GetParentItem(hTreeItem)))
{
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_UPLOAD, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_UPLOADAS, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_ADDTOQUEUE, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_DELETE, MF_GRAYED);
pPopup->EnableMenuItem(ID_LOCALTREECONTEXT_RENAME, MF_GRAYED);
}
}
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,pWndPopupOwner);
}
void CDirTreeCtrl::OnLocaltreecontextAddtoqueue()
{
HTREEITEM item;
if (m_hDragSource)
item = m_hDragSource;
else
item = GetSelectedItem();
if (!item)
return;
if (!GetParentItem(item))
return;
CString path = GetFullPath(item);
CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
path.TrimRight(_T("\\"));
pMainFrame->UploadDir(path + "\\*.*", GetItemText(item) + "\\", FALSE, m_transferuser, m_transferpass);
}
void CDirTreeCtrl::OnLocaltreecontextDelete()
{
HTREEITEM item = GetSelectedItem();
if (!item)
return;
if (!GetParentItem(item) || !GetParentItem(GetParentItem(item)))
return;
CString path=GetFullPath(item);
path.TrimRight(_T("\\"));
HTREEITEM parentitem=GetParentItem(item);
LPTSTR buffer=new TCHAR[path.GetLength()+2];
memset(buffer,0,path.GetLength()*sizeof(TCHAR)+2*sizeof(TCHAR));
_tcscpy(buffer,path);
SHFILEOPSTRUCT op;
memset(&op,0,sizeof(op));
op.hwnd=m_hWnd;
op.wFunc=FO_DELETE;
op.fFlags=(GetKeyState(VK_SHIFT)&128)?0:FOF_ALLOWUNDO;
op.pFrom=buffer;
if (!SHFileOperation(&op) && !op.fAnyOperationsAborted)
{
SelectItem(parentitem);
DeleteItem(item);
}
SetFocus();
delete buffer;
}
void CDirTreeCtrl::OnLocaltreecontextRename()
{
HTREEITEM item=GetSelectedItem();
if (!item)
return;
if (!GetParentItem(item) || !GetParentItem(GetParentItem(item)))
return;
EditLabel(item);
}
void CDirTreeCtrl::OnLocaltreecontextUpload()
{
HTREEITEM item;
if (m_hDragSource)
item = m_hDragSource;
else
item = GetSelectedItem();
if (!item)
return;
if (!GetParentItem(item))
return;
CString path=GetFullPath(item);
CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
path.TrimRight(_T("\\"));
pMainFrame->UploadDir(path + "\\*.*", GetItemText(item) + "\\", TRUE, m_transferuser, m_transferpass);
pMainFrame->TransferQueue(2);
}
void CDirTreeCtrl::OnLocaltreecontextUploadas()
{
CTransferAsDlg dlg;
if (dlg.DoModal()==IDOK)
{
m_transferuser=dlg.m_User;
m_transferpass=dlg.m_Pass;
if (dlg.m_bTransferNow)
OnLocaltreecontextUpload();
else
OnLocaltreecontextAddtoqueue();
}
m_transferuser="";
m_transferpass="";
}
void CDirTreeCtrl::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
{
*pResult = 0;
NM_TREEVIEW *pNMTreeView = (NM_TREEVIEW *)pNMHDR;
CMainFrame *pMainFrame = DYNAMIC_DOWNCAST(CMainFrame, GetParentFrame());
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
if (!hItem)
return;
CString path = GetFullPath(hItem);
if (path == "" || path == "\\")
return;
EnsureVisible(hItem);
m_hDragSource = hItem;
//Let the main window handle the rest
pMainFrame->OnBegindrag(this, pNMTreeView->ptDrag);
}
BOOL CDirTreeCtrl::DragPosition(CImageList *pImageList, CWnd* pDragWnd, CPoint point)
{
ScreenToClient(&point);
HTREEITEM hItem = HitTest(point);
if (pDragWnd == this && hItem)
{
CString dragPath = GetFullPath(m_hDragSource);
CString path = GetFullPath(hItem);
if (dragPath.GetLength() < path.GetLength() &&
path.Left(dragPath.GetLength()) == dragPath)
{
DragLeave(pImageList);
return FALSE;
}
}
if (hItem)
{
if (hItem != m_hDragHilited)
{
pImageList->DragShowNolock(false);
if (m_hDragHilited)
{
SetItemState(m_hDragHilited, 0, LVIS_DROPHILITED);
}
m_hDragHilited = hItem;
SetItemState(hItem, TVIS_DROPHILITED, TVIS_DROPHILITED);
UpdateWindow();
pImageList->DragShowNolock(true);
}
}
else
DragLeave(pImageList);
return TRUE;
}
void CDirTreeCtrl::DragLeave(CImageList *pImageList)
{
if (!m_hDragHilited)
return;
if (pImageList)
pImageList->DragShowNolock(false);
SetItemState(m_hDragHilited, 0, TVIS_DROPHILITED);
UpdateWindow();
if (pImageList)
pImageList->DragShowNolock(true);
m_hDragHilited = NULL;
}
void CDirTreeCtrl::OnDragEnd(int target, CPoint point)
{
m_transferuser = m_transferpass = "";
if (target == 1)
OnLocaltreecontextAddtoqueue();
else if (!target)
OnLocaltreecontextUpload();
else if (target == 2 || target == 3)
{
CString to;
if (target == 2)
{
if (!m_hDragHilited)
return;
if (m_hDragSource == m_hDragHilited)
return;
to = GetFullPath(m_hDragHilited);
}
else
{
CMainFrame *pMainFrame = DYNAMIC_DOWNCAST(CMainFrame, GetParentFrame());
to = reinterpret_cast<CLocalFileListCtrl *>(pMainFrame->GetLocalPane2()->GetListCtrl())->GetDropTarget();
if (to == "" || to == "\\")
return;
}
CString from = GetFullPath(m_hDragSource);
if (from.GetLength() < to.GetLength() &&
to.Left(from.GetLength()) == from)
return;
from.TrimRight('\\');
to.TrimRight('\\');
if (to == "")
return;
LPTSTR pFrom = new TCHAR[from.GetLength() + 2];
_tcscpy(pFrom, from);
pFrom[from.GetLength() + 1] = 0;
LPTSTR pTo = new TCHAR[to.GetLength() + 2];
_tcscpy(pTo, to);
pTo[to.GetLength() + 1] = 0;
SHFILEOPSTRUCT op;
op.hwnd = m_hWnd;
op.wFunc = FO_MOVE;
op.pFrom = pFrom;
op.pTo = pTo;
op.fFlags = 0;
op.hNameMappings = NULL;
op.lpszProgressTitle = NULL;
SHFileOperation(&op);
delete [] pFrom;
delete [] pTo;
RefreshDir(GetParentItem(m_hDragSource));
if (target == 2)
RefreshDir(m_hDragHilited);
else
RefreshDir(to);
CMainFrame *pMainFrame = DYNAMIC_DOWNCAST(CMainFrame, GetParentFrame());
CLocalFileListCtrl *pList = reinterpret_cast<CLocalFileListCtrl *>(pMainFrame->GetLocalPane2()->GetListCtrl());
if (pList->GetFolder() == (to + "\\"))
pList->SetFolder(to);
int pos = from.ReverseFind('\\');
if (pos < 2)
return;
from = from.Left(pos + 1);
if (pList->GetFolder() == from)
pList->SetFolder(from);
}
}
CString CDirTreeCtrl::GetDropTarget() const
{
return GetFullPath(m_hDragHilited);
}
// Struct for children list
// Unfortunately declared outside scope of RefreshDir due to linkage problems
// (at least in VC++ 6)
struct t_children
{
HTREEITEM hItem;
CString text;
};
void CDirTreeCtrl::RefreshDir(HTREEITEM hRefreshItem)
{
if (!hRefreshItem)
return;
CString path = GetFullPath(hRefreshItem);
//
// Displaying the Path in the TreeCtrl
//
CFileFind find;
CString strPathFiles = path;
BOOL bFind;
std::vector<CString> strDirArray;
if ( strPathFiles.Right(1) != "\\" )
strPathFiles += "\\";
strPathFiles += "*.*";
bFind = find.FindFile( strPathFiles );
while ( bFind )
{
bFind = find.FindNextFile();
if ( find.IsDirectory() && !find.IsDots() )
{
strDirArray.push_back( find.GetFilePath() );
}
}
// Get children list which is already sorted
std::vector<t_children> childrenArray;
HTREEITEM hChildItem = GetChildItem(hRefreshItem);
while (hChildItem)
{
t_children child;
child.hItem = hChildItem;
child.text = GetItemText(hChildItem);
childrenArray.push_back(child);
hChildItem = GetNextSiblingItem(hChildItem);
}
SortArray(strDirArray);
SetRedraw(FALSE);
CWaitCursor wait;
// Search for new/deleted entries
unsigned int j = 0;
for (UINT i = 0; i < strDirArray.size(); i++)
{
CString subPath = GetSubPath(strDirArray[i]);
int comp;
if (j < childrenArray.size())
comp = subPath.CollateNoCase(childrenArray[j].text);
else
comp = -1;
if (!comp)
j++;
else if (comp < 0)
{
HTREEITEM hItem = AddItem( hRefreshItem, strDirArray[i] );
if (FindSubDir(strDirArray[i]))
InsertItem(_T(""), 0, 0, hItem);
}
else
{
i--;
DeleteItem(childrenArray[j].hItem);
j++;
}
}
SortChildren(hRefreshItem);
SetRedraw(TRUE);
}
void CDirTreeCtrl::RefreshDir(CString dir)
{
if (dir == "")
return;
if (dir.Right(1) != _T("\\"))
dir += "\\";
HTREEITEM hParent = GetRootItem();
while (dir != _T(""))
{
int pos = dir.Find(_T("\\"));
if (pos == -1)
return;
CString sub = dir.Left(pos);
dir = dir.Mid(pos + 1);
HTREEITEM hItem = GetChildItem(hParent);
while (hItem)
{
if (!GetItemText(hItem).CollateNoCase(sub))
{
hParent = hItem;
break;
}
hItem = GetNextSiblingItem(hItem);
}
if (!hItem)
return;
}
if (hParent != GetRootItem())
RefreshDir(hParent);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?