library Project1;
uses
SysUtils,
windows,
messages,
controls,
forms,
dialogs,
graphics,
Classes,
Unit1 in 'Unit1.pas' {Form1};{$R *.RES}
var dllapplication :tapplication;
dllproc:pointer; procedure provachild(parentapplication:tapplication;parentform:tform);export;stdcall;
var form1:tform1; begin
application:=parentapplication;
form1:=tform1.Create(parentform);
form1.myparentapplication:=parentapplication;
form1.myparentform:=parentform;
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.
mdi 子窗体
unit1;
public
myparentapplication:tapplication;
myparentform:tform;
{ Public declarations }
end;
var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
application.Handle:=0;
action:=caFree ;end;
调用代码
procedure TForm1.Button1Click(Sender: TObject);
var
proaddr:farproc;
provachild:T_provachlid;begin
dllhandle:=loadlibrary('Project1.dll');
@provachild:=getprocaddress(dllhandle,'provachild');
if @provachild<>nil then
provachild(application,self); end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin while dllhandle<>0 do
FreeLibrary(dllhandle);
close;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
dllhandle:=0;
end;
1: 程关闭时,按 ctrl+alt+delete 看,程序还存在啊,
2:mdi的application 关闭时,是否释放,怎样释放
uses
SysUtils,
windows,
messages,
controls,
forms,
dialogs,
graphics,
Classes,
Unit1 in 'Unit1.pas' {Form1};{$R *.RES}
var dllapplication :tapplication;
dllproc:pointer; procedure provachild(parentapplication:tapplication;parentform:tform);export;stdcall;
var form1:tform1; begin
application:=parentapplication;
form1:=tform1.Create(parentform);
form1.myparentapplication:=parentapplication;
form1.myparentform:=parentform;
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.
mdi 子窗体
unit1;
public
myparentapplication:tapplication;
myparentform:tform;
{ Public declarations }
end;
var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
application.Handle:=0;
action:=caFree ;end;
调用代码
procedure TForm1.Button1Click(Sender: TObject);
var
proaddr:farproc;
provachild:T_provachlid;begin
dllhandle:=loadlibrary('Project1.dll');
@provachild:=getprocaddress(dllhandle,'provachild');
if @provachild<>nil then
provachild(application,self); end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin while dllhandle<>0 do
FreeLibrary(dllhandle);
close;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
dllhandle:=0;
end;
1: 程关闭时,按 ctrl+alt+delete 看,程序还存在啊,
2:mdi的application 关闭时,是否释放,怎样释放
provachild;
begin
dllapplication:=application;
dllproc:=@dllunloadproc;
//去掉这里的注释
end.
这种模式很常用的,但动态加载功能dll是不可取的,
静态是很简单的。主程序有一个主窗口,各个功能用dll来实现,dll中可能会有子窗口
我不知道你具体用的什么方式。我说一下我们以前一个程序的处理方式,1.
dll中提供一个函数,用来创建子窗口,假设子窗口类名为TGIS02F01
函数名为GIS02F01_Open;
procedure GIS02F01_Open(var Form: TForm; Parameter: string);
begin
Form := TGIS02F01.Create(nil);
Form.WindowState:= ...;
end;子窗口关闭的时候用action:= caFree;2.
在主窗口中点击相应的菜单时,调用GIS02F01_Open就行了;
子窗口在关闭后是可以释放的
Windows,
Forms in 'forms.pas',
udll in 'udll.pas' {dll_Frm},
umainformsVar in 'umainformsVar.pas';{}
{Function: Load the child Form
Returns : FormVariable
Par0: Application var off ExeFile
Par1: CallBack procedure pointer to inform exefile of unloaded (freed)
Form
}
function ShowChild(App:TApplication;PFormFreeCallBack:Pointer):TForm;stdcall; export;
begin
Application:=App;
Result:=TDll_Frm.Create(Application);
@FormFreeCallBack:=PFormFreeCallBack;
end;
{Function: Set Dll-Application Var back to originall Value
}
procedure SetOldApplication;stdcall;export;
begin
Application:=OldApp;
end;
{$R *.RES}
exports ShowChild,SetOldApplication;
begin
{Save original Applicatioin Variable}
OldApp:=Application;
end.unit udll;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;type
Tdll_Frm = class(TForm)
Memo1: TMemo;
procedure FormDestroy(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
// procedure CreateParams(var Params: TCreateParams);override;
end;
{ProtoType of Exe_CallBackFunction}
tf_FormFreeCallBack=procedure ;stdcall;var
dll_Frm: Tdll_Frm;
FormFreeCallBack:Tf_FormFreeCallBack;
implementationuses mdidll,umainformsVar;{$R *.DFM}procedure Tdll_Frm.FormDestroy(Sender: TObject);
begin
{notify exe-File that Form is onloaded}
FormFreeCallBack;
end;procedure Tdll_Frm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
action:=caFree;
end;end.
program maindb;uses
Forms,
uexe in 'uexe.pas' {Form1},
Umain in 'Umain.pas' {main};{$R *.RES}begin
Application.Initialize;
Application.CreateForm(Tmain, main);
Application.CreateForm(TForm1, Form1);
Application.Run;
end.mainform:
unit Umain;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus;type
Tmain = class(TForm)
MainMenu1: TMainMenu;
Datei1: TMenuItem;
Neu1: TMenuItem;
ffnen1: TMenuItem;
Speichern1: TMenuItem;
Speichernunter1: TMenuItem;
N1: TMenuItem;
Drucken1: TMenuItem;
Druckereinrichtung1: TMenuItem;
N2: TMenuItem;
Beenden1: TMenuItem;
Bearbeiten1: TMenuItem;
Rckgngig1: TMenuItem;
WiederholenBefehl1: TMenuItem;
N3: TMenuItem;
Ausschneiden1: TMenuItem;
Kopieren1: TMenuItem;
Einfgen1: TMenuItem;
Inhalteeinfgen1: TMenuItem;
N4: TMenuItem;
Suchen1: TMenuItem;
Ersetzen1: TMenuItem;
Gehezu1: TMenuItem;
N5: TMenuItem;
Verknpfungen1: TMenuItem;
Objekt1: TMenuItem;
Fenster1: TMenuItem;
NeuesFenster1: TMenuItem;
Nebeneinander1: TMenuItem;
berlappend1: TMenuItem;
Alleanordnen1: TMenuItem;
N6: TMenuItem;
Verbergen1: TMenuItem;
Zeigen1: TMenuItem;
Hilfe1: TMenuItem;
Inhalt1: TMenuItem;
Index1: TMenuItem;
Befehle1: TMenuItem;
Verfahren1: TMenuItem;
Tastatur1: TMenuItem;
Suchen2: TMenuItem;
Lernprogramm1: TMenuItem;
Hilfebenutzen1: TMenuItem;
Info1: TMenuItem;
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;var
main: Tmain;implementation{$R *.DFM}end.unit uexe;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;type
TForm1 = class(TForm)
Panel1: TPanel;
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
procedure LoadDll;
end;
{types for dynamical load from dll}
TF_ShowChild = function (App:TApplication;PFormFreeCallBack:Pointer):TForm;stdcall;
{Set old Applicaton Var in Dll to protect for GPF}
TF_SetOldApplication=procedure ;stdcall;
EDLLLoadError = class(Exception);
procedure FormFreeCallBack;stdcall;
var
Form1: TForm1;
ChildForm:TForm;
ShowChild :TF_ShowChild;
SetOldApplication:TF_SetOldApplication;
dlldbhWnd:hwnd=0;
implementationuses Umain;{$R *.DFM}
{must be called in dll to recognize if childform is onloaded}
procedure FormFreeCallBack;
begin
ChildForm:=Nil;
end;
{dynamically load functions from dlldb.dll}
procedure TForm1.LoadDll;
var LastError:DWord;
begin
if dlldbhWnd= 0 then begin
dlldbhWnd:=loadLibrary('DLLDB.DLL');
if dlldbhWnd =0 then begin
LastError := GetLastError;
Raise EDLLLoadError.create(IntToStr(LastError) +
': Unable to load DLLDB.dll');
end;
ShowChild:=getProcAddress(dlldbhWnd,'ShowChild');
if @showChild=Nil then begin
Raise EDLLLoadError.create(IntToStr(LastError) +
': Unable to find function ShowChild');
end;
SetOldApplication:=getProcAddress(dlldbhWnd,'SetOldApplication');
if @SetOldApplication=Nil then begin
Raise EDLLLoadError.create(IntToStr(LastError) +
': Unable to find function SetOldApplication');
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
loadDll;
if not assigned(ChildForm) then begin
ChildForm:=ShowChild(Application,@FormFreeCallBack);
end;
ChildForm.Show;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
if dlldbhWnd<>0 then begin
SetOldApplication;
FreeLibrary (dlldbhWnd);
end;
end;
end.