Must AutoIt
Сообщения: 3054
Благодарности: 1009
|
Профиль
|
Сайт
|
Отправить PM
| Цитировать
Diamond
Цитата:
Этот функция была взята с официального форума или... точно не помню
|
Да да, иименно от туда, я и сам ей пользуюсь с удовольствием  , взял тоже именно с оф. форума (её наисал кажется gafrost).
У меня почему то при вызове $dict.Exists скрипт выпадает с ошибкой:
Цитата:
The requested action with this object has failed.
|
Вобщем я немного изменил скрипт, надеюсь что в лучшую сторону, изменения таковы:
-Функцию _FileOpenDialog() добавил самдельную (от amel27) - позволяет открыть диалог для выбора файла как дочерний диалог ГУИ.
-Добавил функцию для поиска в самом ListView, имхо, так надёжнее, и не так уж намного медленнее
-Во всех функциях где добавляются новые айтемы (файлы), вызывается AutoSize на каждый добавляемый файл, хотя логичнее бдет вызвать один раз эту функцию по оканчанию добавления всех файлов.
-Теперь при добавлении файлов используя перетаскивание, существующие в списке файлы будут подсвечиваться (выделяться) - так думаю более удобно  .
-Функцию GetFileName() немного укоротил
-Добавил отображение иконок для добавляемых файлов, иконки определяются используя функцию _FileGetIcon() (тоже где то на оф. форуме нашел, правда немного изменил).
-Чтобы можно было присваивать иконки айтемам, пришлось вместо вставки айтемов, создавать их встроенными средствами, т.к требуется ControlID.
Вот что получилось:
Код: 
#include <GUIConstants.au3>
#include <GuiListView.au3>
Opt("GUIOnEventMode",1)
Opt("TrayIconHide",1)
Global Const $WM_DROPFILES = 0x233
Global $StringCount=0
Global $Dict=ObjCreate("Scripting.Dictionary") ; <- Словарь
$hGUI=GUICreate("Конвертор ;)",600,500,-1,-1,-1,$WS_EX_ACCEPTFILES)
GUISetOnEvent($GUI_EVENT_CLOSE,"Quit")
$listview=GUICtrlCreateListView ("Файл|Путь",5,5,590,450,BitOR($LVS_NOSORTHEADER,$LVS_SHOWSELALWAYS))
$ButtonDelete=GUICtrlCreateButton("Удалить",250,465,80,24)
GUICtrlSetOnEvent(-1,"StrDelete")
$ButtonAdd=GUICtrlCreateButton("Добавить",120,465,80,24)
GUICtrlSetOnEvent(-1,"AddOpenFiles")
GUISetState(@SW_SHOWNORMAL)
;~ Регистрируем событие Drag&Drop
GUIRegisterMsg ($WM_DROPFILES, "DropFiles")
While 1
Sleep(1000)
WEnd
;~ Выход из приложения
Func Quit()
Exit(0)
EndFunc
;~ Этот функция была взята с официального форума или... точно не помню ;)
;~ Создаёт массив $gaDropFiles, из файлов полученный при перетаскивании
;~ Вызывается событием, прописанным в GUIRegisterMsg()
Func DropFiles($hWnd, $msgID, $wParam, $lParam)
Local $nSize, $pFileName, $gaDropFiles[1]
Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255)
For $i = 0 To $nAmt[0] - 1
$nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0)
$nSize = $nSize[0] + 1
$pFileName = DllStructCreate("char[" & $nSize & "]")
DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", DllStructGetPtr($pFileName), "int", $nSize)
ReDim $gaDropFiles[$i+1]
$gaDropFiles[$i] = DllStructGetData($pFileName, 1)
$pFileName = 0
Next
Call ("AddDropedFiles", $gaDropFiles)
EndFunc
;~ Добавляет в ListViev файлы, полученные с помощью перетаскивания (Drag&Drop)
;~ Является продолжением функции DropFiles()
Func AddDropedFiles($gaDropFiles)
Local $SelCount = 1, $LVIID, $IconFile, $IconID
For $o In $gaDropFiles
$FindPathInLV = _FindInListView($listview, 1, $o)
If $FindPathInLV = -1 Then
$LVIID = GUICtrlCreateListViewItem(GetFileName($o) & '|' & $o, $listview)
_FileGetIcon($IconFile, $IconID, $o)
GUICtrlSetImage($LVIID, $IconFile, $IconID)
Else
If $SelCount = 1 Then ControlListView($hGUI, "", $listview, "SelectClear")
_GUICtrlListViewSetItemSelState($listview, $FindPathInLV)
$SelCount = -1
EndIf
Next
If $SelCount = -1 Then ControlFocus($hGUI, "", $listview)
Call ("AutoSize")
EndFunc
;~ Добавляет файлы в ListViev с помощью FileOpenDialog()
;~ Вызывается кнопкой
Func AddOpenFiles()
$FilePath = _FileOpenDialog("Открыть","","Wave файлы (*.wav) | Все файлы (*.*)",4+1, "", "", $hGUI)
If Not @error Then
$FilePath = StringStripCR($FilePath)
Local $array = StringSplit($FilePath, "|")
Local $LVIID, $IconFile, $IconID
If $array[0]>1 Then
$path=$array[1]
For $i=2 To $array[0]
$FullPath=$path & "\" & $array[$i]
If _FindInListView($ListView, 1, $FullPath) = -1 Then
$LVIID = GUICtrlCreateListViewItem($array[$i] & '|' & $FullPath, $listview)
_FileGetIcon($IconFile, $IconID, $FullPath)
GUICtrlSetImage($LVIID, $IconFile, $IconID)
EndIf
Next
ElseIf $array[0]=1 Then
If _FindInListView($ListView, 1, $array[1]) = -1 Then
$LVIID = GUICtrlCreateListViewItem(GetFileName($array[1]) & '|' & $array[1], $listview)
_FileGetIcon($IconFile, $IconID, $array[1])
GUICtrlSetImage($LVIID, $IconFile, $IconID)
EndIf
EndIf
Call ("AutoSize")
EndIf
EndFunc
;~ Удаляет выбранные элементы в ListViev
;~ Вызывается кнопкой
Func StrDelete()
_GUICtrlListViewDeleteItemsSelected($listview)
If _GUICtrlListViewGetItemCount($listview) Then AutoSize()
EndFunc
;~ ========================
;~ Вспомогательные функции:
;~ ========================
; Возвращает имя файла или папки из пути
;~ Вызывается некоторыми функциями
Func GetFileName($FilePath)
Return StringRegExpReplace($FilePath, "^.*\\", "")
EndFunc
;~ Изменяет размеры колонок в ListViev
;~ Вызывается некоторыми функциями
Func AutoSize()
_GUICtrlListViewSetColumnWidth($listview,1,$LVSCW_AUTOSIZE)
_GUICtrlListViewSetColumnWidth($listview,0,$LVSCW_AUTOSIZE)
EndFunc
;~ Добавляет в словарь все элементы второй колонки ListViev (Пути к файлам)
;~ З.Ы. Поиск дубликатов по словарю, значительно быстрее чем перебор-сравнение в массиве!
Func DictionaryAdd()
$StringCount=_GUICtrlListViewGetItemCount($listview)
For $i=0 To $StringCount
$Item = _GUICtrlListViewGetItemTextArray ($listview, $i)
If IsArray($Item) Then
$Dict.Add($Item[2],"")
EndIf
Next
EndFunc
;~ Функция производит поиск в списке List View, в случае удачи, возвращает индекс найденного айтема в списке,
;в противном случае возвращает -1
Func _FindInListView($ListViewID, $SubItem, $WhatToFind, $SubItem2=-1, $WhatToFind2="")
Local $TotalItemsArr = _GUICtrlListViewGetItemCount($ListViewID)
Local $CurrentText, $CurrentText2
If $TotalItemsArr > 0 Then
For $i = 0 To $TotalItemsArr - 1
$CurrentText = _GUICtrlListViewGetItemText($ListViewID, $i, $SubItem)
If $SubItem2 <> -1 Then
$CurrentText2 = _GUICtrlListViewGetItemText($ListViewID, $i, $SubItem2)
If $CurrentText = $WhatToFind And $CurrentText2 = $WhatToFind2 Then Return $i
Else
If $CurrentText = $WhatToFind Then Return $i
EndIf
Next
EndIf
Return -1
EndFunc
;~ Самодельная функци FileOpenDialog() - позволяет открыть диалог для выбора файла как дочерний диалог ГУИ.
Func _FileOpenDialog($sTitle, $sInitDir, $sFilter = 'All (*.*)', $iOpt = 0, $sDefaultFile = "", $sDefaultExt = "", $mainGUI = 0)
Local $iFileLen = 65536 ; Max chars in returned string
; API flags prepare
Local $iFlag = BitOR ( _
BitShift (BitAND ($iOpt, 1),-12), BitShift (BitAND ($iOpt, 2),-10), BitShift (BitAND ($iOpt, 4),-7 ), _
BitShift (BitAND ($iOpt, 8),-10), BitShift (BitAND ($iOpt, 4),-17) )
; Filter string to array convertion
Local $asFLines = StringSplit ( $sFilter, '|'), $asFilter [$asFLines [0] *2+1]
Local $i, $iStart, $iFinal, $suFilter = ''
$asFilter [0] = $asFLines [0] *2
For $i=1 To $asFLines [0]
$iStart = StringInStr ($asFLines [$i], '(', 0, 1)
$iFinal = StringInStr ($asFLines [$i], ')', 0,-1)
$asFilter [$i*2-1] = StringStripWS (StringLeft ($asFLines [$i], $iStart-1), 3)
$asFilter [$i*2] = StringStripWS (StringTrimRight (StringTrimLeft ($asFLines [$i], $iStart), StringLen ($asFLines [$i]) -$iFinal+1), 3)
$suFilter = $suFilter & 'byte[' & StringLen ($asFilter [$i*2-1])+1 & '];byte[' & StringLen ($asFilter [$i*2])+1 & '];'
Next
; Create API structures
Local $uOFN = DllStructCreate ('dword;int;int;ptr;ptr;dword;dword;ptr;dword' & _
';ptr;int;ptr;ptr;dword;short;short;ptr;ptr;ptr;ptr;ptr;dword;dword' )
Local $usTitle = DllStructCreate ('byte[' & StringLen ($sTitle) +1 & ']')
Local $usInitDir= DllStructCreate ('byte[' & StringLen ($sInitDir) +1 & ']')
Local $usFilter = DllStructCreate ($suFilter & 'byte')
Local $usFile = DllStructCreate ('byte[' & $iFileLen & ']')
Local $usExtn = DllStructCreate ('byte[' & StringLen ($sDefaultExt) +1 & ']')
For $i=1 To $asFilter [0]
DllStructSetData ($usFilter, $i, $asFilter [$i])
Next
; Set Data of API structures
DllStructSetData ($usTitle, 1, $sTitle)
DllStructSetData ($usInitDir, 1, $sInitDir)
DllStructSetData ($usFile, 1, $sDefaultFile)
DllStructSetData ($usExtn, 1, $sDefaultExt)
DllStructSetData ($uOFN, 1, DllStructGetSize($uOFN))
DllStructSetData ($uOFN, 2, $mainGUI)
DllStructSetData ($uOFN, 4, DllStructGetPtr ($usFilter))
DllStructSetData ($uOFN, 7, 1)
DllStructSetData ($uOFN, 8, DllStructGetPtr ($usFile))
DllStructSetData ($uOFN, 9, $iFileLen)
DllStructSetData ($uOFN, 12, DllStructGetPtr ($usInitDir))
DllStructSetData ($uOFN, 13, DllStructGetPtr ($usTitle))
DllStructSetData ($uOFN, 14, $iFlag)
DllStructSetData ($uOFN, 17, DllStructGetPtr ($usExtn))
DllStructSetData ($uOFN, 23, BitShift (BitAND ($iOpt, 32), 5))
; Call API function
$ret = DllCall ('comdlg32.dll', 'int', 'GetOpenFileName', _
'ptr', DllStructGetPtr ($uOFN) )
If $ret [0] Then
If BitAND ($iOpt, 4) Then
$i = 1
While 1
If DllStructGetData ($usFile, 1, $i) =0 Then
If DllStructGetData ($usFile, 1, $i+1) Then
DllStructSetData ($usFile, 1, 124, $i)
Else
ExitLoop
EndIf
EndIf
$i += 1
Wend
EndIf
Return DllStructGetData ($usFile, 1)
Else
SetError (1)
Return ""
EndIf
EndFunc
;~ Функция задаёт значения для переменных $szIconFile и $nIcon путь к файлу и идентификатор иконки в файле
; (для определения иконки по заданному пути к файлу).
Func _FileGetIcon(ByRef $szIconFile, ByRef $nIcon, $szFile)
Local $OldEES = Opt("ExpandEnvStrings", 1)
Local $szRegDefault = "", $szDefIcon = "", $szExt
$nIcon = 0
If _IsDir($szFile) Then
$szRegDefault = RegRead("HKCR\Folder", "")
If $szRegDefault <> "" Then $szDefIcon = RegRead("HKCR\Folder\DefaultIcon", "")
Else
$szExt = StringRegExpReplace($szFile, '^.*\.', '.')
If $szExt = $szFile Then
$szExt = FileFindFirstFile($szFile & ".*")
$szExt = StringRegExpReplace(FileFindNextFile($szExt), '^.*\.', '.')
$szFile = $szFile & $szExt
EndIf
$szRegDefault = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $szExt, "ProgID")
If $szRegDefault = "" Then $szRegDefault = RegRead("HKCR\" & $szExt, "")
If $szRegDefault <> "" Then $szDefIcon = RegRead("HKCR\" & $szRegDefault & "\DefaultIcon", "")
EndIf
If $szDefIcon = "" Then
$szIconFile = "shell32.dll"
ElseIf $szDefIcon <> "%1" Then
If StringRegExpReplace($szFile, "^.*\\", "") = "shell32.dll" Then
$szIconFile = $szFile
$nIcon = 0
Else
$arSplit = StringSplit($szDefIcon, ",")
If IsArray($arSplit) Then
$szIconFile = $arSplit[1]
If $arSplit[0] > 1 Then $nIcon = $arSplit[2]
Else
Opt("ExpandEnvStrings", $OldEES)
Return 0
EndIf
EndIf
ElseIf $szDefIcon = "%1" Then
$szIconFile = $szFile
$nIcon = 0
EndIf
Opt("ExpandEnvStrings", $OldEES)
Return 1
EndFunc
;~ Функция предназначена для проверки, является ли заданый путь каталогом.
Func _IsDir($Path)
Return StringInStr(FileGetAttrib($Path), "D")
EndFunc
;~ ---------------------------------------------
;~ Позволят получить файловое расширение из пути или имени файла.
;~ Это единственная функция которая нигде не используется!
Func FileGetExtension($name)
Local $Count=StringInStr($name,".",0,-1)
If $Count=0 Then
Return 0
Else
Return StringTrimLeft($name,$Count)
EndIf
EndFunc
|