2013-12-22 5 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 :

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

그리고으로 onClose 절차에

이있다 : 솔루션으로

Release; 

내가 다른 명령 시도 :

myPackagForm := TmyPackagForm.Create(Application); 

에를

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

exports 
    ItemClickExecute; 

end. 

myPackagForm 그것을 보여줄 수있는 클래스 프로 시저가 myPackagForm 생성;

누구나 무슨 일이 있었는지 알 수 있습니까? 패키지에서 CreateForm 명령을 사용하여 Delphi XE4을 사용할 수 있습니까?

+0

변경된 사항이 없습니다. CreateForm으로 만든 첫 번째 폼이 주요 폼입니다. –

+0

@David Heffernan 네 말이 맞아. 하지만 내 패키지에서 Application.CreateForm 명령을 사용할 때 Delphi7에서 Package Forms를 닫는 데 아무런 문제가 없었습니까? –

+0

나는 무슨 일이 일어나고 있는지 잘 알고있다. 나는 대답을 쓸 것이다. –

답변

3

경 Rufo는 기본 사항을 다룹니다. CreateForm을 호출하여 생성 된 첫 번째 양식이 기본 양식이됩니다. 기본 폼이 닫히면 응용 프로그램이 닫힙니다.

이제 CreateForm에 대한 두 번의 호출이 표시되었습니다. 하나는 호스트 응용 프로그램에 있고 다른 하나는 동적으로로드 된 패키지에 있습니다. 그리고 실행할 첫 번째 응용 프로그램은 호스트 응용 프로그램에서 가져온 것입니다. 그렇다면 패키지의 양식이 어떻게 응용 프로그램을 중단시킬 수 있습니까? Rufo 경이 말한 것처럼 프로세스에 두 개의 응용 프로그램 인스턴스가있는 경우에만 발생할 수 있습니다.

그럼 다음 질문은 프로세스에 두 개의 응용 프로그램 인스턴스가있을 수 있다는 것입니다. 그렇게해서는 안됩니다. 패키지의 전체적인 포인트는 델파이 유닛들이 다른 모듈들 사이에서 공유되도록 허용하는 것입니다. 응용 프로그램을 올바르게 빌드 한 경우 TApplication의 인스턴스는 호스트 실행 파일과 모든 패키지간에 공유됩니다.

도달 할 수있는 유일한 결론은 모듈 중 하나가 런타임 패키지를 사용하여 빌드되지 않았다는 것입니다. 예를 들어 호스트 응용 프로그램에는 실행 파일 내에 정적으로 링크 된 RTL/VCL이 포함되어있을 수 있습니다. 패키지가 RTL/VCL 런타임 패키지에 링크됩니다. 또는 정적으로 링크 된 RTL/VCL을 포함하는 동적으로로드 된 패키지 일 수 있습니다. IIRC이지만 컴파일러는 이러한 일이 발생하지 않도록합니다.

무엇이 잘못 되었든, 모든 모듈은 런타임 패키지를 사용하여 빌드해야합니다. 모든 RTL/VCL 라이브러리는 런타임 패키지를 통해 링크되어야하며 정적으로 링크되어서는 안됩니다.

따라서 Application.CreateFormTMyPackageForm.Create으로 바꾸는 것은 단순히 더 넓은 문제를 억제하는 것입니다. 애플리케이션에 RTL/VCL 인스턴스가 하나만있는 것이 중요합니다. 모든 모듈에서 런타임 패키지를 사용하여이를 달성하십시오.

TMyPackageForm.Create이 패키지에 양식을 만드는 올바른 방법입니다. 기본 양식으로는 Application.CreateForm 만 사용합니다. 나는 결코 다른 곳에서는 사용하지 않는다. 그러나 패키지에서 Application.CreateForm을 제거하여 직접적인 문제를 해결하려고하지 마십시오. RTL/VCL 로의 연결을 수정하십시오.

3

TApplication.CreateForm 양식을 만들뿐만 아니라이 방법으로 만든 첫 번째 양식을 TApplication.MainForm으로 만드십시오.

MainForm을 닫으면 응용 프로그램이 닫힙니다. 당신은 당신의 응용 프로그램 내부에 2 개 TApplication 인스턴스를

UPDATE.

  1. BPL 내부의 BPL

그래서 양식 내부의 일반 응용 프로그램

  • 은 BPL의 MainForm이 될 것입니다. Application이 양식을 닫으면 기본 응용 프로그램 프로세스의 컨텍스트에서 PostQuitMessage(0)을 수행하므로 전체 응용 프로그램을 강제 종료합니다.

  • +0

    패키지를 호출하는 기본 프로젝트에는 MainForm이 있습니다. 내부 패키지에서 createForm으로 변경 될 것이라고 생각하십니까? 이전 버전의 델파이 (예 : 7.0)에서 작동합니다! –

    +0

    애플리케이션 MainForm은 'TApplication.CreateForm'에 의해 생성 된 첫 번째 양식에 의존합니다. 이것은 정적이 아니며 어디서 작성되지 않은지에 따라 달라집니다. 양식을 작성할 때 우리에게 보여주기 위해 질문에 코드를 추가하십시오. –

    +0

    완전한 답변을 위해 고맙습니다. 그러나 또 다른 질문은 PostQuitMessage가 DelphiXE의 새로운 성능이라는 것입니다. 내 패키지에있는 Application.CreateForm 명령으로 델파이 7에는 문제가 없었기 때문에. –