View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002587 | Far Manager | Plugins API.Dialog | public | 2014-01-29 21:52 | 2014-03-19 13:18 |
Reporter | JohnDoe | Assigned To | |||
Priority | normal | Severity | minor | Reproducibility | always |
Status | new | Resolution | open | ||
Product Version | 3.0 | ||||
Summary | 0002587: В момент первого DN_GOTFOCUS неверно работают функции AdvControl | ||||
Description | После открытия диалога активируется первый фокусный элемент и посылается сообщение DN_GOTFOCUS. Если в этот момент обработчик события воспользуется функциями ACTL_REDRAWALL, ACTL_GETWINDOWINFO, ACTL_GETWINDOWTYPE, то их результат будет неожиданным. Этой проблемы нет с последующими DN_GOTFOCUS | ||||
Steps To Reproduce | local F = far.Flags Event { group="DialogEvent"; condition=function(Event,param) return Event==2 and param.Msg==F.DN_GOTFOCUS end; action=function(Event,param) far.AdvControl (F.ACTL_REDRAWALL) local TypeName = far.AdvControl (F.ACTL_GETWINDOWINFO).TypeName local Type = far.AdvControl (F.ACTL_GETWINDOWTYPE).Type far.Text(1,0,1,TypeName) far.Text(1,1,1,Type) end; } После установки данного обработчика необходимо открыть диалог, например диалог копирования (F5). Видно, что панели исчезли (проблема с ACTL_REDRAWALL), и в левом верхнем углу отображается текст Panels. После нажатия Tab всё нормализуется. | ||||
Additional Information | Не уверен что это связано, но в момент первого DN_GOTFOCUS также неверно работают функции макроязыка, например Area.Current, Menu.Id, Dialog.Id После второго DN_GOTFOCUS всё нормализуется | ||||
Tags | No tags attached. | ||||
Build | |||||
|
http://api.farmanager.com/ru/dialogapi/dmsg/dn_gotfocus.html Сказано: "Событие также приходит для фокусного элемента сразу после DN_INITDIALOG." Значит первый DN_GOTFOCUS приходит до того как диалог отрисован, от этого и проблемы. Поскольку "раннее" появление DN_GOTFOCUS упоминается в документации, то описываемая проблема строго говоря не является багом. Вероятно стоит переместить в проект "Wishes" |
|
Вижу два пути: 1. вынести посыл DN_GOTFOCUS из инициализации диалога поближе к отрисовке 2. для первого DN_GOTFOCUS в Param2 указать не 0, а скажем, -1 (по своей сути первый DN_GOTFOCUS - это всё еще этап инциализации диалога) Второй вариант более разумный ибо для первого варианта возможны интересные визуальные эффекты ;-) |
|
в чём разумность второго варианта, если он по сути ничего не меняет? |
|
Внимательно прочти |
|
я прочитал. первый DN_GOTFOCUS можно отследить и сейчас. |
|
Для чего вообще первый DN_GOTFOCUS приходит так рано? Может быть всё можно решить посылая ещё один DN_GOTFOCUS после того как диалог отрисуется? >первый DN_GOTFOCUS можно отследить и сейчас. Какой способ рекомендуется? |
|
Возможно первый DN_GOTFOCUS неудачно назван. Задача этого сообщения указать диалоговой процедуре где будет клавиатурный фокус ввода после того, как запустится основной цикл взаимодействия с юзером. Плагин, при передаче "массива контролов" в Far, может указать флаг DIF_FOCUS на элементе не имеющего отношения к "клавиатурному фокусу" (или вообще не указывать этот флаг). Это как бы не ошибка, но пользователю будет не комфортно. В процессе инициализации элементов диалога Far прослеживает этот факт (и то, что нет элементов с таким флагом) и корректирует значение "фокуса" на "следующий" ближайший допустимый элемент. После этого сообщает диалоговой процедуре "истинное" значение индекса элемента с фокусом (который может совпадать с тем, что передал плагин, если плагин не наврал). |
|
Возможно ли корректировать значение фокуса ещё на этапе DN_INITDIALOG? Если нет, то что если посылать ещё один DN_GOTFOCUS после отрисовки? И о каких интересных визуальных эффектах речь выше 0002587:0011906? |
|
> Возможно ли корректировать значение фокуса ещё на этапе DN_INITDIALOG? Это и так делается при инициализации. Событие DN_GOTFOCUS это информационный сигнал свершившегося факта. > Если нет, то что если посылать ещё один DN_GOTFOCUS после отрисовки? Не перебор? :-) (hint: отрисовка достаточно часто происходит) > И о каких интересных визуальных эффектах речь выше? Я пытаюсь всего лишь предположить ;-) |
|
>Это и так делается при инициализации. Я о DN_INITDIALOG/Param1: "ID элемента, который получит фокус ввода по умолчанию." "По умолчанию" здесь на основании данных переданных плагином, или уже скорректированное значение? >Не перебор? :-) (hint: отрисовка достаточно часто происходит) Я имел ввиду после отрисовки диалога, но однократно. |
|
> Я о DN_INITDIALOG/Param1: Зачем? В передаваемом массиве элементов это уже есть в виде флага DIF_FOCUS. Сегодня у тебя в диалоге "рамка" и "строка редактирования", ты ставишь Param1 равный 1 (если от нуля считать). Потом понимаешь, что неплохо обозначить что это за строка редактирования и ставишь перед ней "метку" (индекс строки редактирования сместился), но забываешь скорректировать Param1... |
|
Это понятно. Возможно я не совсем понимаю как это работает, но выше сказано: > DN_GOTFOCUS ... Задача этого сообщения указать диалоговой процедуре где будет клавиатурный фокус ввода ... В связи с этим вопрос: та самая диалоговая процедура о которой говорится в цитате ведь получает DN_INITDIALOG после завершения инициализации? Почему тогда DN_INITDIALOG не может выполнить указанную задачу? |
|
Понял. Ок. Смотрим как это работает: 1. Элементы проинициализированы (в т.ч. вычислен "истинный" индекс фокусного элемента) 2. Far отсылает DN_INITDIALOG в функцию-обработчик диалога, передавая в Param1-"вычисленный" ID фокусного элемента. 3. В случае, если диалоговая функция изменили данные (вернула в Far значение TRUE), то Far переинициализирует данные с учетом "сейчасных" изменений (в т.ч. перерасчитывает индекс фокусного элемента, т.к. "есть подозрение, что плагин поменял фокусный элемент при обработке DN_INITDIALOG"). После этой вторичной реинициализации повторно DN_INITDIALOG не посылается. 4. Независимо от наличия п.3 идет посыл DN_GOTFOCUS с "новым" индексом фокусного элемента. Если отправку DN_GOTFOCUS делать _только_ для случая, если процедура-обработчик в ответ на DN_INITDIALOG вернула TRUE, то не получим ли мы ситуацию, когда некий плагин (написанный с учетом Писания) всегда ждёт DN_GOTFOCUS сразу после DN_INITDIALOG, а тут бац - а он не пришел и плагин сломался. Я всё таки склоняюсь к тому, чтобы "первый" DN_GOTFOCUS (который относится к инициации) в Param2 содержал что-то, отличное от нуля. 1. Поломки из-за отсутствия DN_GOTFOCUS нет (пред.абзац) 2. Функция-обработчик всегда знает (без собственных вычислений этого факта), что для варианта DN_GOTFOCUS(Param2=-1) лишних движений с отрисовкой не делать, а ждать... |
|
>"первый" DN_GOTFOCUS (который относится к инициации) В своём скрипте я хочу по DN_GOTFOCUS выполнять определённые действия для которых необходимо чтобы диалог уже был отрисован. Всё бы ничего, но первый DN_GOTFOCUS приходит слишком рано. Предлагаемый вами Param2 позволит легко отфильтровать первый DN_GOTFOCUS, но это не решит проблему. Потому что в таком случае при открытии диалога мой скрипт вообще не сработает. Вижу такие варианты - Посылать первый DN_GOTFOCUS после отрисовки (я так понял это не получится) - Сразу после отрисовки посылать ещё один DN_GOTFOCUS. >Возможно первый DN_GOTFOCUS неудачно назван Да, когда-нибудь при очередной ломке стоит завести для него отдельное сообщение. |
|
А для чего указанный скрипт? |
|
http://forum.farmanager.com/viewtopic.php?f=60&t=8463 Изначально задумывался для автоматической активации фильтра в меню, листбоксах, комбобоксах. (на данный момент DN_GOTFOCUS не используется, ввиду описанных проблем) |
|
В общем тут нашел багу (??) Вместо DN_GOTFOCUS подставил DN_DRAWDIALOGDONE и получил переполнение стека - процедура отрисовки диалога зацикливалась (при срабатывании вызова диалога и заюзывания этого скрипта). Зацикливание убрал, но "far.AdvControl (F.ACTL_REDRAWALL)" дает непрорисовку диалога вообще (правда работают, но тихо :-)). Закомментировал строку - проблемы этого тикета исчезли. На тестирование - https://dl.dropboxusercontent.com/u/13020996/far/m2587.7z |
|
>Зацикливание убрал Правильно ли это? Вроде логично чтобы после ACTL_REDRAWALL приходило сообщение DN_DRAWDIALOGDONE >Вместо DN_GOTFOCUS подставил DN_DRAWDIALOGDONE Правильно ли я понимаю, что вместо DN_GOTFOCUS предлагается использовать DN_DRAWDIALOGDONE? Мне не кажется это хорошей идеей, и я даже не знаю всех случаев когда DN_DRAWDIALOGDONE может приходить. Например во всех меню оно приходит самопроизвольно (как DN_ENTERIDLE) |
|
>>Зацикливание убрал >Правильно ли это? Это юмор такой? > Вроде логично чтобы после ACTL_REDRAWALL приходило сообщение DN_DRAWDIALOGDONE Оно и придет, но только не в момент отрисовки диалога. Отлови идле-событие и дай команду ACTL_REDRAWALL. Зацикливание было по причине, что скрипт запускал ACTL_REDRAWALL в момент, когда отрисовка диалога еще не закончилась. >>Вместо DN_GOTFOCUS подставил DN_DRAWDIALOGDONE >Правильно ли я понимаю, что вместо DN_GOTFOCUS предлагается использовать DN_DRAWDIALOGDONE? Как вариант. Функция отрисовки вызывается достаточно часто: изменилось состояние элемента - вызывается функция отрисовки для ЭТОГО элемента. DN_DRAWDIALOGDONE при этом общий (отрисовка и для всего диалога так и для отрисовки конкретного элемента) > Мне не кажется это хорошей идеей, и я даже не знаю всех случаев когда DN_DRAWDIALOGDONE может приходить. Хмм.. Так, вроде неточность есть в АПИ. а) Отрисовка всего диалога: 1. DN_DRAWDIALOG 2. DN_CTLCOLORDIALOG 3. N раз { DN_DRAWDLGITEM DN_CTLCOLORDLGITEM } 4. DN_DRAWDIALOGDONE б) Отрисовка элемента: 3. N раз { DN_DRAWDLGITEM DN_CTLCOLORDLGITEM } 4. DN_DRAWDIALOGDONE Т.е. для элемента нет DN_DRAWDIALOG, парной для DN_DRAWDIALOGDONE. В писании сказано, что "Сообщение DN_DRAWDIALOGDONE посылается после прорисовкой всего диалога". Т.е. такое событие не должно приходить для элемента. Как вариант - DN_DRAWDIALOG так же посылать для отрисовки элемента, передавая в Param1 ID отрисовываемого элемента. Только в этом случае что делать с индексом. Сейчас Param1 всегда = 0. |
|
>DN_DRAWDIALOGDONE [...] Т.е. такое событие не должно приходить для элемента. Вероятно здесь логично было бы иметь отдельное событие DN_DRAWDLGITEMDONE. Ломать поздно? (хотя не знаю какой плагин это вообще мог использовать) >Как вариант - DN_DRAWDIALOG так же посылать для отрисовки элемента[...] Для элемента уже есть DN_DRAWDLGITEM, зачем его дублировать. Проще передавать ID в DN_DRAWDIALOGDONE ... Возвращаясь к теме: почему не сделать как я предлагал выше: 0002587:0011927 |
|
> почему не сделать как я предлагал выше Потому, что не логично DN_GOTFOCUS использовать иначе как "такой то элемент получил фокус ввода". Событие должно приходить "вовремя и к месту". Я не вижу смысла переносить первый DN_GOTFOCUS сразу после отрисовки ("ближе к прорисовке" - он уже и так присылается сразу после инитдиалога и перед прорисовкой). В принципе можно первый DN_GOTFOCUS вообще убрать, чтобы не вводил в заблуждение. Если плагин захочет узнать у кого фокус - кинет месаг DM_GETFOCUS. Вопрос. Ты планируешь использовать весь функционал, даже если в этот момент он не к месту (например, "в DN_INITDIALOG что-то рисовать, вместо того, чтобы инциализировать элементы")? |
|
>Я не вижу смысла переносить первый DN_GOTFOCUS сразу после отрисовки Как же смысла не видишь, когда это и есть суть тикета, заявленная ещё в описании. Сейчас первый DN_GOTFOCUS приходит ДО отрисовки диалога, и поэтому я нормальным образом не могу ничего сделать. >например, "в DN_INITDIALOG что-то рисовать, вместо того, чтобы инциализировать элементы" Вообще-то об этом 0002616, и нет, я как раз хочу делать "к месту", но места такого нет. (Рисовать не надо было, в том примере задача была прочитать заголовок окна, который в тот момент ещё недоступен. А в другом примере - воспользоваться фильтром меню, который опять же не доступен) |
|
> Сейчас первый DN_GOTFOCUS приходит ДО отрисовки диалога, и поэтому я нормальным образом не могу ничего сделать. Это означает, что удаляем первый DN_GOTFOCUS? > Рисовать не надо было, в том примере задача была прочитать заголовок окна,... Значит DN_DRAWDIALOGDONE с установкой внутреннего флага, что ты уже получил данные. Второй вариант: добавить новый месаг DM_GETDIALOGTITLE (который тебе вернет строку, используемую ФАРом для выставления заголовка диалога) и использовать его в DN_INITDIALOG. Делать? > А в другом примере - воспользоваться фильтром меню, который опять же не доступен Как воспользоваться? Очистить? Заполнить? Отобразить? Что именно? Разжовывай на пальцах. Если в скриптах юзается плагиновое АПИ, то видимо и поступать надо так, как будто плагин пишешь :-) |
|
>Это означает, что удаляем первый DN_GOTFOCUS? Я хочу получать DN_GOTFOCUS при активации первого элемента диалога, но после отрисовки (чтобы не было никакой разницы между первым и последующими DN_GOTFOCUS) По остальному ответил в соседнем тикете: 0002616:0011983 |
Date Modified | Username | Field | Change |
---|---|---|---|
2014-01-29 21:52 | JohnDoe | New Issue | |
2014-01-30 12:13 | JohnDoe | Note Added: 0011801 | |
2014-03-13 07:42 | vskirdin | Note Added: 0011906 | |
2014-03-13 08:29 | zg | Note Added: 0011910 | |
2014-03-13 08:36 | vskirdin | Note Added: 0011911 | |
2014-03-13 08:47 | zg | Note Added: 0011912 | |
2014-03-13 11:56 | JohnDoe | Note Added: 0011914 | |
2014-03-13 13:25 | vskirdin | Note Added: 0011916 | |
2014-03-13 13:42 | JohnDoe | Note Added: 0011917 | |
2014-03-13 14:19 | vskirdin | Note Added: 0011919 | |
2014-03-13 14:30 | JohnDoe | Note Added: 0011921 | |
2014-03-13 15:43 | vskirdin | Note Added: 0011923 | |
2014-03-13 15:56 | JohnDoe | Note Added: 0011924 | |
2014-03-13 17:26 | vskirdin | Note Added: 0011926 | |
2014-03-13 19:49 | JohnDoe | Note Added: 0011927 | |
2014-03-18 10:25 | vskirdin | Note Added: 0011959 | |
2014-03-18 10:30 | JohnDoe | Note Added: 0011960 | |
2014-03-18 10:41 | vskirdin | Note Added: 0011961 | |
2014-03-18 12:45 | JohnDoe | Note Added: 0011967 | |
2014-03-18 12:46 | JohnDoe | Note Edited: 0011967 | |
2014-03-19 06:48 | vskirdin | Note Added: 0011972 | |
2014-03-19 08:17 | JohnDoe | Note Added: 0011976 | |
2014-03-19 08:18 | JohnDoe | Note Edited: 0011976 | |
2014-03-19 10:58 | vskirdin | Note Added: 0011979 | |
2014-03-19 11:56 | JohnDoe | Note Added: 0011980 | |
2014-03-19 12:48 | vskirdin | Note Added: 0011981 | |
2014-03-19 12:50 | vskirdin | Note Edited: 0011981 | |
2014-03-19 12:53 | JohnDoe | Note Added: 0011982 | |
2014-03-19 13:18 | JohnDoe | Note Edited: 0011982 |