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

Место, где разработчики плагинов могут поделиться своим опытом.
Post Reply
IlyaK
Posts: 5
Joined: Thu 28 Jun, 2018 13:29

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

Post by IlyaK »

Добрый день,

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

Но может быть есть менее болезненное решение?
User avatar
HaRT
Moderator
Posts: 10806
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 220 times
Been thanked: 357 times

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

Post by HaRT »

Есть какой-то стандартный способ, при котором прогресс ещё и на кнопке в таскбаре отображается.
Но я плагины не пишу, поэтому конкретнее сказать не могу. Пусть лучше специалисты ответят.
Фар есть инструмент, а не нянька. © 2009 DrKnS
IlyaK
Posts: 5
Joined: Thu 28 Jun, 2018 13:29

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

Post by IlyaK »

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

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

Post by IlyaK »

В смысле разве он рисует что-то на экране фара?
User avatar
HaRT
Moderator
Posts: 10806
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 220 times
Been thanked: 357 times

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

Post by HaRT »

IlyaK wrote: Thu 28 Jun, 2018 13:55 разве он рисует что-то на экране фара?
Понятия не имею. При большом желании можно в коде имеющихся плагинов посмотреть, как они делают прогресс/ отмену/ таймаут и пр., — например, в NetBox. Насколько оно там хорошо сделано, не имею представления.
Фар есть инструмент, а не нянька. © 2009 DrKnS
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post by Shmuel »

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

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

Post by IlyaK »

Имеется ввиду другой поток (CreateThread). Оно работает конечно, но мысль слать DMP_SETTEXT из другого потока мне не нравится (сегодня работает, завтра нет).

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

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

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

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

А у Message разве handle есть? Как ей что-то послать?
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post 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 эта функция не создаёт окно, а просто рисует на экране. Вы просто вызываете её каждый раз с новыми данными, она рисует новое окошко поверх старого.
User avatar
HaRT
Moderator
Posts: 10806
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 220 times
Been thanked: 357 times

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

Post by HaRT »

Shmuel wrote: Thu 28 Jun, 2018 14:31 не создаёт окно, а просто рисует на экране
А как при таком подходе рекомендуется реализовывать досрочную отмену операции пользователем (Cancel)?
Фар есть инструмент, а не нянька. © 2009 DrKnS
IlyaK
Posts: 5
Joined: Thu 28 Jun, 2018 13:29

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

Post by IlyaK »

Спасибо вам огромное, все получилось:

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


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


Про message попробую, спасибо.
User avatar
zg
zero-gravity
Posts: 6015
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 185 times
Contact:

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

Post by zg »

IlyaK wrote: Thu 28 Jun, 2018 14:16Смотрите:
main: создает диалог и передает его handle в CreateProcess (handle же просто int)
background: качает что мне нужно переодически с помощью ProcessSynchroEventW вызывает код который шлет DM_SETTEXT
это самый правильный вариант.
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

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

Post by Shmuel »

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

Return to “Разработка плагинов”