Имам многонишково приложение с много формуляри, но трябва да инстанцирам някои класове и да извикам някои неща за инициализация преди създаването на формулярите. Разбира се, трябва да изпълня съответния код за финализиране.
Ето опростен пример за .dpr файл:
begin // .dpr project file
LoadDlls;
try
Config := TConfig.Create;
try
Application.Initialize;
Application.Title := 'Foo';
Application.CreateForm(TMainForm, MainForm);
Application.CreateForm(TOtherForm, OtherForm);
//...other forms...
Application.Run;
finally
Config.Free;
end;
finally
UnloadDlls;
end;
end;
Проблемът тук е, че кодът вътре в finally
блока се изпълнява ПРЕДИ OnDestroy
/ destructor
s на моите формуляри. Това става ясно, ако погледнете раздела finalization
на Form
единица:
finalization
if Application <> nil then DoneApplication;
И DoneApplication
извиква Application.DestroyComponents
, което на практика освобождава всички формуляри, притежавани от Application
.
Така че формулярите, създадени с Application.CreateForm
, ще бъдат унищожени след всеки код в главния блок begin..end
.
Това, което искам, е след Application.Run
всички формуляри да бъдат унищожени, така че техните OnDestroy
манипулатори на събития да могат да видят Config
обекта и външните функции, дефинирани в моите dlls. Същото, ако се повдигне изключение. Но също така искам да имам стандартна обработка на изключенията на приложението, ако Config.Free
или UnlodDlls
се повдигнат (Приложението все още трябва да съществува).
Забележи, че:
- Бих предпочел да не използвам блок
finalization
(би ли било възможно в .dpr?), за да поддържам кода по-ясен и с възможност за отстраняване на грешки; - Засега предпочитам да не променям твърде много код (напр. динамично създаване на формуляри)
Мисля, че най-простото решение е изрично да се извика Application.DestroyComponents
след Application.Run
. Мислите ли, че има някакви недостатъци? Има ли по-елегантно решение?
Благодаря ти