Немодальный диалог

Место, где разработчики плагинов могут поделиться своим опытом.
User avatar
John Doe
Бюрократ
Posts: 11981
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 136 times

Немодальный диалог

Post by John Doe » Mon 21 May, 2018 17:22

Latest post of the previous page:

@2useven10

Code: Select all

zg 17.10.2014 04:06:40 +0200 - build 4138

1. ACTL_GETWINDOWINFO возвращает все окна в порядке текущего z-order'а.
Текущее окно имеет максимальный индекс, окно под ним на единицу меньше.

Не документировано, но пока так.

2useven10
Posts: 3622
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 3 times
Been thanked: 143 times

Немодальный диалог

Post by 2useven10 » Mon 21 May, 2018 18:36

Т.е. фактически actl(SETCURRENTWINDOW, actl(GETWINDOWCOUNT) - 2)
Вроде работает, но хотелось бы всё-таки сертифицированный способ...

User avatar
zg
zero-gravity
Posts: 5508
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 73 times
Contact:

Немодальный диалог

Post by zg » Mon 21 May, 2018 20:40

а чем этот несертифицированный?

2useven10
Posts: 3622
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 3 times
Been thanked: 143 times

Немодальный диалог

Post by 2useven10 » Mon 21 May, 2018 21:00

Тем что такой порядок окон упоминается только в changelog.

buniak_a_h
Posts: 592
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 59 times
Been thanked: 13 times
Contact:

Немодальный диалог

Post by buniak_a_h » Tue 06 Nov, 2018 08:15

John Doe wrote:
Sat 30 Sep, 2017 09:24
Сомневаюсь что должно.

Code: Select all

--здесь был Ваш пример
Тут то же самое, без DM_REDRAW не отображается.
Я попробовал добавить в диалог элемент, который может получать фокус (конкретно - кнопку). Но, как выяснилось, диалог не получает событий от мыши и клавиатуры, пока не закончится цикл. Более того! ФАР, похоже, не получает прерываний (как если бы цикл выполнялся в главном потоке). А как организовать "фоновое"выполнение цикла? Надо делать coroutine и т.д.?
Посмотрите, пожалуйста, слегка усложненный диалог. Всё бы хорошо, но пока цикл не кончится, он ни на что не реагирует

просто если диалог нужен только для отображения информации, то вполне достаточно было бы использовать far.Text (например, в процедуре копирования файлов я именно так и выводил прогресс)
Last edited by buniak_a_h on Tue 06 Nov, 2018 08:31, edited 1 time in total.

User avatar
John Doe
Бюрократ
Posts: 11981
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 136 times

Немодальный диалог

Post by John Doe » Tue 06 Nov, 2018 09:19

buniak_a_h, вы неправильно тестируете, и соответственно делаете преждевременные выводы.
Для начала стоит посмотреть вызывается ли обработчик, и с какими параметрами.
Для этого удобно использовать win.OutputDebugString.

В конкретном данном случае вы ошиблись с параметрами функции-обработчика, должно быть так: https://api.farmanager.com/ru/defs/dlgproc.html

User avatar
John Doe
Бюрократ
Posts: 11981
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 136 times

Немодальный диалог

Post by John Doe » Tue 06 Nov, 2018 09:25

P.S.
Но я и сам кое-что не понял: почему-то первые 15 раз обработчик вызывается с закрытым дескриптором в качестве первого параметра: FarDialog (closed).

https://bugs.farmanager.com/view.php?id=3669
Last edited by John Doe on Wed 07 Nov, 2018 09:22, edited 1 time in total.

buniak_a_h
Posts: 592
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 59 times
Been thanked: 13 times
Contact:

Немодальный диалог

Post by buniak_a_h » Tue 06 Nov, 2018 13:36

John Doe wrote:
Tue 06 Nov, 2018 09:19
buniak_a_h, вы неправильно тестируете, и соответственно делаете преждевременные выводы.
Для начала стоит посмотреть вызывается ли обработчик, и с какими параметрами.
Для этого удобно использовать win.OutputDebugString.

В конкретном данном случае вы ошиблись с параметрами функции-обработчика, должно быть так: https://api.farmanager.com/ru/defs/dlgproc.html
1. Обработчик вызывается. Проверено в немодальном варианте
2. Можно в списке аргументов указать трижды _,, но на работу это не повлияет - проверено в другом скрипте.
3. Просто уберите обработчик и попробуйте переключиться на другое окно (Ctrl+Tab). Пока цикл не закончится, у Вас это не получится.
  1. local id = win.Uuid"45B09D0D-6AE8-416C-BB5A-F5FA7B5CC430"
  2. local F = far.Flags
  3. local cont=true -- BAX - признак активности диалога
  4. local function Progress(text,title)
  5.   local len = math.max(10,text:len()+2)
  6.   local items = {
  7.     --[[01]]  {F.DI_SINGLEBOX,0,0,len,4,0,0,0,0,title},
  8.     --[[02]]  {F.DI_TEXT,     1,1,0,0,0,0,0,"DIF_CENTERGROUP",text},
  9.               {"DI_BUTTON", -1,2,-1,2,0,0,0,"DIF_CENTERGROUP",'Ok'} -- BAX, добавлена кнопка
  10.   }
  11.   local flags = F.FDLG_NONMODAL
  12.   return far.DialogInit(id,-1,-1,len,4,len,items,flags)
  13. end
  14.  
  15. local hDlg = Progress("  ")
  16. for i=1,20 do
  17.   --hDlg:send"DM_REDRAW"
  18.   if not cont then break end -- BAX, проверка, надо ли снимать цикл
  19.   win.Sleep(500)
  20.   hDlg:send("DM_SETTEXT",2,i)
  21. end
  22. if cont then hDlg:send("DM_CLOSE") end -- BAX закрытие диалога по окончании цикла, если он сам не закрылся ACTL_SYNCHRO
Так что дело не в обработчике - 100%

User avatar
John Doe
Бюрократ
Posts: 11981
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 136 times

Немодальный диалог

Post by John Doe » Tue 06 Nov, 2018 13:59

buniak_a_h wrote:
Tue 06 Nov, 2018 13:36
Так что дело не в обработчике - 100%
В нём тоже:

Code: Select all

  local function DlgProc(hDlg,Msg,Param1,Param2) -- JD: правильные аргументы
   if Msg==F.DN_CLOSE then cont=false end -- BAX, при закрытии диалога выставляю признак, что цикл можно снимать
  end
  return far.DialogInit(id,-1,-1,len,4,len,items,flags, DlgProc)
end
А цикл в отдельном потоке, по ACTL_SYNCHRO:

Code: Select all

local hDlg = Progress("  ")
local i = 1
far.Timer(500,function(t)
  i = i+1
  if not cont or i>20 then t:Close(); return end
  hDlg:send("DM_SETTEXT",2,i)
end)
Last edited by John Doe on Tue 06 Nov, 2018 14:35, edited 1 time in total.

buniak_a_h
Posts: 592
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 59 times
Been thanked: 13 times
Contact:

Немодальный диалог

Post by buniak_a_h » Tue 06 Nov, 2018 14:18

John Doe wrote:
Tue 06 Nov, 2018 13:59
В нём тоже:
Вы пробовали?
1. До окончания цикла DN_BTNCLICK не приходит обработчику
2. Добавление "правильных" параметров не исправляет ситуацию
3. Можете обработчик просто убрать - даже в этом случае управление ФАР не получит. Ни на другое окно не переключиться, ни диалог закрыть.
John Doe wrote:
Tue 06 Nov, 2018 13:59
А цикл в отдельном потоке, по ACTL_SYNCHRO:
Спасибо, попробую...
А где можно почитать про классы? В мануале по LeaFar написано:
timer = far.Timer (interval, handler [, ...])
Returns:
timer : userdata (timer object), or nil
У timer object-а, видимо, должен быть метод типа Free() ? Ведь надо как-то его останавливать после закрывания диалога...

User avatar
John Doe
Бюрократ
Posts: 11981
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 136 times

Немодальный диалог

Post by John Doe » Tue 06 Nov, 2018 14:26

buniak_a_h wrote:
Tue 06 Nov, 2018 14:18
Вы пробовали?
Разумеется.
Замените ваш код моим и всё.
buniak_a_h wrote:
Tue 06 Nov, 2018 14:18
В мануале упомянут timer:Close(), но это не ответ. Хотелось бы описание типа с перечислением доступных методов и пропертей...
В мануале всё есть.

User avatar
John Doe
Бюрократ
Posts: 11981
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 136 times

Немодальный диалог

Post by John Doe » Tue 06 Nov, 2018 14:31

John Doe wrote:
Tue 06 Nov, 2018 14:26
Замените ваш код моим и всё.
Поправка: этого достаточно для демонстрации, что желаемое вами достижимо, но не гарантирую, что код полный.

buniak_a_h
Posts: 592
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 59 times
Been thanked: 13 times
Contact:

Немодальный диалог

Post by buniak_a_h » Tue 06 Nov, 2018 14:37

John Doe wrote:
Tue 06 Nov, 2018 14:26
buniak_a_h писал(а): ↑Вт 06 ноя, 2018 16:18
Вы пробовали?
Разумеется.
Замените ваш код моим и всё.
Заменил. (обработчик, не far.Timer!) Есессно, ничего не заработало.
Если ФАР висит без обработчика, то исправление ошибок в нём на результат не влияет. Чудес не бывает...

User avatar
John Doe
Бюрократ
Posts: 11981
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 26 times
Been thanked: 136 times

Немодальный диалог

Post by John Doe » Tue 06 Nov, 2018 14:42

John Doe wrote:
Tue 06 Nov, 2018 13:59
А цикл в отдельном потоке, по ACTL_SYNCHRO:
Из этого разве не следует что вы должны заменить и свой цикл моим таймером?

Update
Вот чуть причёсанный вариант:

Code: Select all

local id = win.Uuid"45B09D0D-6AE8-416C-BB5A-F5FA7B5CC430"
local F = far.Flags
local timer
local function Progress(text,title)
  local len = math.max(10,text:len()+2)
  local items = {
    --[[01]]  {F.DI_SINGLEBOX,0,0,len,4,0,0,0,0,title},
    --[[02]]  {F.DI_TEXT,     1,1,0,0,0,0,0,F.DIF_CENTERGROUP,text},
    --[[03]]  {F.DI_BUTTON, -1,2,-1,2,0,0,0,F.DIF_CENTERGROUP,"Ok"},
  }
  local flags = F.FDLG_NONMODAL
  return far.DialogInit(id,-1,-1,len,4,len,items,flags,function(hDlg,Msg)
    if Msg==F.DN_CLOSE then timer:Close() end
  end)
end
 
local hDlg = Progress("  ")
local i = 0
timer = far.Timer(500,function(t)
  i = i+1
  if i>20 then t:Close(); return end
  hDlg:send(F.DM_SETTEXT,2,i)
end)
Last edited by John Doe on Tue 06 Nov, 2018 16:36, edited 2 times in total.

buniak_a_h
Posts: 592
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 59 times
Been thanked: 13 times
Contact:

Немодальный диалог

Post by buniak_a_h » Tue 06 Nov, 2018 17:17

John Doe wrote:
Tue 06 Nov, 2018 14:42
з этого разве не следует что вы должны заменить свой цикл моим таймером?
Я же про обработчик писал, что он не влияет. А что таймер поможет - я просто тогда не пробовал.
Теперь попробовал. работает, спасибо.

Post Reply

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