2013-12-22 2 views
2

У меня есть пакет test.bpl в моем приложении и он имеет форму с именем myPackageForm. после загрузки моего пакета, когда я хочу закрыть myPackageForm, приложение завершится.Delphi XE4: Закрытие внутренней формы пакета приводит к завершению приложения

Главная инициализация проекта:

Application.Initialize; 
Application.CreateForm(TMainForm,MainForm); 
Application.Run; 

MainForm FormCreate:

aPackage := LoadPackage('my bpl path'+test.bpl); 
@P_ItemClick := GetProcAddress(aPackage,'ItemClickExcecute'); 

MainForm ButtonClick:

P_ItemClick(Sender);

testPackage CommandsUnit:

Procedure ItemClickExecute(Sender : TObject) 
begin 
    TmyPackageForm.ShowForm(); 
end; 

exports 
    ItemClickExecute; 

end. 

myPackagForm есть процедура класса, чтобы показать его:

Class Procedure TmyPackagForm.ShowForm; 
begin 
if not Assigned(myPackagForm) 
    myPackagForm := Application.CreateForm(TmyPackagForm ,myPackagForm); 
myPackagForm.Show; 
end; 

И OnClose процедура:

Release; 

В качестве решения я попробовать другую команду:

myPackagForm := TmyPackagForm.Create(Application); 

в создание myPackagForm;

Может ли кто-нибудь знать, что произошло в Delphi XE4 с командой CreateForm на пакетах?

+0

Ничего не изменилось. Первая форма, созданная с помощью CreateForm, является основной формой. –

+0

@ Дэвид Хеффернан Вы правы. но почему у меня не было проблем с закрытием форм пакета в Delphi7 при использовании команды Application.CreateForm в моих пакетах? –

+0

Я уверен, что знаю, что происходит. Я напишу ответ. –

ответ

3

Сэр Руфо имеет основы. Первая форма, созданная с вызовом CreateForm, становится основной формой. Когда основная форма закрывается, приложение закрывается.

Теперь вы указали два звонка на CreateForm. Один в главном приложении и один в вашем динамически загруженном пакете. И кажется ясным, что первый из них запускается из главного приложения. Итак, как форма в пакете может сбить приложение? Ну, это может произойти только, как сказал сэр Руфо, если в вашем процессе есть два экземпляра приложения.

Итак, следующий вопрос: как может быть два экземпляра приложения в вашем процессе? Этого не должно быть. Весь пакет пакетов позволяет объединить модули Delphi между различными модулями. Если вы правильно создали приложение, у вас будет только один экземпляр TApplication, который будет использоваться между исполняемым файлом хоста и всеми вашими пакетами.

Итак, единственный разумный вывод заключается в том, что один из ваших модулей не построен с использованием пакетов времени исполнения. Например, возможно, приложение-хост включает RTL/VCL, связанный статически внутри исполняемого файла. И ваши пакеты связаны с пакетами времени выполнения RTL/VCL. Или, возможно, это динамически загруженный пакет, который включает RTL/VCL, связанный статически. Хотя IIRC, компилятор предотвращает это.

Что бы ни случилось, решение состоит в том, что все ваши модули должны быть созданы с использованием пакетов времени исполнения. Все библиотеки RTL/VCL должны быть связаны через пакеты времени выполнения и не должны быть связаны статически.

Таким образом, замена Application.CreateForm на TMyPackageForm.Create просто подавляет более широкую проблему. Очень важно, чтобы в вашем приложении был только один экземпляр RTL/VCL. Достичь этого, используя пакеты времени выполнения во всех ваших модулях.

Это, безусловно, тот случай, когда TMyPackageForm.Create - это правильный способ создания формы в вашем пакете. Я использую только Application.CreateForm для основной формы. Я никогда не использую его нигде. Но не пытайтесь исправить вашу непосредственную проблему исключительно, удалив Application.CreateForm из вашего пакета. Исправьте ссылку на RTL/VCL.

3

TApplication.CreateForm не только просто создайте форму, но и создайте первую форму, созданную этим методом TApplication.MainForm.

И закрытие MainForm приводит к закрытию приложения.

UPDATE

У вас есть 2 TApplication экземпляров внутри приложения.

  1. ваше обычное приложение
  2. внутри BPL

Так что ваша форма внутри BPL станет MainForm вашего BPL. Application и закрытие этой формы будет выполнять PostQuitMessage(0) в контексте вашего основного процесса приложения, и это вынудит все приложение выйти.

+0

Основной проект, который вызывает пакет, имеет MainForm. вы думаете, что он изменится с помощью createForm во внутреннем пакете? в старой версии delphi (например, 7.0) это работает! –

+0

Приложение MainForm зависит от первой формы, созданной 'TApplication.CreateForm'. Это не является статичным и зависит от того, когда он создан не на месте. Пожалуйста, добавьте больше кода на свой вопрос, чтобы показать нам, когда формы будут созданы. –

+0

Спасибо, сэр Руфо, за ваш полный ответ. но другой вопрос в том, что PostQuitMessage - это новая производительность в DelphiXE? потому что у меня не было проблем в Delphi 7 с помощью команды Application.CreateForm в моих пакетах. –

Смежные вопросы