【已解决】请帮忙修改小程序,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建立的列表框建立错误,每个根目录只有一个子目录,而且子目录与根目录完全一致。
当搜索文件名有中文的时候,列表框中显示的文件名不会显示中文。
我自己的水平真解决不了,以上的代码也是在高人的指导下才完成的,所以想在这里发问,但有没有人可以帮我解决,再次谢谢了。 回复 1# Darren_Lin
测试发现:
关于 TreeView 的列表, 建立无错误.
搜索文件不显示中文名,是正则错误, 把59行的最后的正则表达式的2个 \b 去掉即可. 回复 2# user3000
晚上好,把59行的“/b”删除后,可以正确显示中文了,但又发现了一个问题,如是在根目录中搜索文件,在ListView的目录列中不会显示完整的盘符,如“F:\”,只会显示“F”
请问这个怎样解决啊? 本帖最后由 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: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 文件夹,再输入搜索内容后,就可以正常搜索。 回复 5# Darren_Lin
你没测试4楼的代码吗?
它就是搜索后,把相关结果列出来.
要用它 取代了原来 59 至 62 行的代码, 这样哪里还有 For $FILE In $Match ?? 楼主请指导一下?谢谢了
回复 7# zhaoyun
少了一个 ', ^([^\|]+)\|([^\|]+)\|',
ShellExecute(StringRegExpReplace(GUICtrlRead(GUICtrlRead($g_ListView_ID)), '^([^\|]+)\|([^\|]+)\|', '$2\\$1')) 回复 8# chzj589
谢谢指导。。 回复 6# user3000
原来是取代原来59至62行的代码,我以为直接加入进去,不好意思。真谢谢你! 回复 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: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 不为空再搜索就可以了. 好吧,楼主我又看见你了,半成品的代码写给你了,我没发现你改进一点代码 回复 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) 回复 14# chzj589
这是搜索次序问题.
用 _FileListToArray() 搜索目录下的文件夹. 查看下,顺序不对的,排序后再建立TreeView Item
页:
[1]
2