Darren_Lin 发表于 2013-9-18 21:02:11

【已解决】请帮忙修改小程序,TreeView功能和搜索功能

本帖最后由 Darren_Lin 于 2013-9-26 21:22 编辑

大家好,本人水平太低,但为了方便工作想做一个小程序,做了很多遍,但还没有做好,故想请人帮我完成这个小程序,先谢谢大家。
程序界面如下:

代码如下:
#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

Global $g_Form1 = GUICreate("Form1", 615, 477, -1, -1)

$g_Label1 = GUICtrlCreateLabel("地址:", 16, 16, 40, 17)
$g_Label2 = GUICtrlCreateLabel("文件名:", 16, 48, 52, 17)

Global $g_Input_Path = GUICtrlCreateInput("", 64, 16, 297, 21)
Global $g_Button_Path = GUICtrlCreateButton("...", 376, 16, 49, 25)

Global $g_Input_Search = GUICtrlCreateInput("", 64, 48, 297, 21)
Global $g_Button_Search = GUICtrlCreateButton("搜索", 376, 48, 49, 25)

Global $g_TreeView_ID = GUICtrlCreateTreeView(16, 80, 201, 321, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT), $WS_EX_CLIENTEDGE)
Global $g_TreeView_hWnd = GUICtrlGetHandle($g_TreeView_ID)

Global $g_ListView_ID = GUICtrlCreateListView("文件|目录", 240, 80, 337, 329, -1, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_GRIDLINES))
Global $g_ListView_hWnd = GUICtrlGetHandle($g_ListView_ID)
_GUICtrlListView_SetColumnWidth($g_ListView_ID, 0, $LVSCW_AUTOSIZE_USEHEADER)

Global $g_Button_Open = GUICtrlCreateButton("打开", 16, 432, 81, 33)

Global $g_Button_Exit = GUICtrlCreateButton("退出", 112, 432, 81, 33)

Global $g_Button5 = GUICtrlCreateButton("关于", 496, 432, 81, 33)

Global $Path

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetState()

While 1
      Local $msg = GUIGetMsg()
      Switch $msg
                Case $g_Button_Exit, -3
                        Exit
                Case $g_Button_Path
                        Local $hPath = FileSelectFolder("选择文件夹.", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 7)
                        If @error Then ContinueLoop
                        $Path = $hPath & "\"
                        _GUICtrlTreeView_DeleteAll($g_TreeView_hWnd)
                        _GUICtrlTreeView_BeginUpdate($g_TreeView_hWnd)
                        _AddPath($Path, $g_TreeView_ID)
                        _GUICtrlTreeView_EndUpdate($g_TreeView_hWnd)
                        GUICtrlSetData($g_Input_Path, $Path)
                        _AddFile($Path)
                Case $g_Button_Search
                        Local $SearchFile = GUICtrlRead($g_Input_Search)
                        If @error Or $SearchFile = "" Then ContinueLoop
                        Local $PID = Run('"' & @ComSpec & '" /c dir /s /a:-d /b "' & $Path & '\*' & $SearchFile & '*"', '', @SW_HIDE, 6), $STDOUT
                        ProcessWaitClose($PID)
                        $STDOUT = StdoutRead($PID)
                        _GUICtrlListView_BeginUpdate($g_ListView_hWnd)
                        _GUICtrlListView_DeleteAllItems($g_ListView_hWnd)
                        Local $Match = StringRegExp(StringRegExpReplace($STDOUT, '(.+)\\([^\r]+)', '$2\|$1'), "\b[^\r\n]+\b", 3)
                        For $FILE In $Match
                              GUICtrlCreateListViewItem($FILE, $g_ListView_ID)
                        Next
                        _GUICtrlListView_SetColumnWidth($g_ListView_hWnd, 0, $LVSCW_AUTOSIZE)
                        _GUICtrlListView_EndUpdate($g_ListView_hWnd)
                Case $g_Button_Open
                        ShellExecute(StringRegExpReplace(GUICtrlRead(GUICtrlRead($g_ListView_ID)), '^([^\|]+)\|([^\|]+)\|, '$2\\$1'))
                                                
      EndSwitch
      Sleep(10)
WEnd

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
      Local $tNMHDR, $hwndFrom, $code
      $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
      $code = DllStructGetData($tNMHDR, "Code")
      Switch $code
                Case $NM_DBLCLK
                        If DllStructGetData($tNMHDR, "hWndFrom") == $g_ListView_hWnd Then ShellExecute(StringRegExpReplace(GUICtrlRead(GUICtrlRead($g_ListView_ID)), '^([^\|]+)\|([^\|]+)\|, '$2\\$1'))
                Case $TVN_SELCHANGINGW
                        $pTV = DllStructCreate($tagNMTREEVIEW, $lParam);_DebugPrint("$TVN_SELCHANGING")
                        Local $hItem = DllStructGetData($pTV, 'NewhItem')
                        If Not $hItem Then Return 0
                        Local $hParent = _GUICtrlTreeView_GetParentHandle($g_TreeView_hWnd, $hItem)
                        Local $hPath = _GUICtrlTreeView_GetText($g_TreeView_hWnd, $hItem)
                        While $hParent
                              $hPath = _GUICtrlTreeView_GetText($g_TreeView_hWnd, $hParent) & "\" & $hPath
                              $hParent = _GUICtrlTreeView_GetParentHandle($g_TreeView_hWnd, $hParent)
                        WEnd
                        _AddFile($Path & $hPath)
      EndSwitch
      Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _AddFile($Dir)
      Local $hSearch = FileFindFirstFile($Dir & "\*")
      If @error Then Return 0
      _GUICtrlListView_DeleteAllItems($g_ListView_hWnd)
      _GUICtrlListView_BeginUpdate($g_ListView_hWnd)
      While 1
                Local $sFile = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If Not @extended Then
                        GUICtrlCreateListViewItem($sFile & "|" & $Dir, $g_ListView_ID)
                EndIf
      WEnd
      _GUICtrlListView_EndUpdate($g_ListView_hWnd)
      _GUICtrlListView_SetColumnWidth($g_ListView_hWnd, 0, $LVSCW_AUTOSIZE)
      _GUICtrlListView_SetColumnWidth($g_ListView_hWnd, 1, $LVSCW_AUTOSIZE)
      _GUICtrlListView_SetColumnWidth($g_ListView_hWnd, 1, $LVSCW_AUTOSIZE_USEHEADER)
      FileClose($hSearch)
EndFunc   ;==>_AddFile

Func _AddPath($Dir, $ParentID)
      Local $hSearch = FileFindFirstFile($Dir & "\*")
      If $hSearch = -1 Then Return 0
      While 1
                Local $sFile = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If @extended Then
                        Local $hItem = GUICtrlCreateTreeViewItem($sFile, $ParentID)
                        _AddPath($Dir & "\" & $sFile, $hItem)
                        ContinueLoop
                EndIf
      WEnd
      FileClose($hSearch)
EndFunc   ;==>_AddPath运行后,TreeView建立的列表框建立错误,每个根目录只有一个子目录,而且子目录与根目录完全一致。
当搜索文件名有中文的时候,列表框中显示的文件名不会显示中文。
我自己的水平真解决不了,以上的代码也是在高人的指导下才完成的,所以想在这里发问,但有没有人可以帮我解决,再次谢谢了。

user3000 发表于 2013-9-18 23:00:09

回复 1# Darren_Lin

测试发现:
关于 TreeView 的列表, 建立无错误.
搜索文件不显示中文名,是正则错误, 把59行的最后的正则表达式的2个 \b 去掉即可.

Darren_Lin 发表于 2013-9-19 00:01:40

回复 2# user3000
晚上好,把59行的“/b”删除后,可以正确显示中文了,但又发现了一个问题,如是在根目录中搜索文件,在ListView的目录列中不会显示完整的盘符,如“F:\”,只会显示“F”

请问这个怎样解决啊?

user3000 发表于 2013-9-19 01:08:48

本帖最后由 user3000 于 2013-9-19 01:11 编辑

回复 3# Darren_Lin
加个判断, 使用不同的正则表达式就可以了.Local $aMatch = StringRegExp($STDOUT, '(.+)\\([^\r]+)', 3)
If @error Then ContinueLoop
For $i = 0 To UBound($aMatch)-1 Step 2
Local $sText =''
If StringRegExp($aMatch[$i], '^$') Then
   $sText = $aMatch[$i+1] & '|' &        $aMatch[$i] & ':\'
Else                                                               
    $sText = $aMatch[$i+1] & '|' &        $aMatch[$i]
EndIf
GUICtrlCreateListViewItem($sText, $g_ListView_ID)
Next

Darren_Lin 发表于 2013-9-19 07:05:30

本帖最后由 Darren_Lin 于 2013-9-19 07:06 编辑

回复 4# user3000
你好,又出现一个问题了,就是当我打开的目录是C:\、D:\等盘,而不是分区里面的目录,输入搜索关键字,再点搜索会弹出以下错误:
"C:\Users\Administrator\Desktop\1.au3" (60) : ==> ???????????("Object").:
For $FILE In $Match
For $FILE In $Match^ ERROR
->07:03:37 AutoIT3.exe 完成::1
+>07:03:39 ACNWrapper 完成..
>退出代码: 1        运行时间: 57.395 秒

如果是选择分区内的目录,如D:\123   文件夹,再输入搜索内容后,就可以正常搜索。

user3000 发表于 2013-9-19 09:19:22

回复 5# Darren_Lin

你没测试4楼的代码吗?
它就是搜索后,把相关结果列出来.
要用它 取代了原来 59 至 62 行的代码, 这样哪里还有 For $FILE In $Match ??

zhaoyun 发表于 2013-9-19 10:05:04

楼主请指导一下?谢谢了

chzj589 发表于 2013-9-19 10:53:01

回复 7# zhaoyun
少了一个 ', ^([^\|]+)\|([^\|]+)\|',
ShellExecute(StringRegExpReplace(GUICtrlRead(GUICtrlRead($g_ListView_ID)), '^([^\|]+)\|([^\|]+)\|', '$2\\$1'))

zhaoyun 发表于 2013-9-19 13:06:21

回复 8# chzj589

谢谢指导。。

Darren_Lin 发表于 2013-9-20 18:03:09

回复 6# user3000
原来是取代原来59至62行的代码,我以为直接加入进去,不好意思。真谢谢你!

Darren_Lin 发表于 2013-9-20 18:59:26

回复 6# user3000
问题1:
取代59至62行的代码后,选择打开的目录是C:\、D:\等盘,运行搜索没有错误,但输入搜索关键字后,点搜索搜索的结果没有东西。
问题2:
当没有选择目录,输入搜索关键字,点搜索后,程序的所有按键都失效。

下面是按你说的方法修改后的代码,如果你有空,再劳烦你过目一下,谢谢:#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
;Opt("TrayMenuMode", 3)
Global $g_Form1 = GUICreate("Form1", 615, 477, -1, -1)
Global $g_Label1 = GUICtrlCreateLabel("地址:", 16, 16, 40, 17)
Global $g_Label2 = GUICtrlCreateLabel("文件名:", 16, 48, 52, 17)
Global $g_Input_Path = GUICtrlCreateInput("", 64, 16, 297, 21)
Global $g_Button_Path = GUICtrlCreateButton("...", 376, 16, 49, 25)
Global $g_Input_Search = GUICtrlCreateInput("", 64, 48, 297, 21)
Global $g_Button_Search = GUICtrlCreateButton("搜索", 376, 48, 49, 25)
Global $g_TreeView_ID = GUICtrlCreateTreeView(16, 80, 201, 321, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT), $WS_EX_CLIENTEDGE)
Global $g_TreeView_hWnd = GUICtrlGetHandle($g_TreeView_ID)
Global $g_ListView_ID = GUICtrlCreateListView("文件|目录", 240, 80, 337, 329, -1, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_GRIDLINES))
Global $g_ListView_hWnd = GUICtrlGetHandle($g_ListView_ID)
_GUICtrlListView_SetColumnWidth($g_ListView_ID, 0, $LVSCW_AUTOSIZE_USEHEADER)
Global $g_Button_Open = GUICtrlCreateButton("打开", 16, 432, 81, 33)
Global $g_Button_Exit = GUICtrlCreateButton("退出", 112, 432, 81, 33)
Global $g_Button5 = GUICtrlCreateButton("关于", 496, 432, 81, 33)
Global $Path
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState()

While 1
        Local $msg = GUIGetMsg()
        Switch $msg
                Case $g_Button_Exit, -3
                        Exit
                Case $g_Button_Path
                        Local $hPath = FileSelectFolder("选择文件夹.", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 7)
                        If @error Then ContinueLoop
                        ;$Path = $hPath & "\"
                        $Path = $hPath
                        _GUICtrlTreeView_DeleteAll($g_TreeView_hWnd)
                        _GUICtrlTreeView_BeginUpdate($g_TreeView_hWnd)
                        _AddPath($Path, $g_TreeView_ID)
                        _GUICtrlTreeView_EndUpdate($g_TreeView_hWnd)
                        GUICtrlSetData($g_Input_Path, $Path)
                        _AddFile($Path)
                Case $g_Button_Search
                        Local $SearchFile = GUICtrlRead($g_Input_Search)
                        If @error Or $SearchFile = "" Then ContinueLoop
                        Local $PID = Run('"' & @ComSpec & '" /c dir /s /a:-d /b "' & $Path & '\*' & $SearchFile & '*"', '', @SW_HIDE, 6), $STDOUT
                        ProcessWaitClose($PID)
                        $STDOUT = StdoutRead($PID)
                        _GUICtrlListView_BeginUpdate($g_ListView_hWnd)
                        _GUICtrlListView_DeleteAllItems($g_ListView_hWnd)
                        ;Local $Match = StringRegExp(StringRegExpReplace($STDOUT, '(.+)\\([^\r]+)', '$2\|$1'), "[^\r\n]+", 3)
                        ;For $FILE In $Match
                        ;        GUICtrlCreateListViewItem($FILE, $g_ListView_ID)
                        ;Next
                        Local $aMatch = StringRegExp($STDOUT, '(.+)\\([^\r]+)', 3)
                        If @error Then ContinueLoop
                        For $i = 0 To UBound($aMatch) - 1 Step 2
                                Local $sText = ''
                                If StringRegExp($aMatch[$i], '^) Then
                                        $sText = $aMatch[$i + 1] & '|' & $aMatch[$i] & ':\'
                                Else
                                        $sText = $aMatch[$i + 1] & '|' & $aMatch[$i]
                                EndIf
                                GUICtrlCreateListViewItem($sText, $g_ListView_ID)
                        Next

                        _GUICtrlListView_SetColumnWidth($g_ListView_hWnd, 0, $LVSCW_AUTOSIZE)
                        _GUICtrlListView_EndUpdate($g_ListView_hWnd)
                Case $g_Button_Open
                        ShellExecute(StringRegExpReplace(GUICtrlRead(GUICtrlRead($g_ListView_ID)), '^([^\|]+)\|([^\|]+)\|', '$2\\$1'))

        EndSwitch
        Sleep(10)
WEnd

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
        Local $tNMHDR, $hwndFrom, $code
        $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
        $code = DllStructGetData($tNMHDR, "Code")
        Switch $code
                Case $NM_DBLCLK
                        If DllStructGetData($tNMHDR, "hWndFrom") == $g_ListView_hWnd Then ShellExecute(StringRegExpReplace(GUICtrlRead(GUICtrlRead($g_ListView_ID)), '^([^\|]+)\|([^\|]+)\|', '$2\\$1'))
                Case $TVN_SELCHANGINGW
                        $pTV = DllStructCreate($tagNMTREEVIEW, $lParam);_DebugPrint("$TVN_SELCHANGING")
                        Local $hItem = DllStructGetData($pTV, 'NewhItem')
                        If Not $hItem Then Return 0
                        Local $hParent = _GUICtrlTreeView_GetParentHandle($g_TreeView_hWnd, $hItem)
                        Local $hPath = _GUICtrlTreeView_GetText($g_TreeView_hWnd, $hItem)
                        While $hParent
                                $hPath = _GUICtrlTreeView_GetText($g_TreeView_hWnd, $hParent) & "\" & $hPath
                                $hParent = _GUICtrlTreeView_GetParentHandle($g_TreeView_hWnd, $hParent)
                        WEnd
                        _AddFile($Path & $hPath)
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _AddFile($Dir)
        Local $hSearch = FileFindFirstFile($Dir & "\*")
        If @error Then Return 0
        _GUICtrlListView_DeleteAllItems($g_ListView_hWnd)
        _GUICtrlListView_BeginUpdate($g_ListView_hWnd)
        While 1
                Local $sFile = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If Not @extended Then
                        GUICtrlCreateListViewItem($sFile & "|" & $Dir, $g_ListView_ID)
                EndIf
        WEnd
        _GUICtrlListView_EndUpdate($g_ListView_hWnd)
        _GUICtrlListView_SetColumnWidth($g_ListView_hWnd, 0, $LVSCW_AUTOSIZE)
        _GUICtrlListView_SetColumnWidth($g_ListView_hWnd, 1, $LVSCW_AUTOSIZE)
        _GUICtrlListView_SetColumnWidth($g_ListView_hWnd, 1, $LVSCW_AUTOSIZE_USEHEADER)
        FileClose($hSearch)
EndFunc   ;==>_AddFile

Func _AddPath($Dir, $ParentID)
        Local $hSearch = FileFindFirstFile($Dir & "\*")
        If $hSearch = -1 Then Return 0
        While 1
                Local $sFile = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If @extended Then
                        Local $hItem = GUICtrlCreateTreeViewItem($sFile, $ParentID)
                        _AddPath($Dir & "\" & $sFile, $hItem)
                        ContinueLoop
                EndIf
        WEnd
        FileClose($hSearch)
EndFunc   ;==>_AddPath

user3000 发表于 2013-9-20 20:30:47

本帖最后由 user3000 于 2013-9-20 20:32 编辑

回复 11# Darren_Lin


    Case $g_Button_Search
                        If Not StringInStr($Path, '\') Then ContinueLoop
                        Local $SearchFile, $PID, $STDOUT, $aMatch
                         $SearchFile = GUICtrlRead($g_Input_Search)
                        If @error Or $SearchFile = "" Then ContinueLoop
                        $SearchFile = $Path & '\*' & $SearchFile & '*"'
                        $SearchFile = StringReplace($SearchFile, '\\', '\')
                        $PID = Run('"' & @ComSpec & '" /c dir /s /a:-d /b "' & $SearchFile, '', @SW_HIDE, 6)
                        ProcessWaitClose($PID)
                        $STDOUT = StdoutRead($PID)
                        _GUICtrlListView_BeginUpdate($g_ListView_hWnd)
                        _GUICtrlListView_DeleteAllItems($g_ListView_hWnd)
                        ConsoleWrite($Path & @TAB & $SearchFile & @CRLF & $STDOUT & @CRLF)
                        $aMatch = StringRegExp($STDOUT, '(.+\\)([^\r\n]+)', 3)
                        If @error Then ContinueLoop
                        For $i = 0 To UBound($aMatch) - 1 Step 2
                                GUICtrlCreateListViewItem($aMatch[$i + 1] & '|' & $aMatch[$i], $g_ListView_ID)
                        Next
                        _GUICtrlListView_SetColumnWidth($g_ListView_hWnd, 0, $LVSCW_AUTOSIZE)
                        _GUICtrlListView_EndUpdate($g_ListView_hWnd)
在适当位置加入 ConSoleWrite 或 MsgBox ...这样可以自己尝试调试脚本.
...
原来搜索分区根目录没有结果, 因为:
$Path= 'C:\' , 但在RUN里, 还 $Path & '\*' & $SearchFile 就导致搜索 c:\\*123* 之类,多了一个 \
第2个问题,先判断下 $Path 不为空再搜索就可以了.

Ycxw2008 发表于 2013-9-22 21:53:43

好吧,楼主我又看见你了,半成品的代码写给你了,我没发现你改进一点代码

chzj589 发表于 2013-9-25 19:29:03

回复 12# user3000
读取文件目录显示在TreeView,为何会这样?01月显示在最下面?



代码如下:
        Local $hPath = @ScriptDir & "\" & @YEAR & "年"
        If @error Then ContinueLoop
        $Path = $hPath & "\"
        _GUICtrlTreeView_DeleteAll($g_TreeView_hWnd)
        _GUICtrlTreeView_BeginUpdate($g_TreeView_hWnd)
        _AddPath($Path, $g_TreeView_ID)
        _GUICtrlTreeView_EndUpdate($g_TreeView_hWnd)
        _AddFile($Path)

user3000 发表于 2013-9-25 19:48:37

回复 14# chzj589
这是搜索次序问题.
用 _FileListToArray() 搜索目录下的文件夹. 查看下,顺序不对的,排序后再建立TreeView Item
页: [1] 2
查看完整版本: 【已解决】请帮忙修改小程序,TreeView功能和搜索功能