为何dll调用非模式窗体时没有什么反映?
-------dll --------
library dll1;uses
SysUtils,
Classes,
Unit2 in 'Unit2.pas' {DLLFrm};exports
showform,
closeform;
{$R *.res}begin
end.--DLL 中的窗体单元---
unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TDLLFrm = class(TForm)
Label1: TLabel;
private
{ Private declarations }
public
{ Public declarations }
end; function showform(AHandle:THandle;ACaption:String):Longint;stdcall;
procedure closeform(AFormRef:Longint);stdcall;implementation{$R *.dfm}
function showform(AHandle:THandle;ACaption:String):Longint;stdcall;
var
dllform:TDLLFrm;
begin
Application.Handle := AHandle;
dllform := TDLLFrm.Create(Application);
Result := Longint(dllform);
dllform.Caption := ACaption;
dllform.ShowModal;
end;procedure closeform(AFormRef:Longint);stdcall;
begin
if AFormRef > 0 then
TDllFrm(AFormRef).Release;
end;
end.
--------调用程序的单元文件---------
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TShowForm = function(A: TApplication): Bool; StdCall;
EDLLLoadError = class(Exception);
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
LibHandle: THandle;
ShowForm: TShowForm;
begin
LibHandle := LoadLibrary('c:\dll1.dll'); --注确保c:下有dll1.dll
try
if LibHandle = HINSTANCE_ERROR then
raise EDLLLoadError.Create('Unable to Load DLL');
@ShowForm := GetProcAddress(LibHandle, 'ShowForm');
if not (@ShowForm = nil) then
ShowForm(Application);
finally
FreeLibrary(LibHandle);
end;end;end.
-------dll --------
library dll1;uses
SysUtils,
Classes,
Unit2 in 'Unit2.pas' {DLLFrm};exports
showform,
closeform;
{$R *.res}begin
end.--DLL 中的窗体单元---
unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TDLLFrm = class(TForm)
Label1: TLabel;
private
{ Private declarations }
public
{ Public declarations }
end; function showform(AHandle:THandle;ACaption:String):Longint;stdcall;
procedure closeform(AFormRef:Longint);stdcall;implementation{$R *.dfm}
function showform(AHandle:THandle;ACaption:String):Longint;stdcall;
var
dllform:TDLLFrm;
begin
Application.Handle := AHandle;
dllform := TDLLFrm.Create(Application);
Result := Longint(dllform);
dllform.Caption := ACaption;
dllform.ShowModal;
end;procedure closeform(AFormRef:Longint);stdcall;
begin
if AFormRef > 0 then
TDllFrm(AFormRef).Release;
end;
end.
--------调用程序的单元文件---------
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TShowForm = function(A: TApplication): Bool; StdCall;
EDLLLoadError = class(Exception);
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
LibHandle: THandle;
ShowForm: TShowForm;
begin
LibHandle := LoadLibrary('c:\dll1.dll'); --注确保c:下有dll1.dll
try
if LibHandle = HINSTANCE_ERROR then
raise EDLLLoadError.Create('Unable to Load DLL');
@ShowForm := GetProcAddress(LibHandle, 'ShowForm');
if not (@ShowForm = nil) then
ShowForm(Application);
finally
FreeLibrary(LibHandle);
end;end;end.
begin
try
Application.Handle:= hOwner;
if frm_MainDLL<>nil then
TForm(frm_MainDLL).Free;
if not Assigned(frm_MainDLL) then
begin
Application.CreateForm(Tfrm_MainDLL,frm_MainDLL);
frm_MainDLL.Show;
end;
finally end;
end;
TDllInterface = procedure (hOwner: hInst);stdcall;
procedure ExecuteDllQ(DllPath:string);
var
hInst:THandle;
DllInterfaceQ:TDllInterfaceQ;
begin
hInst:=LoadLibrary(PChar('C:\dll1.dll'));
try
@DllInterfaceQ:=GetProcAddress(HInst,'ShowForm');
DllInterfaceQ(frm_Main.Handle);
finally
FreeLibrary(HInst);
end;
end;
****
finally
FreeLibrary(LibHandle);
end; 调用非模式窗体,那么执行完调用后语句继续执行,那不是就FreeLibrary,
Dll就将释放了,所以没有任何效果。
若要实现,需要将 LibHandle: THandle; 定义成为全局变量,不能是过程变量。
当记得关闭前 释放DLL资料。