Показать полную графическую версию : [Архив - Часть 1.3] AutoIt скрипты
Creat0RМоя версия на функцию деления пути используя регулярные выраженияугу, полезное упражнение, кстати в 4-м есть неточность.... и зачем дважды искать одно и тоже?.. (см. [6]) еще два момента:
- какие еще ты предполагал разделители кроме '\' ?... имхо часто перегружаешь функции избыточностью, да и читаются они так сложней - легко ошибку пропустить... знаком с "бритвой Оккама"? ;)
- зачем последний цикл?.. какие случаи имелись ввиду?... или опять на всякий случай? ;)
amel27
в 4-м есть неточность
Ты про то что в начале слешь остаётся? ну это так задуманно, но хотя да, нужно бы его убрать...
зачем дважды искать одно и тоже?.. (см. [6])
Ок, намёк понял ;) (см. ниже поправлены вариант)...
какие еще ты предполагал разделители кроме '\' ?
Ну вообще то я считал что символ \ “позволяет” считать последующий после этого символ дословно, и если как разделитель будет задан один из служебных (для StringRegExpReplace()) символов, то это позволит не считать символ как служебны - это не так?
Просто путь может быть и как ссылка, тогда разделитель будет другой.
знаком с "бритвой Оккама"?
Неа :no:
зачем последний цикл?
Чтобы проверить весь массив на пренадлежность НЕ замены, т.е если какой то элемент массива ровняется исходному пути, то я предполагаю что замена не осуществлялась, поэтому нужно опусташить этот элемент (это по мативам оригинальной функции _PathSplit() ;) ).
Соответсвенно замечаниям немного переделал функцию :) :
Func _PathSplitByRegExp($sPath, $pDelim="\")
Local $RetArray[8], $iArr
$pDelim = "\" & $pDelim
$RetArray[0] = $sPath
$RetArray[1] = StringRegExpReplace($sPath, $pDelim & '.*', $pDelim) ;Drive letter
$RetArray[2] = StringRegExpReplace($sPath, $pDelim & '[^' & $pDelim & ']*$', '') ;Path without FileName and extension
$RetArray[3] = StringRegExpReplace($sPath, '\.[^.]*$', '') ;Full path without File Extension
$RetArray[4] = StringRegExpReplace($sPath, '^.' & $pDelim & '*:.', '') ;Full path without drive letter
$RetArray[5] = StringRegExpReplace($sPath, '^.*' & $pDelim, '') ;FileName and extension
$RetArray[6] = StringRegExpReplace($RetArray[5], '\.[^.]*$', '') ;Just Filename
$RetArray[7] = StringRegExpReplace($sPath, '^.*\.', '') ;Just Extension of a file
;Проверяем все значения (элементы массива), если в каком то из них небыла произведена замена, то присваеваем ему пустое значение ("")
For $iArr = 1 To 7
If $RetArray[$iArr] = $sPath Then $RetArray[$iArr] = ""
Next
Return $RetArray
EndFunc
Вот ссылка на пост в котором я оставил пример использования функции _StringStripNotNumber() - этот пример по сути предназначен для демонстрации чтения данных из консольного окна (при архивировании или расспаковке), вывод этих данных в статус баре, и собственно обнаженные значения до чисел для того чтобы корректно отобразить процесс распаковки/запаковки в прогресс баре.
http://www.autoitscript.com/forum/index.php?showtopic=41371&st=0&p=307745&#
P.S
Функцию может переименовать так: _StringStripWords() ?
Creat0RПросто путь может быть и как ссылка, тогда разделитель будет другой.разделитель не может быть любым (попробуй поставить точку :) ), поэтому (строго говоря) нужно брать спецификацию формата (например для UNC) и на его основе строить разбор - что является служебным символом, а что нет, что идет за чем и прочее... типа:Func _IsUNCPath ($str)
Return StringRegExp ($str, '^(?i)([A-Z]:|\\)(\\[^\\]+)+$')
EndFuncНеаhttp://ru.wikipedia.org/wiki/%D0%91%D1%80%D0%B8%D1%82%D0%B2%D0%B0_%D0%9E%D0%BA%D0%BA%D0%B0%D0%BC%D0%B0 ;)Чтобы проверить весь массив на пренадлежность НЕ замены, т.е если какой то элемент массива ровняется исходному пути, то я предполагаю что замена не осуществлялась, поэтому нужно опусташить этот элемент (это по мативам оригинальной функции _PathSplit() ничего такого в исходном _PathSplit нету - если искомый элемент не найден, тогда получится пустая строка... Если разбор ведется правильно, то никаких "хвостов" не дожно оставаться.
amel27
на его основе строить разбор - что является служебным символом, а что нет, что идет за чем и прочее
Как я понял эта функция проверяет является ли путь корректным путём, но как можно универсально проверить разделитель? т.е к примеру имеем такой путь - C:|program files|Program|Program.exe, нужно чтобы если как второй параметр задан разделитель |, то путь делился именно используя этот делитель.
http://ru.wikipedia.org/wiki/%D0%91...%B0%D0%BC%D0%B0
Интересно, ну я кажется понял суть, но если смотреть в сторону программирования таким подходом, то тут нужен исключительно немалы опыт (которым обладаешь ты ;) ), имхо.
если искомый элемент не найден, тогда получится пустая строка...
Вот я примерно также и сделал, если не было замены, значит тот элемент в котором небыло замены становится пустым...
Если разбор ведется правильно, то никаких "хвостов" не дожно оставаться.
Ну а если в качестве пути задаётся не разбираемый путь? т.е даже вовсе не путь, а просто любое значение.
Можно последний цикл прописать так (чтобы не было хвостов в виде пустых элементов массива):
For $iArr = 7 To 1 Step -1
If $RetArray[$iArr] = $sPath Or $RetArray[$iArr] = "" Then _ArrayDelete($RetArray, $iArr)
Next
Creat0RВот ссылка на пост Хм, чтение консольного вывода... что-то подобное давно собирался сделать вместо батника, на базе твоего сделал свой вариант (к сожалению, комментарии некогда делать, но думаю итак чсе понятно):#include <File.au3>
#include <GuiStatusBar.au3>
$sSourceFiles = @MyDocumentsDir & '\*.*'
$sDestinRarFile = @ScriptDir & '\test'
$Gui = GUICreate("Add files to archive: ", 500, 200)
$Progress = GUICtrlCreateProgress(40, 45, 430, 20)
$CancelButton = GUICtrlCreateButton("Cancel", 220, 80)
$ProgressStatus = _GUICtrlStatusBarCreate($Gui, 0, "")
_GUICtrlStatusBarSetSimple($ProgressStatus)
_GUICtrlStatusBarSetText($ProgressStatus, '123')
GUISetState()
$sCMD = 'rar.exe a ' & '"' & $sDestinRarFile & '" "' & $sSourceFiles & '"'
$foo = Run ($sCMD, @ScriptDir, @SW_HIDE, 2)
Dim $arrStatus [2] = ['','0%']
While _StdoutRefresh ($foo)
$Msg = GUIGetMsg()
If $Msg=-3 Or $Msg=$CancelButton Then
ProcessClose($foo)
Exit
EndIf
WEnd
Exit
Func _StdoutRefresh ($foo)
Local $sOut, $aOut, $i
If StdoutRead ($foo,0,True) Then
$sOut = StdoutRead ($foo)
$aOut = StringSplit ($sOut, @CRLF & Chr(0x08))
For $i=1 To $aOut[0]
If StringRight ($aOut[$i],1)='%' Then
$arrStatus[1] = $aOut[$i]
ElseIf StringLen($aOut[$i]) >0 Then
$arrStatus[0] = $aOut[$i]
EndIf
Next
WinSetTitle ('Add files to archive','','Add files to archive: ' & $sDestinRarFile & ' (' & $arrStatus[1] & ')')
GUICtrlSetData($Progress, StringTrimRight($arrStatus[1],1))
_GUICtrlStatusBarSetText($ProgressStatus, $arrStatus[0],$SB_SIMPLEID)
EndIf
Return ProcessExists ($foo)
EndFuncНу а если в качестве пути задаётся не разбираемый путь?тогда зачем его разбирать?... поставить на входе что-нибудь типа _IsStringPath() и не зависеть от случая... :)тут нужен исключительно немалы опыт плохая отмазка, а главное вредная... ;) дело не в опыте, а в отношении к результату своего труда
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
Функция для ограничения размеров гуи при испольовании стиля $WS_SIZEBOX (я кажется как то спрашивал тут про это, но тогда не имел понятия как сделать, а сегодня уже знании побольше :) )...
#include <GuiConstants.au3>
$Title = "Resize Limit GUI Demo"
GUICreate($Title, 300, 250, -1, -1, $WS_SIZEBOX)
GUISetState()
While 1
$Msg = GUIGetMsg()
Switch $Msg
Case -3
Exit
Case -11, -8
_ResizeLimit($Title, "", 200, 200, 600, 500)
EndSwitch
Sleep(10)
WEnd
Func _ResizeLimit($Title, $Text="", $MinWidth=150, $MinHeight=100, $MaxWidth=@DesktopWidth, $MaxHeight=@DesktopHeight)
If Not WinExists($Title, $Text) Then
SetError(1)
Return -1
EndIf
Local $PosArr = WinGetPos($Title, $Text), $xPos, $yPos, $wPos, $hPos
If IsArray($PosArr) Then
$xPos = $PosArr[0]
$yPos = $PosArr[1]
$wPos = $PosArr[2]
$hPos = $PosArr[3]
If ($wPos <> $MinWidth And $hPos <> $MinHeight) Or ($wPos <> $MaxWidth And $hPos <> $MaxHeight) Then
If $wPos < $MinWidth And $hPos < $MinHeight Then WinMove($Title, $Text, $xPos, $yPos, $MinWidth, $MinHeight)
If $wPos < $MinWidth And $hPos >= $MinHeight Then WinMove($Title, $Text, $xPos, $yPos, $MinWidth, $hPos)
If $wPos >= $MinWidth And $hPos < $MinHeight Then WinMove($Title, $Text, $xPos, $yPos, $wPos, $MinHeight)
If $wPos > $MaxWidth And $hPos > $MaxHeight Then WinMove($Title, $Text, $xPos, $yPos, $MaxWidth, $MaxHeight)
If $wPos > $MaxWidth And $hPos <= $MaxHeight Then WinMove($Title, $Text, $xPos, $yPos, $MaxWidth, $hPos)
If $wPos <= $MaxWidth And $hPos > $MaxHeight Then WinMove($Title, $Text, $xPos, $yPos, $wPos, $MaxHeight)
EndIf
EndIf
EndFunc
Есть правда пару недостатков - к примеру, если достигать максимального/минимального размера используя левую или верхнюю сторону (дл изменения размера), то окно как бы сдвигается в ту сторону в которую произведена попытка изменить размер на столько же на сколько был промежуток от текущего размера и позволенного минимального/максимального размера.
Полагаю и это можно как то решить, но мне и так пока нравится, если у кого то есть желаение, милости просим ;) - буду благодарен.
Как можно изменить функцию _ChooseColor чтобы в ней был параметр hWnd?
Я пробовал подсталять этот параметр в DllStructCreate и потом задать его при заплонении структуры данных (DllStructSetData) но всё безуспешно :( ... может кто-то знает как это сделать, и возможно ли вообще?
P.S
В начале самой функции есть упоминание об этом:
;~ HWND hwndOwner;
;~ HWND hInstance;
Значит видимо возможно, но как?
Creat0RВот более модифицированный пример архивирования файлов Если заметил, то перед чтением выходного потока StdoutRead($Pid) я добавил проверку на наличие данных в потоке StdoutRead ($foo,0,True) - это позволяет избежать подвисания окна AutoIT на время отсутствия выходных данных (об этом кстати сказано в справке к StdoutRead())... соответственно, пришлось изменить способ определения конца архивации - с проверки @error на ProcessExists ($foo).Как можно изменить функцию _ChooseColor чтобы в ней был параметр hWnd?так пробовал?Func _ChooseColor($i_ReturnType = 0, $i_colorref = 0, $i_refType = 0, $hwnd = 0)
...
DllStructSetData($p, 1, DllStructGetSize($p))
DllStructSetData($p, 2, $hwnd)
DllStructSetData($p, 4, $i_colorref)
...
EndFunc ;==>_ChooseColor
Здравия желаю!
Простите если повторюсь,просто не нашёл(а может плохо искал).
Есть скрипт ,который архивирует,а потом с помощью встроенного в винду ftp клиента отсылает архив восвояси.так вот хотелось бы перехватывать сообщения ftp и писать их в лог ,что бы занать что и когда
как это можно сделать?
amel27
Если заметил, то перед чтением выходного потока StdoutRead($Pid) я добавил проверку на наличие данных в потоке StdoutRead ($foo,0,True) - это позволяет избежать подвисания окна AutoIT на время отсутствия выходных данных (об этом кстати сказано в справке к StdoutRead())...
Интересно, я если честно не обратил внимания, спасибо, пойду поправлю свой пример ;)
так пробовал?
Нет, но мне уже на офф. форуме подсказали, нужно точно также но чтобы $hwnd = 0 был как первый параметр, иначе не работает (не знаю даже почему, вроде никак не должо влиять) - но всё же биг сенкс!
13ghost
перехватывать сообщения ftp и писать их в лог
Если это консольная утилита, то попробуй применить методы из примера для архивирования тут (http://forum.oszone.net/post-554071-734.html).
amel27
так вот второй параметр (после имени инициатора) отвечает за тип подключения
Где именно мне в функции поравить 0 на 1 (это я ещё по поводу _InetGetSource() (http://forum.oszone.net/post-550976-708.html) )?
Вот исходник функции:
(если не трудно, укажи где именно нужно менять)
Func _INetGetSource($s_URL, $s_Header = '')
If StringLeft($s_URL, 7) <> 'http://' And StringLeft($s_URL, 8) <> 'https://' Then $s_URL = 'http://' & $s_URL
Local $h_DLL = DllOpen("wininet.dll")
Local $ai_IRF, $s_Buf = ''
Local $ai_IO = DllCall($h_DLL, 'int', 'InternetOpen', 'str', "AutoIt v3", 'int', 0, 'int', 0, 'int', 0, 'int', 0)
If @error Or $ai_IO[0] = 0 Then
DllClose($h_DLL)
SetError(1)
Return ""
EndIf
Local $ai_IOU = DllCall($h_DLL, 'int', 'InternetOpenUrl', 'int', $ai_IO[0], 'str', $s_URL, 'str', $s_Header, 'int', StringLen($s_Header), 'int', 0x80000000, 'int', 0)
If @error Or $ai_IOU[0] = 0 Then
DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IO[0])
DllClose($h_DLL)
SetError(1)
Return ""
EndIf
Local $v_Struct = DllStructCreate('udword')
DllStructSetData($v_Struct, 1, 1)
While DllStructGetData($v_Struct, 1) <> 0
$ai_IRF = DllCall($h_DLL, 'int', 'InternetReadFile', 'int', $ai_IOU[0], 'str', '', 'int', 256, 'ptr', DllStructGetPtr($v_Struct))
$s_Buf &= StringLeft($ai_IRF[2], DllStructGetData($v_Struct, 1))
WEnd
DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IOU[0])
DllCall($h_DLL, 'int', 'InternetCloseHandle', 'int', $ai_IO[0])
DllClose($h_DLL)
Return $s_Buf
EndFunc
Creat0RLocal $ai_IO = DllCall($h_DLL, 'int', 'InternetOpen', 'str', "AutoIt v3", 'int', 1, 'int', 0, 'int', 0, 'int', 0)
amel27
Спасибо!
[hr]
Такой вопрос по регулярным вырожениям - Как возможно получить определённый текст, который находится между двумя заранее известными символами?
Т.е к примеру, имеем такой текст:
test1*этот текст нам нужен*test2
Заранее известны только разделители *, и нужно бы получить всё что между ними... я конечно могу использовать разного рода ухитрения со StringSplit, StringInStr, StringLeft...Right и т.д, но мне хотелось бы узнать как это можно достичь регулярными выражениями, и тем более, что подобные методы будут не очень надёжны.
Creat0R
что-то подобное я делал в скрипте "расцветки":$str='test1*этот текст нам нужен*test2'
$chr='\*'
MsgBox (0,'Результат',StringRegExpReplace ($str,'^.*' & $chr & '(.*)' & $chr & '.*$','\1'))PS: естественно, разделителей должно быть два
amel27
Я имел ввиду получить текст между двумя символами, но они могут быть разные, к примеру если этот метод использовать так (как функию):
$String = '1теперь нам нужен этот текст2'
MsgBox(0, "", _StringInside($String, "1", "2"))
Func _StringInside($String, $Start, $End)
Return StringRegExpReplace($String, '^.*\' & $Start & '(.*)\' & $End & '.*$', '\1')
EndFunc
То результат будет не верный, нужно как то получать текст между двумя заданными символами, и неважно какие символы, или где они стоят, если между ними ничего нет, то можно возвращать весь $String...
Добавлено:
Во! сделал, правда я не уверен что учёл все символы...
$String = '_теперь нам нужен этот текст^'
MsgBox(0, "", _StringInside($String, "_", "^"))
Func _StringInside($String, $Start, $End)
If StringRegExp($Start, "[\+\|\*\^\$\.\[\]\(\)\?\\]") Then $Start = "\" & $Start
If StringRegExp($End, "[\+\|\*\^\$\.\[\]\(\)\?\\]") Then $End = "\" & $End
Local $Ret = StringRegExpReplace($String, '^.*' & $Start & '(.*)' & $End & '.*$', '\1')
If $Ret = "" Then Return $String
Return $Ret
EndFunc
Спасибо!
Хм, но теперь другая проблема - если более чем два совпадения символов, то возвращается последнее межсимвольное значение, а нужно чтобы в таком случае возвращалось первое совпадение (с левой стороны, т.е сначала).
Creat0R
ну... вот еще вариант, выбирающий фрагмент от первого вхождения 1-го символа до первого вхождения 2-го:$String = '_теперь нам нужен этот текст^'
MsgBox(0, "", _StringInside($String, "_", "^"))
Func _StringInside($String, $Start, $End)
$Start = StringRegExpReplace ($Start, '([\+\|\*\^\$\.\[\]\(\)\?\\])', '\\\1')
$End = StringRegExpReplace ($End, '([\+\|\*\^\$\.\[\]\(\)\?\\])', '\\\1')
Local $pattern = '^[^' & $Start & ']*' & $Start & '([^' & $End & ']*)' & $End & '.*$'
Return StringRegExpReplace($String, $pattern, '\1')
EndFunc
amel27
вот еще вариант
Во! это то что нужно (правда Local там лишних два раза встречается ;) ), спасибо большое (см. ниже полный пример для подобной функции, я её уже переименовал :) )...
Поздравляю со статусом Ветерана! :4u:
$String = 'Это нам не нужно. Нам нужен этот текст, :и этот тоже:, а :этот нам не нужен:'
MsgBox(0, "", _StringMidle($String, ".", ","))
MsgBox(0, "", _StringMidle($String, ":", ":"))
Func _StringMidle($String, $Start, $End)
$Start = StringRegExpReplace ($Start, '([\+\|\*\^\$\.\[\]\(\)\?\\])', '\\\1')
$End = StringRegExpReplace ($End, '([\+\|\*\^\$\.\[\]\(\)\?\\])', '\\\1')
Local $pattern = '^[^' & $Start & ']*' & $Start & '([^' & $End & ']*)' & $End & '.*$'
Return StringRegExpReplace($String, $pattern, '\1')
EndFunc
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.