www.pudn.com > NetPaw.rar > LeftView.cpp


// LeftView.cpp : CLeftView 类的实现 
// 
 
#include "stdafx.h" 
#include "NetPaw.h" 
 
#include "mainfrm.h" 
#include "NetPawDoc.h" 
#include "fileview.h" 
#include ".\leftview.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 
 
 
// CLeftView 
IMPLEMENT_DYNCREATE(CLeftView, CTreeView) 
 
BEGIN_MESSAGE_MAP(CLeftView, CTreeView) 
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnTvnItemExpanding) 
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnTvnSelChanged) 
	ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnTvnBeginLabelEdit) 
	ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnTvnEndLabelEdit) 
	ON_COMMAND(ID_FOLDER_NEW, OnFolderNew) 
	ON_COMMAND(ID_FOLDER_RENAME, OnFolderRename) 
	ON_COMMAND(ID_FOLDER_DEL, OnFolderDel) 
	ON_UPDATE_COMMAND_UI(ID_FOLDER_NEW, OnUpdateFolderNew) 
	ON_UPDATE_COMMAND_UI(ID_FOLDER_DEL, OnUpdateFolderDel) 
	ON_UPDATE_COMMAND_UI(ID_FOLDER_RENAME, OnUpdateFolderRename) 
	ON_WM_RBUTTONDOWN() 
	ON_WM_INITMENUPOPUP() 
END_MESSAGE_MAP() 
 
 
// CLeftView 构造/析构 
 
CLeftView::CLeftView() 
	: m_pImageList(NULL) 
{ 
	// TODO: 在此处添加构造代码 
} 
 
CLeftView::~CLeftView() 
{ 
	if( m_pImageList ) 
	{ 
		delete m_pImageList; 
	} 
} 
 
BOOL CLeftView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// 在此处通过修改 CREATESTRUCT cs 来修改窗口类或树控件的样式 
	cs.style |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS; 
 
	return CTreeView::PreCreateWindow(cs); 
} 
 
void CLeftView::OnInitialUpdate() 
{ 
	CTreeView::OnInitialUpdate(); 
 
	// create image list for tree view 
	m_pImageList = new CImageList(); 
	if( m_pImageList ) 
	{ 
		m_pImageList->Create( 16, 16, ILC_COLOR32|ILC_MASK, MAX_FOLDER_ICONS, 2 ); 
 
		CBitmap bitmap; 
		bitmap.LoadBitmap(IDB_BMPFOLDERS); 
		m_pImageList->Add(&bitmap, RGB(255, 0, 255)); 
	} 
 
	// now add the image list to the tree control 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
	treeCtrl.SetImageList(m_pImageList, TVSIL_NORMAL); 
 
	// TODO: 调用 GetTreeCtrl() 直接访问 TreeView 的树控件, 
	// 从而可以用项填充 TreeView。 
	FillTreeCtrl(); 
} 
 
 
// CLeftView 诊断 
 
#ifdef _DEBUG 
void CLeftView::AssertValid() const 
{ 
	CTreeView::AssertValid(); 
} 
 
void CLeftView::Dump(CDumpContext& dc) const 
{ 
	CTreeView::Dump(dc); 
} 
 
CNetPawDoc* CLeftView::GetDocument() // 非调试版本是内联的 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CNetPawDoc))); 
	return (CNetPawDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
 
// CLeftView 消息处理程序 
 
void CLeftView::FillTreeCtrl(void) 
{ 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	// form the tree root - the NetPaw 
	TV_INSERTSTRUCT	stTVInsert; 
	stTVInsert.hParent = NULL; // a root item's parent is NULL 
	stTVInsert.hInsertAfter = NULL; 
	stTVInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; // must use a selectedimage even if same 
	stTVInsert.item.iImage = 0; 
	stTVInsert.item.iSelectedImage = stTVInsert.item.iImage; 
	stTVInsert.item.pszText = (LPTSTR)"NetPaw"; 
 
	HTREEITEM hRoot = treeCtrl.InsertItem(&stTVInsert); 
 
	// now add default folders 
	UINT nStrID; 
	CString sFolderName; 
	HTREEITEM hTreeItem; 
	for( int i = 0; i < MAX_DEFAULT_FOLDERS; i++ ) 
	{ 
		stTVInsert.hParent = hRoot; 
		stTVInsert.item.iImage = i + 1; 
		stTVInsert.item.iSelectedImage = stTVInsert.item.iImage + HALF_FOLDER_ICONS; 
 
		nStrID = IDS_DEFAULT_FOLDER1 + i; 
		sFolderName.LoadString(nStrID); 
		stTVInsert.item.pszText = (LPTSTR)(LPCTSTR)sFolderName; 
 
		hTreeItem = treeCtrl.InsertItem(&stTVInsert); 
 
		// add virtual child to make nodes openable 
		AddDummyChild(hTreeItem, TRUE); 
	} 
 
	// add custom folders here 
	// under work ... 
 
	// expand the root 
	treeCtrl.Expand(hRoot, TVE_EXPAND); 
} 
 
void CLeftView::OnTvnItemExpanding(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
	LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); 
	HTREEITEM hItem = pNMTreeView->itemNew.hItem; 
 
	// TODO: 在此添加控件通知处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	// should not remove the root nodes 
	if( hItem != treeCtrl.GetRootItem() ) 
	{ 
		// remove dummy child of this directory 
		HTREEITEM hTemp; 
		HTREEITEM hChild = treeCtrl.GetChildItem(hItem); 
		while( hChild != NULL ) 
		{ 
			hTemp = treeCtrl.GetNextSiblingItem(hChild); 
			treeCtrl.DeleteItem(hChild); 
			hChild = hTemp; 
		} 
 
		// find and add real children to this node 
		AddRealChildren(hItem); 
	} 
 
	*pResult = 0; 
} 
 
void CLeftView::OnTvnSelChanged(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
	LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); 
	HTREEITEM hItem = pNMTreeView->itemNew.hItem; 
 
	// TODO: 在此添加控件通知处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
	int nClassID = GetItemID(hItem); 
 
	// notify file view that selected tree item has changed 
	CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd(); 
	CFileView *pView = pFrame->GetRightPane(); 
	if( pView ) 
	{ 
		pView->OnTreeItemChanged(nClassID); 
	} 
 
	*pResult = 0; 
} 
 
void CLeftView::AddDummyChild(HTREEITEM hItem, BOOL bFind) 
{ 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
	BOOL bHasChild = FALSE; 
 
	if( bFind ) 
	{ 
		// get the absolute path of this item 
		CString sPathName; 
		GetFullPathOfItem(hItem, sPathName); 
 
		// find if sPathName has a child folder 
		CFileFind finder; 
		sPathName += _T("\\*.*"); 
		BOOL bContinue = finder.FindFile(sPathName); 
		while( bContinue ) 
		{ 
			bContinue = finder.FindNextFile(); 
			if( finder.IsDirectory() && !finder.IsDots() ) 
			{ 
				bHasChild = TRUE; 
				break; 
			} 
		} 
 
		finder.Close(); 
	} 
	else 
	{ 
		bHasChild = TRUE; 
	} 
 
	TV_INSERTSTRUCT stTVInsert; 
	if( bHasChild ) 
	{ 
		stTVInsert.hParent = hItem; 
		stTVInsert.hInsertAfter = TVI_LAST; 
		stTVInsert.item.iImage = 4; // folder icon 
		stTVInsert.item.iSelectedImage = stTVInsert.item.iImage + HALF_FOLDER_ICONS; 
		stTVInsert.item.pszText = _T("1"); 
		stTVInsert.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; 
		treeCtrl.InsertItem(&stTVInsert); 
	} 
} 
 
void CLeftView::AddRealChildren(HTREEITEM hParent) 
{ 
	// TODO: 在此添加控件通知处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	// build up the path to htreeitem 
	CString sPathName; 
	GetFullPathOfItem(hParent, sPathName); 
 
	// use file finder to find first child 
	CFileFind finder; 
	sPathName += _T("\\*.*"); 
	BOOL bContinue = finder.FindFile(sPathName); 
 
	CString sFileName; 
	HTREEITEM hChildItem; 
	TV_INSERTSTRUCT stTVInsert; 
	while( bContinue ) // set up and insert a stTVInsert for each item in the directory 
	{ 
		// FindNextFile muxt be called before info can be gleaned from finder 
		bContinue = finder.FindNextFile(); 
 
		if( finder.IsDirectory() && !finder.IsDots() ) 
		{ 
			sFileName = finder.GetFileName(); 
 
			// file or directory 
			stTVInsert.item.iImage = 4; // folder icon 
			stTVInsert.item.iSelectedImage = stTVInsert.item.iImage + HALF_FOLDER_ICONS; 
 
			stTVInsert.hParent = hParent; 
			stTVInsert.hInsertAfter = TVI_LAST; 
			stTVInsert.item.pszText = (LPTSTR)(LPCTSTR)sFileName;   // GetFileName() returns a CString 
			stTVInsert.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; 
 
			hChildItem = treeCtrl.InsertItem(&stTVInsert); 
 
			// because a file node has no child, only directory need dummy child 
			AddDummyChild( hChildItem, TRUE ); 
		} 
	} 
 
	finder.Close(); 
} 
 
void CLeftView::GetFullPathOfItem(HTREEITEM hItem, CString& sPathName) 
{ 
	CString sTemp; 
	sPathName = _T(""); 
 
	// build up the path to htreeitem 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
	while( hItem && (hItem != treeCtrl.GetRootItem()) ) 
	{ 
		if( sPathName.IsEmpty() ) 
		{ 
			sTemp = treeCtrl.GetItemText(hItem); 
		} 
		else 
		{ 
			sTemp.Format(_T("%s\\%s"), treeCtrl.GetItemText(hItem), (LPCTSTR)sPathName); 
		} 
 
		sPathName = sTemp; 
		hItem = treeCtrl.GetParentItem(hItem); 
	} 
 
	// make the full path 
	GetModuleFileName(NULL, sTemp.GetBuffer(MAX_PATH), MAX_PATH); 
	sTemp.ReleaseBuffer(); 
 
	int nIndex = sTemp.ReverseFind('\\'); 
	if( nIndex != -1 ) 
	{ 
		sTemp = sTemp.Left(nIndex); 
	} 
 
	sPathName = sTemp + _T("\\") + sPathName; 
} 
 
void CLeftView::OnFolderNew() 
{ 
	// TODO: 在此添加命令处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	// TODO: Add your control notification handler code here 
	HTREEITEM hItem, hNewItem; 
	hItem = treeCtrl.GetSelectedItem(); 
	if( hItem != NULL ) 
	{ 
		CString str, sFullPath; 
		str.LoadString(IDS_DEFAULT_NEWFOLDER); 
 
		// Insert a new node under the current selected node 
		TVINSERTSTRUCT stTVInsert; 
		stTVInsert.hParent = hItem; 
		stTVInsert.hInsertAfter = TVI_LAST; 
		stTVInsert.item.iImage = 4; // folder icon 
		stTVInsert.item.iSelectedImage = stTVInsert.item.iImage + HALF_FOLDER_ICONS; 
		stTVInsert.item.pszText = (LPTSTR)(LPCTSTR)str; 
		stTVInsert.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; 
 
		hNewItem = treeCtrl.InsertItem(&stTVInsert); 
 
		// create new folder using default name 
		GetFullPathOfItem(hNewItem, sFullPath); 
		if( !sFullPath.IsEmpty() ) 
		{ 
			::CreateDirectory( sFullPath, NULL ); 
		} 
 
		UINT nFlag = treeCtrl.GetItemState(hItem, 0xFF); 
		if( (nFlag & TVIS_EXPANDED) == 0 ) 
		{ 
			treeCtrl.Expand(hItem, TVE_EXPAND); 
		} 
 
		treeCtrl.SelectItem(hNewItem); 
		treeCtrl.EditLabel(hNewItem); 
	} 
} 
 
void CLeftView::OnFolderRename() 
{ 
	// TODO: 在此添加命令处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	HTREEITEM hItem = treeCtrl.GetSelectedItem(); 
	if( hItem != NULL ) 
	{ 
		treeCtrl.EditLabel(hItem); 
	} 
} 
 
void CLeftView::OnFolderDel() 
{ 
	// TODO: 在此添加命令处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	CString sPathName; 
	HTREEITEM hItem = treeCtrl.GetSelectedItem(); 
	if( hItem != NULL ) 
	{ 
		GetFullPathOfItem(hItem, sPathName); 
		DWORD dwAttrib = GetFileAttributes(sPathName); 
		if( dwAttrib & FILE_ATTRIBUTE_DIRECTORY ) 
		{ 
			DelDirectory(sPathName); 
		} 
		else 
		{ 
			DeleteFile(sPathName); 
		} 
 
		// should delete this item at last 
		treeCtrl.DeleteItem(hItem); 
	} 
} 
 
void CLeftView::OnTvnBeginLabelEdit(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
	LPNMTVDISPINFO pTVDispInfo = reinterpret_cast(pNMHDR); 
	HTREEITEM hItem = pTVDispInfo->item.hItem; 
 
	// 不允许编辑根节点及主节点 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
	if( ( hItem == treeCtrl.GetRootItem() ) 
		|| ( treeCtrl.GetParentItem(hItem) == treeCtrl.GetRootItem() ) ) 
	{ 
		*pResult = -1; // label edit will not continue 
		return; 
	} 
 
	*pResult = 0; 
} 
 
void CLeftView::OnTvnEndLabelEdit(NMHDR *pNMHDR, LRESULT *pResult) 
{ 
	LPNMTVDISPINFO pTVDispInfo = reinterpret_cast(pNMHDR); 
	HTREEITEM hItem = pTVDispInfo->item.hItem; 
 
	// TODO: 在此添加控件通知处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
	*pResult = -1; 
 
	// 获取节点编辑框中的文字 
	CString sEditText(""); 
	CEdit *pEdit = treeCtrl.GetEditControl(); 
	if(!pEdit) 
	{ 
		return; 
	} 
 
	pEdit->GetWindowText(sEditText); 
	if( sEditText.IsEmpty() ) 
	{ 
		return; 
	} 
 
	// first get old path name 
	CString sOldDirName, sPath; 
	GetFullPathOfItem(hItem, sOldDirName); 
 
	// now get the new path name 
	HTREEITEM hParentIT = treeCtrl.GetParentItem( hItem ); 
	GetFullPathOfItem(hParentIT, sPath); 
	sPath += _T("\\") + sEditText; 
	if( sPath != sOldDirName ) 
	{ 
		// file/directory node 
		MoveFile(sOldDirName, sPath); 
		treeCtrl.SetItemText( hItem, sEditText ); 
	} 
 
	*pResult = 0; 
} 
 
void CLeftView::OnUpdateFolderNew(CCmdUI *pCmdUI) 
{ 
	// TODO: 在此添加命令更新用户界面处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	HTREEITEM hItem = treeCtrl.GetSelectedItem(); 
	pCmdUI->Enable( (hItem != treeCtrl.GetRootItem()) && IsItemDirectory(hItem) ); 
} 
 
void CLeftView::OnUpdateFolderDel(CCmdUI *pCmdUI) 
{ 
	// TODO: 在此添加命令更新用户界面处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	HTREEITEM hItem = treeCtrl.GetSelectedItem(); 
	pCmdUI->Enable( (hItem != treeCtrl.GetRootItem()) 
		&& (treeCtrl.GetParentItem(hItem) != treeCtrl.GetRootItem()) ); 
} 
 
void CLeftView::OnUpdateFolderRename(CCmdUI *pCmdUI) 
{ 
	// TODO: 在此添加命令更新用户界面处理程序代码 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	HTREEITEM hItem = treeCtrl.GetSelectedItem(); 
	pCmdUI->Enable( (hItem != treeCtrl.GetRootItem()) 
		&& (treeCtrl.GetParentItem(hItem) != treeCtrl.GetRootItem()) ); 
} 
 
BOOL CLeftView::IsItemDirectory(HTREEITEM hItem) 
{ 
	BOOL bResult = FALSE; 
 
	CString sPathName; 
	GetFullPathOfItem(hItem, sPathName); 
 
	DWORD dwAttrib = GetFileAttributes(sPathName); 
	if( dwAttrib & FILE_ATTRIBUTE_DIRECTORY ) 
	{ 
		bResult = TRUE; 
	} 
 
	return bResult; 
} 
 
void CLeftView::OnRButtonDown(UINT nFlags, CPoint point) 
{ 
	// TODO: 在此添加消息处理程序代码和/或调用默认值 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	HTREEITEM hItem = treeCtrl.GetSelectedItem(); 
	if( hItem == treeCtrl.HitTest(point) ) 
	{ 
		CMenu menu; 
		menu.LoadMenu(IDR_MAINFRAME); 
 
		CMenu *pPopup = menu.GetSubMenu(1); 
		if( pPopup ) 
		{ 
			CPoint pt(point); 
			ClientToScreen(&pt); 
			pPopup->TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, this); 
		} 
	} 
 
	CTreeView::OnRButtonDown(nFlags, point); 
} 
 
void CLeftView::DelDirectory(LPCTSTR szDirName) 
{ 
	CString sPathName; 
	CFileFind finder; 
 
	CString sWildCard(szDirName); 
	sWildCard += _T("\\*.*"); 
	BOOL bContinue = finder.FindFile( sWildCard ); 
 
	while( bContinue ) 
	{ 
		bContinue = finder.FindNextFile(); 
		if( finder.IsDots() ) 
		{ 
			continue; 
		} 
 
		sPathName = finder.GetFilePath(); 
		if( finder.IsDirectory() ) 
		{ 
			DelDirectory(sPathName); 
		} 
		else 
		{ 
			DeleteFile(sPathName); 
		} 
	} 
 
	finder.Close(); 
	RemoveDirectory(szDirName); 
} 
 
int CLeftView::GetItemID(HTREEITEM hItem) 
{ 
	CTreeCtrl &treeCtrl = GetTreeCtrl(); 
 
	// first get main class item 
	HTREEITEM hTmpItem; 
	while( ( hTmpItem = treeCtrl.GetParentItem(hItem) ) != NULL ) 
	{ 
		if( hTmpItem == treeCtrl.GetRootItem() ) 
		{ 
			break; 
		} 
 
		hItem = hTmpItem; 
	} 
 
	// now get the item ID 
	int nID = FOLDER_DOWNLDING; 
	while( ( hTmpItem = treeCtrl.GetPrevSiblingItem(hItem) ) != NULL ) 
	{ 
		nID++; 
		hItem = hTmpItem; 
	} 
 
	return nID; 
} 
 
void CLeftView::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/) 
{ 
	// TODO: 在此添加专用代码和/或调用基类 
} 
 
// We have to add this when using update ui mechanism in no-CFrameWnd derived class 
void CLeftView::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) 
{ 
	CTreeView::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); 
 
	// TODO: 在此处添加消息处理程序代码 
	CMainFrame* pFrameWnd = (CMainFrame* )AfxGetMainWnd(); 
    if(NULL != pFrameWnd) 
	{ 
        pFrameWnd->SendMessage( WM_INITMENUPOPUP, 
			WPARAM(pPopupMenu->m_hMenu), MAKELPARAM(nIndex, bSysMenu) ); 
	} 
}