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

Место, где разработчики плагинов могут поделиться своим опытом.
User avatar
zg
zero-gravity
Posts: 5507
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 73 times
Contact:

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

Post by zg » Fri 29 Sep, 2017 10:53

Latest post of the previous page:

причём тут вообще DN_CLOSE? у меня всё правильно написано.

User avatar
NightRoman
Posts: 5909
Joined: Fri 18 Aug, 2006 13:52
Location: Cambridge, UK
Has thanked: 10 times
Been thanked: 11 times
Contact:

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

Post by NightRoman » Fri 29 Sep, 2017 10:57

zg wrote:
Fri 29 Sep, 2017 09:54
на DN_CONTROLINPUT с param1==-1 вернуть true.
Частично помогает, это предотвращает закрытие. Но это буквально команда Фару "я обработал, ничего не делай", а ведь хотелось бы переключения в другое окно в данном новом случае.

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

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

Post by zg » Fri 29 Sep, 2017 11:07

NightRoman wrote:
Fri 29 Sep, 2017 10:57
Частично помогает, это предотвращает закрытие. Но это буквально команда Фару "я обработал, ничего не делай", а ведь хотелось бы переключения в другое окно в данном новом случае.
1. ACTL_SETCURRENTWINDOW вроде никто не запрещает использовать.
2. это не новый случай. немодальные окна не во весь экран есть в фаре очень-очень давно. хотите чтобы переключалось мышкой, пишите вишь на мантис.

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

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

Post by John Doe » Fri 29 Sep, 2017 11:19

Ещё надо записать:
В случае немодального диалога очень уместен индикатор фоновых экранов, тот что в левом верхнем углу, тот из которого убрали диалоги в 4824. Оказывается уже.
Обработка клавиш типа AltF11 (наверно и других, в зависимости от контекста)

(это я для себя)
Last edited by John Doe on Fri 29 Sep, 2017 11:42, edited 1 time in total.

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

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

Post by zg » Fri 29 Sep, 2017 11:32

John Doe wrote:
Fri 29 Sep, 2017 11:19
Туда же надо записать:
Обработка клавиш типа AltF11 (наверно и других, в зависимости от контекста)
ну вот почему туда же? вот клик вне немодального окна. это же общее отсутствие функциональности. оно и к диалогам относится, и к редакторам, и к просмотрам. altf11 — только к диалогам. зачем всё смешивать?
John Doe wrote:
Fri 29 Sep, 2017 11:19
В случае немодального диалога очень уместен индикатор фоновых экранов, тот что в левом верхнем углу, тот из которого убрали диалоги в 4824.
[?] Show background screens number

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

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

Post by John Doe » Fri 29 Sep, 2017 11:39

zg wrote:
Fri 29 Sep, 2017 11:32
зачем всё смешивать?
"Туда же" это на мантис.
Я уже сам заметил двусмысленность, и исправил пост.

Update
0003518: Клик за пределами (немодального) окна
0003520: Индикатор фоновых экранов (для диалогов)
Last edited by John Doe on Sun 08 Oct, 2017 17:21, edited 1 time in total.

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

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

Post by John Doe » Fri 29 Sep, 2017 11:50

Code: Select all

local id = win.Uuid"45B09D0D-6AE8-416C-BB5A-F5FA7B5CC430"
local F = far.Flags
local items = {
  --[[01]]  {F.DI_TEXT,1,1,0,0,0,0,0,0,"test"},

}
local flags = "FDLG_NONMODAL"
hDlg = far.DialogInit (id,-1,-1,6,3,HelpTopic,items,flags,function(hDlg,Msg,Param1,Param2)
  if Msg==F.DN_CONTROLINPUT and Param1==-1 then
    local wi = far.AdvControl(F.ACTL_GETWINDOWINFO)
    far.AdvControl(F.ACTL_SETCURRENTWINDOW,wi.Pos-1)
    return 1
  end
  return
end)
Кликаю за пределами диалога.
Жму F12, возвращаюсь в диалог.
Теперь любое движение мыши вызывает уход диалога в фон (срабатывает обработчик).

Если исхитриться и кликнуть в диалоге, то эффект пропадает.

И падает периодически, последовательность ещё не нашёл.

Code: Select all

╔══════════════════════════ Exception occurred ══════════════════════════╗
║ Exception:   Access violation (write to 0x01AAAB40)                    ║
║ Address:     0x66F935FB lua_pushlightuserdata                          ║
║ Function:    main                                                      ║
║ Module:      C:\APPs\Far3\Far.exe                                      ║
╟────────────────────────────────────────────────────────────────────────╢
║          { Terminate Far } [ Stack ] [ Minidump ] [ Ignore ]           ║
╚════════════════════════════════════════════════════════════════════════╝
(Стек будет когда скачаю pdb)
Last edited by John Doe on Fri 29 Sep, 2017 12:10, edited 1 time in total.

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

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

Post by zg » Fri 29 Sep, 2017 12:20

проверяли бы для начала на обычном диалоге:

Code: Select all

local id = win.Uuid"45B09D0D-6AE8-416C-BB5A-F5FA7B5CC430"
local F = far.Flags
local items = {
  --[[01]]  {F.DI_TEXT,1,1,0,0,0,0,0,0,"test"},

}
local flags = 0
hDlg = far.DialogInit (id,-1,-1,6,3,HelpTopic,items,0,function(hDlg,Msg,Param1,Param2)
  if Msg==F.DN_CONTROLINPUT and Param1==-1 then
    local wi = far.AdvControl(F.ACTL_GETWINDOWINFO)
    far.Show('hit')
    return 1
  end
  return
end)
far.DialogRun(hDlg)
far.DialogFree(hDlg)
всё то же самое.

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

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

Post by John Doe » Fri 29 Sep, 2017 12:41

>(Стек будет когда скачаю pdb)
В стеке ничего не показывает всё равно.

Минимальную последовательность воспроизведения не скажу, но вот такая есть.

Code: Select all

far.exe /p%FARHOME%\Plugins /m
Запускаю вышеприведённый макрос из файла

Code: Select all

lua:@crash.lua
Далее играюсь с диалогом, увожу его в фон, и некоторое время фар не трогаю (или работаю с другой копией).

В итоге фар или сам падает, или после того как я вернусь в него и нажму CtrlTab.

Edit
Есть и минимальная последовательность.

Code: Select all

CtrlTab
lua:collectgarbage()
CtrlTab
Если не упал сразу, то повторить.
Last edited by John Doe on Fri 29 Sep, 2017 12:51, edited 1 time in total.

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

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

Post by zg » Fri 29 Sep, 2017 14:02

если эту закомментировать строку, то у меня падать перестаёт. насколько я понимаю (возможно не совсем правильно), loadfile загружает файл с новым lua_State, который сохраняется в dd->L и который же уничтожается при завершении файла. т.е. диалоговая процедура использует невалидную lua_State. но опять же, никто нам не мешает в файле создать диалог, присвоить его глобальной переменной, а уже из командной строки сделать lua:collectgarbage() и lua:far.DialogRun(...). у меня имевшийся под рукой far 4937 — упал.
в общем в дискуссию призывается Shmuel, для разъяснения для чего вообще эта странная магия с сохранением состояния в диалоге нужна.
Last edited by zg on Fri 29 Sep, 2017 14:04, edited 1 time in total.

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

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

Post by John Doe » Fri 29 Sep, 2017 20:36

Code: Select all

   DialogRun и DialogFree для такого диалога указывать не нужно. при закрытии диалог автоматически уничтожается.
Хочу прояснить для себя пару моментов (возможно упустил что-то из документации).
  1. Будет ли ошибкой после закрытия диалога попытаться использовать SendDlgMessage?
  2. Есть ли возможность узнать о том, что диалог закрыт?
    (Можно конечно в обработчике диалога устанавливать при этом флаг, но это довольно неудобно)
P.S.
Моя цель — управлять диалогом снаружи. В том числе и из far.Timer()
Last edited by John Doe on Fri 29 Sep, 2017 20:38, edited 1 time in total.

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

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

Post by zg » Fri 29 Sep, 2017 20:57

John Doe wrote:
Fri 29 Sep, 2017 20:36
Будет ли ошибкой после закрытия диалога попытаться использовать SendDlgMessage?
будет то же, что SendDlgMessage для обычного диалога, которому сделали DialogFree.
John Doe wrote:
Fri 29 Sep, 2017 20:36
Есть ли возможность узнать о том, что диалог закрыт?
проверить наличие в списке окон.

User avatar
NightRoman
Posts: 5909
Joined: Fri 18 Aug, 2006 13:52
Location: Cambridge, UK
Has thanked: 10 times
Been thanked: 11 times
Contact:

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

Post by NightRoman » Fri 29 Sep, 2017 21:04

Как задать некоторые процедуры, которые выполнятся после положительного (ОК, Enter) и отрицательного (Esc, click outside) закрытия диалога? Или одну процедуру, но с параметром (как в DN_CLOSE). В настоящее время все, что приходит в голову, это само событие DN_CLOSE. С ним нет никаких проблем, кроме одной, диалог-то еще не закрыт, а это может быть нежелательно для продолжения работы с полученным результатом диалога.

Если ничего такого нет, то хотелось бы иметь некий пост-DN_CLOSE с хендлом диалога (уже невалидным, диалога больше нет, но знать-то надо для какого именно бывшего диалога это вызывается) и индексом контрола (результат закрытия).

User avatar
NightRoman
Posts: 5909
Joined: Fri 18 Aug, 2006 13:52
Location: Cambridge, UK
Has thanked: 10 times
Been thanked: 11 times
Contact:

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

Post by NightRoman » Fri 29 Sep, 2017 21:15

Еще лучше было бы, если такой пост-DN_CLOSE вызывался с уже закрытым (не виден, убран из списков окон), но еще не разрушенным диалогом, чтобы можно было получить текущие данные). Жить без этого, впрочем, можно, в DN_CLOSE надо сохранить данные еще живого диалога на потом. Но вот без самого пост-DN_CLOSE (с убитым или живым диалогом, неважно) непонятно пока, как быть.

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

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

Post by John Doe » Fri 29 Sep, 2017 21:21

zg wrote:
Fri 29 Sep, 2017 20:57
John Doe wrote:
Fri 29 Sep, 2017 20:36
Будет ли ошибкой после закрытия диалога попытаться использовать SendDlgMessage?
будет то же, что SendDlgMessage для обычного диалога, которому сделали DialogFree.
Что если (по дополнительному флагу) не освобождать диалог, а требовать явного DialogFree?
zg wrote:
Fri 29 Sep, 2017 20:57
John Doe wrote:
Fri 29 Sep, 2017 20:36
Есть ли возможность узнать о том, что диалог закрыт?
проверить наличие в списке окон.
Это ещё более громозко, чем установка флага в обработчике диалога..
Имеет ли шанс виш на мантисе о функции проверки валидности хэндла?

User avatar
NightRoman
Posts: 5909
Joined: Fri 18 Aug, 2006 13:52
Location: Cambridge, UK
Has thanked: 10 times
Been thanked: 11 times
Contact:

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

Post by NightRoman » Sat 30 Sep, 2017 07:59

В примере ниже (PowerShellFar) немодальный диалог используется для показа прогресса. Работает. Но приходится вызывать
ACTL_REDRAWALL ($Far.UI.Redraw()), иначе диалог не отрисовывается, ни при открытии, ни при обновлении данных. Так и должно быть?

Code: Select all

$dialog = $Far.CreateDialog(-1, -1, 52, 4)
$t1 = $dialog.AddText(1, 1, 50, 'Progress')
$t2 = $dialog.AddText(1, -1, 50, '')
$dialog.Open()
1..9 | .{process{
    $t2.Text += $_
    $Far.UI.Redraw()
    Start-Sleep 1
}}
$dialog.Close()

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

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

Post by John Doe » Sat 30 Sep, 2017 09:24

Сомневаюсь что должно.

Code: Select all

local id = win.Uuid"45B09D0D-6AE8-416C-BB5A-F5FA7B5CC430"
local F = far.Flags
local function Progress(text,title)
  local len = text:len()
  local items = {
    --[[01]]  {F.DI_SINGLEBOX,0,0,len+2,3,0,0,0,0,title},
    --[[02]]  {F.DI_TEXT,     1,1,0,0,0,0,0,0,text},
  }
  local flags = F.FDLG_NONMODAL
  return far.DialogInit(id,-1,-1,len+2,3,len,items,flags)
end

local hDlg = Progress(" ")
for i=1,5 do
  --hDlg:send"DM_REDRAW"
  win.Sleep(500)
  hDlg:send("DM_SETTEXT",2,i)
end
Тут то же самое, без DM_REDRAW не отображается.

Post Reply

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