5.4.5 文件管理
在测试上面的结果时,我们会发现,切换文件类别后原先设定的类别并没有被保存。应该如何解决这个问题呢?
1.理清功能的需要
要解决这个问题,我们就要增加一个内部的存储。这个内部的存储应该如何设计呢?
考虑这个内部存储所采用的形式,用数组还是列表?
由于我们的"文件类别"目录结构是不确定的,显然这个地方用列表比较合适。
列表中的元素应该如何构造呢?
1)如果将类别与类别下的文件列表内容关联起来呢?
有两种方式我们可以采用。
使用类别目录的完整路径作为关联字。
注意:不能使用类别名称,因为我们的规定是同级下不能存在重名,也就是说不同级别下可以存在同名选项,因此单纯使用类别名称会造成存储的混乱。必须采用完整的路径名。
该方法的优点是通用性较强,仅逻辑相关与具体的实现控件无关。缺点是关联字比较复杂。
使用Tree Control中item相关的HTREEITEM进行关联。
该方法的优点是比较简单,只需要关心选中项相关的HTREEITEM即可。缺点是控件相关,降低了代码的可复用性。
在此我们采用方式b实现我们的功能。
2)应该包含哪些内容呢?
关联项
文件列表
2.定义用于存储的数据结构
在CFilesAssistantDlg中增加以下代码。
FilesAssistantDlg.h …… #include <list>
using namespace std; // CFilesAssistantDlg dialog class CFilesAssistantDlg : public CDialog { …… struct FILES_IN_CLASS//类别中的文件 { HTREEITEM hItemClass;//关联项 CStringList strlstFiles;//文件列表 }; list<FILES_IN_CLASS*> m_lstClassFiles; //文件分类列表 }
|
3.确定触发类别内容更新的机制
在此,笔者选择在IDC_TREE_FILE_CLASS控件的TVN_SELCHANGED事件中进行处理。
在CfilesAssistantDlg中增加相关的处理代码。
FilesAssistantDlg.h afx_msg void OnTvnSelchangedTreeFileClass(NMHDR *pNMHDR, LRESULT *pResult); FilesAssistantDlg.cpp void CFilesAssistantDlg::OnTvnSelchangedTreeFileClass (NMHDR *pNMHDR, LRESULT *pResult) { LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); *pResult = 0; HTREEITEM hOld = pNMTreeView->itemOld.hItem; HTREEITEM hNew = pNMTreeView->itemNew.hItem; //判断存储列表是否为空,如果是空则直接添加 if (m_lstClassFiles.empty()) { FILES_IN_CLASS *clsfiles = new FILES_IN_CLASS; clsfiles->hItemClass = pNMTreeView->itemNew.hItem; m_lstClassFiles.push_back(clsfiles); return; } //初始化用于定位的迭代器 list <FILES_IN_CLASS*>::iterator it =m_lstClassFiles.end(); //用于查询 list <FILES_IN_CLASS*>::iterator oldIt = m_lstClassFiles.end(); //选中类别变化时,旧类别相关的文件列表 list <FILES_IN_CLASS*>::iterator newIt = m_lstClassFiles.end(); //选中类别变化时,新类别相关的文件列表 //搜索现有类别,分别找到选中类别变化中新旧类别在列表中的位置 for(it = m_lstClassFiles.begin();it!=m_lstClassFiles.end();it++) { if (((FILES_IN_CLASS*)*it)->hItemClass == hOld) { oldIt = it; } else if (((FILES_IN_CLASS*)*it)->hItemClass == hNew) { newIt = it; } } //重置上一个的文件列表 ((FILES_IN_CLASS*)*oldIt)->strlstFiles.RemoveAll(); CString str; for (int i=0;i<m_lbClassifiedFiles.GetCount();i++) { m_lbClassifiedFiles.GetText(i,str); ((FILES_IN_CLASS*)*oldIt)->strlstFiles.AddTail(str); } //处理新的文件列表 if ( newIt == m_lstClassFiles.end()) { FILES_IN_CLASS *clsfiles = new FILES_IN_CLASS; clsfiles->hItemClass = pNMTreeView->itemNew.hItem; m_lstClassFiles.push_back(clsfiles); } else { m_lbClassifiedFiles.ResetContent(); for (POSITION pos=((FILES_IN_CLASS*)*newIt)->strlstFiles. GetHeadPosition();pos != NULL;) { m_lbClassifiedFiles.AddString(((FILES_IN_CLASS*)*newIt) ->strlstFiles.GetNext(pos)); } } } |
编译并测试结果。
至此我们完成了一个粗糙的文件管理器。
【责任编辑:
云霞 TEL:(010)68476606】