Вверх ↑
Этот топик читают: Гость
Ответов: 1926
Рейтинг: 172
#1: 2017-11-21 18:24:52 ЛС | профиль | цитата
Решил сделать такой код:

Add(InlineCode,7379325,322,217)
{
@Hint=#10:SRData 2.0|
DataPoints=#5:dtPH_|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|17: ini:PIniFile;|31: procedure RestoreData_3042;|9: public|45: //PHandle всех компонентов для сохранения|20: dtPH_:THI_Event;|0:|23: constructor Create;|33: destructor Destroy; override;|0:|5: end;|0:|14:implementation|0:|31:constructor THiAsmClass.Create;|5:begin|18: inherited Create;|27: InitAdd(RestoreData_3042);|4:end;|0:|31:destructor THiAsmClass.Destroy;|5:begin|16: //SaveData_3042|67: ini := OpenIniFile(GetStartDir + '1.ini'); //Указать имя ini-файла|50: ini.Section := 'main'; //Указать секцию ini-файла|22: ini.Mode := ifmWrite;|45: //Указываем ключи и соотв. свойства объектов|63: ini.ValueInteger('left',PControl(ToIntegerEvent(dtPH_)).Left);|3: //|19: Free_And_Nil(ini);|19: inherited Destroy;|4:end;|0:|39:procedure THiAsmClass.RestoreData_3042;|5:begin|1: |17: //_hi_OnEvent();|4:end;|0:|4:end.|
link(dtPH_,2214374:PHandle,[])
}
Add(Button,2214374,322,140)
{
Left=190
Top=25
Name="789"
Point(PHandle)
}
, чтобы сохранять и загружать свойства при закрытии/открытии программы. Код пока ещё не дописан. Но с загрузкой, кажется, проблем не будет, т.к. используется InitAdd, к-ый срабатывает, когда все объекты будут загружены. Я прав?

А вот с сохранением вопрос: Destroy в IC не может сработать уже после того, как остальные объекты будут уничтожены (в т.ч. те, св-ва которых сохраняем)? Т.е. интересует порядок выполнения Destroy разных объектов.
карма: 9
0
Ответов: 1926
Рейтинг: 172
#2: 2017-11-21 23:20:19 ЛС | профиль | цитата
Я проверил свой код из первого поста - часто при закрытии вылетает runtime error, данные не сохраняются в ini.

Спрошу по-другому: есть ли аналогичная InitAdd процедура, но которая бы добавляла процедуры для вызова перед закрытием? То есть, какую конструкцию следует использовать, чтобы процедура вызывалась непосредственно перед началом уничтожения объектов?

Редактировалось 1 раз(а), последний 2017-11-21 23:20:29
карма: 9
0
Ответов: 2059
Рейтинг: 132
#3: 2017-11-22 00:27:39 ЛС | профиль | цитата
3042, Всё OK и никаких "runtime error".
[main]
left=190

Win 7

Редактировалось 1 раз(а), последний 2017-11-22 00:29:37
карма: 6

0
Ответов: 1926
Рейтинг: 172
#4: 2017-11-22 09:56:29 ЛС | профиль | цитата

Add(Edit,13545452,322,203)
{
Left=75
Top=145
Width=215
Point(PHandle)
}
Add(InlineCode,7379325,329,259)
{
@Hint=#10:SRData 2.0|
DataPoints=#5:dtPH_|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|17: ini:PIniFile;|20: im:TIniFileMode;|26: procedure SRData_3042;|9: public|45: //PHandle всех компонентов для сохранения|20: dtPH_:THI_Event;|0:|23: constructor Create;|33: destructor Destroy; override;|0:|5: end;|0:|14:implementation|0:|31:constructor THiAsmClass.Create;|5:begin|18: inherited Create;|15: im := ifmRead;|73: InitAdd(SRData_3042); //Видимо, запуск после инициализации всех объектов|4:end;|0:|31:destructor THiAsmClass.Destroy;|5:begin|16: im := ifmWrite;|13: SRData_3042;|19: inherited Destroy;|4:end;|0:|34:procedure THiAsmClass.SRData_3042;|38: function PCtl(ev:THI_Event):PControl;|52: begin Result := PControl(ToIntegerEvent(ev)); end;|5:begin|67: ini := OpenIniFile(GetStartDir + '1.ini'); //Указать имя ini-файла|16: ini.Mode := im;|52: ini.Section := 'fields'; //Указать секцию ini-файла|57: //Указать точки данных, ключи и соотв. свойства объектов|61: PCtl(dtPH_).Text := ini.ValueString('txt',PCtl(dtPH_).Text);|3: //|19: Free_And_Nil(ini);|17: //_hi_OnEvent();|4:end;|0:|4:end.|
link(dtPH_,13545452:PHandle,[])
}
А вот так мало того что не сохраняет текст, так ещё и если IC поставить на передний план (Правка -> Передний план), вылетает ошибка. Однако если вручную поставить текст в ini, - загружает при старте.
карма: 9
0
Ответов: 1926
Рейтинг: 172
#5: 2017-11-22 12:03:10 ЛС | профиль | цитата
Ребят, ау, вижу же, что читают топик, но не отвечают, а ведь знают!
карма: 9
0
Ответов: 4629
Рейтинг: 749
#6: 2017-11-22 12:07:36 ЛС | профиль | цитата
Процесс исполнения такой:
- создаётся элемент 1 (первым создаётся MainForm)
- заполняются его свойства
- создаётся элемент 2
- заполняются его свойства
....
- выполняется THIMainForm.Start, в которой вызывается InitDo

- когда програма получает команду закрытия - уничтожается элемент 2
- уничтожается элемент 1

На порядок "элемент 1-2-N" влияет "Задний план"/"Передний план".
Следовательно, если некоторый код элемента N обращается к элементу X до того, как создан элемент X, или после того, как он был уничтожен - получится ошибка. В твоём IC THiAsmClass.Create выполняется в процессе создания элементов, а THiAsmClass.Destroy - в процессе уничтожения. Так вот, вполне обычная ситуация, что в зависимости от порядка создания/уничтожения элементов твой метод Create/Destroy может пытаться обратиться к элементу, который ещё не создан или был уже уничтожен - вот и получается ошибка. При этом можно добиться нужного порядка создания/уничтожения, чтобы было без ошибки, но это не лучший вариант.

Редактировалось 2 раз(а), последний 2017-11-22 12:09:29
карма: 26

0
Ответов: 1926
Рейтинг: 172
#7: 2017-11-22 12:20:11 ЛС | профиль | цитата
Вот я тоже так подумал, что это не лучший вариант - с передним/задним планом.

Но в Create я использую InitAdd, так что проблем при загрузке нет.
А вот что-то подобное для закрытия программы...

Есть какая-то возможность перехватить сообщение закрытия в IC? Так как в MainForm обрабатывается WM_CLOSE, после чего вызывается _onClose. Там ещё все контролы существуют, ведь происходит вызов _prop_Position(true), к-е сохраняет позицию формы.
карма: 9
0
Ответов: 4629
Рейтинг: 749
#8: 2017-11-22 12:26:23 ЛС | профиль | цитата
Да, похоже, стоило бы перед началом уничтожения элементов добавить вызов заинтересованных процедур типа FinalDo() аналогично InitDo().

3042 писал(а):
Есть какая-то возможность перехватить сообщение закрытия в IC?
В KOL есть возможность добавить свой обработчик сообщений через процедуру Applet.AttachProc(). Но в нём надо ещё понять, что сообщение идёт именно главной форме, а не какой-нибудь из дочерних. Может там по классу окна можно будет отличить.
карма: 26

0
Ответов: 1926
Рейтинг: 172
#9: 2017-11-22 12:35:44 ЛС | профиль | цитата
Netspirit писал(а):
стоило бы перед началом уничтожения элементов добавить вызов заинтересованных процедур типа FinalDo()

О! Ну просто мысли мои читаешь, я тоже об этом думал. Странно, что Dilma в своё время это не сделал. Но сейчас вряд ли кто-то будет изменять код share & mainform, наверное.

А по AttachProc будем разбираться...
карма: 9
0
Ответов: 2059
Рейтинг: 132
#10: 2017-11-22 13:24:22 ЛС | профиль | цитата
Netspirit писал(а):
Да, похоже, стоило бы перед началом уничтожения элементов добавить вызов заинтересованных процедур типа FinalDo() аналогично InitDo().

Недавно у меня была похожая задача с InitDo().
3042 писал(а):
Но сейчас вряд ли кто-то будет изменять код share & mainform, наверное.

По этому забросил эту идею и сделал через точки, что не очень красиво.
3042, если разбирёшься, не забудь показать решение.
карма: 6

0
Ответов: 4629
Рейтинг: 749
#11: 2017-11-22 14:07:34 ЛС | профиль | цитата
Это не сложно - добавить список и пару процедур в Share.pas и впечатывать вызов из Codegen.dpr.
Тем не менее остаётся проблема с динамическими контейнерами. По-хорошему, эти процедуры должны присутствовать в каждом контейнере (одним из которых является MainForm), но для этого компоненты должны иметь доступ к своему контейнеру, а это, наверное, сложно.
карма: 26

0
Ответов: 2059
Рейтинг: 132
#12: 2017-11-22 15:12:07 ЛС | профиль | цитата
Это не сложно - добавить список и пару процедур в Share.pas

Как раз это самое трудное, потому что не достаточно изменит Share.pas.
Главное чтобы изменения были внесены в SVN.
А то,одни сделают изменения, а другие будут писать - " у меня не работает".

Редактировалось 1 раз(а), последний 2017-11-22 15:16:08
карма: 6

0
Ответов: 4629
Рейтинг: 749
#13: 2017-11-22 15:15:04 ЛС | профиль | цитата
Ну, само собою, на SVN.
карма: 26

0
Ответов: 2059
Рейтинг: 132
#14: 2017-11-22 15:21:12 ЛС | профиль | цитата
Размеры моей благодарности будут безграничны... в пределах разумного!
карма: 6

0
Ответов: 1926
Рейтинг: 172
#15: 2017-11-22 15:22:19 ЛС | профиль | цитата
Netspirit писал(а):
вызов из Codegen.dpr.

А почему оттуда? InitDo из mainform же вызывается.
Кстати, не нашёл, откуда вызывается THIMainForm.Start, никто не в курсе? В Codegen тоже не увидел.

Netspirit, а у тебя есть возможность править SVN?
карма: 9
0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)