你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STemWin 树形文件 目录 执行 初始化速度 和 内存优化

[复制链接]
lovewyufeng 发布时间:2014-12-12 17:35
本帖最后由 lovewyufeng 于 2014-12-12 17:55 编辑

不知道大家有没有  这样的应用,需要将磁盘上面的文件以列表方式显示出来。,

TREEVIEW 无疑是最佳选择了,可是 假如存在这样一种情况,你的设备经常需要保存文件,  比如每个小时保存一个 文件  每天或者每个月一个文件夹
也许没这么频繁,但是无论如何  设备使用到一定时间  磁盘里面的文件数量将不可估量。
那么问题来了

第一、 树形目录  一个节点消耗100字节  一个树叶 消耗  50字节 当你的文件成千上万的时候  你的内存消耗得起么?
第二、众所周知磁盘操作速度很慢的,就算你获取文件名  同样需要操作磁盘   当你的文件成千上万的时候 你初始化这个 树形结构 可能都需要10多秒甚至更多。
         别认为没那么慢,笔者曾经在 NAND FLASH上使用JFFS2文件系统  从文件一个有500个子文件的文件夹中  遍历检索第  100-103 4个文件花的时间长达2s   
         当然这个 JFFS2这个文件系统有关系, 后来使用FATFS文件系统  就快了起来   但是第一点依然是很严重的问题


为解决这个问题   笔者提出一个方案。
初始化 TREE的时候只将第一层  节点添加进去,对于文件夹, 在节点内添加一个占位 叶节点,这样看起来这个节点前面就有一个 +号可以被打开。
当打开这个节点的时候查看子节点是否为预添加的占位符, 如果是 再去遍历   对应的文件夹,同时删除占位符,添加节点。
如此  遍历的时间由单个文件夹的文件数量决定,不会因为总数量 庞大而慢。
内存则由 打开过的文件决定, 甚至  当系统内存不足的是否可以 删除被关闭的  节点内容 再次添加占位符。释放内存。






那么现在方案有了  具体怎么实现呢?


这里笔者提供一个已经实现的  回调函数  callback




  1. TREEVIEW_ITEM_Handle Item_get_next(TREEVIEW_ITEM_Handle hItem)//用到辅助函数
  2. {
  3.     TREEVIEW_ITEM_OBJ *itemobj;
  4.     if(hItem)
  5.     {
  6.         itemobj=(TREEVIEW_ITEM_OBJ*)GUI_ALLOC_h2p(hItem);
  7.         return itemobj->hNext;
  8.     }
  9.     return 0;
  10. }

  11. void _cbtree(WM_MESSAGE * pMsg)
  12. {
  13.     int Id, NCode;
  14.     TREEVIEW_ITEM_Handle hItem,fristitem;
  15.     char buf[20];
  16.     int num[2]={1,2000};
  17.     TREEVIEW_ITEM_INFO info;
  18.     switch (pMsg->MsgId)
  19.     {
  20.     case WM_KEY://拦截 按键消息
  21.         {
  22.             int pressed;
  23.             pressed=((WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt;
  24.             NCode = ((WM_KEY_INFO*)(pMsg->Data.p))->Key;

  25.             switch(NCode)
  26.             {
  27.             default:
  28.                 if(pressed)
  29.                 {
  30.                     if (NCode==GUI_KEY_RIGHT)// 树默认right 键打开节点,再打开前  添加节点
  31.                     {
  32.                         hItem=TREEVIEW_GetSel(pMsg->hWin);
  33.                         TREEVIEW_ITEM_GetInfo(hItem,&info);
  34.                         if(info.IsNode)
  35.                         {
  36.                             fristitem=TREEVIEW_GetItem(pMsg->hWin,hItem,TREEVIEW_GET_FIRST_CHILD);
  37.                             TREEVIEW_ITEM_GetText(fristitem,(uint8_t*)buf,20);
  38.                             if(strcmp("space",buf)==0)//比较是否为占位符
  39.                             {
  40.                                 TREEVIEW_ITEM_Delete(fristitem);
  41.                                 tree_add_filelist(num,0,pMsg->hWin,hItem);//这个函数将  遍历磁盘文件添加到树 指定节点
  42.                             }
  43.                         }

  44.                     }
  45.                 }
  46.                 else
  47.                 {
  48.                     ((WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt=1;
  49.                     TREEVIEW_Callback(pMsg);
  50.                 }
  51.                 break;
  52.             }
  53.         }
  54.         break;
  55.     case WM_TOUCH:// 这个是处理触摸事件   比较麻烦一点  主要是获得触摸的地方, 遍历TREE 取得被点击的节点  判断是否为 节点  然后的操作就和  按键一样了
  56.         {
  57.             TREEVIEW_ITEM_Handle hNode;
  58.             GUI_PID_STATE* pState;
  59.             TREEVIEW_OBJ *treeobj;

  60.             pState     = (GUI_PID_STATE*)pMsg->Data.p;
  61.             treeobj       = (TREEVIEW_OBJ*)GUI_ALLOC_h2p(pMsg->hWin);
  62.             if(pState->y/treeobj->Props.MinItemHeight<treeobj->NumVisItems+1)
  63.             {
  64.                 hNode=TREEVIEW_GetItem(pMsg->hWin,0,TREEVIEW_GET_FIRST);
  65.                 if(hNode)
  66.                 {
  67.                     int num=pState->y/treeobj->Props.MinItemHeight +((pState->y%treeobj->Props.MinItemHeight)>0 ?1:0)-1;//计算被点击的是第几个节点
  68.                     if(treeobj->ScrollStateV.v>0)
  69.                         num+=treeobj->ScrollStateV.v;

  70.                     while(num--)//这个while  遍历得到被点击的  节点handle
  71.                     {
  72.                         TREEVIEW_ITEM_GetInfo(hNode,&info);
  73.                         if(info.IsNode)
  74.                         {
  75.                             if(info.IsExpanded)
  76.                             {
  77.                                 hNode=TREEVIEW_GetItem(pMsg->hWin,hNode,TREEVIEW_GET_FIRST_CHILD);
  78.                             }
  79.                             else
  80.                             {
  81.                                 hNode=TREEVIEW_GetItem(pMsg->hWin,hNode,TREEVIEW_GET_NEXT_SIBLING);
  82.                             }

  83.                         }
  84.                         else
  85.                         {
  86.                             hNode=Item_get_next(hNode);
  87.                         }
  88.                     }
  89.                 }
  90.                 TREEVIEW_ITEM_GetInfo(hNode,&info);
  91.                 if(info.IsExpanded==0)
  92.                 {
  93.                     if(info.IsNode&&(pState->x<((info.Level+1)*treeobj->Props.Indent-treeobj->ScrollStateH.v))&&
  94.                         pState->x>((info.Level)*treeobj->Props.Indent-treeobj->ScrollStateH.v)
  95.                         )
  96.                     {
  97.                         fristitem=TREEVIEW_GetItem(pMsg->hWin,hNode,TREEVIEW_GET_FIRST_CHILD);
  98.                         TREEVIEW_ITEM_GetText(fristitem,(uint8_t*)buf,20);
  99.                         if(strcmp("space",buf)==0)
  100.                         {
  101.                             TREEVIEW_ITEM_Delete(fristitem);
  102.                             tree_add_filelist(num,0,pMsg->hWin,hNode);
  103.                         }
  104.                     }
  105.                 }
  106.                 else
  107.                 {

  108.                 }
  109.                 TREEVIEW_Callback(pMsg);
  110.             }

  111.         }
  112.         break;
  113.     default:
  114.         TREEVIEW_Callback(pMsg);
  115.         break;
  116.     }

  117. }


复制代码


收藏 1 评论10 发布时间:2014-12-12 17:35

举报

10个回答
lovewyufeng 回答时间:2014-12-12 17:38:16
自己占沙发
aderson 回答时间:2014-12-12 17:41:54
石头板凳顶龙少
沐紫 回答时间:2014-12-12 17:41:58
赞赞赞!
lovewyufeng 回答时间:2014-12-12 17:47:26

3Q  大家的肯定是我的动力
lovewyufeng 回答时间:2014-12-12 17:53:44
上传一张效果图片 QQ图片20141212175156.jpg

大器所成 回答时间:2014-12-12 21:00:42
太棒了!膜拜下
善良的女性 回答时间:2014-12-12 23:47:53
好复杂啊 好好学下



Dylan疾风闪电 回答时间:2014-12-13 21:43:16
点赞,支持。
lovewyufeng 回答时间:2014-12-13 23:10:09

这个控件不是很好用  改天介绍另一个   文件操作专用 小工具
yang 回答时间:2014-12-18 12:07:47
牛人
学习了

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版