У меня есть многопоточное приложение со многими формами, но мне нужно создать экземпляры некоторых классов и вызвать некоторые элементы инициализации перед созданием форм. Конечно, я должен выполнить соответствующий код завершения.
Вот упрощенный пример файла .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
моих форм. Это становится очевидным, если посмотреть на секцию finalization
блока Form
:
finalization
if Application <> nil then DoneApplication;
И DoneApplication
вызывает Application.DestroyComponents
, что эффективно освобождает все формы, принадлежащие Application
.
Таким образом, формы, созданные с помощью Application.CreateForm
, будут уничтожены после любого кода внутри основного блока begin..end
.
Я хочу, чтобы после Application.Run
все формы были уничтожены, чтобы их OnDestroy
обработчики событий могли видеть объект Config
и внешние функции, определенные в моих dll. То же самое, если возникает исключение. Но я также хочу иметь стандартную обработку исключений приложения, если Config.Free
или UnlodDlls
повышаются (приложение все еще должно существовать).
Обратите внимание, что:
- Я бы предпочел не использовать блок
finalization
(возможно ли это в .dpr?), чтобы сделать код более ясным и поддающимся отладке; - На данный момент я предпочитаю не менять слишком много кода (например, динамически создавать формы).
Я думаю, что самое простое решение — явно вызвать Application.DestroyComponents
после Application.Run
. Как думаете, есть ли недостатки? Есть ли более элегантное решение?
Спасибо