PDA

Показать полную графическую версию : [решено] Прогресс бар


semiono
14-02-2009, 05:22
Мне нужен прогресс бар чтоб запустить в начале кода, и к завершению чтоб он был 100% типо как заставка
Я вставил в начало
ProgressOn()
далее код проги идёт
и в конце
Progressff()

Но он просто висит без всякого прогресса! В ProgressSet тоже ничего путного не найду. Sleep() тут как бы не уместен.
Потомучто нужен результат хода работы скрипта, а не виртуальное засыпание...
?
---------
Я пока хитро зделал :) так как скрипт работает быстро создаётся ощущение что готово... 100%
ProgressOn("Running...","","")
ProgressSet(100)

BlockInput(1)
....

BlockInput(0)

WinClose("MyWin") ; это на всякий случай лучше иметь за пределами BlockInput(1)

ProgressOff()

Creat0R
14-02-2009, 11:15
нужен прогресс бар »
А в справке пример не подходит?

semiono
14-02-2009, 14:23
Нет, там задаётся Sleep(1000) и по нему отсчитывается прогресс. Мне кажется тут совсем ничего не поделаешь. А мой пример самый нормальный, особенно если скрипт работает быстро.

Creat0R
14-02-2009, 14:49
мой пример самый нормальный, особенно если скрипт работает быстро »
Я тогда вообще не понял в чём проблема :dont-know .

semiono
14-02-2009, 14:57
Ну это вы с сарказмом так. Прогресс бар должен отображать ход работы, другое дело что его пример не совсем удачный в хелпе и вообще не ясно что с ним можно зделать. Я лишь как прикол нашёл решение, всё лучше чем ничего.
Creat0R, что-то вы не в духе сегодня. Я пожалуй спрячусь подальше на время...

Creat0R
14-02-2009, 22:56
Ну это вы с сарказмом так »
Как раз нет, я серъёзно не понимаю суть проблемы.

Прогресс бар должен отображать ход работы »
В справке разве это не происходит, тогда вот ещё пример:


ProgressOn("Заголовок", "Главный текст", "Под-текст")

$iPrecent = 0

While 1
;Тут выполняется что угодно

;Увеличиваем прогресс на 5 единиц
$iPrecent += 5
ProgressSet($iPrecent, "Под-текст, проценты: " & $iPrecent & "%")

;Спим 0.5 секунд
Sleep(500)

If $iPrecent = 100 Then ExitLoop
WEnd

MsgBox(262144+64, "Фенито!", "Прогресс окончен!", 0, WinGetHandle("Заголовок"))

что-то вы не в духе сегодня »
Дело не в этом, просто если у Вас нет терпения читать подробности у функции в справке, то почему у меня (или у любого другого кто желает помочь) должно быть терпение к тривиальным задачам?

P.S
А тему назвали неудачно, переименуйте во что-то более вразумительное :).

semiono
15-02-2009, 11:23
Изначально хотел назвать, типа графическое оформление, что и было почти, но думаю на одном таск баре и остановимся.
В справке разве это не происходит, »
Ну да, всё так. Просто я ожидал что ProgressOn(), будет сам всю работу обеспечивать.
А тут получается для него надо всю функцию расписать. Я бы просто, извините с разработчиками поспорил,
так как нет смысла в редактировании такой простой штуки... уже бы было всё в # include прописанно одним вызовом чтоб. Я только этот случай имею ввиду! Вот именно этим я и озадачился. Мы же не описываем функцию RegWrite() например, только поля редактирум!

Creat0R
15-02-2009, 12:02
я ожидал что ProgressOn(), будет сам всю работу обеспечивать »
Тогда у меня есть для вас новость. В других языках программирования, всё намного сложнее, там ВСЁ нужно самому делать (если не брать в счёт готовые библиотеки), в AutoIt' же, многие задачи реализованы уже за нас, вшиты в ядро языка.

Мне просто интересно, как функция будет знать сколько устанавливать прогресс? когда менять его, или имеется в виду чтобы он покругу ходил как маятник? :)

Creat0R
15-02-2009, 12:22
Тогда вот так например:

#include <Timers.au3>

Global $i_Timer, $h_Timer_GUI, $i_Precent = 0

_ProgressOn("Заголовок", "Главный текст", "Под-текст")

While 1
;Тут выполняется что угодно

Sleep(5000)
ExitLoop
WEnd

_Timer_KillTimer($h_Timer_GUI, $i_Timer)
ProgressSet(100, "Проценты: 100%")

MsgBox(262144+64, "Фенито!", "Прогресс окончен!", 0, WinGetHandle("Заголовок"))

Func _ProgressOn($sTitle="", $sMainText="", $sSubText="", $iXPos=-1, $iYPos=-1, $iOpt=16)
ProgressOn($sTitle, $sMainText, $sSubText, $iXPos, $iYPos, $iOpt)

$h_Timer_GUI = GUICreate("__TIMER__")
$i_Timer = _Timer_SetTimer($h_Timer_GUI, 100, "_ProgressSet")
EndFunc

Func _ProgressSet($hWnd, $Msg, $iIDTimer, $dwTime)
;Увеличиваем прогресс на 5 единиц
$i_Precent += 5
ProgressSet($i_Precent, "Проценты: " & $i_Precent & "%")

;Если достигли 100 процентов, сбрасываем на 0.
If $i_Precent = 100 Then $i_Precent = 0
EndFunc

semiono
15-02-2009, 13:08
Мне просто интересно, как функция будет знать сколько устанавливать прогресс? »
Надо чтобы функция рисовала прогресс от слова ProgressOn до слоава ProgressOff, достаточно лишь их указать как вход и выход из программы... Не знаю как, но у форматирования диска или копирования файлов это как-то высчитывается.
Это только в lowlevel code language надо всё вручную собирать :)
Хотя gif анимация тоже часто присутствует, тоже круговая неподконтрольная.

Сегодня у чувака подпись увидел, прямо в тему :)))
Надпись: "Выполнено 99%" радует только первые три часа.

Creat0R
16-02-2009, 00:33
Надо чтобы функция рисовала прогресс от слова ProgressOn до слоава ProgressOff »
Так а в чём проблема?

Это только в lowlevel code language надо всё вручную собирать »
Это откуда такая информация? :)

semiono
16-02-2009, 12:31
Это откуда такая информация? »
Ну под win32 тоже не надо, там макросы рулят почти что как в си
invoke MessageBoxA, 0 ,_message,_caption, MB_ICONQUESTION + MB_YESNO
:) однако оффтопик...
для сравнения MsgBox(0, "AutoIt", "OK. Bye!") - почти как асм :)

PS однако если извращатся, то можно
xor eax, eax
push eax
push eax
...
call... одним словом lowlevel

mr.Zorg
24-03-2009, 00:23
Подниму тему, так как столкнулся с такой же проблемой как и топик стартера.
Опишу подробно мою ситуацию. Имеется скрипт, который запускает и устанавливает 10 различных программ. Хочется при помощи функции Progress отображать ход развития установки.
На данный момент применяю такой вариант:

...
ProgressSet (10)
Run("Prog2.exe")
WinWait("Prog2",'"')
ContolClick...
...
ProgressSet (20)
Run("Prog3.exe")
...

Но из-за разного времени выполнения программ прогрессбар движется неравномерно. А хотелось бы получить плавное движение. Как вариант, даже без привязки в процентном отношении к ходу выполнения скрипта. Типа, как индикатор работы

Creat0R
24-03-2009, 01:28
как индикатор работы »
Можно так:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
;

Global $aProgress_Ctrls[10]
Global $hCallBack, $ahTimer
Global $iProgress_InitSet

_Progress_Initialize()

Sleep(1500)

_Progress_Set(5)

Sleep(2500)

_Progress_Set(25)

Sleep(2500)

_Progress_Set(55)

Sleep(2500)

_Progress_Set(85)

Sleep(2500)

_Progress_Set(100, "Main Progress: ", "Working Progress", "Done!", 100)

Sleep(2500)

_Progress_ShutDown()

Func _Progress_Initialize($sMain_Data="Please wait...", $sMainPrgrs_Data="Main Progress: 0%", $sCrntPrgs_Data="Working Progress")
$aProgress_Ctrls[1] = GUICreate("Installation Progress", 300, 150, -1, -1, -1, $WS_EX_TOOLWINDOW)

$aProgress_Ctrls[2] = GUICtrlCreateLabel($sMain_Data, 20, 10, 260, 30)
GUICtrlSetFont(-1, 10, 800)

$aProgress_Ctrls[3] = GUICtrlCreateLabel($sCrntPrgs_Data, 20, 50, 260, 20)
$aProgress_Ctrls[4] = GUICtrlCreateProgress(20, 65, 260, 17)

$aProgress_Ctrls[5] = GUICtrlCreateLabel($sMainPrgrs_Data, 20, 100, 260, 20)
$aProgress_Ctrls[6] = GUICtrlCreateProgress(20, 115, 260, 20)

GUISetState(@SW_SHOW, $aProgress_Ctrls[1])
EndFunc

Func _Progress_Set($iMPrgrs, $sMPrgrs_Data="Main Progress: ", $sCrntPrgs_Data="Working Progress", $sMain_Data="", $iCrntPrgrs=-1)
GUICtrlSetData($aProgress_Ctrls[6], $iMPrgrs)

If $hCallBack = 0 Then
$hCallBack = DllCallbackRegister("_Callback_ProgressSet_Proc", "int", "hwnd;int;int;dword")
$ahTimer = DllCall("User32.dll", "int", "SetTimer", _
"hwnd", 0, "int", TimerInit(), "int", 50, "ptr", DllCallbackGetPtr($hCallBack))
EndIf

If $iCrntPrgrs > 0 Then
If $hCallBack > 0 Then DllCallBackFree($hCallBack)
DllCall("user32.dll", "int", "KillTimer", "hwnd", 0, "int", $ahTimer[0])

$hCallBack = 0
$ahTimer = 0

GUICtrlSetData($aProgress_Ctrls[4], $iCrntPrgrs)
EndIf

GUICtrlSetData($aProgress_Ctrls[3], $sCrntPrgs_Data)
GUICtrlSetData($aProgress_Ctrls[5], $sMPrgrs_Data & $iMPrgrs & "%")

If $sMain_Data <> "" Then GUICtrlSetData($aProgress_Ctrls[2], $sMain_Data)
EndFunc

Func _Progress_ShutDown()
If $hCallBack > 0 Then DllCallBackFree($hCallBack)
If IsArray($ahTimer) Then DllCall("user32.dll", "int", "KillTimer", "hwnd", 0, "int", $ahTimer[0])

$hCallBack = 0
$ahTimer = 0

GUIDelete($aProgress_Ctrls[1])
EndFunc

Func _Callback_ProgressSet_Proc($hWnd, $iIDEvent, $iElapse, $pTimerFunc)
$iProgress_InitSet += 5
If $iProgress_InitSet > 100 Then $iProgress_InitSet = 0

GUICtrlSetData($aProgress_Ctrls[4], $iProgress_InitSet)
EndFunc

Вместо пауз, естественно нужно использовать запуск приложении и прочую обработку.

mr.Zorg
24-03-2009, 02:05
Уууу... Это выше моего понимания:(
Попрошу совсем убрать Main Progress. А Working Progress пусть бегает тут

_Progress_Initialize()
_Progress_Set(0)
Sleep(5000)
_progress_ShutDown()

Creat0R
24-03-2009, 10:34
Попрошу совсем убрать Main Progress »
Тогда такая "каша" не нужна, можно и проще:

Global $hCallBack = 0, $ahTimer = 0
Global $iProgress_InitSet = 0
Global $sProgress_Title = "Installation Progress"
Global $sProgress_SubText = "Working Progress: %i%%"
Global $sProgress_MainText = "Please wait..."

_Progress_Initialize()

Sleep(5000)

_Progress_ShutDown()

Func _Progress_Initialize()
;Если callback-функция уже запущена (см. комменты далее), нет смысла продолжать далее (Return = выход из функции).
If $hCallBack <> 0 Then Return

;Включаем диалог прогресса
ProgressOn($sProgress_Title, $sProgress_MainText, $sProgress_SubText, -1, -1, 16)

;Регистрируем callback-функцию для запуска по таймеру
$hCallBack = DllCallbackRegister("_Callback_ProgressSet_Proc", "int", "hwnd;int;int;dword")

;Запускаем таймер - каждые 50 мс будет вызываться ранее зарегистрированная функция (_Callback_ProgressSet_Proc)
$ahTimer = DllCall("User32.dll", "int", "SetTimer", _
"hwnd", 0, "int", TimerInit(), "int", 50, "ptr", DllCallbackGetPtr($hCallBack))
EndFunc

Func _Progress_ShutDown()
;Если callback-функция запущена, высвобождаем её (останавливаем её выполнение)
If $hCallBack > 0 Then DllCallbackFree($hCallBack)
If IsArray($ahTimer) Then DllCall("user32.dll", "int", "KillTimer", "hwnd", 0, "int", $ahTimer[0])

;Выключаем диалог прогресса
ProgressOff()

;Обнуляем переменные callback-функции
$hCallBack = 0
$ahTimer = 0
EndFunc

;Это и есть callback-функция
Func _Callback_ProgressSet_Proc($hWnd, $iIDEvent, $iElapse, $pTimerFunc)
;Прибавляем 2 к главному счётчику (для прогресса)
$iProgress_InitSet += 2

;Если счётчик перевалил за 100, обнуляем его, чтобы прогрес работал с начала.
If $iProgress_InitSet > 100 Then $iProgress_InitSet = 0

;Задаём текузий прогресс
ProgressSet($iProgress_InitSet, StringFormat($sProgress_SubText, $iProgress_InitSet))
EndFunc

mr.Zorg
24-03-2009, 21:15
Премного благодарен :bow:
Подогнал под свой скрипт. Всё работает
Еще хотелось бы понять принцип работы данного скрипта. С DllCall до селе дела не имел. Если вас не затруднит, опишите построчно "человеческим языком" функции _Progress_Initialize и _Callback_ProgressSet_Proc

Creat0R
24-03-2009, 23:18
опишите построчно "человеческим языком" функции _Progress_Initialize и _Callback_ProgressSet_Proc »

Добавил комментарии в свой скрипт выше.

Премного благодарен »
Благодарности можно выражать нажатием на ссылку «Полезное сообщение» под тем самым сообщением за которое хочется выразить благодарность :)




© OSzone.net 2001-2012