MFC——CTreeCtrl数据的处理:如何将数据和逻辑分开?
来源:互联网 发布:美橙互联怎么解析域名 编辑:程序博客网 时间:2024/05/28 23:12
CTreeCtrl是windows界面开发中经常用到,也是windows系统中经常见到的一种控件,比如文件夹目录,那就是一个典型的应用,不过,很多资料中,对于CTreeCtrl的数据的处理,存在一些问题。我们可以先看下面的代码:
void CFileTreeCtrl::InitTreeCtrl(const CString& strDir, HTREEITEM hItem){CFileFind finder;CString strFindDir = strDir;strFindDir += _T("\\*.*");BOOL bWorking = finder.FindFile(strFindDir);while(bWorking){HTREEITEM hItemTmp;bWorking = finder.FindNextFile();if(finder.IsDirectory() && !finder.IsDots()){CString szFileName = finder.GetFileName();CString strNextDir = finder.GetFilePath();SHFILEINFO sfi;SHGetFileInfo(strNextDir+_T("\\"), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_DISPLAYNAME);TV_INSERTSTRUCT TCItem;ZeroMemory(&TCItem,sizeof(TV_INSERTSTRUCT));TCItem.hInsertAfter = TVI_LAST;TCItem.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_STATE|TVIF_SELECTEDIMAGE;TCItem.item.pszText = sfi.szDisplayName;TCItem.item.iImage = sfi.iIcon;TCItem.item.iSelectedImage = sfi.iIcon;TCItem.item.lParam = 0;if(hItem == NULL){TCItem.hParent = m_hRoot;//hItemTmp = InsertItem(szFileName, m_hRoot);hItemTmp = InsertItem(&TCItem);}else{TCItem.hParent = hItem;//hItemTmp = InsertItem(szFileName, hItem);hItemTmp = InsertItem(&TCItem);}TCHAR* pData = new TCHAR[strNextDir.GetLength()];lstrcpy(pData, (LPCTSTR)strNextDir);SetItemData(hItemTmp, (DWORD_PTR)pData);InitTreeCtrl(strNextDir, hItemTmp);}}Expand(m_hRoot,TVE_EXPAND);finder.Close();}
这种写法是比较常见的,这样写有什么问题呢?首先数据和逻辑混在一起;其次,每刷新一次,都要重新读取目录一次;再次,就是扩展性不好。这里是读取一个指定目录,那如果目录数据来源于数据库呢,又或者来源于服务程序?
所以,网上搜的资料,可以参考,可以借鉴,更要深入的思考和优化。
都提倡设计模式,但是说一套,做一套,并不是一个好的方式。有的人说起来一套套的,似乎这也会,那也懂,但是写的东西不是有内存泄露,就是导致程序异常。对于这种数据和逻辑混淆在一起的情况,其实大有存在。
先看看下面的代码:
int CFileTreeCtrl::InitData(int parentId, HTREEITEM hItem){COprMySql OprMySql;BOOL bFlag=FALSE;TFile* temp;int nData = m_file[parentId];if (nData == 1){Expand(hItem,TVE_EXPAND);temp = m_fileData[parentId];((CDlgUpFile*)(GetParent()))->m_EditPath.SetWindowText(temp->url);return 1;}vector<TFile> tFile;tFile.empty();vector<TFile>::iterator iter;char strtemp[20];OprMySql.QueryFileSqlByParentId(tFile, parentId);for(iter=tFile.begin(); iter!=tFile.end(); iter++){temp = new TFile();*temp = *iter;TV_INSERTSTRUCT TCItem;ZeroMemory(&TCItem,sizeof(TV_INSERTSTRUCT));TCItem.hInsertAfter = TVI_LAST;TCItem.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_STATE|TVIF_SELECTEDIMAGE;TCItem.item.pszText = temp->name.GetBuffer();//TCItem.item.iImage = sfi.iIcon;//TCItem.item.iSelectedImage = sfi.iIcon;TCItem.item.lParam = temp->id;TCItem.hParent = hItem;InsertItem(&TCItem);m_fileData[temp->id] = temp;}OprMySql.Close();m_file[parentId] = 1;Expand(hItem,TVE_EXPAND);temp = m_fileData[parentId];((CDlgUpFile*)(GetParent()))->m_EditPath.SetWindowText(temp->url);return 0;}
这段代码是从数据库获取目录信息,参数parentId,是表示选中的级数,一般默认加载一级的,当选中某个的时候,就在查询数据库获取它的子项,在这里做了一个标记,m_file[parentId],第一次从数据库获取后,就设置m_file[parentId]=1,同时保存节点的信息m_fileData[temp->id] = temp。
而如果换成一个目录的话,只需要把这一句:OprMySql.QueryFileSqlByParentId(tFile, parentId);里的函数查询数据库,改成本地文件路径的数据。
这是初始的数据,当有增加和删除操作的时候,也一样。同时更新数据库和map的数据就好。
同样的道理,对于CListCtrl里的数据也是如此。
转载请注明原创链接:http://blog.csdn.net/wujunokay/article/details/13278131
- MFC——CTreeCtrl数据的处理:如何将数据和逻辑分开?
- 优雅的代码:将处理用户界面和处理业务逻辑的代码分开
- CTreeCtrl如何设置和获取自己定义的数据
- 窗体 数据 分开的处理方法
- 如何将用分号分开的一行数据保存到一个二维矩阵中?
- android开发笔记之activity之数据逻辑分开处理后界面更新
- (5)业务逻辑的实现:数据如何处理
- MFC CTreeCtrl节点存储额外数据
- 数据和界面显示分开
- 如何分离模板文件的表现和数据逻辑
- 指令和数据混合存储与分开存储的比较
- ORACLE数据库表和数据分开导出导入的方法
- 指令和数据混合存储与分开存储的比较
- 指令和数据混合存储与分开存储的比较
- RO段、RW段和ZI段。全局数据区为什么将已初始化数据和未初始化数据分开!
- RO段、RW段和ZI段。全局数据区为什么将已初始化数据和未初始化数据分开!
- 窗口和线程漫谈之工作线程如何将数据的处理结果显示到窗口
- 服务器 在接受数据 处理的逻辑
- library sort (图书馆排序)
- java之回调函数
- 国内搞机器学习和数据挖掘的大牛
- IP源路由原理和作用
- vim环境设置和自动对齐
- MFC——CTreeCtrl数据的处理:如何将数据和逻辑分开?
- ibatis 批量插入[类对象]到 oracle 数据库
- OCP-1Z0-053-V12.02-186题
- VM虚拟机如何和主机相连
- 结构体变量分析
- TCP长连接与短连接的区别
- 清空Qtablewiget 表格的内容
- AlarmManager的使用
- scrollview与gridview及listview嵌套冲突问题