Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Прогресс бар (http://forum.oszone.net/showthread.php?t=131949)

semiono 14-02-2009 05:22 1038016

Прогресс бар
 
Мне нужен прогресс бар чтоб запустить в начале кода, и к завершению чтоб он был 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 1038104

Цитата:

Цитата semiono
нужен прогресс бар »

А в справке пример не подходит?

semiono 14-02-2009 14:23 1038201

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

Creat0R 14-02-2009 14:49 1038225

Цитата:

Цитата semiono
мой пример самый нормальный, особенно если скрипт работает быстро »

Я тогда вообще не понял в чём проблема :dont-know .

semiono 14-02-2009 14:57 1038230

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

Creat0R 14-02-2009 22:56 1038600

Цитата:

Цитата semiono
Ну это вы с сарказмом так »

Как раз нет, я серъёзно не понимаю суть проблемы.

Цитата:

Цитата semiono
Прогресс бар должен отображать ход работы »

В справке разве это не происходит, тогда вот ещё пример:

Код:

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("Заголовок"))

Цитата:

Цитата semiono
что-то вы не в духе сегодня »

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


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

semiono 15-02-2009 11:23 1038907

Изначально хотел назвать, типа графическое оформление, что и было почти, но думаю на одном таск баре и остановимся.
Цитата:

Цитата Creat0R
В справке разве это не происходит, »

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

Creat0R 15-02-2009 12:02 1038940

Цитата:

Цитата semiono
я ожидал что ProgressOn(), будет сам всю работу обеспечивать »

Тогда у меня есть для вас новость. В других языках программирования, всё намного сложнее, там ВСЁ нужно самому делать (если не брать в счёт готовые библиотеки), в AutoIt' же, многие задачи реализованы уже за нас, вшиты в ядро языка.

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

Creat0R 15-02-2009 12:22 1038952

Тогда вот так например:

Код:

#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 1038995

Цитата:

Цитата Creat0R
Мне просто интересно, как функция будет знать сколько устанавливать прогресс? »

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

Сегодня у чувака подпись увидел, прямо в тему :)))
Цитата:

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

Creat0R 16-02-2009 00:33 1039613

Цитата:

Цитата semiono
Надо чтобы функция рисовала прогресс от слова ProgressOn до слоава ProgressOff »

Так а в чём проблема?

Цитата:

Цитата semiono
Это только в lowlevel code language надо всё вручную собирать »

Это откуда такая информация? :)

semiono 16-02-2009 12:31 1039969

Цитата:

Цитата Creat0R
Это откуда такая информация? »

Ну под 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 1072724

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

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

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

Creat0R 24-03-2009 01:28 1072761

Цитата:

Цитата mr.Zorg
как индикатор работы »

Можно так:

Код:

#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 1072773

Уууу... Это выше моего понимания:(
Попрошу совсем убрать Main Progress. А Working Progress пусть бегает тут
Код:

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


Creat0R 24-03-2009 10:34 1072987

Цитата:

Цитата mr.Zorg
Попрошу совсем убрать 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 1073678

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

Creat0R 24-03-2009 23:18 1073776

Цитата:

Цитата mr.Zorg
опишите построчно "человеческим языком" функции _Progress_Initialize и _Callback_ProgressSet_Proc »

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

Цитата:

Цитата mr.Zorg
Премного благодарен »

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


Время: 07:57.

Время: 07:57.
© OSzone.net 2001-