目前为止尚无人能解答的难题(300分)

  • 主题发起人 主题发起人 gameabc
  • 开始时间 开始时间
测试用的代码如下,如果您能通过添加代码让程序在win98或者windows me下体面的退出,
我把600分全部送上!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ShellApi, ExtCtrls;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FTimer : TTimer;
TmpBmp : TBitmap;
procedure Timer1Timer(Sender: TObject);
public
{ Public declarations }
end;
var Form1: TForm1;
 
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var I : Integer;
begin
FTimer := TTimer.Create(self);
FTimer.Interval := 10;
FTimer.OnTimer := Timer1Timer;
WindowState := wsMaximized;
TmpBmp := TBitmap.Create;
TmpBmp.LoadFromFile('c:/windows/Bubbles.bmp');
For I:=1 To 100 Do
ShellExecute(Application.Handle, PChar('open'),
PChar('About:blank'), PChar(0), nil, SW_NORMAL);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin TmpBmp.Destroy;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var X,Y : Integer;
begin
If (TmpBmp.Width = 0) or (TmpBmp.Height = 0) Then Exit;
For X := 0 To (Width div TmpBmp.Width) Do
For Y:= 0 To (Height div TmpBmp.Height) Do
Canvas.Draw(X*TmpBmp.Width,Y*TmpBmp.Height,TmpBmp);
end; end.
 
你把绘画的过程放在 Form 的 OnPaint 事件中就行了,为什么要
用TTimer,嫌你的 CPU 不够忙?
 
问题不是在这里。
如何截获这个异常才是关键。
这只是一个产生异常的代码
 
如xeen提出的,你的程序设计有错误,你不是去修改错误,反而想着怎么在发生错误
时体面的退出。然后还说这个问题无人能解。

你如果把系统的资源都耗尽了,系统怎么有资源来让你体面的退出?除非你能在
程序启动的时候判断你需要的资源和系统所剩的资源,进行比较,如果小于就退出。
 
就是改成在OnPaint中也是一样的错误
 
因为是上班一族,没有太多时间去作测试,只提供一个思路给你,希望能够
有所帮助……至于说积分,真不明白到底有什么用,又不能换钱……唉!
现在最缺的就是钱哪!哈哈!

一、到底谁是造成资源泄漏的凶手?
Win9x天生的就是一个不防泄漏的蠢家伙,以前我用Win98+Delphi开发系统,
每天至少蓝屏一次,当然,单元测试阶段几率高些,系统测试阶段几率低些,
这其中固然有系统本身的问题,但现在采用Win2k,一个星期不关机也不会倒……

二、TApplication.OnException事件可以利用
Delphi定义了一些错误类型:EOutOfMemory和EOutOfResources,只要
在Application.OnException里面处理这两个异常,然后其他的异常
执行默认异常处理方法HandelException就行了。

三、至于说通过获取系统的可用资源率来判断系统是否可运行,
我个人认为不适合作为一种解决问题的方法。
 
原来是这个问题:
1、无论如何,这个程序证明不了是因为Delphi编的程序的问题,如果你有机会试试VC或者其他任何开发工具,用同样的方法,做同样的事。结果也会是一样的。
2、IE在耗资源早已是不可否认的事实,你一口气开了100个IE,天哪,Win9X仅有的那一点点资源哪!
3、还把Timer的时间间隔设为10ms!My GOD!
4、在Form的OnDestory事件中应该先把Timer1.Enabled:=False,最好是手动把Timer释放掉,因为可能会在TmpBmp.Destroy后还Form没有释放Timer的时候触发
一次OnTimer,这时会触发异常,因为TmpBmp已经不存在了。
5、Delphi为对象设了一个Free方法不是没事找事,这个方法在调用Destory函数前会检查对象指针是否为nil,直接调用Destory不是个好习惯。
6、还是不明白楼主的意思?是说Delphi有问题呢(我是觉得扯不上边)?还是说Win9X的问题呢(好象是不用说的)?还是说你的程序的问题?还是。。。?
 
to:aizb
我不是想说明什么问题,而是说如何去捕捉这个异常?
并且让程序能自己退出来,而不是关电源重新启动
 
to:gztomash
为了钱,我们在日夜打拼。
我的问题是如果程序在刚开始运行,或者运行中,因为外界的影响,
系统资源已经严重不足了,如何让程序能自动退出,而不是继续去自行下一步,
以致机器死机。
如果程序能在Draw的时候知道自己的下一个操作会使系统资源不够的,
那么就让自己退出来,而不是继续执行下去
 
你这样做让我感觉到好象是:
我一口气吃了100Kg压缩饼干,喝了10kg水,手喝拿着啤酒瓶去到医院问医生我如何才能去参加奧运行花样滑冰比赛。
 
我建议你试试看TApplication.OnException,应该会有所帮助。

type
TMainForm = class(TForm) // 你的主窗口
private
procedure AppOnException(Sender: TObject; E: Exception);
...
end;

...
procedure TMainForm.FormCreate(Sender: TObject);
begin
Application.OnException := AppOnException;
end;

procedure TMainForm.AppOnException(Sender: TObject; E: Exception);
begin
if (E is EOutOfMemory) or (E is EOutOfResources) then
Application.Terminate // 当然,你也可以退出得体面些
else Application.ShowException(E);
end;

另外,我想程序为什么这样写,当然有你的理由,
不过从我的分析来看,你大概只是想画一个背景而已吧?
那么你的做法就未免有点太狠了……呵呵!
还不如直接放一个TImage在上面……
 
to:aizb
你的比喻非常好,不过,我的想法不是说要去比赛,而是在吃100Kg压缩饼干的过程中,
不要等肚子破了,才停止吃饼干。
 
那么,如何判断自己是否已经吃饱了呢?
 
Ftimer的Interval设得太短了,导致CPU资源基本全被这个程序占用。
 
可以检查系统资源、GDI资源使用情况,如果太小就及时退出
有一个SystemInfo控件可以得到资源使用情况
个人想法,不知行不行。
 
图片在DELPHI中本来就消耗资源,让你这样一搞,还能正常才怪,设计有问题
 
前面有人给出方案了,挺好
SetErrroMode(SEM_FAILCRITICALERRORS);
然后自己try...except...吧
我试了一下,在form2里设了100多个控件,
然后在form1里不停创建、显示,
捕获异常后再把创建的form2全部删除,
大约在创建170多个form2后结束,
而没有出现资源不足的系统警告
 
我这里也有一段循环,不知道怎么才能使它知道退出:
unit Unit1;
interface
uses
Windows, Forms;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;
var
Form1: TForm1;
str:string='dxdiag.exe';
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
SI:TStartupInfo;
PIfo:TProcessInformation;
begin
i:=0;
FillChar(SI, SizeOf(SI), #0);
SI.cb:=SizeOf(SI);
SI.dwFlags:=1;
SI.wShowWindow:=i;
while i < 1024 do begin
CreateProcess(nil,PChar(str),nil,nil,false,128,nil,nil,SI,PIfo);
inc(i);
end;
end;
end.
我对这方面知道得不多,最好详细讲讲,谢谢了。
( 哈哈哈哈,本代码初学者请勿使用,它将导致你的系统崩溃。特此注明 )
( 中国的共享软件作者如果都是这样的,最好从字典上去掉共享这两个字 )
 
后退
顶部