Валидность хэндлов диалогов

Здесь обсуждается всё, что касается макросов.
Post Reply
User avatar
John Doe
Бюрократ
Posts: 13862
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 74 times
Been thanked: 428 times
Contact:

Валидность хэндлов диалогов

Post by John Doe »

Дано:
  1. local F = far.Flags
  2.  
  3. Event { group="DialogEvent";
  4.  
  5.   condition=function(Event,param)
  6.  
  7.     return Event==F.DE_DLGPROCEND and param.Msg==F.DN_INITDIALOG
  8.  
  9.   end;
  10.  
  11.   action=function(Event,param)
  12.  
  13.     mf.postmacro(function()
  14.  
  15.       far.SendDlgMessage (param.hDlg, F.DM_LISTGETTITLES)
  16.  
  17.     end);
  18.  
  19.   end;
  20.  
  21. }
В командной строке запускаем lm:post Keys "F9 c a" (язык интерфейса английский, должен открыться список ассоциаций)
В результате плагин падает.
Shmuel
Posts: 6840
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Re: LuaMacro — Lua как язык макросов

Post by Shmuel »

John Doe wrote:В результате плагин падает.
По всей видимости, param.hDlg валиден только на время обработки события (это предположение, не утверждение). Прямой вызов far.SendDlgMessage, то-есть производимый до выхода из ф-ции обработчика, к падению не приводит. А вызов mf.postmacro приводит к отложенному вызову far.SendDlgMessage, производимому уже после выхода из ф-ции обработчика. Никто не гарантировал, что param.hDlg будет валиден и после выхода из ф-ции обработчика.

Если вместо mf.postmacro использовать far.Timer - результат тот же - падение.
User avatar
John Doe
Бюрократ
Posts: 13862
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 74 times
Been thanked: 428 times
Contact:

Re: LuaMacro — Lua как язык макросов

Post by John Doe »

Shmuel wrote:По всей видимости, param.hDlg валиден только на время обработки события (это предположение, не утверждение).
Проблема не возникает в других меню кроме File associations
Для воспроизведения обязательно использовать макрос lm:post
Во всех прочих случаях проблем с param.hDlg нет.

В случае если param.hDlg не валиден, то хотелось бы тоже обойтись без падений.
Shmuel
Posts: 6840
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Re: LuaMacro — Lua как язык макросов

Post by Shmuel »

John Doe wrote:Проблема не возникает в других меню кроме File associations
Для воспроизведения обязательно использовать макрос lm:post
Во всех прочих случаях проблем с param.hDlg нет.
Возникает и при вызове макросом диалога LF History. Думаю, найдутся и другие примеры.
Помещайте на мантис. Или исследуйте сами до победного конца.
User avatar
John Doe
Бюрократ
Posts: 13862
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 74 times
Been thanked: 428 times
Contact:

Re: LuaMacro — Lua как язык макросов

Post by John Doe »

Если поместить в тот обработчик вот эти строки, то легко определить, что проблема действительно связана с изменением хэндла:

Code: Select all

      local hDlg = far.AdvControl(F.ACTL_GETWINDOWINFO).Id
      if hDlg ~= param.hDlg then mf.beep() end
Видно что в большинстве случаев хэндл не меняется (меняется только в случае когда меню открывается посредством lm:post)
User avatar
John Doe
Бюрократ
Posts: 13862
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 74 times
Been thanked: 428 times
Contact:

Re: LuaMacro — Lua как язык макросов

Post by John Doe »

Shmuel wrote:По всей видимости, param.hDlg валиден только на время обработки события
Ранее в параллельной теме писалось что хэндл это адрес диалога в памяти.
Непонятно как адрес уже открытого диалога может меняться с ходом времени.
User avatar
zg
zero-gravity
Posts: 6036
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 185 times
Contact:

Re: LuaMacro — Lua как язык макросов

Post by zg »

John Doe wrote:Ранее[/url] в параллельной теме писалось что хэндл это адрес диалога в памяти.
Непонятно как адрес уже открытого диалога может меняться с ходом времени.
во время выполнения макроса "f9 c a" появляется 2 диалога. первый — выпадающее меню. mf.postmacro — асинхронна и к моменту её выполнения, первого диалога уже нет.
User avatar
John Doe
Бюрократ
Posts: 13862
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 74 times
Been thanked: 428 times
Contact:

Re: LuaMacro — Lua как язык макросов

Post by John Doe »

Действительно.
Осталось выяснить можно ли как-то избежать падения при попытке использования неверного hDlg?

Update
http://bugs.farmanager.com/view.php?id=2614
Shmuel
Posts: 6840
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Re: LuaMacro — Lua как язык макросов

Post by Shmuel »

John Doe wrote:Осталось выяснить можно ли как-то избежать падения при попытке использования неверного hDlg?
Например, Фар может поддерживать список хэндлов незакрытых диалогов. При каждом вызове SendDlgMessage, проверять, находится ли переданный хэндл в списке.
User avatar
zg
zero-gravity
Posts: 6036
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 185 times
Contact:

Re: LuaMacro — Lua как язык макросов

Post by zg »

John Doe wrote:Действительно.
Осталось выяснить можно ли как-то избежать падения при попытке использования неверного hDlg?
  1. function IsDlgValid(hdlg)
  2.  
  3.   local wincount=far.AdvControl(F.ACTL_GETWINDOWCOUNT,0,0)
  4.  
  5.   for ii=1,wincount do
  6.  
  7.     local info=far.AdvControl(F.ACTL_GETWINDOWINFO,ii,0)
  8.  
  9.     if info and F.WTYPE_DIALOG==info.Type and hdlg==info.Id then
  10.  
  11.       return true
  12.  
  13.     end
  14.  
  15.   end
  16.  
  17.   return false
  18.  
  19. end
Shmuel
Posts: 6840
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Re: LuaMacro — Lua как язык макросов

Post by Shmuel »

zg wrote:function IsDlgValid(hdlg)
Приведенная функция не учитывает диалоги, которые не являются окнами в данный момент, то-есть вызывалась функция DialogRun, но не вызывалась DialogFree.

Code: Select all

local items = {{"DI_EDIT",1,3,10,3, 0,0,0,0,"text"}}
local h = far.DialogInit ("",-1,-1,40,10,nil,items)
for k=1,3 do
  far.DialogRun(h)
  far.Message(IsDlgValid(h))
end
far.DialogFree(h)
Кроме того, ф-ция IsDlgValid не отвечает оригинальному запросу (предотвращение падения в случае, если скрипт всё-таки применил невалидный хэндл).
Post Reply

Return to “Обсуждение макросов”