Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Аватара для Creat0R

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

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community

Это сообщение посчитали полезным следующие участники:

Отправлено: 22:17, 06-06-2007 | #484