在调用dll窗体的时候要把主程序的Application以及Screen对象传递到DLL中,而在退出DLL的时候(应该是之前)又要将它们还原为Dll原来的Application和Screen.
现在问题是 Application和Screen在主程序中 和在DLL中有什么不同.
欢迎大家贴上 关于 TApplication TScreen DLL的相关资料,特别欢迎 具有一定深度的讨论.
现在问题是 Application和Screen在主程序中 和在DLL中有什么不同.
欢迎大家贴上 关于 TApplication TScreen DLL的相关资料,特别欢迎 具有一定深度的讨论.
exe程序有一个默认的入口比如sub main,dll里面若干入口点供其他程序调用。
就是说exe有车头的货柜车而dll只是货柜。
除去有主线程外,DLL和EXE完全相同,都可以被调用,但EXE可以编译为DLL,而DLL不能被编译为EXE,因为它比EXE少了主线程入口
其實一切謎底在controls單元里面的initcontrols過程。當編譯器編譯exe或者dll,會將引用單元鏈接,并調用各單元的初始化段initializaiton,而initcontrols就在初始化段!
因此執行exe會產生一個application和screen,dll同樣也會創建,是兩個不同的實例!但前提是:兩者都引用了controls單元。
這樣夠了吧?
//主程序MainProject.dpr
program MainProject;uses
Forms,
MainUnit1 in 'MainUnit1.pas' {MainForm};{$R *.RES}begin
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
//主程序MainUnit1.pas
unit MainUnit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ToolWin, ComCtrls, Menus;type
TMainForm = class(TForm)
MainMenu1: TMainMenu;
Start: TMenuItem;
procedure StartClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; T_ProvaChild = procedure (ParentApplication: TApplication; ParentForm: TForm); stdcall;var
MainForm: TMainForm;implementation{$R *.DFM}procedure TMainForm.StartClick(Sender: TObject);
var
DllHandle: THandle;
ProcAddr: FarProc;
ProvaChild: T_ProvaChild;
begin
DllHandle := LoadLibrary('ProjectDll');
ProcAddr := GetProcAddress(DllHandle, 'ProvaChild');
if ProcAddr <> nil then
begin
ProvaChild := ProcAddr;
ProvaChild(Application,Self);
end;
end;end.//Dll程序PoojectDll.dpr
library ProjectDll;uses
Windows,
Messages,
SysUtils,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
UnitDll in 'UnitDll.pas' {Form1};//注意这里
procedure ProvaChild(ParentApplication: TApplication; ParentForm: TForm); export; stdcall;
var
Form1: TForm1;
DllProc: Pointer; begin
Application:=ParentApplication; Form1:=TForm1.Create(ParentForm);
Form1.MyParentForm:=ParentForm;
Form1.MyParentApplication:=ParentApplication;
windows.SetParent(Form1.Handle,ParentForm.Handle);
Form1.FormStyle:=fsMDIChild;
Form1.Show;
end;procedure DLLUnloadProc(Reason: Integer); register;
begin
if Reason = DLL_PROCESS_DETACH then Application:=DllApplication;
end;exports
ProvaChild;begin
DllApplication:=Application;
DLLProc := @DLLUnloadProc;
end.
//Dll程序UnitDll.pas
unit UnitDll;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;type
TForm1 = class(TForm)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
MyParentForm: TForm;
MyParentApplication: TApplication;
end;var
DllApplication: TApplication;implementation{$R *.DFM}procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
Application:=DllApplication;
end;end.