《Delphi5程序员指南》中讲到dll显示模式窗口与非模式窗口,用的是动态调用的方法,感觉有些繁琐,自己测试了一下,其实完全可以用静态调用的方法,也不用维护Application的Handle,这样不按书上的规范使用或许有什么问题,但以我目前的delphi水平暂时看不出。
课本教程的调用方法如下:
一.Dll库源码:
library DllModuleWin;
uses
DllWin in 'DllWin.pas' {Form8};
{$R *.res}
exports
showCalendar;
begin
end.
非常简洁,只有一个输出接口函数:showCalendar
其封装的窗体代码在DllWin.pas中
二.Dll窗体代码:
unit DllWin;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, Grids, Calendar, ExtCtrls, Buttons;
type
TForm8 = class(TForm)
Calendar1: TCalendar;
procedure Calendar1DblClick(Sender: TObject);
end;
function showCalendar({AHandle:THandle;}ACaption:ShortString):TDateTime;stdcall;
//用shortstring代替string就可避免使用sharemem和borlnmm.dll
implementation
{$R *.dfm}
function showCalendar({AHandle:THandle;}ACaption:ShortString):TDateTime;
var
DllForm:TForm8;//这里是曾经忽略的地方,要使用窗体,应该创建实例
begin
//Application.Handle:=AHandle;
DllForm:=TForm8.Create(Application);
try //这里用异常处理,学习DllForm.Free用法
DllForm.Caption:=string(ACaption);
DllForm.ShowModal;
Result:=DllForm.Calendar1.CalendarDate;
finally
DllForm.Free;
end;
end;
procedure TForm8.Calendar1DblClick(Sender: TObject);
begin
Close;
end;
end.
三.调用dll的代码
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm8 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
FshowCalendar=function({AHandle:THandle;}ACaption:ShortString):TDateTime;stdcall;
ELoadDll=class(Exception);
var
Form8: TForm8;
implementation
{$R *.dfm}
procedure TForm8.Button1Click(Sender: TObject);
var
Hhandle:THandle;
showCalendar:FshowCalendar;
begin
Hhandle:=LoadLibrary('DllModuleWin.dll');
try
if Hhandle=0 then
raise ELoadDll.Create('Dll Load Error!');
@showCalendar:=GetProcAddress(Hhandle,'showCalendar');
if not(@showCalendar=nil) then
Label1.Caption:=DateToStr(showCalendar({Application.Handle,}ShortString(Caption)));
finally
FreeLibrary(Hhandle);
end;
end;
end.
这里有3个地方要学习
1.定义了一个function方法:FshowCalendar和dll中的showCalendar一致
2.用EdllError异常类监视异常
3.@取地址的用法,把showCalendar函数指向了@showCalendar。
这样动态调用的好处就是节省了内存资源,使用后立即释放内存。