请问:如何在例外时停止程序的运行,并接受重新输入?

kkk321 2000-07-17 06:47:00
请问:如何在例外时停止程序的运行,并接受重新输入?

另:我第一次使用,还不会给分,请一并告知.
...全文
299 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
ymxxm 2000-07-18
  • 打赏
  • 举报
回复
kkk321:
在主Form的active 中处理LoginForm 注意Loginform 的返回值;
例:
设置 LoginForm 的private 变量LoginSuccess:boolean;并在Loginform 的create事件中预为为false;
Button:验证密码成功则LoginSuccess:=true;
// 验证密码
if {验证密码成功} Then
button1.ModalResult:=mrok;
mainform的active事件:
var loginform:tloginform;
Begin
loginform:=tloginform.create(application);
try
with loginform do
if showmodal=mrok then
Exit
Else
Begin
showmessage('you want to show message');
halt;
End;
finally
loginform.free;
End;
End;
w102272 2000-07-18
  • 打赏
  • 举报
回复
to kkk321:
其实对于DATABASE的处理方法和LOGIN的处理方法是类似的。
现描述如下:
在普通DELPHI程序中,DATABASE是放在一个FORM上,然后你的FORM的创建时间中去连接数据库,然后使用TQUERY,TDATASET,等等。但是这样处理,相当于你每FORM都去连数据,是有问题的。
因为:
1、DATABASE连接和一些公共表在程序的FORM之间其实是需要共享的
2、建立一个DATABASE连接要占用比较长的时间
3、如果FORM处理,每FORM都要占用一个DB连接,那么数据库就受不了啦。
4、重复书写DB和表的连接代码,既烦琐又不便于管理。
所以,
DELPHI处理这个的方法,其实就是使用它的DATAMODULE,把所有相关的表放在一个DATAMODULE种,然后在DATAMODULE中使用一个DB连接,所有表SHARE这个连接,然后在FORM中引用这个DATAMODULE,相当于一个统一的数据提供者。

但是,这里其实隐含了一个前提:DATA模块应该是最先被加载的模块,因为DATA模块要为所有的Login等模块提供数据。
这样,我们审视APPLICATION的PROJECT SOURCE,就会发现自动方式有问题,因为APPLICATION。CREATEFORM的顺序其实是有限制的。而且也不能完成象你要求的那样的控制,它只能完成平行结构的控制。而且消息循环是在APPLICATION。INIT到RUN之间CREATEFORM的FORM之间循环的,我们并不一定非要遵循这种结构。

所以程序的结构大致应该是这样的:
1、APPLICATION。INIT
2、初始化一些公共资源,这其实应该是软件服务层的东西:
例如:Tdatamodule, shared form, shared variable, shared object
3、执行应用层的控制,对你的应用来说,就是
create loginform
if loginform.loginok then
mainmodule.execute
else
....
end if
而在LOGINFORM中自然要用到DATAMODULE的数据支持。
在实现上很多结构都要采用动态创建的方法,不能采用DELPHI提供的CREATEFORM,
因为你的应用是分层的,不是APPLICATION中间包含所有FORM的平行结构。

从这里再多说一些,其实你的应用程序也应该是分层的,即:
完整的大系统 :就是卖很多钱的工程实现了。
应用层服务集成 :体现为DLL封装,或者三层体系的应用层
小应用程序 : 你的APPLICATION
应用层FORM : LOGIN, 等处理FORM
软件服务层FORM : TDATAMODULE,SHARED RESOURCE。。。
软件实现部件 : 公共函数库,VCL,COM等等,引入的DLL,
基本实现 : DELPHI的函数,语法和结构
你的程序应该在这个体系上实现,然后在必要的地方做OOP封装。所以这个问题往深里头看,其实是DELPHI程序如何实现应用软件的体系架构问题,不那么简单。

另外,还要说的是:
这里的矛盾反应的其实是OO和传统的结构化设计的矛盾,
我们为什么没法采用 APPLICATION。INIT, CREATFORMS, RUN的方法?
因为存在TDATA,SHARED RESOURCE这样的东西,
尽管DELPHI可以做到完全的OOP封装,但是我们的数据确只有一份,
我们的数据库连接只能共享。
程序可以变成CLASS,但是资源却只有一份,不能OO的。因此必须要变通,在最终实现的时候,OO的方法和传统的结构化,自顶向下方法要妥协。不是单用什么就全能够解决问题的。

OK?

kkk321 2000-07-18
  • 打赏
  • 举报
回复
回复Hank:
我想这里99%以上的人都认为Delphi比PowerBuilder好用!
为什么PB实现登录后打开MDIForm那样轻松,到了这里反而你要劝我放弃MDIForm,用不用MDIForm,是由需求定的,怎能想不用就不用!
答: "停止"是暂停的意思!
问: "太多了"是什么意思?!
"TDataBase控件的位置与实际的情况有很大关系"是什么意思?!,请说具体一些!

另外,W102272的回复我看过了,他的方法我可以接受一部分,我会给他加分的!
但我更想按我的方法来实现.
而且我想应该是可以做到的,为什么我不去尝试呢!
作为一名程序员,我更想去体验,而不是重复.
Hank 2000-07-18
  • 打赏
  • 举报
回复
你需要知道的很多,不过最好按W102272提供的方法。但要提醒的一点是如果你在MainForm的Active事件中加入,那即使切换窗口时也会激活LOGIN窗口!最好在OnShow事件加入!
再说,你的“停止”到底是什么意思?如果真的是停止,那就用线程;如果是再接受输入,那用最基本的代码即可(if 条件 then ... else XXX.Setfocus);如果要捕获错误,那就用异常;如果停止退出,那就用Application.Terminated。
而且TDataBase控件的位置与实际的情况有很大关系,你最好先理解一下W102272的意思。
另:LOGIN的FORM类型要是fsNormal或fsStayOnTop、fsMDIChild应视具体情况而定,但最好不要是fsMDIForm!太多了,最好看一下书!
kkk321 2000-07-18
  • 打赏
  • 举报
回复
回复w102272
首先谢谢各位,
我想再说一句:
是这样的,因为我的应用在运行中需要连接不同的数据库,所以在运行中还会多次打开loginForm,去连接其他数据库。所以我必须要在MainForm中去调用LoginForm,
我现在已经想到了一个办法,等我试过之后在说吧!
kkk321 2000-07-18
  • 打赏
  • 举报
回复
回复ymxxm
对不起,我的LoginForm是自己写的,没有返回值.
kkk321 2000-07-17
  • 打赏
  • 举报
回复
续回复w102272:
上面为假如按照你的方法.
我还是希望知道如何在例外时停止程序的运行.
kkk321 2000-07-17
  • 打赏
  • 举报
回复
回复w102272:
我需要用到database控件,在程序运行期间保持打开.
请问将它放在哪个Form上?我的MDIFormChild们需要它.如果放在LOGIN中,将无法使用,除非不FREE LOGIN;如果放在MainForm中,则无法在LOGIN 中设置!

w102272 2000-07-17
  • 打赏
  • 举报
回复
PS:在大规模DELPHI程序中,除了LOGIN外,其实还要做很多工作,比如设置环境,
设置数据模块,设置公共访问的资源等。都需要这样在主模块启动前自行处理。DELPHI的CREATEFORM不是总好用的。
而且DELPHI这种方式相当于在执行前把所有FORM都CREATE,
当你的FORM达到一定的程度后,机器资源会被惊人地吃掉,那时也一定要采用动态创建的方式来处理啦。
w102272 2000-07-17
  • 打赏
  • 举报
回复
hehe,你不能用DELPHI去设置这个主FORM呀。直接去VIEW PROJECT SOURCE。
DELPHI都是用、
APPlication.initialize;
application.createform(tform,youform);
application.run;来做的。

不要用自动方式,你要把它改成类似:
var myloginform:tmyloginform;

Application.Initialize;

loginok:boolean;
loginok:=false;
while not loginok or logintimes<=3 begin
myloginform:=nil;
try
myloginform:=tmyloginform.create(nil);
myloginform.hide;
myloginform.showmodal;
//然后在MYLOGINFORM中设置这个全局变量login,当然你用类的变量也可以。
Finally
myloginform.free;
end;
end;
//总之程序不是很对,看明白逻辑就行啦。
然后
if loginok then
Application.CreateForm(Tmainform, mainform)
Application.Run;
end;
//否则,自然是TERMINATE啦。
end else application.Terminate;
kkk321 2000-07-17
  • 打赏
  • 举报
回复
回复w102272 :

因为我的MainForm是MDIForm,如果LOGIN为主Form,就无法打开MDIChild(我不明白为什么).所以我只好改为将MainForm作为主Form.

w102272 2000-07-17
  • 打赏
  • 举报
回复
你不应该在MAINFORM中激活LOGIN。
应该把LOGIN过程直接写到APPLICATION的代码中,这样失败后返回的才是最上面的控制。
然后在控制中你就可以决定是启动MAILFORM还是在循环中让他再LOGIN了。
kkk321 2000-07-17
  • 打赏
  • 举报
回复
对不起:

是这样的:

我在MainForm的Active事件中弹出login窗口(自制,没用Delphi带的),
当登录后,应进入MainForm,若失败,则应停止,等待重新输入.

但现在失败后仍然进入MainForm,请教?
lowhand 2000-07-17
  • 打赏
  • 举报
回复
try
begin
...
end
except
end;
edit1.setfocus;
Hank 2000-07-17
  • 打赏
  • 举报
回复
用异常操作!
try
Edit3.Text:=FloatToStr(StrToFloat(Edit1.Text)/StrToFloat(Edit2.Text));
except
on EZeroDivide do
begin
ShowMessage('被除数不能为零!');
Edit2.SetFocus;
end
end;
WHQ 2000-07-17
  • 打赏
  • 举报
回复
听不明白你的意思

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧