在大富翁转了几圈,发现富翁们爱讨论理论性的问题,而不太喜欢技术细节方面的问题(对于富翁们来说,重复的太多),我的问题估计富翁们以前不会遇到过,也不能算是细节类的

  • 主题发起人 主题发起人 wk_knife
  • 开始时间 开始时间
W

wk_knife

Unregistered / Unconfirmed
GUEST, unregistred user!
在大富翁转了几圈,发现富翁们爱讨论理论性的问题,而不太喜欢技术细节方面的问题(对于富翁们来说,重复的太多),我的问题估计富翁们以前不会遇到过,也不能算是细节类的问题,求教富翁为我弄懂基本概念(100分)<br />为了不让富翁们多跑路,我把问题贴过来:


[blue]问题:小小的问题————给还愿意为初学者解惑答疑的富翁————也许值得一看,路过了别错过 ! ( 积分:100, 回复:6, 阅读:68 )
分类:IDE/使用技巧 ( 版主:luyear, menxin )
来自:wk_knife, 时间:2001-10-25 14:11:00, ID:689640 | 编辑 [显示:小字体 | 大字体]
Marco Cantu在《Delphi5从入门到精通》中说“在处理对象某个时间的同时,不能
消除该对象,否则会引起一个异常”

在Delphi的帮助中有如下一段话:
Warning: Never explicitly free a component within one of its own event
handlers or free a component from the event handler of a
component it owns or contains. For example, don't free a button
in its OnClick event handler or free the form that owns the
button from the button's OnClick event.

在窗体中建立一个按纽,处理OnClick
事件时:
procedure TForm1.ButtonKeyPress(Sender:TObject,var Key:Char)
begin
if Key=#8 then
Sender.Free;
end;
未出现任何问题(当然一般没人会写这样的代码)


请各位富翁就KeyPress事件写一个可以引发异常的代码。
或者是Marco Cantu说错了,而帮助也并没有说会发生异常。










来自:wk_knife, 时间:2001-10-25 14:28:00, ID:689681 | 编辑
对于OnClick也是一样的 。



来自:wk_knife, 时间:2001-10-25 14:30:00, ID:689684 | 编辑
难道富翁们不觉得的这背后隐藏着很深的奥秘?



来自:wk_knife, 时间:2001-10-25 14:38:00, ID:689702 | 编辑
就算“GZ”也行啊,给点信心好吗?



来自:Cowry, 时间:2001-10-25 14:46:00, ID:689719
Sender.Free是不是把整个程序给终止了?
改成Button.Free试试?应该就会引发异常了吧


来自:wk_knife, 时间:2001-10-25 14:51:00, ID:689731 | 编辑
试过了的,一样的结果。按钮不见了,其他什么也没发生。


来自:zhangkan, 时间:2001-10-25 14:52:00, ID:689734
我将Form的KeyPress事件中加上,结果居然表单都不见了,但程序还在运行.程序又只有这一个
表单,我也想知道原因.
[/blue]

 
有想法尽管说:
包括批评我脑袋不转弯——只不过是个特例
或者钻了牛角尖等等。
无所谓的。

我不想不求甚解
给我个明白吧,打清醒也可以。

我会噎得睡不着的
 
帮助里又没有说一定会发生异常.

也就是说这并不是不合语法的用法,只是这样用不是一个很好的编程习惯.
 
没问题,click的消息已经发出,而事件处理代码为form所有。
 
agree liuyuch2000
Sebder只是调用一下procedure而已
 
是不是你的Free后没代码...所以没异常~?
 
新建一个工程,什么都不做,只写了下面的事件,执行报错。
你可以试一试,我认为帮助上说的是正确的。
procedure TForm1.FormClick(Sender: TObject);
begin
Form1.Free;
end;
 
警告的意思是可能出错的代码,谁也没有说一定会出错啊。就象源代码的Warning一样。
不过下段代码出是必定出错的:
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
S: string;
P: PChar;
begin
Sender.Free;
S := 'asdfasdf';
P := @S[1];
for I := 1 to Length(S) do
begin
ShowMessage(Char(P^));
Inc(Integer(P));
end;
end;
 
在form建立时free它试试[:D][:D][:D]
 
来自:marknew, 时间:2001-10-25 16:58:00, ID:690060
Button的click事件的要sender是这个Button本身。
Form的Keypress里的Sender是这个Form。你Free它们当然会消失啦.研究这种东西有什么
意义,要理解它们。在Button上click里写Free,这时候并没有任何操作同时处理
处理这个Button呀。

来自:westboy2000, 时间:2001-10-25 18:38:00, ID:690243
新建一个工程,什么都不做,只写了下面的事件,执行报错,你可以试一试。
procedure TForm1.FormClick(Sender: TObject);
begin
Form1.Free;
end;

来自:sword_liu, 时间:2001-10-25 18:59:00, ID:690309
sender.free表示你发送对象free掉,当然按钮就不见了。

来自:Jiao_he, 时间:2001-10-26 1:11:00, ID:690781
是不是先Free了再执行事件,如在OnKey中
begin
button1.Free;
showmessage('test');
end;
showmessge可正常提示,但之后就会出错.



来自:wk_knife, 时间:2001-10-26 8:12:00, ID:690848 | 编辑
以上我的问题并不是对所有的类,及事件都成立的,这一点我也很清楚。
比方在拖动的一系列操作的开始阶段肯定不能释放对象。

我只是想知道为什么在Form以下的控件被释放时(用Click),它居然不弹出异常。
同marknew所说的意思有点一样,在Click中究竟是谁操作了消息,Button还是它的拥有者?




 
按帮助上的说明,在处理KeyPress消息时,消息由谁处理是由form的keypreview属性来决定的
默认为false,即交给控件本身处理。也就是说至少button处理了按键,但释放是由谁释放的呢?

另外想到一点,TLabel本身不具备处理消息的能力,但Delphi 为它包装了消息事件,那么又是谁为它处理了事件?
这个大家都比较好理解。

所以我想,问题总并不总是我们所看到的那样。

 
我想 如果会出问题是因为内存访问出错

一个对象在释放后 不去使用它 当然不会有问题
 
lha ,我也是这样想的。
可是Marco Cantu的意思应该是不可以。我就想知道不可以在那,包括帮助所说。

在我提供的例子中再free后加上一句nil和showmessage程序照样没问题说明其实button并没有处理事件,而是Form
在处理。

如果消息和所有的操作事实上都是由Application或Form来操作,而非控件本身(虽然名义上是它)
那么就好理解了。出错是因为后面还有消息是由现在的消息引发而还要继续,而不出错是因为到此就打住了。

所以出不出错要视具体的消息而定,也就是出错是因为还要用到它,如果不再用了就不会出错。
所以Marco Cantu在Warning之上的进一步阐述是不全面的。

不知道大家认为我的想法是否正确。

 
如果对Form重复上面的步骤就会出错。
 
多人接受答案了。
 
这要看具体的情况。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
634
import
I
后退
顶部