haijie1223 发表于 2015-7-14 08:10:26

如何读取固定格式的txt并有效率的写到Treeview[已解决]

本帖最后由 haijie1223 于 2015-7-15 18:42 编辑

如何将下列格式的标题的txt内容快速读取并写入到treeview,如图格式的treeview:

逐条读取写入完全可以,但是效率实在太慢,如果有上千条实在不可取。有没有更加效率的读取方法。在txt内容格式不变的情况下。一、第一个大标题
1、第一个小标题1
1.1、test第一个小标题1
1.2、test第一个小标题1
1.3、test第一个小标题1
2、第二个小标题1
2.1、test第一个小标题2
2.2、test第一个小标题2
2.3、test第一个小标题2

二、第二个大标题
1、第一个小标题1
1.1、test第一个小标题1
1.2、test第一个小标题1
1.3、test第一个小标题1
1.4、test第一个小标题1
2、第二个小标题1
2.1、test第一个小标题2
2.2、test第一个小标题2
2.3、test第一个小标题2
2.4、test第一个小标题2

三、第三个大标题
1、第一个小标题1
1.1、test第一个小标题1
1.2、test第一个小标题1
1.3、test第一个小标题1
2、第二个小标题1
2.1、test第一个小标题2
2.2、test第一个小标题2
2.3、test第一个小标题2
2.4、test第一个小标题2
2.5、test第一个小标题2

afan 发表于 2015-7-14 12:32:37

一般是点击加号图标时再加载下一级吧,整体载入全部子项似乎有些不太合理

haijie1223 发表于 2015-7-14 17:03:08

回复 2# afan


    Afan,麻烦给个示例。

afan 发表于 2015-7-14 18:05:46

回复 3# haijie1223


    试试先解析txt档到数组,在再单击项目时读取相应数组再载入子项目

haijie1223 发表于 2015-7-14 21:53:54

回复 4# afan


    先解析到数组,再载入。我的理解是:还是固定数组,比如点击1,那么载入1.1,1.2,1.3,1.4。。。因为这个是不固定的,总不能$array to $array 吧。能自己循环就好了。

afan 发表于 2015-7-15 12:50:34

解析一次到数组这个数组肯定是固定的你指的不固定估计是示例所指的条目数量不固定吧那依旧是解析到数组的问题了如何构建这个数组比较重要比如 数组的元素也可以是数组 这就相当于下级项目了

haijie1223 发表于 2015-7-15 15:11:25

回复 6# afan


    多谢指点,我再琢磨一下。

afan 发表于 2015-7-15 18:19:18

试下
Local $Str = _
                '一、第一个大标题' & @CRLF & _
                '1、一大第一个小标题1' & @CRLF & _
                '1.1、一大一小test第一个小标题1' & @CRLF & _
                '1.2、一大一小test第一个小标题1' & @CRLF & _
                '1.3、一大一小test第一个小标题1' & @CRLF & _
                '2、一大第二个小标题1' & @CRLF & _
                '2.1、一大二小test第一个小标题2' & @CRLF & _
                '2.2、一大二小test第一个小标题2' & @CRLF & _
                '2.3、一大二小test第一个小标题2' & @CRLF & @CRLF & _
                '二、第二个大标题' & @CRLF & _
                '1、二大第一个小标题1' & @CRLF & _
                '1.1、二大一小test第一个小标题1' & @CRLF & _
                '1.2、二大一小test第一个小标题1' & @CRLF & _
                '1.3、二大一小test第一个小标题1' & @CRLF & _
                '1.4、二大一小test第一个小标题1' & @CRLF & _
                '2、二大第二个小标题1' & @CRLF & _
                '2.1、二大二小test第一个小标题2' & @CRLF & _
                '2.2、二大二小test第一个小标题2' & @CRLF & _
                '2.3、二大二小test第一个小标题2' & @CRLF & _
                '2.4、二大二小test第一个小标题2' & @CRLF & @CRLF & _
                '三、第三个大标题' & @CRLF & _
                '1、三大第一个小标题1' & @CRLF & _
                '1.1、三大一小test第一个小标题1' & @CRLF & _
                '1.2、三大一小test第一个小标题1' & @CRLF & _
                '1.3、三大一小test第一个小标题1' & @CRLF & _
                '2、三大第二个小标题1' & @CRLF & _
                '2.1、三大二小test第一个小标题2' & @CRLF & _
                '2.2、三大二小test第一个小标题2' & @CRLF & _
                '2.3、三大二小test第一个小标题2' & @CRLF & _
                '2.4、三大二小test第一个小标题2' & @CRLF & _
                '2.5、三大二小test第一个小标题2'
;~MsgBox(0, '原字符串', $Str)

#include <GuiTreeView.au3>

Local $hGui = GUICreate('TreeView 逐级载入')
Local $iTreeView = GUICtrlCreateTreeView(10, 10, 350, 300)
Local $aTree = _2DArrayCreat($Str)
_TreeLoad($aTree)
GUISetState()
GUIRegisterMsg(0x4E, '_WM_NOTIFY')
While GUIGetMsg() <> -3
WEnd

Func _TreeLoad($aTree)
        If Not IsArray($aTree) Or UBound($aTree, 0) <> 2 Then Return
        Local $i, $iItem
        For $i = 0 To UBound($aTree) - 1
                $iItem = GUICtrlCreateTreeViewItem($aTree[$i], $iTreeView)
                If IsArray($aTree[$i]) Then _GUICtrlTreeView_SetChildren($iTreeView, $iItem, 1)
        Next
EndFunc   ;==>_TreeLoad

Func _WM_NOTIFY($hWnd, $msg, $wParam, $lParam)
        Local $tNMHdr = DllStructCreate($tagNMHDR, $lParam), $tNM_TREEVIEW
        Local $hWndFrom = DllStructGetData($tNMHdr, 'hWndFrom')
        Local $iIDFrom = DllStructGetData($tNMHdr, 'IDFrom')
        Local $iCode = DllStructGetData($tNMHdr, 'Code')
        If $iIDFrom = $iTreeView Then
                Switch $iCode
                        Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
                                _TreeLoadAdd()
                EndSwitch
        EndIf
        Return 'GUI_RUNDEFMSG'
EndFunc   ;==>_WM_NOTIFY

Func _TreeLoadAdd()
        Local $iT = _GetHitTestItem()
        If _GUICtrlTreeView_ExpandedOnce($iTreeView, $iT) Then Return
        Local $hParent = _GUICtrlTreeView_GetParentHandle($iTreeView, $iT)
        Local $hItem
        If Not $hParent Then        ;---- 没有上级,即为第0级
                Local $Index = _GUICtrlTreeView_Index($iTreeView, $iT)
                If IsArray($aTree[$Index]) Then
                        Local $aTmp = $aTree[$Index]
                        For $i = 0 To UBound($aTmp) - 1
                                $hItem = _GUICtrlTreeView_AddChild($iTreeView, $iT, $aTmp[$i])
                                If IsArray($aTmp[$i]) Then _GUICtrlTreeView_SetChildren($iTreeView, $hItem, 1)
                        Next
                EndIf
        Else
                Local $hParent1 = _GUICtrlTreeView_GetParentHandle($iTreeView, $hParent)
                If Not $hParent1 Then        ;---- 第1级
                        Local $Index0 = _GUICtrlTreeView_Index($iTreeView, $hParent)        ;---- 0级索引
                        Local $Index1 = _GUICtrlTreeView_Index($iTreeView, $iT)                ;---- 1级索引
                        Local $aTreeXm = $aTree[$Index0]
                        If IsArray($aTreeXm) And IsArray($aTreeXm[$Index1]) Then
                                Local $aTmp1 = $aTreeXm[$Index1]
                                For $ii = 0 To UBound($aTmp1) - 1
                                        $hItem = _GUICtrlTreeView_AddChild($iTreeView, $iT, $aTmp1[$ii])
                                Next
                        EndIf
                EndIf
        EndIf
EndFunc   ;==>_TreeLoadAdd

Func _GetHitTestItem()
        Local $aW = _ControlGetPos($hGui, '', $iTreeView)
        Local $iX = MouseGetPos(0) - $aW
        Local $iY = MouseGetPos(1) - $aW
        Local $iT = _GUICtrlTreeView_HitTestItem($iTreeView, $iX, $iY)
        Return $iT
EndFunc   ;==>_GetHitTestItem

Func _ControlGetPos($hWnd, $text, $Ctrlid)
        Local $ControlPos = ControlGetPos($hWnd, $text, $Ctrlid)
        If @error Then Return SetError(1)
        If Not IsHWnd($hWnd) Then $hWnd = WinGetHandle($hWnd, $text)
        Local $tPoint = DllStructCreate('int X;int Y')
        DllStructSetData($tPoint, 'X', $ControlPos)
        DllStructSetData($tPoint, 'Y', $ControlPos)
        DllCall('user32.dll', 'bool', 'ClientToScreen', 'hwnd', $hWnd, 'ptr', DllStructGetPtr($tPoint))
        If @error Then Return SetError(2)
        Local $xy = , $ControlPos, $ControlPos, $ControlPos]
        Return $xy
EndFunc   ;==>_ControlGetPos

Func _2DArrayCreat($Str)
        Local $aSR1 = StringRegExp($Str, '(?m)^([^\x00-\xff]+\V+)([\S\s]*?)(?=\r\n[^\x00-\xff]|\Z)', 3) ;---- 一、大标题
        If @error Then Return SetError(1)
        Local $a2D1, $x = 0, $i
        ;$a2D1 = 大标题; $a2D1 = 为数组则有下级

        For $i = 0 To UBound($aSR1) - 1 Step 2
                $a2D1[$x] = $aSR1[$i]
                $a2D1[$x] = $aSR1[$i + 1]
                Local $aSR2 = StringRegExp($a2D1[$x], '(?m)^(\d+、\V+)((?:\v+\d+\.\d+、\V+)*)', 3) ;---- 1、第x个小标题
                If Not @error Then
                        Local $a2D2, $xx = 0, $ii
                        For $ii = 0 To UBound($aSR2) - 1 Step 2
                                $a2D2[$xx] = $aSR2[$ii]
                                $a2D2[$xx] = $aSR2[$ii + 1]
                                $a2D2[$xx] = StringRegExp($a2D2[$xx], '(?m)^\d+\.\d+、\V+', 3) ;---- 1.1、test第x个小标题
                                $xx += 1
                        Next
                        $a2D1[$x] = $a2D2 ;---- 赋值为数组
                EndIf
                $x += 1
        Next
        Return $a2D1
EndFunc   ;==>_2DArrayCreat

haijie1223 发表于 2015-7-15 18:42:22

回复 8# afan


    经过Afan的提示,已经想到是这种方法,忙了一下午还没来得及自己写一下试试,Afan已经给出了这么高精尖的代码,感觉有点太高大上!{:face (396):}

afan 发表于 2015-7-15 19:25:38

回复 9# haijie1223


    好吧 代码好像是有点长 但都是简单的堆积… _ _||

chzj589 发表于 2015-7-16 14:42:34

谢谢分享!学习学习了

ak47gglllk 发表于 2015-7-17 09:08:37

{:face (332):}{:face (332):}学习,学习,感谢,感谢

Huiseyu 发表于 2015-7-17 21:58:18

谢谢前辈共享~

卓越科技 发表于 2015-7-19 17:29:35

谢谢分享 学习了 前辈辛苦了
页: [1]
查看完整版本: 如何读取固定格式的txt并有效率的写到Treeview[已解决]