Page 1 of 1

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 13:34
by IlyaK
Добрый день,

У меня плагин Panel, она умеет скачивать файл с удаленного сервера по своему протоколу. Процесс долгий, хочется показывать прогресс.
Я пока что вижу один вариант: создать диалог, взять его handle и из другого процесса слать ему сообщения (диалоги потокобезопасны, кстати?) чтобы он увеличивал прогресс. По заверешии послать месседж чтобы его закрыли.

Но может быть есть менее болезненное решение?

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 13:43
by HaRT
Есть какой-то стандартный способ, при котором прогресс ещё и на кнопке в таскбаре отображается.
Но я плагины не пишу, поэтому конкретнее сказать не могу. Пусть лучше специалисты ответят.

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 13:55
by IlyaK
Есть, через advanced functions, но он же только рисует прогресс на иконке в винде через API винды.
Разве он на фар влияет?

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 13:55
by IlyaK
В смысле разве он рисует что-то на экране фара?

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 14:00
by HaRT
IlyaK wrote:
Thu 28 Jun, 2018 13:55
разве он рисует что-то на экране фара?
Понятия не имею. При большом желании можно в коде имеющихся плагинов посмотреть, как они делают прогресс/ отмену/ таймаут и пр., — например, в NetBox. Насколько оно там хорошо сделано, не имею представления.

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 14:04
by Shmuel
IlyaK wrote:
Thu 28 Jun, 2018 13:34
создать диалог, взять его handle и из другого процесса слать ему сообщения (диалоги потокобезопасны, кстати?)
Из другого потока имеется в виду, или всё-таки процесса?
Ничего в Фаре не потокобезопасно. Для подобных ситуаций можно воспользоваться ACTL_SYNCHRO.
Диалог создавать не надо, обычная Message() без кнопок годится, обновляется по ACTL_SYNCHRO.

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 14:16
by IlyaK
Имеется ввиду другой поток (CreateThread). Оно работает конечно, но мысль слать DMP_SETTEXT из другого потока мне не нравится (сегодня работает, завтра нет).

Во! Спасибо за мыслю про ACTL_SYNCHRO!

Если я с помощью ProcessSynchroEventW буду переключаться в главный поток и оттуда слать DM_SETTEXT но все будет хорошо, верно?

Смотрите:
main: создает диалог и передает его handle в CreateProcess (handle же просто int)
background: качает что мне нужно переодически с помощью ProcessSynchroEventW вызывает код который шлет DM_SETTEXT

все будет нормально?

А у Message разве handle есть? Как ей что-то послать?

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 14:31
by Shmuel
IlyaK wrote:
Thu 28 Jun, 2018 14:16
Если я с помощью ProcessSynchroEventW буду переключаться в главный поток и оттуда слать DM_SETTEXT но все будет хорошо, верно?
ProcessSynchroEvent и так вызывается в главном потоке, переключаться не надо, надо просто использовать данные из её параметра.
IlyaK wrote:
Thu 28 Jun, 2018 14:16
А у Message разве handle есть? Как ей что-то послать?
При ButtonsNumber==0 эта функция не создаёт окно, а просто рисует на экране. Вы просто вызываете её каждый раз с новыми данными, она рисует новое окошко поверх старого.

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 14:33
by HaRT
Shmuel wrote:
Thu 28 Jun, 2018 14:31
не создаёт окно, а просто рисует на экране
А как при таком подходе рекомендуется реализовывать досрочную отмену операции пользователем (Cancel)?

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 14:39
by IlyaK
Спасибо вам огромное, все получилось:

фоновый поток:
xxx.AdvControl(&xx_guid, ACTL_SYNCHRO, 0, &my_data);


главный поток:
ProcessSynchroEventW(info)
где info->Param и есть указатель на мою my_data.


Про message попробую, спасибо.

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 14:44
by zg
IlyaK wrote:
Thu 28 Jun, 2018 14:16
Смотрите:
main: создает диалог и передает его handle в CreateProcess (handle же просто int)
background: качает что мне нужно переодически с помощью ProcessSynchroEventW вызывает код который шлет DM_SETTEXT
это самый правильный вариант.

Как лучше сделать индикатор прогресса для долгой операции?

Posted: Thu 28 Jun, 2018 14:46
by Shmuel
HaRT wrote:
Thu 28 Jun, 2018 14:33
А как при таком подходе рекомендуется реализовывать досрочную отмену операции пользователем (Cancel)?
Как рекомендуется - не знаю, я периодически (достаточно часто) делаю опрос нажатия клавиш, и при обнаружении Esc прерываю процесс (с запросом подтверждения от юзера, или без оного, в зависимости от ситуации).