香港帝景园:Delphi捕捉DLL执行所抛出的异常。
来源:百度文库 编辑:偶看新闻 时间:2024/05/03 10:37:25
先来说一下我如何写我的Dll文件的。
先看代码:
代码 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的过程,我这里是直接传递对象指针进来。这个对象的定义在下面的代码中:
代码 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.
下面是这个登录传递的源码:
代码 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
根据这个提示,我把异常处理的方法也传进去了,这样,在验证登录方法时出错了,也能调用主程序中的捕捉异常的方法。
关于抛出异常的问题
oracle触发器如何抛出异常
怎么抛出14个异常呢?应该是4个异常啊!!那里的问题哦
java异常捕捉特点
delphi 编程 关于语句的执行问题?
要在Servlet的doPost里面访问数据库,doPost的异常抛出怎么写?
在java中抛出异常的时候,throw和throws有什么区别?
客户端中断,服务器socket抛出异常,怎么办?
delphi写的dll文件怎么编译?
关于delphi中DLL释放的困惑
delphi编写的DLL如何连接数据库?
delphi中封装DLL的问题!!!
delphi 语句不执行?
delphi如何执行文件
能禁止.dll文件的执行吗????
执行当前 Web 请求期间生成了未处理的异常。
vb如果捕捉datagrid 所单击行的某一列
DELPHI编写DLL问题
delphi dll 获得路径
delphi dll 动态连接
java高手请指点--为什么总是抛出异常
cin失败时会不会抛出一个异常啊?
我用金山杀毒的时候发现了-异常捕捉缺少文件
delphi执行入口在哪里?