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

📄 workspace.cpp

📁 功能: 实现目录树中文件夹
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	if(strPathName.IsEmpty())//如果strPathName为空,则返回
	{ ASSERT(FALSE); return;}

	HTREEITEM hTreeItem = m_pTreeCtrl->GetSelectedItem();//得到当前结点信息
	CFolder* pFolder = (CFolder*)m_pTreeCtrl->GetItemData(hTreeItem);//获取当前结点数据
	if(!pFolder->AddFileName(strPathName))//调用CFolder中的AddFileName函数。
     	return	;   //文件没有增加到m_FileNameArray则返回

	TV_INSERTSTRUCT TreeCtrlItem;//定义TreeCtrlItem
	TreeCtrlItem.hParent = hTreeItem;//父结点=hTreeItem
	TreeCtrlItem.hInsertAfter = TVI_LAST;//最后一个结点
	TreeCtrlItem.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_PARAM | TVIF_SELECTEDIMAGE;
//激活上述iImage,iSelectedImage,lParam属性
	int nCount = strPathName.GetLength() - strPathName.ReverseFind('\\')-1;//求得文件库路径字符数
	CString strFileName = strPathName.Right(nCount);//获得文件名称

	TreeCtrlItem.hParent = hTreeItem;//父结点=hTreeItem
	TreeCtrlItem.item.pszText = strFileName.GetBuffer(strFileName.GetLength());//结点上得到文件名
	strFileName.ReleaseBuffer();//释放GetBuffer
	TreeCtrlItem.item.iImage = 2;//选取一个新建文件图象
	TreeCtrlItem.item.iSelectedImage = 2;//选中该节点时的图象
	TreeCtrlItem.item.lParam = (LPARAM)pFolder;

	m_pTreeCtrl->InsertItem(&TreeCtrlItem);//插入结点
	m_pTreeCtrl->Expand(hTreeItem, TVE_EXPAND);//扩充列表

	//AfxGetApp()->OpenDocumentFile(strFileName);
}

void CWorkSpace::OnLButtonUp(UINT nFlags, CPoint point) 
{
	TCHAR szFullPath[MAX_PATH];

	int nSize = ::GetModuleFileName(AfxGetInstanceHandle(), szFullPath, MAX_PATH);//获得应用程序的路径
	if(nSize == 0)
	{
		Invalidate();
		return;	
	}
	CString strPath(szFullPath);
	int n = strPath.ReverseFind( '\\' )+1;
	strPath = strPath.Left(n);//去掉可执行文件名
	if(m_hDragItem)//如果拖动文件
	{
		UINT uFlag = 0;
		HTREEITEM hTreeItem = m_pTreeCtrl->HitTest(point, &uFlag);//获取点击的节点信息
		BOOL bIsFolder = FALSE;//定义bIsFolder
		CString strItemText, strDragItemText;//定义strItemText, strDragItemText
		BOOL bAddSuccess = TRUE;//定义bAddSuccess
		if(hTreeItem && (uFlag & TVHT_ONITEM))
		{
			CFolder* pFolder = (CFolder*)m_pTreeCtrl->GetItemData(hTreeItem);//获取结点Data
			if(CanBeDropTargert(hTreeItem, m_hDragItem))//如果是可以拖动的目标
			{    //将被拖动的目标名称赋给strDragItemText
				strDragItemText = m_pTreeCtrl->GetItemText(m_hDragItem);
				//获取被拖动的目标结点Data赋给pDragFolder
				CFolder* pDragFolder = (CFolder*)m_pTreeCtrl->GetItemData(m_hDragItem);

				TV_INSERTSTRUCT TreeCtrlItem;//定义TreeCtrlItem
				if(pDragFolder->IsFolder(strDragItemText))//选中文件夹
				{
				if(pDragFolder->m_pFather)
						pDragFolder->m_pFather->RemoveFolder(pDragFolder, FALSE);
					else
						RemoveFolder(pDragFolder, FALSE);
					pFolder->AddFolder(pDragFolder);//调用AddFolder函数在目标结点增加文件夹										
					TreeCtrlItem.item.iImage = 0;//选取一个新建文件夹图象
					TreeCtrlItem.item.iSelectedImage = 1;//选中该节点时的图象(为打开的文件夹)
					bIsFolder = TRUE;//是文件夹
				}
				else//选中文件
				{        //获取文件完整路径
					CString strPathName = pDragFolder->FindFullFileName(strDragItemText);//获取文件完整路径
					if(strPathName.IsEmpty())
					{                        //如果路径为空则返回
						ASSERT(FALSE);
						return;
					}
					BOOL b = pDragFolder->RemoveFileName(strDragItemText);//删除文件是否成功
					ASSERT(b);
					bAddSuccess = pFolder->AddFileName(strPathName);//增加文件是否成功
					ASSERT(bAddSuccess);
					TreeCtrlItem.item.iImage = 2;//选取一个新建文件图象
					TreeCtrlItem.item.iSelectedImage = 2;//选中该节点时的图象
				}
				strItemText = m_pTreeCtrl->GetItemText(hTreeItem);//获取鼠标结点文件名称
				if(!pFolder->IsFolder(strItemText))//如果不是文件夹
					hTreeItem = m_pTreeCtrl->GetParentItem(hTreeItem);//获取父亲结点信息

				TreeCtrlItem.hParent = hTreeItem;
				m_pTreeCtrl->DeleteItem(m_hDragItem);
				TreeCtrlItem.hInsertAfter = TVI_LAST;//在最后位置插入结点
                //激活上述iImage,iSelectedImage,lParam属性
				TreeCtrlItem.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_PARAM | TVIF_SELECTEDIMAGE;
                  //得到文件名
				TreeCtrlItem.item.pszText = strDragItemText.GetBuffer(strDragItemText.GetLength());
                  //释放GetBuffer
				strDragItemText.ReleaseBuffer();
				TreeCtrlItem.item.lParam = (LPARAM)pFolder;
				if(bIsFolder)//如果是文件夹
					m_pTreeCtrl->FillItem(pDragFolder, hTreeItem);//填充文件夹下的目录
				else if(bAddSuccess)
					m_pTreeCtrl->SelectDropTarget(m_pTreeCtrl->InsertItem(&TreeCtrlItem));
				else 
					ASSERT(FALSE);
				m_pTreeCtrl->SortChildren(hTreeItem);
				m_pTreeCtrl->Expand(hTreeItem, TVE_EXPAND);//扩充列表
				::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));//拖动时的箭头Cursor
			}
		}
	}
	m_hDragItem = NULL;//没有拖动文件
	CTreeView::OnLButtonUp(nFlags, point);
	GetParent()->Invalidate();
}

void CWorkSpace::OnHideWorkSpace() 
{
	((CMainFrame*)AfxGetMainWnd())->m_wndWorkSpaceBar.ShowWindow(SW_HIDE);	
	((CMainFrame*)AfxGetMainWnd())->RecalcLayout();	
}

void CWorkSpace::OnUpdateWorkspceBar(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	
}

void CWorkSpace::OnDelWorkspaceItem() 
{
	HTREEITEM hCurItem = m_pTreeCtrl->GetSelectedItem();//获得当前结点信息
	if(!hCurItem)//当前结点为空则返回
		return;

	if(AfxMessageBox(IDS_DEL_IT, MB_YESNO) != IDYES)//弹出“确定删除”对话框判断是否删除
		return;

	CFolder* pFolder = (CFolder*)m_pTreeCtrl->GetItemData(hCurItem);//获取结点Data
	ASSERT(pFolder);
	CString strItemText = m_pTreeCtrl->GetItemText(hCurItem);//获取当前结点名
	if(pFolder->IsFolder(strItemText))//删除的是否文件夹
	{
/**/		if(pFolder->m_pFather)
			pFolder->m_pFather->RemoveFolder(pFolder);	//调用RemoveFolder函数,调用父亲结点的m_FolderList中删除。		
	else
			RemoveFolder(pFolder);//删除文件夹
	}
	else//删除文件
		pFolder->RemoveFileName(strItemText, FALSE);//调用RemoveFileName函数

	m_pTreeCtrl->DeleteItem(hCurItem);//删除结点
	Invalidate();	
}
void CWorkSpace::RemoveFolder(CFolder* pFolder, BOOL bDelete/*=TRUE*/)//删除文件夹,
{                                                 //在OnDelWorkspaceItem()等函数中调用 
	ASSERT(pFolder != NULL);//如果文件夹存在

	POSITION pos;//定义索引指针
	pos = m_FolderLi.Find(pFolder);//指针指向要删除的文件夹
	if(!pos)//指针为空则返回
		return;

	m_FolderLi.RemoveAt(pos);//删除指针
	if(bDelete)
		delete pFolder;//释放指针指向的对象

	Invalidate();
} 

void CWorkSpace::Serialize(CArchive& ar) 
{
	m_FolderLi.Serialize(ar);
	if (ar.IsStoring())
	{	// storing code
	}
	else
	{	// loading code
	}
}
BOOL CWorkSpace::OpenStockFile()//打开存储的文件函数(from文件库)
{
  // int nPos = m_strStockName.ReverseFind(_T('\\'));//返回路径字符个数
	CFile file; 
    if(!file.Open(m_strStockName, CFile::modeRead))//如果不是以只读方式打开或路径不对则返回
	{
		return FALSE;
	}
	CArchive ar(&file, CArchive::load);//定义CArchive对象(地址file,类型为读取文件)
	Serialize(ar);//完成序列化打开文件
    ar.Close(); //关闭CArchive缓冲区
	file.Close();//关闭文件
	return TRUE;
}

void CWorkSpace::SaveStockFile()//保存文件
{
    CString m_strPath;
	CFile file; 
    if(!file.Open(m_strStockName, CFile::modeCreate|CFile::modeWrite))
		return;
    CArchive ar(&file, CArchive::store);
	Serialize(ar);
    ar.Close(); 
	file.Close();

}

void CWorkSpace::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
    m_hDragItem = pNMTreeView->itemNew.hItem;      //获取选定被拖动结点的消息	
	*pResult = 0;
}

void CWorkSpace::OnMouseMove(UINT nFlags, CPoint point) 
{
	if(!(MK_LBUTTON & nFlags))
		return;

	UINT uFlag = 0;
	HTREEITEM hTreeItem = m_pTreeCtrl->HitTest(point , &uFlag);//获取点击的节点信息
	if(hTreeItem && (uFlag & TVHT_ONITEM))
	{
		CFolder* pFolder = (CFolder*)m_pTreeCtrl->GetItemData(hTreeItem);//获取结点Data
		if(CanBeDropTargert(hTreeItem, m_hDragItem))//如果是可以拖动的结点
		{
			CString strItemText = m_pTreeCtrl->GetItemText(hTreeItem);//得到当前结点名
			if(pFolder->IsFolder(strItemText))//选中文件夹
				m_pTreeCtrl->SelectDropTarget(hTreeItem);//重画结点的样式
			else//选中文件
				m_pTreeCtrl->SelectDropTarget(m_pTreeCtrl->GetParentItem(hTreeItem));//父亲一定为文件夹
		}//重画结点的样式
	else
			m_pTreeCtrl->SelectDropTarget(m_hDragItem);//重画结点的样式
	}
	if(m_hDragItem)
		::SetCursor(AfxGetApp()->LoadCursor(IDC_DRAG_FOLDER));	//获取光标拖动时状态

}
BOOL CWorkSpace::CanBeDropTargert(HTREEITEM hTreeItem, HTREEITEM hDragItem)//判断是否是可以拖动的函数
{
	if(hTreeItem == hDragItem)//如果拖动到的结点与被拖动结点是同一结点则返回
		return FALSE;

	while(hTreeItem != NULL)//如果拖动到的结点不为空
	{
		if(hTreeItem == hDragItem)//如果拖动到的结点与被拖动结点是同一结点则返回
			return FALSE;

		hTreeItem = m_pTreeCtrl->GetParentItem(hTreeItem);//获取拖动到的结点的父亲结点的信息
	}

	return TRUE;//是可以拖动的目标
}

⌨️ 快捷键说明

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