Dll 模式窗口与非模式窗口

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

你可能感兴趣的:(dll)