Must AutoIt
Сообщения: 3054
Благодарности: 1009
|
Профиль
|
Сайт
|
Отправить PM
| Цитировать
amel27
Вот более модифицированный пример архивирования файлов с выводом процесса в гуи (я там использовал новую твою функцию _FileSelectFolder(), а также заметь, я накалякал свою собственную функцию для InputBox() - она позволяет прикреплять InputBox к окну гуи, и также в ней есть всё тоже что и в обычной функции, и даже больше, мне впервые удалось реализовать ограничение на изменение размера гуи  - т.е установить минимально допустимы размер окна гуи ) :
Код: 
#include <GuiStatusBar.au3>
#include <GUIConstants.au3>
#include <Array.au3>
$ArchivatorPath = RegRead("HKEY_CURRENT_USER\Software\7-Zip", "Path") & "\7z.exe"
If Not FileExists($ArchivatorPath) Then
$RegReadRar = RegRead("HKEY_CLASSES_ROOT\.rar\ShellNew", "FileName")
$ArchivatorPath = StringReplace($RegReadRar, StringRegExpReplace($RegReadRar, "^.*\\", ""), "rar.exe;")
EndIf
If Not FileExists($ArchivatorPath) Then
MsgBox(16, "Error!", "Archiving Program was not found" & @CR & @CR & "OK --> EXIT")
Exit
EndIf
$ArchiveName = "Archive.zip"
$Gui = GUICreate("Add files to archive GUI", 500, 200)
$Progress = GUICtrlCreateProgress(40, 45, 430, 20)
$ProgressStatus = _GUICtrlStatusBarCreate($Gui, 0, "")
_GUICtrlStatusBarSetSimple($ProgressStatus)
$AddButton = GUICtrlCreateButton("Add file(s)/folder...", 200, 80, 110, 20)
$ContextMenu = GUICtrlCreateContextMenu()
$AddFiles = GUICtrlCreateMenuitem("Add files...", $ContextMenu)
$AddFolders = GUICtrlCreateMenuitem("Add folder...", $ContextMenu)
GUISetState()
While 1
$Msg = GUIGetMsg()
Switch $Msg
Case -3
Exit
Case $AddButton
ShowMenu($GUI, $AddButton, $ContextMenu)
Case $AddFiles
$OpenFiles = _FileOpenDialog("Choose file(s) to add to archive", "", "All Files (*.*)", 4, "", "", $GUI)
If Not @error Then
If StringInStr($OpenFiles, "|") Then
$OpenFiles = '"' & StringReplace(StringReplace($OpenFiles, @WorkingDir & "|", ""), '|', '" "') & '"'
Else
$OpenFiles = '"' & StringStripCR($OpenFiles) & '"'
EndIf
$ArchiveNameInput = _InputBox("Archive Name", "Type archive name that files will be added into it:", $ArchiveName, 0, 0, 280, 150, -1, -1, 0, 0, 0, $GUI)
If $ArchiveNameInput <> "" Then
$ArchiveNameInput = StringRegExpReplace($ArchiveNameInput, '["?:|/\\*<>]', '_')
$Pid = Run($ArchivatorPath & ' a "' & @WorkingDir & "\" & $ArchiveNameInput & '" ' & $OpenFiles, "", @SW_HIDE, 2)
GUICtrlSetData($AddButton, "Abort")
AddFiles($Pid)
EndIf
EndIf
Case $AddFolders
$OpenFolder = _FileSelectFolder("Choose directory for add it to archive...", 0, 0, $GUI)
If $OpenFolder <> "" Then
$ArchiveNameInput = _InputBox("Archive Name", "Type archive name that files will be added into it:", $ArchiveName, 0, 0, 280, 150, -1, -1, 0, 0, 0, $GUI)
If $ArchiveNameInput <> "" Then
$ArchiveNameInput = StringRegExpReplace($ArchiveNameInput, '["?:|/\\*<>]', '_')
$Pid = Run($ArchivatorPath & ' a "' & StringTrimRight($OpenFolder, StringLen(StringRegExpReplace($OpenFolder, "^.*\\", ""))) & $ArchiveNameInput & '" "' & $OpenFolder & '"', "", @SW_HIDE, 2)
GUICtrlSetData($AddButton, "Abort")
AddFiles($Pid)
EndIf
EndIf
EndSwitch
WEnd
Func AddFiles($Pid)
While ProcessExists($Pid)
$Msg = GUIGetMsg()
$ReadLine = StdoutRead($Pid, 0, True)
_GUICtrlStatusBarSetText($ProgressStatus, "Add files process... " & $ReadLine, 255)
GUICtrlSetData($Progress, _StringStripWords($ReadLine))
$LastRead = $ReadLine
If $Msg = $AddButton Then ExitLoop
WEnd
If $Msg = $AddButton Then
ProcessClose($Pid)
GUICtrlSetData($Progress, 0)
EndIf
GUICtrlSetData($AddButton, "Add file(s)/folder...")
$DoneMsg = "Done!"
If StringInStr($LastRead, "Warning") Or StringInStr($LastRead, "Error") Then
If StringInStr($LastRead, "Warning") Then $ErrPos = StringInStr($LastRead, "Warning")
If StringInStr($LastRead, "Error") Then $ErrPos = StringInStr($LastRead, "Error")
$DoneMsg = "Done! (" & StringTrimLeft($LastRead, $ErrPos-2) & ")"
EndIf
_GUICtrlStatusBarSetText($ProgressStatus, $DoneMsg, 255)
EndFunc
Func _StringStripWords($String, $RetType=0)
$String = StringRegExpReplace($String,'[^0-9]','') ; Удаляем все не-цифры
If $RetType = 1 Then Return StringSplit($String, "")
Return $String
EndFunc
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
Func _FileSelectFolder ($title, $root = 0, $flags = 0, $hwnd = 0)
Local $ret, $pidl, $res = ''
; Создание структур данных
Local $ubi = DllStructCreate ("hwnd;ptr;ptr;ptr;int;ptr;ptr;int") ; управляющая структура BROWSEINFO
Local $utl = DllStructCreate ("char[512],char") ; заголовок окна
Local $urs = DllStructCreate ("char[260]") ; буфер для возвращаемого пути (длиной MAX_PATH)
Local $ulf = BitOR (BitShift(BitAnd ($flags,1),-9), _ ; 1: не позволять создавать новые каталоги
BitShift(BitAnd ($flags,2),-5), _ ; 2: использовать новый стиль диалога
BitShift(BitAnd ($flags,4),-2)) ; 4: включить cтроку редактирования
; Заполнение структур данных
DllStructSetData ($utl, 1, $title)
DllStructSetData ($ubi, 1, $hwnd)
DllStructSetData ($ubi, 3, DllStructGetPtr($urs))
DllStructSetData ($ubi, 4, DllStructGetPtr($utl))
DllStructSetData ($ubi, 5, $ulf)
$ret = DllCall ("shell32.dll", "ptr", "SHGetSpecialFolderLocation", _
"int", 0 , _
"int", $root , _
"ptr", DllStructGetPtr($ubi, 2))
If $ret[0] Then Return $res
; Открытие окна выбора каталога
$pidl = DllCall ("shell32.dll", "ptr", "SHBrowseForFolder", "ptr", DllStructGetPtr ($ubi))
If $pidl[0] Then
$ret = DllCall ("shell32.dll", "int", "SHGetPathFromIDList", _
"ptr", $pidl[0], _
"ptr", DllStructGetPtr ($urs))
If $ret[0] Then $res = DllStructGetData ($urs, 1)
DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", $pidl[0]) ; чистим за собой
EndIf
DllCall ("ole32.dll", "int", "CoTaskMemFree", "ptr", DllStructGetData ($ubi, 2))
Return $res ; Вывод результата
EndFunc
Func _InputBox($Title,$Promt,$Default="",$IsPassword=0,$IsDigits=0,$Width=-1,$Height=-1,$Left=-1,$Top=-1,$Style=0,$exStyle=0,$Timeout=0,$Parent=0)
GUISetState(@SW_DISABLE, $Parent)
If $Width < 200 Then $Width = 200
If $Height < 150 Then $Height = 150
Local $InputGui, $OKButton, $CancelButton, $InputBoxID, $Msg, $GuiCoords, $RetValue, $InputMsg, $TimerStart
$InputGui = GUICreate($Title, $Width, $Height, $Left, $Top, 0x00040000+$Style, $exStyle, $Parent)
GUICtrlCreateLabel($Promt, 20, 5, $Width-40, 35)
GUICtrlSetResizing(-1, 32)
$OKButton = GUICtrlCreateButton("OK", ($Width/2)-70, $Height-95, 60, 25)
GUICtrlSetResizing(-1, 0x0240)
$CancelButton = GUICtrlCreateButton("Cancel", ($Width/2)+10, $Height-95, 60, 25)
GUICtrlSetResizing(-1, 0x0240)
If $IsPassword <> 0 Then $IsPassword = 32
If $IsDigits <> 0 Then $IsDigits = 8192
$InputBoxID = GUICtrlCreateInput($Default, 20, $Height-60, $Width-40, 20, $IsPassword+$IsDigits, 0x00000001)
GUICtrlSetResizing(-1, 0x0240)
GUICtrlSetState(-1, 256)
GUISetState(@SW_SHOW, $InputGui)
If $Timeout > 0 Then $TimerStart = TimerInit()
While 1
$InputMsg = GUIGetMsg()
Switch $InputMsg
Case -3, $CancelButton
GUISetState(@SW_ENABLE, $Parent)
GUISetState(@SW_RESTORE, $Parent)
GUIDelete($InputGui)
SetError(1)
Return ""
Case -12
$GuiCoords = WinGetPos($Title)
If $GuiCoords <> 0 Then
$Width = $GuiCoords[2]
$Height = $GuiCoords[3]
If $Width < 200 And $Height >= 150 Then
WinMove($Title, "", $GuiCoords[0], $GuiCoords[1], 200, $Height)
ElseIf $Width < 200 And $Height < 150 Then
WinMove($Title, "", $GuiCoords[0], $GuiCoords[1], 200, 150)
EndIf
If $Height < 150 And $Width >= 200 Then
WinMove($Title, "", $GuiCoords[0], $GuiCoords[1], $Width, 150)
ElseIf $Height < 150 And $Width < 200 Then
WinMove($Title, "", $GuiCoords[0], $GuiCoords[1], 200, 150)
EndIf
EndIf
Case $OKButton
$RetValue = GUICtrlRead($InputBoxID)
GUISetState(@SW_ENABLE, $Parent)
GUISetState(@SW_RESTORE, $Parent)
GUIDelete($InputGui)
SetError(0)
Return $RetValue
EndSwitch
If $Timeout > 0 And Round(TimerDiff($TimerStart)/1000) = $Timeout Then
$RetValue = GUICtrlRead($InputBoxID)
GUISetState(@SW_ENABLE, $Parent)
GUISetState(@SW_RESTORE, $Parent)
GUIDelete($InputGui)
SetError(2)
Return $RetValue
EndIf
WEnd
EndFunc
Func ShowMenu($hWnd, $CtrlID, $nContextID)
Local $hMenu = GUICtrlGetHandle($nContextID)
$arPos = ControlGetPos($hWnd, "", $CtrlID)
Local $x = $arPos[0]
Local $y = $arPos[1] + $arPos[3]
ClientToScreen($hWnd, $x, $y)
TrackPopupMenu($hWnd, $hMenu, $x, $y)
EndFunc
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
Local $stPoint = DllStructCreate("int;int")
DllStructSetData($stPoint, 1, $x)
DllStructSetData($stPoint, 2, $y)
DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
$x = DllStructGetData($stPoint, 1)
$y = DllStructGetData($stPoint, 2)
; release Struct not really needed as it is a local
$stPoint = 0
EndFunc
Func TrackPopupMenu($hWnd, $hMenu, $x, $y)
DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)
EndFunc
|