《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。
这样动态调用的好处就是节省了内存资源,使用后立即释放内存。