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

先看代码:

代码 

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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的过程,我这里是直接传递对象指针进来。这个对象的定义在下面的代码中:

代码 

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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.

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

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

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->unit pub_Event;

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

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

代码 

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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 = # then
begin
Key := #;
Keybd_Event(VK_TAB, , , );
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/

http://www.cnblogs.com/kfarvid/archive/2010/08/06/1794307.html

Delphi捕捉DLL执行所抛出的异常。的更多相关文章

  1. 捕获Java线程池执行任务抛出的异常

    捕获Java线程池执行任务抛出的异常Java中线程执行的任务接口java.lang.Runnable 要求不抛出Checked异常, public interface Runnable { publi ...

  2. 想抛就抛:Application_Error中统一处理ajax请求执行中抛出的异常

    女朋友不是想抛就抛,但异常却可以,不信请往下看. 今天在MVC Controller中写代码时,纠结了一下: public async Task<ActionResult> Save(in ...

  3. 外部无法捕捉Realm的doGetAuthenticationInfo方法抛出的异常

    shiro权限框架,用户登录方法的subject.login(token)会进入自定义的UserNamePasswordRealm类的doGetAuthenticationInfo身份验证方法 通常情 ...

  4. 应该抛出什么异常?不应该抛出什么异常?(.NET/C#)

    我在 .NET/C# 建议的异常处理原则 中描述了如何 catch 异常以及重新 throw.然而何时应该 throw 异常,以及应该 throw 什么异常呢? 究竟是谁错了? 代码中从上到下从里到外 ...

  5. druid抛出的异常------javax.management.InstanceAlreadyExistsException引发的一系列探索

    最近项目中有个定时任务的需求,定时检查mysql数据与etcd数据的一致性,具体实现细节就不说了,今天要说的就是实现过程中遇到了druid抛出的异常,以及解决的过程 异常 异常详细信息 五月 05, ...

  6. Java中主线程如何捕获子线程抛出的异常

    首先明确线程代码的边界.其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界.Runnable接口中run方法原型如下: public void run(); 而所有的具 ...

  7. 记录一次dubbo不能正常抛出特定异常

    BUG场景 今天同事的代码中出现一个问题,让我帮忙排查一下.原代码大致如下 dubbo服务消费者: @Resource private IPayWayService payWayService; @R ...

  8. 将Controller抛出的异常转到特定View

    <!-- 将Controller抛出的异常转到特定View --> <bean class="org.springframework.web.servlet.handler ...

  9. 使用visual studio 2015调用阿里云oss .net sdk 2.2的putobject接口抛出outofmemory异常

    问题描述: 使用阿里云oss .net sdk 2.2版本,使用putobject接口上传文件时,抛出outofmemory异常. 原因分析: 上传时,用于准备上传的数据缓冲区内存分配失败.与应用软件 ...

随机推荐

  1. 微信公众账号 Senparc.Weixin.MP SDK 开发教程

    http://www.cnblogs.com/szw/archive/2013/05/14/weixin-course-index.html 微信公众账号 Senparc.Weixin.MP SDK ...

  2. C# 高精度减法 支持小数(待优化)

    是现实思路 1,先小数点补位,8913758923475893274958738945793845-4893127498372459823745324532453245.284929384729837 ...

  3. C语言 宏/macor/#define/

    C语言 宏/macor/#define 高级技巧 1.在进行调试的时候,需要进行打印/PRINT,可以通过define进行自定义.例如,自己最常用的DEBUG_PRINT() #define DEBU ...

  4. windows phone 操作 http异步返回结果

    wp中为了提升用户体验,砍掉了http的同步操作,仅支持http异步请求,那么该如何及时处理异步操作返回的结果.纠结了很久,终于在技术群中好友的帮助下解决了问题,借助事件,将异步编程模型模式简单的处理 ...

  5. Nwjs从入门到精通 菜鸟实践笔记【1】

    最近公司有想使用Nw来开发浏览器的想法,自己一直学的PHP,在网上并没有找到太多的相关资料,所以,就自己摸索着撸一条自学笔记: 当然呢,这里记录的都是我自己学习中遇到的问题,以及收获,希望通过自己的分 ...

  6. ubuntu的syslog为空,停止写入解决方法

    修改syslog权限: chown syslog:adm syslog

  7. Python3 内建模块 hashlib、itertools、HTMLParser、urllib

    Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制 ...

  8. 大型B/S系统技术总结(不断更新)

    看了<淘宝技术这十年>和<大型网站系统与Java中间件实践>这些书,对大型B/S系统的构建越来越感兴趣,于是尝试收集和总结一些常用的技术手段.不过大型网站的架构是根据业务需求不 ...

  9. Linux硬链接和符号链接(转)

    Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接]  硬连接指通过索引节点来进行连接.在Li ...

  10. 整理sed实战修改多行配置技巧

    老男孩老师有关sed实战技巧分享,来自课堂教学内容实战1.在指定行前插入两行内容,分别为oldboy和oldgirl.提示:被修改的文件内容必须要大于等于2行 1 sed -i '2 ioldboy\ ...