Что нового

[Элементы GUI] При выполнение функции, работа остальных элементов

TIgor

Новичок
Сообщения
10
Репутация
0
Добрый день. Накидал скрипт, который пингует определенные хосты, но появился вопрос, который не знаю как решить. Мне необходимо было сделать таймер, который можно было бы кнопками на GUI запускать и останавливать (тоже самое когда кнопку Ping! нажимаю, все остальное ждет выполнения функции). А получается, что элементы GUI не действуют, пока функция не будет до конца выполнена. Вот код программы. Я так понял, надо либо опрос GUI дополнительный в цикл встраивать, либо чтобы ф-ция в другом потоке работала? Заранее спасибо :smile:
Код:
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Include <File.au3>

Opt('MustDeclareVars', 1)

Local $FileServers = @ScriptDir & "\servers"
Local $FileRouters = @ScriptDir & "\routers"
Local $FileInetserv = @ScriptDir & "\inetserv"
Local $FilePrinters = @ScriptDir & "\printers"
Local $FileHosts = @ScriptDir & "\hosts"
Local $nMsg
Local $aServers, $aRouters, $aInetserv, $aPrinters, $aHosts
Local $nNumVer = 1, $nAutopInt = 30
Local $sOutText

If Not FileExists($FileServers) Or Not FileExists($FileRouters) Or Not FileExists($FileInetserv) Or Not FileExists($FilePrinters) Or Not FileExists($FileHosts) Then
   MsgBox (0, "", "Конфигуратор адресов сканирования" & @LF & "Создайте отсутствующие файлы вручную!")
EndIf

#region Read file in to array
_FileReadToArray($FileServers,$aServers)
_FileReadToArray($FileRouters,$aRouters)
_FileReadToArray($FileInetserv,$aInetserv)
_FileReadToArray($FilePrinters,$aPrinters)
_FileReadToArray($FileHosts,$aHosts)
#endregion

#Region
Local $Form1 = GUICreate("ICMP test", 571, 530, -1, -1)
Local $Edit1 = GUICtrlCreateEdit("", 8, 8, 433, 480, BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_READONLY,$ES_WANTRETURN,$WS_HSCROLL,$WS_VSCROLL))
GUICtrlSetFont(-1, 9, 400, 0, "Courier New")
Local $Button1 = GUICtrlCreateButton("Ping!", 16, 496, 75, 25, $WS_GROUP)
Local $Button2 = GUICtrlCreateButton("Exit", 480, 496, 75, 25, $WS_GROUP)
Local $Label5 = GUICtrlCreateLabel("", 104, 496, 84, 17, $SS_CENTERIMAGE)

Local $Group1 = GUICtrlCreateGroup("Object", 448, 8, 113, 161)
Local $Checkbox1 = GUICtrlCreateCheckbox("Servers", 456, 24, 97, 17)
	If Not UBound($aServers) Then GUICtrlSetState(-1, $GUI_DISABLE)
Local $Checkbox2 = GUICtrlCreateCheckbox("Hosts", 456, 48, 97, 17)
	If Not UBound($aHosts) Then GUICtrlSetState(-1, $GUI_DISABLE)
Local $Checkbox3 = GUICtrlCreateCheckbox("Inetservers", 456, 72, 97, 17)
	If Not UBound($aInetserv) Then GUICtrlSetState(-1, $GUI_DISABLE)
Local $Checkbox4 = GUICtrlCreateCheckbox("Routers", 456, 96, 97, 17)
	If Not UBound($aRouters) Then GUICtrlSetState(-1, $GUI_DISABLE)
Local $Checkbox5 = GUICtrlCreateCheckbox("Printers", 456, 120, 97, 17)
	If Not UBound($aPrinters) Then GUICtrlSetState(-1, $GUI_DISABLE)
Local $Checkbox6 = GUICtrlCreateCheckbox("Select all", 456, 144, 97, 17)
GUICtrlCreateGroup("", -99, -99, 1, 1)

Local $Group2 = GUICtrlCreateGroup("Number verification:", 448, 176, 113, 57)
Local $Input1 = GUICtrlCreateInput($nNumVer, 464, 200, 25, 21, BitOR($ES_RIGHT,$ES_NUMBER))
Local $Button3 = GUICtrlCreateButton("Set", 504, 198, 35, 25, $WS_GROUP)
GUICtrlCreateGroup("", -99, -99, 1, 1)

Local $Group3 = GUICtrlCreateGroup("Autoping", 448, 240, 113, 153)
Local $Input2 = GUICtrlCreateInput($nAutopInt, 512, 264, 25, 21, BitOR($ES_RIGHT,$ES_NUMBER))
Local $Label1 = GUICtrlCreateLabel("Interval:", 464, 266, 42, 17)
Local $Label2 = GUICtrlCreateLabel("Next ping after:", 464, 296, 76, 17)
Local $Label3 = GUICtrlCreateLabel("- -", 464, 320, 48, 28, $ES_RIGHT)
GUICtrlSetFont(-1, 14, 800, 0, "MS Sans Serif")
GUICtrlSetResizing(-1, $GUI_DOCKRIGHT)
Local $Label4 = GUICtrlCreateLabel("sec", 520, 326, 21, 17)
Local $Button4 = GUICtrlCreateButton("Start", 480, 360, 57, 25, $WS_GROUP)
Local $Button5 = GUICtrlCreateButton("Stop", 480, 360, 57, 25, $WS_GROUP)
GUICtrlSetState(-1, $GUI_HIDE)
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $Button1 ; <Ping!> Button
				$sOutText = ''
				If BitAND (GUICtrlRead($Checkbox1), $GUI_CHECKED) Then
					$sOutText &= _PlotPing("Servers", $aServers, $nNumVer)
					GUICtrlSetData ($Edit1,$sOutText)
				EndIf
				If BitAND (GUICtrlRead($Checkbox2), $GUI_CHECKED) Then
					$sOutText &= _PlotPing('Hosts', $aHosts, $nNumVer)
					GUICtrlSetData ($Edit1,$sOutText)
				EndIf
				If BitAND (GUICtrlRead($Checkbox3), $GUI_CHECKED) Then
					$sOutText &= _PlotPing('Inetservers', $aInetserv, $nNumVer)
					GUICtrlSetData ($Edit1,$sOutText)
				EndIf
				If BitAND (GUICtrlRead($Checkbox4), $GUI_CHECKED) Then
					$sOutText &= _PlotPing('Routers', $aRouters, $nNumVer)
					GUICtrlSetData ($Edit1,$sOutText)
				EndIf
				If BitAND (GUICtrlRead($Checkbox5), $GUI_CHECKED) Then
					$sOutText &= _PlotPing('Printers', $aPrinters, $nNumVer)
					GUICtrlSetData ($Edit1,$sOutText)
				EndIf
		Case $Button2 ; <Exit> Button
			Exit
		Case $Checkbox6
			If BitAND (GUICtrlRead($Checkbox6), $GUI_CHECKED) Then
				If BitAND (GUICtrlGetState($Checkbox1), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox1, $GUI_CHECKED)
				If BitAND (GUICtrlGetState($Checkbox2), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox2, $GUI_CHECKED)
				If BitAND (GUICtrlGetState($Checkbox3), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox3, $GUI_CHECKED)
				If BitAND (GUICtrlGetState($Checkbox4), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox4, $GUI_CHECKED)
				If BitAND (GUICtrlGetState($Checkbox5), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox5, $GUI_CHECKED)
			Else
				If BitAND (GUICtrlGetState($Checkbox1), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox1, $GUI_UNCHECKED)
				If BitAND (GUICtrlGetState($Checkbox2), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox2, $GUI_UNCHECKED)
				If BitAND (GUICtrlGetState($Checkbox3), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox3, $GUI_UNCHECKED)
				If BitAND (GUICtrlGetState($Checkbox4), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox4, $GUI_UNCHECKED)
				If BitAND (GUICtrlGetState($Checkbox5), $GUI_ENABLE) Then GUICtrlSetState ($Checkbox5, $GUI_UNCHECKED)
			EndIf
		Case $Button3 ; <Set> Button
			If GUICtrlRead($Input1) > 0 Then
				$nNumVer = GUICtrlRead($Input1)
				GUICtrlSetState($Button3, $GUI_DISABLE)
			EndIf
		Case $Button4 ; <Start> Button
			$nAutopInt = GUICtrlRead($Input2)
			;GUICtrlSetData ($Label3, $nAutopInt)
			If BitAND (GUICtrlGetState($Button5), $GUI_HIDE) Then GUICtrlSetState ($Button5, $GUI_SHOW)
			If BitAND (GUICtrlGetState($Button4), $GUI_SHOW) Then GUICtrlSetState ($Button4, $GUI_HIDE)
			While 1
				For $i = $nAutopInt To 1 Step -1
					GUICtrlSetData ($Label3, $i)
					Sleep(1000)
				Next
			WEnd
		Case $Button5 ; <Stop> Button
			GUICtrlSetData ($Label3, "- -")
			If BitAND (GUICtrlGetState($Button5), $GUI_SHOW) Then GUICtrlSetState ($Button5, $GUI_HIDE)
			If BitAND (GUICtrlGetState($Button4), $GUI_HIDE) Then GUICtrlSetState ($Button4, $GUI_SHOW)
	EndSwitch
WEnd


;servers, routers, printers, inetserv, hosts

Func _PlotPing($sNameGroup, $aCheckHost, $nCheck=1)
	Local $aTime, $sOut
	$aTime = _PingHost($aCheckHost, $nCheck)
	$sOut = _AddPoint ("----------" & $sNameGroup, "-", "-", 59) & @CRLF
	For $x = 1 to $aTime[0]
		If $aTime [$x] > 0 Then
			$sOut &= _AddPoint($aCheckHost[$x], "ping to " & $aTime [$x]& " ms") & @CRLF
		Else
			$sOut &= _AddPoint($aCheckHost[$x], "ping fail") & @CRLF
		EndIf
	Next
	$sOut &= _AddPoint ("-", "-", "-", 59) & @CRLF
	Return $sOut
EndFunc

Func _PingHost($aCheckHost, $nCheck=1) ; returned average time
	Local $nPTime, $AvPTime
	If UBound ($aCheckHost)And $nCheck > 0 Then
		Local $aPTime[UBound ($aCheckHost)]
		$aPTime[0] = $aCheckHost[0]
		For $i = 1 To $aCheckHost[0]
			For $j = 1 To $nCheck
				$AvPTime += Ping ($aCheckHost[$i])
			Next
			$aPTime[$i] = Round ($AvPTime/$nCheck, 0)
			$AvPTime = 0
		Next
		Return $aPTime
	Else
		Return @error
	EndIf
EndFunc

Func _AddPoint($sStartVar, $sEndVar, $sDelim = '.', $nChr = 57)
	Local $sStr="",$sDel, $nAdd
	$nAdd = $nChr-StringLen($sStartVar & $sEndVar)-1
	For $i=1 To $nAdd
		$sDel &= $sDelim
	Next
	$sStr = $sStartVar & $sDel & $sEndVar
	Return $sStr
EndFunc
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
TIgor
AutoIt не поддерживает многопоточнтсть. Если и вставлять в разные циклы, то пока работает один до второго очередь не дойдет.
 

VladUs

Скриптер
Сообщения
621
Репутация
181
Сталкнулся примерно с такой же проблеммой в программе с анологичными действиями ("Ping").
Как выход прописал в основном цикле, где происходит вызов функции Ping(), дейстивия происходящие на вызов GUI событий.

Допустим в твоем примере:

Код:
Func _PingHost($aCheckHost, $nCheck=1) ; returned average time
    Local $nPTime, $AvPTime
    If UBound ($aCheckHost)And $nCheck > 0 Then
        Local $aPTime[UBound ($aCheckHost)]
        $aPTime[0] = $aCheckHost[0]
        For $i = 1 To $aCheckHost[0]
            For $j = 1 To $nCheck
                $AvPTime += Ping ($aCheckHost[$i])
                  if  GUIGetMsg()=$Button2  then ExitLoop; Проверяем не нажата ли кнопка $Button2, если  нажата выходим из цикла.
            Next
            $aPTime[$i] = Round ($AvPTime/$nCheck, 0)
            $AvPTime = 0
        Next
        Return $aPTime
    Else
        Return @error
    EndIf
EndFunc
 
Автор
T

TIgor

Новичок
Сообщения
10
Репутация
0
VladUs
Спасибо. Понятно. Буду выкручиваться. А для таймера я сделал вот так:
Код:
While 1
				For $i = $nAutopInt To 1 Step -1
					GUICtrlSetData ($Label3, $i)
					if  GUIGetMsg()=$Button5  then ExitLoop 2
					Sleep(1000)
					if  GUIGetMsg()=$Button5  then ExitLoop 2
				Next
				if  GUIGetMsg()=$Button5  then ExitLoop
			WEnd

выглядит страшно, зато реагирует хоть как-то :smile:
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
TIgor
Тема решена? Т.к.:
{TopicSolvedInfo}
 
Верх