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) );
}
}