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

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

Аватара для Creat0R

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

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

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

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


Последний раз редактировалось Creat0R, 26-02-2007 в 21:56. Причина: Правка кода.


Отправлено: 20:25, 22-02-2007 | #227