Этот топик читают: Гость
Гость
Ответов: 17029
Рейтинг: 0
|
|||
Редактировалось 1 раз(а), последний 2017-03-03 10:00:04 |
|||
карма: 0 |
|
Администрация
Ответов: 15295
Рейтинг: 1519
|
|||
Новую версию программы...
|
|||
карма: 27 |
|
Гость
Ответов: 17029
Рейтинг: 0
|
|||
Редактировалось 1 раз(а), последний 2017-03-03 10:00:03 |
|||
карма: 0 |
|
Ответов: 9906
Рейтинг: 351
|
|||
Slick, а не могли бы Вы примером из 2-3-х элементов разъяснить, какое окно не открывается, а раньше открывалось.
А то, чего-то, ничего не понятно..... |
|||
карма: 9 |
|
Гость
Ответов: 17029
Рейтинг: 0
|
|||
Редактировалось 1 раз(а), последний 2017-03-03 10:00:07 |
|||
карма: 0 |
|
Ответов: 9906
Рейтинг: 351
|
|||
Slick, Вы все-таки прочитайте пару постов:
http://si-tech.ru/hiasm/forum/viewtopic.php?t=450 http://si-tech.ru/hiasm/forum/viewtopic.php?t=1091 Безусловно, не исключено, что здесь и ошибка закралась, но мы могли бы сэкономить много времени на ее поиске, обмениваясь информацией на уровне схем, а не на уровне ля-ля. Dilma, чего-то мне показалось, что технология InitMan совершенно не учитывает динамики контейнера. А такие доработки (причем, очень нужные) - это не две строки подправить....... |
|||
карма: 9 |
|
Администрация
Ответов: 15295
Рейтинг: 1519
|
|||
Не учитывает. Придется скорей всего поступатть так же как с формой - вводить для каждого контейнера InitMan и делать новое поле в конфиге, которое укажет, что компоненту нужно передать ссылку на него. Ну и вызывать его всегда в конце инициализации схемы.
|
|||
карма: 27 |
|
Ответов: 9906
Рейтинг: 351
|
|||
Вот еще.
Это должно быть по-разному для статического контейнера, и - динамического.... И чистка InitMan после Init (или в самом Init) нужна для динамической устойчивости.... А отсюда, мысли такие (думается, что все-таки можно обойтись без заведения дополнительных полей, и т.п.): [code:1]........................ constructor TClassChildForm_XXX.Create; //Такое - для всех контейнеров var tmp:boolean; begin tmp := Init_ON; //Это новая глобальная переменная, определенная в share Init_ON := true; inherited Create; ......................... EditMulti_XXX.MainClass := Self; if not tmp then begin InitMan.Init; InitMan.Clear // Это новый метод, с прозрачным смыслом Init_ON := false; end; end;[/code:1] Ну и обойтись без Start для MainForm.... Впрочем, корректировки и еще будут, наверное... Если подумать :) |
|||
карма: 9 |
|
Администрация
Ответов: 15295
Рейтинг: 1519
|
|||
Это будет работать. Но вот есть вариант(пришло в голову, глядя на код) вообще выкинуть InitMan и переложить все на плечи кодогенератора. Для этого ввести в ini новое поле например такое: Init=True, и затем для каждого такого файла вызывать Element_XXXXX.Init после создания всех элементов схемы. Чтобы такое работало в динамике, нужно делать отдельный метод Init для каждого класса-контейнера и вызывать его скажем сразу после вызова CreateInstance.
|
|||
карма: 27 |
|
Ответов: 9906
Рейтинг: 351
|
|||
Dilma, тут есть вопрос
В случае статического контейнера, хотелось бы, что бы было как сейчас. Исхожу из того, что было бы правильным, чтобы разработчик элемента имел гарантии работоспособности ВСЕЙ схемы на момент вызова метода, помещенного в InitMan. А для этого (в случае статического контейнера) кодогенератор обязан отложить вызов этих хитрых методов на момент окончания конструктора контейнера более высокого уровня (ну и все выше и выше, по мере необходимости ). Т.е., это не локальная задача контейнера. Это, конечно, не значит, что кодогенератор не имеет теоретической возможности с этим справиться. Но вот доросли ли мы до этого уровня - пока не знаю Ну и никто не запрещает сделать это в будущем. Ведь приведенное выше - тоже гипотетический результат работы кодогенератора. Но вот обкатку пройти не мешало бы. Вдруг появятся посты типа как в этом топике (это же я, раскручивая его, этот разговор начал ) |
|||
карма: 9 |
|
Администрация
Ответов: 15295
Рейтинг: 1519
|
|||
Galkov, именно об этой проблеме я в первую очередь и подумал, глядя опять таки на приведенный код. Метод Init будет объявлен в контейнере, но не будет вызываться внутри него. Тогда грубая схема вызовов будет такая:
[code:1] Child := FOnCreate(); // это например в MultiElement1 Child.MainClass.Init; // вызов Init из MultiElement2 .... procedure MultiElement2.Init; begin ... // вызываем Init всех компонент, кому оно надо // а так же Init ВСЕХ контейнеров end; [/code:1] в итоге Init любого контейнера даже теоритически не может быть вызван до тех пор, пока все контейнеры и элементы с большей воженностью не будут созданы. А Init основного контейнера(т.е. главной формы) нужно вызвать из Start. Вот вроде и вся задача. |
|||
карма: 27 |
|
Ответов: 9906
Рейтинг: 351
|
|||
Dilma, ну я и не спорю с тем, что все операции по определению кого и когда вызывать (в смысле INIT) возможно разрешить на этапе компиляции
Вот уточнение только: не "а так же Init ВСЕХ контейнеров", а "а так же Init всех СТАТИЧЕСКИХ контейнеров". Т.е., надо дополнительно (сегодня кодогенератор этого не делает - этим занимается конструктор мультика на этапе исполнения) разбираться со св-м типа _prop_FirstUsage или _prop_Mode. О возможности этого вопросов не возникает Ну и второе (мелочь): вызов метода Init тогда удобней проводить из конструктора Create_UnitName, например. Меньше заморочек при нескольких вызовах FOnCreate в кодах MultiElementEx (или где еще). P.S. именно об этой проблеме я в первую очередь и подумал, глядя опять таки на приведенный код Дак нет этой проблемы в приведенном коде, кстати.... |
|||
карма: 9 |
|
Администрация
Ответов: 15295
Рейтинг: 1519
|
|||
Т.е., надо дополнительно (сегодня кодогенератор этого не делает - этим занимается конструктор мультика на этапе исполнения) разбираться со св-м типа _prop_FirstUsage или _prop_Mode.
Конечно. Проверяется это даже еще проще. Т-к мультиэлемент создается всегда не зависимо от того, статический он или нет то его Init можно смело вызывать, а там уже делать проверку скажем на существование FChild. Ну и второе (мелочь): вызов метода Init тогда удобней проводить из конструктора Create_UnitName, например. Меньше заморочек при нескольких вызовах FOnCreate в кодах MultiElementEx (или где еще).
Согласен. Дак нет этой проблемы в приведенном коде, кстати....
Именно что нет Потому и решение возникло по образу и подобию так сказать... |
|||
карма: 27 |
|
Ответов: 9906
Рейтинг: 351
|
|||
Но смысл то создания дополнительного метода INIT в том, чтобы выполнить действия по проверкам на этапе компиляции, а не на момент исполнения
Было бы как раз правильнее совсем не включать в свой INIT-список INIT-метод вложенного (статического) контейнера, если тот оказался пустым. Как впрочем и для остальных элементов: не включать безусловно метод INIT для элемента, делая его пустым при необходимости, а включать только тот (и только если он есть), который стоит в правой части присваивания в INI-файле. А сделать это уже однопроходным методом может (хотя точно утверждать не буду) и не получиться. Посмотревши более внимательно, вижу, что не во всем был прав до этого. А именно: 1) Разборками со статикой занимается не конструктор мультика, а его property OnCreate. Ерунда, но из песни слова не выкинешь . 2) Нельзя безусловно вызывать Init сразу после вызова FOnCreate(), а следовательно и запихивать Init внуть Create_UnitName(). Можно только в динамическом случае, в статическом - нельзя. К сожалению 3) И все это при том, что по жизни программы это НЕЛЬЗЯ встречается один раз - при конструировании статического контейнера. Хоть перегружай эти действия (одинаковые, кстати, для всех контейнеров) на кодогенератор..... А в кодах элемента оставлять только действия для динамического случая. Ну и ловушки на рекусию (статических :! контейнеров ставить надо. Наверное |
|||
карма: 9 |
|
Администрация
Ответов: 15295
Рейтинг: 1519
|
|||
Да для статики номер не пройдет, потому собственно и предложил вызывать после FOnCreate в методе Add. В общем можно попробовать и посмотреть, что получится..
|
|||
карма: 27 |
|