//DLL library Func;uses ShareMem, SysUtils, Classes, Forms, Windows, MConnect, Child2 in 'Child2.pas' {FormChild2};{$R *.RES}procedure CallModule();stdcall;export; begin if not Assigned(FormChild2) then FormChild2 := TFormChild2.Create(Application); FormChild2.Show; end;exports CallModule;begin end;//MDIChild单元:procedure TFormChild2.N9Click(Sender: TObject); begin Close; end;procedure TFormChild2.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end;procedure TFormChild2.FormDestroy(Sender: TObject); begin FormChild2 := nil; end;
//主程序: type TCallModule = procedure();stdcall;var FormMain: TFormMain; LibHandle: HModule; procedure LoadModule(AModuleName: String);implementation{$R *.DFM} procedure LoadModule(AModuleName: String); var CallModule: TCallModule; begin LibHandle := LoadLibrary(PChar(AModuleName)); if LibHandle = 0 then Exit; @CallModule := GetProcAddress(LibHandle,'CallModule'); if @CallModule <> nil then CallModule(); end;procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean); var iCount: Integer; begin if MessageDLG('是否退出?',mtConfirmation,[mbYes,mbNO],0) = mrYes then begin for iCount := 0 to MDIChildCount - 1 do MDIChildren[iCount].Close; CanClose := True; if not (LibHandle = 0) then FreeLibrary(LibHandle); end else CanClose := False; end;关键是无论DLL还是EXE都要带运行时间包VCL50.bpl编译
library mdidll;
uses
Windows,
Messages,
SysUtils,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
mdi_Unit in 'mdi_Unit.pas' {Form1};procedure LoadChild(ParentApplication: TApplication; ParentForm: TForm); export; stdcall;
var
Form1: TForm1;
DllProc: Pointer; begin
Application:=ParentApplication;
Form1:=TForm1.Create(ParentForm);
Form1.MyParentForm:=ParentForm;
Form1.MyParentApplication:=ParentApplication;
Form1.Show;
end;procedure DLLUnloadProc(Reason: Integer); register;
begin
if Reason = DLL_PROCESS_DETACH then Application:=DllApplication;
end;{$R *.res}
exports
LoadChild;
begin
DllApplication:=Application;
DLLProc := @DLLUnloadProc;
end.
1,请问:为什么要定义MyParentForm,ParentApplication作用是什么,
释放的原理是什么?
2,我要实现父窗体,用代码的方法关闭dll的mdi,如何实现???
3,如何判断,dll的窗体已经打开
4,如何使已经打开的dll窗体显示在前面
传application之类的方法都由很大的缺陷,如果你的工程涉及到复杂的处理,你就会产生一大堆你想不到的问题了。
以前做过,吃了不少亏了。呵呵
释放的原理是什么?
2,我要实现父窗体,用代码的方法关闭dll的mdi,如何实现???
3,如何判断,dll的窗体已经打开
4,如何使已经打开的dll窗体显示在前面
在这方面,delphi本身是有不少问题,但,我们经常可以通过 sendmessage来实现解决问题的途径。我们可以用消息来传递各个 dll窗体的 handle, 可以用自定义消息在主窗体里面来关闭dll里的窗体;和进行其它的操作
MDICHILD不能自动增加到MDI主窗体的MDICHILDREN数组中,所以想通过传递MyParenForm来解决,但是事实上只有传递SCREEN到DLL中,并赋给DLL的SCREEN就可自行解决2.释放的原理: 第一次LoadLibrary把DLL计数设为1,并映射DLL到EXE的进程空间,以后再LoadLibrary,如果DLL没有释放则计数递增1;FreeLibrary每调用一次就使DLL计数递减1,如果DLL计数为0,则释放DLL,如果其中的资源例如FORM没有释放就会出错!
我们通常是LoadLibrary后调用FORM就马上FreeLibrary,这时DLL计数为0(LoadLibrary初次为1,而FreeLibrary为减1,计数自然为0 ),DLL自动释放,而FORM作为其中的资源却没有释放自然会出错!
library Func;uses
ShareMem,
SysUtils,
Classes,
Forms,
Windows,
MConnect,
Child2 in 'Child2.pas' {FormChild2};{$R *.RES}procedure CallModule();stdcall;export;
begin
if not Assigned(FormChild2) then
FormChild2 := TFormChild2.Create(Application);
FormChild2.Show;
end;exports
CallModule;begin
end;//MDIChild单元:procedure TFormChild2.N9Click(Sender: TObject);
begin
Close;
end;procedure TFormChild2.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Action := caFree;
end;procedure TFormChild2.FormDestroy(Sender: TObject);
begin
FormChild2 := nil;
end;
type
TCallModule = procedure();stdcall;var
FormMain: TFormMain;
LibHandle: HModule;
procedure LoadModule(AModuleName: String);implementation{$R *.DFM}
procedure LoadModule(AModuleName: String);
var
CallModule: TCallModule;
begin
LibHandle := LoadLibrary(PChar(AModuleName));
if LibHandle = 0 then Exit;
@CallModule := GetProcAddress(LibHandle,'CallModule');
if @CallModule <> nil then
CallModule();
end;procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
iCount: Integer;
begin
if MessageDLG('是否退出?',mtConfirmation,[mbYes,mbNO],0) = mrYes then
begin
for iCount := 0 to MDIChildCount - 1 do
MDIChildren[iCount].Close;
CanClose := True;
if not (LibHandle = 0) then
FreeLibrary(LibHandle);
end else
CanClose := False;
end;关键是无论DLL还是EXE都要带运行时间包VCL50.bpl编译
怎么做才叫带运行时间包vcl50.bpl编译