:: Visual Foxpro, Foxpro for DOS
Как заставить объект на форме инициализироватся самым последним
Burn
Автор

Сообщений: 5644
Откуда: Днепр
Дата регистрации: 02.01.2002
Коллеги, как всегда хочу странного - нужен класс формы, который после создания всех объектов формы сможет проделать с ними определенные манипуляции.
Естественное место данного кода - Init формы. Но, обычно, в нем проделывается масса действия и дописывать каждый раз DODEFAULT() напрягает.
Так что нужно или специальное место, которое выполняется после инициализации всех объектов формы и в которое обычно никто не лезет. Или сделать отдельный объект, который можно просто кинуть на форму и чья инициализация пройдет последней.
Пока в голову ничего кроме сделать стандартный Init формы защищенным а из него вызвать свой метод куда вынести все подготовительные операции... Но может есть еще какие либо пути?


------------------
В борьбе бобра с козлом побеждает бобро




Исправлено 1 раз(а). Последнее : Burn, 22.06.17 22:03
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
pasha_usue

Сообщений: 3650
Откуда: Е-бург
Дата регистрации: 06.10.2006
Show не комильфо?
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Только Init формы, выполняяется после Init обьектов на форме. Есть еще Activate формы, выполняется после Init всех обьектов на форме, от этого и пляши...

Доб. Я написал подпрограмму-обходчик видеообьектов на форме, и выполняю его в нужный момент, например, при старте формы, или после кнопки, типа "Refresh формы". Художественное дело )



Исправлено 1 раз(а). Последнее : of63, 22.06.17 22:37
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
Burn
Автор

Сообщений: 5644
Откуда: Днепр
Дата регистрации: 02.01.2002
pasha_usue
Show не комильфо?
Не додумался. Проверю. Синкс
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
Chemberzhy

Сообщений: 13142
Откуда: Измаил
Дата регистрации: 28.04.2009
Напиши в Activate просто ссылку на исполнение в самом конце prg- файла, а уже в prg- файле пиши себе всё что душе угодно и когда угодно.

Например, в Activate в конце пишешь:
if MyPrg()=1
WAIT "Лажа вышла " WINDOW
ENDIF
on error

prg- файл (MyPRG.prg)

ON ERROR return 1
with _SCREEN.ActiveForm
.command1.width=.width
endwith



Исправлено 2 раз(а). Последнее : Chemberzhy, 22.06.17 22:56
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Burn
нужен класс формы, который после создания всех объектов формы сможет проделать с ними определенные манипуляции.
Естественное место данного кода - Init формы. Но, обычно, в нем проделывается масса действия и дописывать каждый раз DODEFAULT() напрягает.
Как видно, есть много путей...)
Я делаю так.
Во всех объектах есть метод Fill() (Название - дело вкуса)
В Init формы есть
FOR EACH oo IN this.Objects
IF PEMSTATUS(oo,'fill',5)
oo.fill()
ENDIF
ENDFOR
Соответственно, в конкретном наследнике, в конкретном контроле, можешь переопределить Fill() как хочешь, без изменения кода формы.


------------------
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
Ydin

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
У меня св-во Inited=.F.
Для этого объекта на init:
if not thisform.Inited
return
endif

Там, где надо стоит
thisform.Inited = .t.
<<этот объект>>.Init()
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
Ydin

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
OK



Исправлено 1 раз(а). Последнее : Ydin, 23.06.17 19:56
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
Burn
Автор

Сообщений: 5644
Откуда: Днепр
Дата регистрации: 02.01.2002
Аспид
Как видно, есть много путей...)
Дык, для того и обращаюсь к коллективному разуму чтобы найти оптимальный

Спасибо всем откликнувшимся - буду думать


------------------
В борьбе бобра с козлом побеждает бобро
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Burn
Естественное место данного кода - Init формы. Но, обычно, в нем проделывается масса действия и дописывать каждый раз DODEFAULT() напрягает.
Кому как. Меня не напрягает. От слова вообще

Кроме того, если есть для класса формы определённые "наборы действий при инициализации", то в классе создаёшь под эти наборы свои методы, и из Init (класса) вызываешь их в нужном порядке. Тогда в наследниках не будет надобности переопределять сам Init - всё будет писаться в эти методы...
Burn
Так что нужно или специальное место, которое выполняется после инициализации всех объектов формы и в которое обычно никто не лезет.
Не нужно закладываться на то что "обычно в него никто не лезет". Т.к. обязательно залезут, и испортят - если учить вредному - в частности не пользоваться DODEFAULT-ом.
Burn
Или сделать отдельный объект, который можно просто кинуть на форму и чья инициализация пройдет последней.
Это невозможно. Если бы ещё речь шла про одну форму, то там играясь с BringToFront/SentToBack можно было управлять порядком инициализации (и да, это ж так "очевидно" и "просто" ) но в классах... В общем забудь.

Burn
Пока в голову ничего кроме сделать стандартный Init формы защищенным
Не надо его делать защищённым. А вот сделать методы-пустышки можно. НО! Как только появится 2 уровня в иерархии наследования, то опять без DODEFAULT() будет "и ни туды и ни сюды". Так что просто приучайся ЯВНО вызывать базовый функционал, если он таки нужен.

pasha_usue
Show не комильфо?
Абсолютно. С точки зрения логики прежде всего.

of63
Есть еще Activate формы
Там нужен флажок для защиты от повторных срабатываний. И в общем случае в нём стоит писать:
- то что требует "полной загрузки" формы, включая её показ - т.е. то что "ломается" если форма ещё невидима.
- то что является "тяжёлым" и пользователь пугается не видя вообще ничего на экране - тогда показ "пустой" формы - ну там с надписью "ждите пока всё загрузится" и последующая подгрузка в Activate (конечно же со свойством-флагом - чтобы только 1 раз срабатывала) является допустимым костылём. Ещё с той же целью используют Activate страниц в pageframe - чтобы не грузить сразу инфу на ВСЕ страницы, что может быть долго...
Просто всю инициализацию туда пихать - тоже убогое решение.

Chemberzhy
просто ссылку на исполнение в самом конце prg- файла
Зачем? Чтобы не видеть This/ThisForm в коде и париться с передачей этого в prg? Или тот же убогий, ненадёжный и малоочевидный _SCREEN.ActiveForm пытаться использовать... Зачем смешивать ООП с процедурным подходом?

Ydin
Там, где надо стоит
thisform.Inited = .t.
<<этот объект>>.Init()

Явно вызывать обработчики событий это тоже моветон. Правильный подход - создать метод и вызывать его:
- из Init - если это необходимо делать при инициализации.
- из другого метода - если необходимо и ПОМИМО инициализации иногда выполнять тот же код.
Флаги "пропускающие" логику метода - ну да, это применяется когда нет полного контроля над тем кто и когда вызывает данный код. Но зачастую это "костыли" поддерживающие ту или иную кривизну в архитектуре (особенно когда речь идёт не про "обработчики событий" - которые в общем то сложно или даже невозможно "заставить не работать когда нам это не нужно" - а про ординарный код просто вызываемый из разных мест).


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
Ydin

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
Явно вызывать обработчики событий это тоже моветон. Правильный подход - создать метод и вызывать его:
- из Init - если это необходимо делать при инициализации.
- из другого метода - если необходимо и ПОМИМО инициализации иногда выполнять тот же код.
Флаги "пропускающие" логику метода - ну да, это применяется когда нет полного контроля над тем кто и когда вызывает данный код.
Но зачастую это "костыли" поддерживающие ту или иную кривизну в архитектуре (особенно когда речь идёт не про "обработчики событий" -
которые в общем то сложно или даже невозможно "заставить не работать когда нам это не нужно" - а про ординарный код просто вызываемый из разных мест).
Да, у меня по-разному. И это не один метод, который работает не сразу. Все по ситуации.
Resize у меня часто туда выплывает. Не хочу, чтобы он трудился, пока его не просят. Хотя он мало ресурса просит.
Создать лишний метод? Если он нужен. А он именно лишний, я без него обходился всегда.
Сталин:
Цитата:
Нет человека - нет проблем
Нет лишнего метода - нет проблем.
Цитата:
Флаги "пропускающие" логику метода
Главное тут - самому себе не создать проблем. Написать комменты и постараться быть проще.
Но это не легко, если тебе мешают на этом события.
Казалось бы - все просто, но посмотришь - устанавливаешь высоту формы в Ините, а а у тебя срабатывает Resize.
А тебе пофиг - ты его в упор не видешь, хоть 100 раз.
А потом начинаешь подстраивать форму под любой каприз. И у тебя Resize пляшет где и не надо бы.
Походу, Игорь всех этих прелестей не наблюдал.
Реально - вот он Инит формы и относиться к нему надо очень внимательно, если ты в Фоксе в самом деле что-то писал всерьез, а не специалист по его Хелпу.
Цитата:
Правильный подход - создать метод и вызывать его:
Да, правильный подход лежит на 2 уровня сложнее, чем этот "правильный подход". Там надо решать по ситуации.
А ввести одно или несколько свойств для идентификации на каком подуровне событий находишься в процессе запуска формы и ее существовании - нормально.
Тот же activate - это событие и оно вызывается не всегда там, где хочешь.
Надо иметь опыт по всем событиям, чтобы понять, что они не обязательно написаны под твой сценарий. Он может быть сложней.
Игорь, если ты не использовал Combobox'ы в гриде (как сам это сказал), то я верю, что с проблемой этой темы тоже не знаком.
У нас они (комбобксы) в гриде почти везде, где это не просто справочники. И строятся автоматом. И польза от них у нас не оспаривается.
Думаю, что с проблемой этой темы знаком, но как дилетант и хороший теоретик.
Но не стоит правила выдумывать. Оно с виду простое, но сложнее этого простого правила.
Я это понял потом, не сразу, когда увидел, что в форму надо войти после логина, который определяет, что можешь видеть и что можешь править и еще что-то.
И данные периода могут быть Readonly (закрыты для редактирования) и мне тогда можно проще читать, но стоит кнопка выбора периода и я вызываю
все, что на Ините написано, но согласно статуса нового периода.
А еще можно менять тип периода:
день, день1 - день2, месяц, месяц1-месяц2, квартал, кв1-кв2, год, год1 - год2
На стороне клиента запоминается последний выбор, но в сеансе можем менять.
И еще вагон и маленькая тележка.
Цитата:
Правильный подход
смотрится как наивное представление проблемы.
Свои свойства формы помогают строить события, вернее определять когда вызывать свои методы и когда отключать события Фокса.
Я в своем фреймворке меньше всего хочу там что-то менять и правильного подхода у меня нет.
Вот пока Foxcharts делали, так и у Цезаря и у меня столько было проблем по тому, чтобы не было повторов событий своих и фоксовских.
А на форме для справочника можно и правильный подход придумать. Легко.
Только о чем говорим? Автор, походу, уже порох понюхал. Многие живут без этого вопроса, вроде его и нет.
Но он есть.
Цитата:
Если положишь портмоне в старые брюки и забудешь куда положил, то портмоне все равно лежит в старых брюках
Объективная реальность



Исправлено 6 раз(а). Последнее : Ydin, 23.06.17 22:51
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Ydin
Создать лишний метод? Если он нужен. А он именно лишний, я без него обходился всегда.
Если тот же Init превращается в многостраничную простыню с
IF !This.EnvPrepared
...
ENDIF
IF !This.DataReady
...
ENDIF
IF !This.StyleApplied
...
ENDIF
Это значит что методы НУЖНЫ. И они ни разу не "лишние". Сваливать всё в кучу только на основании того что так можно написать - это плохой подход. Писать какую-то логику в Click кнопки, или в процедуре подвязанной к пункту меню в меню-дизайнере, или в том же Init вызывая его 100500 раз из кучи мест с разным набором "флагов" (чтобы срабатывали разные куски этого мега-метода)... Это г*нокод. И мной это даже не обсуждается.

Ydin
Главное тут - самому себе не создать проблем. Написать комменты и постараться быть проще.
Но это не легко, если тебе мешают на этом события.
Если мне приходится писать комменты к коду, то я понимаю что что-то недодумал - код должен пониматься и безо всяких комментариев - тогда это будет хороший код.
События мешают в том случае если пихать в них "логику" непосредственно. И не то чтобы "мешают", но в общем некоторые неудобства создают... Если логика вынесена отдельно, а в обработчике события стоит лишь вызов этой логики, то и "флаги" борющиеся с многократными и "в самый неподходящий момент" срабатываниями этого события не выглядят так уж плохо - по крайней мере они не в ЛОГИКЕ прописаны, а в коде который решает надо или нет в данный момент эту логику применить. И нужды в вызовах ...Click() или том же ...Init() в прикладном коде практически никогда не возникает (в последнем лично у меня ВООБЩЕ НИКОГДА - тут я даже работаю "чище" авторов фокса с их гениальным костылём для классов курсорадаптеров - который через Ж инициализируются будучи помещёнными в DataEnvironment, от чего и требуют "красивейшего" кода, который можно лицезреть в CADах создаваемых "мастером").
Для пользования логикой нужно дёргать САМУ логику, а не "верёвочку которая привязана к колокольчику, который вызывает дворецкого который сделает то-то и то-то".
Ydin
Походу Игорь всех этих прелестей не наблюдал.
Ну конечно, и сохранение/восстановление размеров формы и положения сплиттеров совместно с самодельным anchor (для 7-го ещё фокса) он не делал, и отслеживания активного "контейнера данных" для логического разграничения частей формы тоже - чисто на форуме поп***ть приходит, "чотким пацанам" прицел посбивать, чтобы оне не писали "ровного кода" в Init на 100500 строк, где вообще вся логика формы прописана - только пару сотен флажков верно выстави (или там сооруди один строковый параметр вида "ПосчитайТо,ОбновиСё,НажмиНаЭто,ПокажиМессагуЧтоВсёОк" - как тут кое кто советовал) да дёргай постоянно ThisForm.Init() - зачем вообще другие "имена" использовать

Ydin
Тот же activate - это событие и оно вызывается не всегда там, где хочешь.
Про то и речь. Show это вообще метод - хотя в фоксе с какого-то перепугу работает как событие. Но надо ж и туда чего-нить напихать инициализирующего - чтобы "понятнее" стало как оно всё работает Странно что Destroy никто не предложил "нагрузить" - а что, ничего ж страшного если какую-то инициализацию там прописать - благо вызов Destroy() ничего и не закрывает/уничтожает - ваще идеальный метод - мало найдётся гениев что полезут туда "искать и портить" код инициализации

Ydin
Игорь, если ты не использовал Combobox'ы в гриде (как сам это сказал), то я верю, что с проблемой этой темы тоже не знаком.
Использовал и понял что это плохо в 99% случаев. Совершенно не обязательно каждый день наступать на грабли (и вырастить себе на лбу отличный защитный мозоль), чтобы посоветовать другому так не делать
Отличная навигация по такому гриду, отличная активация ячейки с комбо мышкой, прекрасная вообще работа комбо (даже безо всякого грида) с источником строк на > 100-200 записей и с "многоколончатым" источником в частности. Нет, твоя "священная корова" меня абсолютно не впечатляет.

И "проблема" как написать код инициализации в форме так, чтобы не потерять код инициализации прописанный в классе - ну лично для меня просто смешна.

В хелпе есть статья для новичков Но зачем нам ходить по понятной прямой дороге, если можно пойти через овраги? Можно придумать какую-то чушь (как половина советов в данной теме), лишь бы не писать ненавистный DODEFAULT()

Ydin
Не стоит правила выдумывать тогда. Это сложнее, по крайней мере этих простых правил
Зачем выдумывать какие-то "правила", если можно просто прочесть хелп? Там такой ерунды по крайней мере не советуют И да - вопросы не ко мне, а к авторам фокса уж.


------------------
WBR, Igor
Ratings: 0 negative/2 positive
Re: Как заставить объект на форме инициализироватся самым последним
Ydin

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
Я поставил лайк, т.к. мне нравится ответ. Но мы по-разному все это себе представляем.
Но уверен, что я хелп читал и помню по-крайней мере хуже твоего. А может на пару порядков хуже.
И спорить мне, поэтому, нет резона. У меня по-другому все работает.
А в хелпе ерунды не советуют, там вообще не советуют, просто описывают.
В документации по Фоксу немного было.
Но там описывает кто? Тот, кто писал Фокс, это в лучшем случае.
Но не те, кто с ним много лет работал. А по этой теме как раз это имеет значение.
Может, мы говорим об одном и том же, но по-разному себе это представляя.
Вроде, я спорю и соглашаюсь одновременно. Но такое бывает, когда получаешь хороший ответ.
В Фоксе до появления готовой формы на экране работает
Load, потом Init'ы объектов, потом Init cамой формы.
А в промежутках и после еще что-то работает.
Если писать много разных форм, то как-то формируются правила.
Если пишешь типовые формы для многоразового использования, то тоже формируются правила.
Но другие.
Но это уже совсем другая история...



Исправлено 1 раз(а). Последнее : Ydin, 24.06.17 01:10
Ratings: 0 negative/0 positive
Re: Как заставить объект на форме инициализироватся самым последним
matod

Сообщений: 3062
Откуда: Иркутск
Дата регистрации: 31.10.2001
Полностью согласен с Игорем - отказ от Init из-за того, что "напрягает" писать dodefault() - надуманная проблема. В Init формы нередко кода значительно больше, чем эти три строки для вызова кода родительского класса. Если проблема в том, что постоянно забываешь это сделать в новых классах, то, можно, например, предусмотреть какой-то индикатор. Разместить в базовом классе lable с подходящим текстом, а в Init устанавливать visible=.f. При отладке сразу будет видно, что забыл )) Хотя по-моему опыту, такая ошибка достаточно редкая и легко отлавливается отладчиком или контрольными точками.

Т.е., на мой взгляд, для кода инициализации, который должен быть выполнен после инициализации всех объектов - Init формы самый естественный, удобный и понятный выбор.

Для каких-то экзотических случаев есть еще один способ - "одноразовый" таймер с крошечным интервалом срабатывания. Вызов события таймера произойдет не раньше, чем дело дойдет до обработки очереди событий, т.е. точно после Init. Такой таймер может пригодиться, например, для организации множественного наследования в ситуации, когда не все формы наследуются от общего предка. Но, еще раз, это способ на тот 1% случаев, когда почему-то Init формы применять не удобно.
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 25 (Гостей: 25)

© 2000-2024 Fox Club 
Яндекс.Метрика