各位大虾好!!!小弟最近在学习的时候发现,在程序动行时动态生成的控件在消毁时有时会弹出系统错误对话框,不知道怎么才可以实现正常消毁动态生成的控件而不会出现系统异常。下面是小弟写的代码,请各位大虾狠P啊!!!谢谢!!!......procedure TForm1.SelfFree(Sender: TOjbect; var Key: Word; TShift: TShiftState);
begin
if Key=VK_RETURN then
a.Free; //这一段小弟认为有错,但不知道该怎么写,痛苦ing啊!!!
end;procedure TForm1.Button1Click(Sender: TOjbect);
var
a: TEdit; //这一段是不是不应该放在这里啊,要是放到TForm1的定义行吗,或做成全局变量!??
begin
a:=TEdit.Create(Self);
a.Parent:=Self;
a.OnKeyDown:=SelfFree;
end;以上代码错误百出,请热心大虾多多指教,小弟走弯路走得实在是太多了,好累啊,呜呜~~~
begin
if Key=VK_RETURN then
a.Free; //这一段小弟认为有错,但不知道该怎么写,痛苦ing啊!!!
end;procedure TForm1.Button1Click(Sender: TOjbect);
var
a: TEdit; //这一段是不是不应该放在这里啊,要是放到TForm1的定义行吗,或做成全局变量!??
begin
a:=TEdit.Create(Self);
a.Parent:=Self;
a.OnKeyDown:=SelfFree;
end;以上代码错误百出,请热心大虾多多指教,小弟走弯路走得实在是太多了,好累啊,呜呜~~~
begin
if Key=VK_RETURN then
tedit(sender).Free; //这一段小弟认为有错,但不知道该怎么写,痛苦ing啊!!!
end;
procedure TForm1.Button1Click(Sender: TObject);
var
a: TEdit; //这一段是不是不应该放在这里啊,要是放到TForm1的定义行吗,或做成全局变量!??
begin
a:=TEdit.Create(Self);
a.Parent:=Self;
a.OnKeyDown:=SelfFree;
end;
a: TEdit;
procedure TForm1.onkeydown(Sender: TObject; var Key: Word; TShift: TShiftState);
begin
if Key=VK_RETURN then
a.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
a:=TEdit.Create(Self);
a.Parent:=Self;
a.OnKeyDown := onkeydown;
end;
这样好象就可以,你试一下
begin
if Key=VK_RETURN then
a.Free; //这句可以不要
end;procedure TForm1.Button1Click(Sender: TOjbect);
begin
a:=TEdit.Create(Self);
a.Parent:=Self;
a.OnKeyDown:=SelfFree;
end;
begin
if Key=VK_RETURN then
tedit(sender).Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TEdit.Create(Self) do
begin
Parent:=Self;
OnKeyDown:=SelfFree;
end;
end;
报错的机率为:40%
unit Main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure EditKeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
iNum: Integer;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
Randomize;
with TEdit.Create(Self) do
begin
Inc(iNum);
Name := 'Edit' + IntToStr(iNum);
Parent := Self;
Top := Random(200);
Left := Random(200);
Text := Name;
OnKeyPress := EditKeyPress;
end;
end;procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);
begin
if (Sender is TEdit) and (Key = #13) then
begin
(Sender as TEdit).Free;
end;
end;end.
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
procedure EditKeyPress(Sender: TObject; var Key: Char);
procedure ReleaseButton(obj: TObject);
{ Private declarations }
public
{ Public declarations }
procedure WMReleaseEdit(var Message: TMessage); message WM_ReleaseEdit;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;//改在这儿。。免得每次都初始化种子
end;procedure TForm1.Button1Click(Sender: TObject);
begin
with TEdit.Create(nil) do
begin
Parent := Self;
Top := Random(200);
Left := Random(200);
Text := Name;
OnKeyPress := EditKeyPress;
end;
end;procedure TForm1.ReleaseButton(obj:TObject);
begin
PostMessage(Handle,WM_ReleaseEdit,Integer(obj),0);
end;procedure TForm1.EditKeyPress(Sender:TObject;var Key: Char);
begin
if (Sender is TEdit) and (Key = #13) then
begin
ReleaseButton(Sender);
end;
end;procedure TForm1.WMReleaseEdit(var Message: TMessage);
begin
if Message.WParam<>0 then
begin
TObject(Message.WParam).Free;
end;
end;
哇,上星的就是牛啊!
会用消息,却想不到用消息。
(Sender as TEdit).Free,(从别的地方看来的),但在释放的时候还是会出现警告对话框的,特别是在做组件编写的时候,比如说:TListViewEx=class(TListView)
a: TEdit;
procedure DBClick(Sender: TObject);
end;procedure TListViewEx.DBClick(Sender: TObject);
begin
a:=TEdit.Create(Self);
a.Parent:=Self; //动态生成TEdit;
end;但我想动态消毁a的话该怎么办呢!??比如当a接到一个回车键消息时自行消毁。再次感谢楼上各位大虾的回复,谢谢!!!
procedure TForm1.EditFree;
begin
a.free
end当你触发回车时触发他吧。
再有,如果你的这个控件是在全局用到的话,建议将将申明在TFORM类的private中吧。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
a : TEdit; //这个变量必须是TForm1类中的全局变量
procedure EditKeyPress(Sender: TObject; var Key: Char);
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
begin
a := nil;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if a = nil then //这个判断是为了防止重复创建TEdit对象, 如果有重复创建的情况出现, 则Free时必定会出错
begin
a := TEdit.Create(Self);
a.Parent := Self;
a.Left := 10;
a.Top := 10;
a.OnKeyPress := EditKeyPress;
a.Visible :=True;
end;
end;procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then
begin
a.Free;
a := nil;
end;
end;end.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
a : TEdit; //这个变量必须是TForm1类中的全局变量
procedure EditKeyPress(Sender: TObject; var Key: Char);
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
begin
a := nil;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if a = nil then //这个判断是为了防止重复创建TEdit对象, 如果有重复创建的情况出现, 则Free时必定会出错
begin
a := TEdit.Create(Self);
a.Parent := Self;
a.Left := 10;
a.Top := 10;
a.OnKeyPress := EditKeyPress;
a.Visible :=True;
end;
end;procedure TForm1.EditKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then
begin
a.Free;
a := nil;
end;
end;end.
so you destroy a object in the object's event may be confilcted.
so you may use timer
in keypress event
timer.enabled=true;
in timer evnet
timer.enable=false;
edit.free;
begin
if Key=VK_RETURN then
tedit(sender).Free; //这一段小弟认为有错,但不知道该怎么写,痛苦ing啊!!!
end;改成:
procedure TForm1.SelfFree(Sender: TObject; var Key: Word; TShift: TShiftState);
beginif Key=VK_RETURN then
begin
if assigned(a) then
a.Free;
end;
end;
测试过可行的,你细心试试就知道的。
相信g961681(Rabby.W.)也试过的。
你这程序出错原因其实应该容易解释的。。
在这样的事件中立即销毁事件所依赖的对象是非常危险的操作.一般应该延后销毁.
无论是我代码中的POSTMESSAGE,还是搂上所说的使用TIMER事件,都是这样思路.
这是一个KEYPRESS事件触发的调用序列:
TWinControl.WMChar(EDIT对象)
。TWinControl.DoKeyPress(EDIT对象)
。。TWinControl.KeyPress(EDIT对象)
TForm1.Edit1KeyPress(FORM1对象) 在这儿一下子把EDIT对象销毁了,
.......这后序的一些调用便不能完成..