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

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

[复制链接]
lovewyufeng 发布时间:2014-12-12 17:35
本帖最后由 lovewyufeng 于 2014-12-12 17:55 编辑
$ W# S/ N: P! H% ^& Z3 d1 L4 ]2 ~9 R2 ]' l# ^+ k
不知道大家有没有  这样的应用,需要将磁盘上面的文件以列表方式显示出来。,7 u. P" k3 k9 O0 y( A

& S' H! d9 X' l& m5 t! P. Z* F+ FTREEVIEW 无疑是最佳选择了,可是 假如存在这样一种情况,你的设备经常需要保存文件,  比如每个小时保存一个 文件  每天或者每个月一个文件夹
! N8 l% \# X. X  f5 U+ `- G- j也许没这么频繁,但是无论如何  设备使用到一定时间  磁盘里面的文件数量将不可估量。
+ ?9 |! V6 Y9 ^' b那么问题来了
1 I2 A7 p1 Y( N# G
+ F: D0 Z( W0 C1 g8 `6 z1 |第一、 树形目录  一个节点消耗100字节  一个树叶 消耗  50字节 当你的文件成千上万的时候  你的内存消耗得起么?
) d* P* [8 P  A5 ~* Y4 l( e第二、众所周知磁盘操作速度很慢的,就算你获取文件名  同样需要操作磁盘   当你的文件成千上万的时候 你初始化这个 树形结构 可能都需要10多秒甚至更多。' x$ o; x# U1 }! }0 b* H) U# u
         别认为没那么慢,笔者曾经在 NAND FLASH上使用JFFS2文件系统  从文件一个有500个子文件的文件夹中  遍历检索第  100-103 4个文件花的时间长达2s   
/ B/ y! F' o% c- {) e         当然这个 JFFS2这个文件系统有关系, 后来使用FATFS文件系统  就快了起来   但是第一点依然是很严重的问题
+ u9 z5 D7 K/ X# \) n. O# c
- f( o) S3 E2 V! w2 H# J$ E
* y  E5 \2 C/ Z' O为解决这个问题   笔者提出一个方案。
4 B8 \- ~" J4 c. W4 w初始化 TREE的时候只将第一层  节点添加进去,对于文件夹, 在节点内添加一个占位 叶节点,这样看起来这个节点前面就有一个 +号可以被打开。- i9 b9 _6 i6 \% x- w2 J0 Q
当打开这个节点的时候查看子节点是否为预添加的占位符, 如果是 再去遍历   对应的文件夹,同时删除占位符,添加节点。2 D" {: P, q' b+ a* n. y2 T3 _% O
如此  遍历的时间由单个文件夹的文件数量决定,不会因为总数量 庞大而慢。
& k; k" P1 Z" y; z. R# G内存则由 打开过的文件决定, 甚至  当系统内存不足的是否可以 删除被关闭的  节点内容 再次添加占位符。释放内存。, U8 A" n4 s) J! Y4 E5 `
) f) S) X2 ^9 e1 R; o8 f7 `* j( w

: w$ [# J' z" q% e" m, @3 x5 ~! ]% J/ o$ d" |
9 l/ H2 a& ]% c5 {3 I! p
( ?, u1 {1 Z% _7 r

; G/ K* ?  B5 }) i/ c3 V  Y, \那么现在方案有了  具体怎么实现呢?9 k1 r) h- F$ R) e  U

( X7 E" z( d3 L) n. c" E/ y
- [* R" @: f* f& E这里笔者提供一个已经实现的  回调函数  callback
$ g1 Q7 t, E9 v; s# R
/ U4 }# O. m- p. t4 f
3 B4 g# }4 ^$ ]' |" D7 U& m1 ]% ^

  1. , C# {8 G% o5 b* h4 {% Q( }
  2. 4 m9 {- j: Q0 c3 B( u1 t; y- l
  3. TREEVIEW_ITEM_Handle Item_get_next(TREEVIEW_ITEM_Handle hItem)//用到辅助函数
    $ ?2 d1 ~8 N& S0 q$ F$ Y3 v
  4. {
    2 ~9 z, l) v2 I5 H
  5.     TREEVIEW_ITEM_OBJ *itemobj;
    4 j3 M! b. o9 V
  6.     if(hItem)0 k0 P# p3 i  k% A$ g  v
  7.     {
    ' V6 C4 ~: w% n& m" S% J+ |
  8.         itemobj=(TREEVIEW_ITEM_OBJ*)GUI_ALLOC_h2p(hItem);
    ; I6 L$ R# k1 w4 A1 N! Y+ w
  9.         return itemobj->hNext;
    9 i* h1 W5 g3 t. O9 c4 p, n5 \3 r
  10.     }5 Y: H# `/ a" @4 ~: x/ Z. y# G3 M
  11.     return 0;
    8 v! X/ w5 f% @0 \2 l0 S
  12. }
    * a3 w- o! l( e) R2 K0 ?4 @( y
  13. - J/ ~; I: r$ s! B8 p. X4 p2 A+ o
  14. void _cbtree(WM_MESSAGE * pMsg)
    % D- e0 Y, P6 w- r  E3 o6 U: s
  15. {2 X- u% ^* f5 D! j& t6 f; Z
  16.     int Id, NCode;/ K. |* ^  A( Z4 D# H& _3 I2 |# J
  17.     TREEVIEW_ITEM_Handle hItem,fristitem;; Q+ {$ k8 V4 ~% H/ A
  18.     char buf[20];& O+ ]# T. z9 ~9 \$ t. m/ i5 m
  19.     int num[2]={1,2000};
    2 \# ~8 l0 j8 [
  20.     TREEVIEW_ITEM_INFO info;, ?3 J$ }/ w! K1 i# p& x1 i# ?
  21.     switch (pMsg->MsgId)
    3 o5 O% H4 ?8 D7 u
  22.     {8 s5 I5 l' d- u& D" k
  23.     case WM_KEY://拦截 按键消息5 v5 M7 O0 E% {+ H' W. A, f$ ~
  24.         {
    # C9 E2 F( ^) r) b+ `; T4 N) X
  25.             int pressed;
    ) o* O. h$ j: C* A/ T
  26.             pressed=((WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt;! z' w: z7 X/ L1 O( ]& D4 ^9 W
  27.             NCode = ((WM_KEY_INFO*)(pMsg->Data.p))->Key;
    % g9 @  |$ G; ?: N' Z" f  u2 i- V
  28. ! E/ t5 O( S3 Z# i( x
  29.             switch(NCode)" f4 ]* y( F/ ~2 D
  30.             {
    * Q7 q( i5 B- E% G* E$ j
  31.             default:
    2 }3 A8 @' e$ E
  32.                 if(pressed)
    ) B2 F& z8 z; a8 @/ l( F& U. R; Z' ~; d
  33.                 {
    ( ?; r6 E  q9 d* K% f
  34.                     if (NCode==GUI_KEY_RIGHT)// 树默认right 键打开节点,再打开前  添加节点
    & N* q5 z( y& D0 B
  35.                     {
    ' J, z$ M/ J, a+ c6 b3 W
  36.                         hItem=TREEVIEW_GetSel(pMsg->hWin);6 K' z: P6 i. B6 H
  37.                         TREEVIEW_ITEM_GetInfo(hItem,&info);" l& @! I# |4 P( D+ O' e6 r1 D
  38.                         if(info.IsNode)
    1 j  W, @/ ?- x& ^0 R% [  T
  39.                         {
    - r; k4 v. X* C" o6 B; c# f2 y
  40.                             fristitem=TREEVIEW_GetItem(pMsg->hWin,hItem,TREEVIEW_GET_FIRST_CHILD);8 X, U' n" x5 N$ u3 m1 m. C
  41.                             TREEVIEW_ITEM_GetText(fristitem,(uint8_t*)buf,20);5 ^6 ]2 @4 K% R% Y  W4 G
  42.                             if(strcmp("space",buf)==0)//比较是否为占位符9 {& d3 i! Q- q- s* z
  43.                             {
    - r2 X4 i) @) y  Q. t
  44.                                 TREEVIEW_ITEM_Delete(fristitem);2 g  K( t( ^  m/ n. G7 M8 I
  45.                                 tree_add_filelist(num,0,pMsg->hWin,hItem);//这个函数将  遍历磁盘文件添加到树 指定节点
    0 H1 I' ~3 r& p9 r* s2 S/ i8 J
  46.                             }
    4 T5 O1 A: A% o2 h, ?
  47.                         }
    - l! [- x3 X! z  i/ _' c0 _5 D
  48. 8 \' {9 X! z7 Q8 i+ Y
  49.                     }* W7 D4 `$ N( O# E$ q& t( z
  50.                 }( @1 a3 ?+ w" y* K6 ?+ H
  51.                 else9 c3 L1 x; K& c+ Z- ^
  52.                 {
    # ~: d6 c& n0 l4 i0 g
  53.                     ((WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt=1;
    % O% ~+ X. |- M6 a- a2 L2 F/ Y
  54.                     TREEVIEW_Callback(pMsg);
    - X' R9 Y8 ^( l* Y- I7 G( B- l
  55.                 }$ i6 k* O( u$ d7 d+ R
  56.                 break;9 f& F6 T8 Y- {' H0 m6 R
  57.             }
    9 h, X$ T/ g% r9 F
  58.         }1 C8 ]3 x; ^3 a) b; y1 _5 w, F
  59.         break;
    ' B' g. {0 [0 q9 e
  60.     case WM_TOUCH:// 这个是处理触摸事件   比较麻烦一点  主要是获得触摸的地方, 遍历TREE 取得被点击的节点  判断是否为 节点  然后的操作就和  按键一样了+ r' I$ ?: x5 I9 M* Z& ?3 o
  61.         {3 W" H  ]( t/ K4 Z; W1 q
  62.             TREEVIEW_ITEM_Handle hNode;
    5 [  A: g/ ?: ?' g% p
  63.             GUI_PID_STATE* pState;
    : A+ T* I0 z+ s6 X! q" K- e
  64.             TREEVIEW_OBJ *treeobj;+ t) z9 Y2 t) o
  65. 3 I# H1 l; Q% ~$ G' R: R/ A
  66.             pState     = (GUI_PID_STATE*)pMsg->Data.p;; }* Q2 f% j4 y1 \
  67.             treeobj       = (TREEVIEW_OBJ*)GUI_ALLOC_h2p(pMsg->hWin);
    ! T. g4 {: ~; h. m3 \' d2 P6 D
  68.             if(pState->y/treeobj->Props.MinItemHeight<treeobj->NumVisItems+1)
    . s" B" R6 N3 L: l9 s7 p. y* T
  69.             {
    ! g( i9 w& @4 p1 F+ A  F; e( Z
  70.                 hNode=TREEVIEW_GetItem(pMsg->hWin,0,TREEVIEW_GET_FIRST);; l3 `4 J' n: X( D) C9 d
  71.                 if(hNode)0 U* F! G# p" c( O
  72.                 {. \! A, n6 ]; ]/ d
  73.                     int num=pState->y/treeobj->Props.MinItemHeight +((pState->y%treeobj->Props.MinItemHeight)>0 ?1:0)-1;//计算被点击的是第几个节点
    - T, t1 `) |# d
  74.                     if(treeobj->ScrollStateV.v>0)# s' A( b& |0 M5 n/ v) N
  75.                         num+=treeobj->ScrollStateV.v;
    , h6 v# a" T" E; Q4 V# x: D, }

  76. & x- n; }( t  Y- ~9 Z( Z7 u) d* E  Q
  77.                     while(num--)//这个while  遍历得到被点击的  节点handle' ^/ y3 ]! v1 P
  78.                     {8 U! w4 v8 N& t
  79.                         TREEVIEW_ITEM_GetInfo(hNode,&info);2 W7 p; {7 Y7 ]; E3 W5 T0 d
  80.                         if(info.IsNode)0 Q" B+ G% I, C
  81.                         {/ X& q' \# ^- t) r
  82.                             if(info.IsExpanded): w& ]* C7 q3 \8 W" j) K
  83.                             {
    / k) F* K5 \+ D9 j" f
  84.                                 hNode=TREEVIEW_GetItem(pMsg->hWin,hNode,TREEVIEW_GET_FIRST_CHILD);
    6 Q0 @4 N1 c/ O+ N  a
  85.                             }+ j$ a- A! @2 `& u* G3 z1 l+ P* F( |1 Y
  86.                             else
    9 z7 w& f0 S: [2 z5 q6 b
  87.                             {
    & J' m" r* X( }9 c- d) C: ]
  88.                                 hNode=TREEVIEW_GetItem(pMsg->hWin,hNode,TREEVIEW_GET_NEXT_SIBLING);/ r$ W# K, f1 o5 k. o0 c
  89.                             }
    - V% o) Z/ T. I

  90. 2 G' w* u* W$ m% z+ v" Y
  91.                         }7 S/ ^; G$ z- Q; d- P0 B# T
  92.                         else
    2 p, K$ W/ \) e) X! i
  93.                         {# N5 e/ r2 o: R! }
  94.                             hNode=Item_get_next(hNode);, t9 `, o! g3 L+ H
  95.                         }3 R. N6 l7 |. }, \
  96.                     }
    ! \& [1 G# i- Z' R+ s7 I1 ~4 E; t6 T
  97.                 }  `4 z  @6 r+ l8 N2 ]4 q3 @* P
  98.                 TREEVIEW_ITEM_GetInfo(hNode,&info);
    ( Z% Q; p) b6 A: q
  99.                 if(info.IsExpanded==0)" }2 D! D+ ?" ~6 f) l7 n+ }, Q! t
  100.                 {
    . a% Q0 O' q  ]8 a( S2 N1 @4 @* `
  101.                     if(info.IsNode&&(pState->x<((info.Level+1)*treeobj->Props.Indent-treeobj->ScrollStateH.v))&&
    - j$ G" \& U7 ^% x6 P  u
  102.                         pState->x>((info.Level)*treeobj->Props.Indent-treeobj->ScrollStateH.v)0 w) D$ U* _. J. [2 U; _) S% l2 B
  103.                         )5 [2 }0 H$ \+ d1 w3 d
  104.                     {  f$ R# A7 ?" ~7 b; p% _
  105.                         fristitem=TREEVIEW_GetItem(pMsg->hWin,hNode,TREEVIEW_GET_FIRST_CHILD);3 ^* J7 o  v: i# w7 j
  106.                         TREEVIEW_ITEM_GetText(fristitem,(uint8_t*)buf,20);
    & \" r* U5 m! f2 e  o6 }! W
  107.                         if(strcmp("space",buf)==0)
    7 q6 J0 X: a. u( K+ |
  108.                         {. ?" s  X" u' O1 y8 u
  109.                             TREEVIEW_ITEM_Delete(fristitem);
    / e3 p& x* y- x9 ?; W% O% P$ V
  110.                             tree_add_filelist(num,0,pMsg->hWin,hNode);
    1 l- E( ]8 y3 o* `: a- e! L& q& l
  111.                         }
    + J* ?8 i7 y; N/ Y
  112.                     }
    % e' _1 }8 f1 @) \- R
  113.                 }
    1 J( j5 t! ]& {( X8 k
  114.                 else
    6 G* r- \4 }0 T! {/ h$ V  E0 E
  115.                 {
    4 W* S0 {6 S% @% n, g3 ?  s5 G

  116. 7 @) l# p/ E# ~$ l& Y7 i
  117.                 }: h0 Q! V/ V" J. J
  118.                 TREEVIEW_Callback(pMsg);
    : ?$ u  R( a) x. z% r' d) n# [
  119.             }
    + N9 c) R3 K+ L8 Q& d
  120. ) T9 d4 u: R! Y6 g$ \
  121.         }) {8 ?8 J/ q! ~2 V4 V$ s0 t  d6 {
  122.         break;
    5 m' R$ o* [' D$ L
  123.     default:5 @) W% Z+ h8 L, W
  124.         TREEVIEW_Callback(pMsg);
    8 V5 a7 n5 H: U& G, k$ B
  125.         break;( a9 W) l2 S( w7 M  T8 @- r
  126.     }
    : h* w; @. m& h+ o

  127. : E1 s' f* k' S
  128. }( r* R1 Q& i# Y7 D& W
  129. , \- g9 [3 Y: c- q

  130. * t; S4 f% t& U* h$ O1 j& m4 \) C
复制代码

% U  x, m" S& o9 X
+ J' w: j$ e# S5 J
收藏 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
adersonl 发表于 2014-12-12 17:41
5 w/ U4 d  y1 n3 l# Y" Q# j! c石头板凳顶龙少
- w8 u$ T6 r* _8 ~, o' ]
3Q  大家的肯定是我的动力
lovewyufeng 回答时间:2014-12-12 17:53:44
上传一张效果图片 QQ图片20141212175156.jpg $ z5 i0 q6 D' S' ^
+ t/ D  g& n- k8 u! j4 H5 t( k! R8 b
大器所成 回答时间:2014-12-12 21:00:42
太棒了!膜拜下
善良的女性 回答时间:2014-12-12 23:47:53
好复杂啊 好好学下8 ^) r( P$ o. y5 l2 `. s+ Z; h

6 g  b2 v' |9 V! f4 C0 F
8 a; u2 Z; v; F" H- H7 h+ k* `
0 F8 s6 l6 p* F" p
Dylan疾风闪电 回答时间:2014-12-13 21:43:16
点赞,支持。
lovewyufeng 回答时间:2014-12-13 23:10:09
Dylan疾风闪电 发表于 2014-12-13 21:43
3 Y$ z* B* B! u$ ~) i点赞,支持。
3 Z5 b' M6 y$ s; L' \
这个控件不是很好用  改天介绍另一个   文件操作专用 小工具
yang 回答时间:2014-12-18 12:07:47
牛人" k" _& [, K  c4 i- h
学习了
; K7 B# P* ?- g* z) W9 E2 S

所属标签

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