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: stringof 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, 
000);
  
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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410940.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker版本Mysql安装

docker部署mysql 1. 下载 [rootlocalhost my.Shells]# ./dockerStart.sh start or stop start Redirecting to /bin/systemctl start docker.service [rootlocalhost my.Shells]# docker pull mysql Using default tag: latest Trying to pull repository docker.io/library/…

matlab 左上角,matlab – 访问’uitable`的左上角

在uitable中,我想访问行标签上方的单元格以及列标签的左侧.我想在该领域加上一些文字.可以这样做吗?最佳答案 简短的回答是肯定的,但这有点痛苦.您可以添加文本uicontrol并正确定位.一个功能的例子:% Dummy figure and tablef figure;d gallery(intege…

eclipse MyEclipse中安装 spket插件 js文件内容字体变小解决方案

在 eclipse 、 MyEclipse 中用 Spket 插件打开 js 文件后,发现字体非常小。(在每次重启eclipse时会出现)这个时候你只需要找到 Window->General->Appearance->Colors and Fonts ->Basic-Text Font ,点击右边的change&…

planning algorithms chapter 2

planning algorithms chapter 2 :Discrete Planning 离散可行规划导论 问题定义 在离散规划中,状态是“可数”的,有限的。 离散可行规划: 非空状态空间 X对于每个状态 x,存在一个有限的动作空间 U(x)对于每个状态和动作空间,存在状…

前端手动封装数组的foreach,map,filter,every,some,Reduce,reduceRight方法

我是歌谣 放弃很容易 但坚持一定很酷 公众号小歌谣 谢谢关注 前言 Foreach Array.prototype.myForEach function (cb) {var _arr this;var _len _arr.length;var _arg2 arguments[1] || window;for (var i 0; i < _len; i ) {cb.apply(_arg2, [_arr[i], i, _arr]);} …

[html] a标签的默认事件禁用后,如何实现跳转?

[html] a标签的默认事件禁用后&#xff0c;如何实现跳转&#xff1f; 给a标签添加点击事件利用 location.href 进行跳转个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面…

锤子剪刀布pat-1018

题目描述 大家应该都会玩“锤子剪刀布”的游戏&#xff1a;现给出两人的交锋记录&#xff0c;请统计双方的胜、平、负次数&#xff0c;并且给出双方分别出什么手势的胜算最大。 输入描述: 输入第1行给出正整数N&#xff08;<105&#xff09;&#xff0c;即双方交锋的次数。随…

mda.helper.php,dedecms后台更新缓慢甚至卡死怎么办

问题描述&#xff1a;如果我们在使用织梦程序(2018-01-09)&#xff0c;有可能会遇到后台更新网站、更新文档HTML、添加文档卡死的问题。该如何解决呢&#xff1f;(学习视频分享&#xff1a;编程视频)解决方法&#xff1a;如果你正在用的是最新版的织梦程序(2018-01-09)&#xf…

关于开心网的服务器

1.开心网的主站采用了DNS轮询技术&#xff0c;所谓DNS轮询&#xff0c;就是一个域名对应几条A记录&#xff0c;如开心网的主站有6台服务器DNS轮询有一个缺点&#xff0c;如果域名所指向的某一个台服务器或几台服务器出现了问题&#xff08;如Web服务器停止服务)&#xff0c;则D…

[html] 如何禁用掉a标签的默认事件?

[html] 如何禁用掉a标签的默认事件&#xff1f; a onclick"prevent" function prevent(e) { e.preventDefault(); }个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关…

PHP3.2.3 where or,WHERE · ThinkPHP3.2.3完全开发手册 · 看云

where方法的用法是ThinkPHP查询语言的精髓&#xff0c;也是ThinkPHP ORM的重要组成部分和亮点所在&#xff0c;可以完成包括普通查询、表达式查询、快捷查询、区间查询、组合查询在内的查询操作。where方法的参数支持字符串和数组&#xff0c;虽然也可以使用对象但并不建议。##…

P2896 [USACO08FEB]一起吃饭Eating Together 解题报告

题目传送门 题目不是很难&#xff0c;看了一会就想到了&#xff0c;但因为一些细节WA了好几遍qwq 但代码却一点一点压短了&#xff08;看了别人的精简写法&#xff09; 题目分析 把一个序列改成不上升或不下降子序列&#xff0c;求最少修改次数。 一般情况有求 LIS 和 LDS 的 O…

[html] 写出不定宽度的子级div,在相对于固定宽度的父级元素水平居中的布局

[html] 写出不定宽度的子级div&#xff0c;在相对于固定宽度的父级元素水平居中的布局 <div class"father"> <div class"son"></div> </div>.fateher { display:flex; algin-items: center; }个人简介 我是歌谣&#xff0c;欢迎…

MySQL第五天

复制表结构 1 #从src_table复制到dst_table2 CREATETABLEdst_table LIKEsrc_table;3 4 #另外一种方法5 CREATETABLEdst_table SELECT*FROMsrc_table WHERE0;6 7 #第一种方法比第二种方法简单实用效率高8 9 10 #复制表中数据11 #完全复制src_table12 CREATETABLEdet_table SELEC…

九种跨域方式实现原理

前言 前后端数据交互经常会碰到请求跨域&#xff0c;什么是跨域&#xff0c;以及有哪几种跨域方式&#xff0c;这是本文要探讨的内容。 本文完整的源代码请猛戳github 博客 一、什么是跨域&#xff1f; 1.什么是同源策略及其限制内容&#xff1f; 同源策略是一种约定&#xff0…

oracle存储过程更新权限不足,oracle创建存储过程时报权限不足

今天在自己的用的下创建了一个简单的存储过程做测试create or replace procedure hello isv_variable number(3);beginselect count(*)into v_variablefrom dual;dbms_output.put_line(‘the variable is’||v_variable);end hello;结果报错&#xff0c;我先检查了一下我用户的…

[html] 说说你对移动优先布局的理解

[html] 说说你对移动优先布局的理解 移动优先布局&#xff0c;应该是基于这样一个前提&#xff1a; 如今web页面的移动端用户量&#xff08;访问量&#xff09;要远远大于pc端等设备 所以是优先服务于移动端的 那么采用移动优先布局的策略才能最大化页面的使用 移动优先布局即…

关于TableView中图片的延时加载(转)

经常我们会用tableView显示很多条目, 有时候需要显示图片, 但是一次从服务器上取来所有图片对用户来浪费流量, 对服务器也是负担.最好是按需加载,即当该用户要浏览该条目时再去加载它的图片。重写如下方法- (void)tableView:(UITableView *)tableView willDisplayCell:(UITable…

oracle数据库视图有红叉,oracle触发器 前面的红叉是什么意思

一个触发器试图修改或查询目前正在触发器语句修改的表。建议改一下你的触发器逻辑。网上也有解释:error:ora-04091: table name is mutating, trigger/function may not see itcause:a statement executed a trigger or custom pl/sql function. that trigger/function tried t…