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。
 
这样动态调用的好处就是节省了内存资源,使用后立即释放内存。
原文地址:https://www.cnblogs.com/delphi7456/p/1858107.html