Delphi捕捉DLL执行所抛出的异常。

先来说一下我如何写我的Dll文件的。

先看代码:

 

ExpandedBlockStart.gif 代码
library  pub_form;

uses
  SysUtils,
  Classes,
  Windows,
  Forms,
  Parameter_Object,
  frm_LoginU 
in   ' ..\公用库单元\frm_LoginU.pas '   { frm_Login } ,
  pub_Event 
in   ' ..\公用库单元\pub_Event.pas ' ,
  Dll_LIB_ConstU 
in   ' ..\公用库单元\Dll_LIB_ConstU.pas ' ;

var
  DLLApp: TApplication;

{ begin-----------------------登录窗体相关------------------------- }

procedure  Login( var  mLoginParam: TLoginParam);  export ;
begin
  
{ 获取调用窗体的Application,显而易见的功能是 能使你的窗体融合到调用程序中。通过它还能进行很多操作 }
  Application :
=  mLoginParam.App;  // 将DLL的Application转为App
  
if  frm_Login  =   nil   then
    frm_Login :
=  Tfrm_Login.Create(mLoginParam.ParentForm);
  frm_Login.DoLoginClick :
=  mLoginParam.DoLogin;
  frm_Login.DoErrCatch:
= mLoginParam.ErrDo;
  frm_Login.E_User.Text:
= mLoginParam.OldUser;
  frm_Login.ShowModal;
end ;

procedure  CloseLogin;  export ;
begin
  
if  frm_Login.Showing  then
    frm_Login.Close;
end ;

{ end-----------------------登录窗体相关------------------------- }

{ 重写Dll入口函数,否则程序会出错 }

procedure  DLLUnloadProc(Reason: Integer);  register ;
begin
  
{ DLL取消调用时,发送DLL_PROCESS_DETACH消息,此时将DLL的Application返回为本身 }
  
if  Reason  =  DLL_PROCESS_DETACH  then  Application : =  DLLApp;
end ;

exports
  Login,CloseLogin;

begin
  
{ 在DLL入口预先储存DLL的Application }
  DLLApp :
=  Application;
  
{ DllProc:DLL入口函数指针。Delphi定义为 DllProc: TDLLProc; }
  
{ 在此指向我们自己定义的函数 }
  DLLProc :
=  @DLLUnloadProc;
end .

 

代码中都有注释了,这个不多说了,说一下Login的过程,我这里是直接传递对象指针进来。这个对象的定义在下面的代码中:

 

ExpandedBlockStart.gif 代码
unit  Parameter_Object;
{
调用DLL的参数对象类

}

interface
uses
  pub_Event,Forms;


type
  TDllFormParam
= class (TObject)
  
public
    App: TApplication;
    ParentForm:TForm;
    ErrDo:TExceptionEvent;
    
constructor  CreateByObject( var  mApp: TApplication; var  mParentForm:TForm;mErrDo:TExceptionEvent);
  
end ;

  TLoginParam
= class (TDllFormParam)
  
public
    DoLogin:TLoginClickEvent;
    OldUser:String;
// 上次登录的用户
    
constructor  CreateByObject( var  mApp: TApplication; var  mParentForm:TForm;mErrDo:TExceptionEvent;mDoLogin:TLoginClickEvent;mUser: string = '' );
  
end ;

implementation

{  TLoginParam  }

constructor  TLoginParam.CreateByObject( var  mApp: TApplication;
   
var  mParentForm: TForm;mErrDo:TExceptionEvent; mDoLogin: TLoginClickEvent;mUser: string = '' );
begin
  
inherited  CreateByObject(mApp,mParentForm,mErrDo);
  DoLogin:
= mDoLogin;
  OldUser:
= mUser;
end ;

{  TDllFormParam  }

constructor  TDllFormParam.CreateByObject( var  mApp: TApplication;
  
var  mParentForm: TForm;mErrDo:TExceptionEvent);
begin
  App:
= mApp;
  ParentForm:
= mParentForm;
  ErrDo:
= mErrDo;
end ;
end .

 

 

这样做的好处是不用那么多参数出现,也方便动态的调用方式。

还有一个不太重要的单元:

 

unit  pub_Event;

interface
uses
  SysUtils;

type
  
// 点击登录按钮时触发外部检测帐号与密码是否正确
  TLoginClickEvent 
=   procedure (UserName, UserPW:  string of   object ;

implementation

end .

 

下面是这个登录传递的源码:

 

ExpandedBlockStart.gif 代码
unit  frm_LoginU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, pub_Event;

type

  Tfrm_Login 
=   class (TForm)
    E_User: TEdit;
    E_PassWD: TEdit;
    btn_Login: TButton;
    btn_Exit: TButton;
    
procedure  FormKeyPress(Sender: TObject;  var  Key: Char);
    
procedure  btn_ExitClick(Sender: TObject);
    
procedure  btn_LoginClick(Sender: TObject);
    
procedure  FormClose(Sender: TObject;  var  Action: TCloseAction);
  
private
    
{  Private declarations  }
  
public
    
{  Public declarations  }
    DoLoginClick: TLoginClickEvent;
    DoErrCatch:TExceptionEvent;
  
end ;

var
  frm_Login: Tfrm_Login;

implementation

{ $R *.dfm }

procedure  Tfrm_Login.FormKeyPress(Sender: TObject;  var  Key: Char);
begin
  
if  key  =  # 13   then
  
begin
    Key :
=  # 0 ;
    Keybd_Event(VK_TAB, 
0 0 0 );
  
end ;
end ;

procedure  Tfrm_Login.btn_ExitClick(Sender: TObject);
begin
  self.close;
end ;

procedure  Tfrm_Login.btn_LoginClick(Sender: TObject);
begin
  
if  Assigned(DoLoginClick)  then
  
begin
    
try
    DoLoginClick(trim(E_User.Text), Trim(E_PassWD.Text));
    
except    on   e:Exception    do
      DoErrCatch(sender,e);
    
end ;
  
end ;
end ;

procedure  Tfrm_Login.FormClose(Sender: TObject;  var  Action: TCloseAction);
begin
  Action:
= caFree;
end ;

end .

 

 

全部都出来了,我说下我这个DLL的登录验证窗体的工作方式:把登录的验证方法放在主程序里面,因为,不同时期不同的开发项目,其登录验证方式都不一样,因此独立出主程序里,采用回调的方式来实现。由于登录窗体需要到数据库中去验证帐号和密码,因此,我特意把字段输错,这里所报的异常不会被主程序捕捉到,为何不会被主程序捕捉到?我猜是因为调用这个验证方法是一个DLL,而DLL毕竟不是主程序,因此,其错误消息是不会被主程序所捕捉到的,就算开始的时候把application传到了dll里面去也一样捕捉不到(如果能捕捉到的,请把方法告诉我,我找了很久都没找到相关的资料),在网上找了个资料,网址是:

http://www.delphibbs.com/delphibbs/dispq.asp?lid=3660866

根据这个提示,我把异常处理的方法也传进去了,这样,在验证登录方法时出错了,也能调用主程序中的捕捉异常的方法。

 

原创作品出自努力偷懒,转载请说明文章出处http://www.cnblogs.com/kfarvid/

转载于:https://www.cnblogs.com/kfarvid/archive/2010/08/06/1794307.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值