DELPHI - 有没有一种方法可以在不获取 'Access Violation?' 的情况下释放在运行时创建的对象
DELPHI - Is there a way to free an object created at runtime without getting 'Access Violation?'
这个问题快把我逼疯了,我有一个编辑框,我可以在其中写一些东西。在编辑框的事件 'change' 中,将创建一个列表框并由 SQL 查询填充。它在写作时用作提示框。
当我在我想要 select 的项目上按下回车键时,列表框应该 'free',但它继续 return 我 'access violation'。这里的代码:
procedure TFTimbra.EditCommessaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
X, Y, W: Integer;
QSugg: TAdoQuery;
begin
if not Assigned(Suggerimento) then
begin
Suggerimento := TListBox.Create(Self);
Y := EditCommessa.Top + EditCommessa.Height;
X := EditCommessa.Left;
W := EditCommessa.Width;
with Suggerimento do
begin
Top := Y;
Left := X;
Width := W;
Height := 200;
Parent := FTimbra;
BorderStyle := bsNone;
Font.Size := 14;
Font.Style := [fsBold];
end;
end else
Suggerimento.Clear;
if Key = 40 then
Suggerimento.SetFocus;
QSugg := TAdoQuery.Create(nil);
QSugg.ConnectionString := DMMain.DBConnection.ConnectionString;
QSugg.SQL.Text := format('select Codice, Descrizione from Commesse where Descrizione like %s',
[quotedstr('%' + EditCommessa.Text + '%')]);
QSugg.Open;
while not QSugg.Eof do
begin
Suggerimento.Items.Add(QSugg.FieldByName('Descrizione').AsString);
QSugg.Next;
end;
QSugg.Close;
if Assigned(Suggerimento) then Suggerimento.OnKeyDown := SuggerimentoKeyDown;
end;
这是第一部分,这是 "should" 释放列表框的代码:
procedure TFTimbra.SuggerimentoKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = 13 then
begin
Commessa := Suggerimento.Items[Suggerimento.ItemIndex];
EditCommessa.Text := Commessa;
Suggerimento.Free;
end;
end;
我认为问题出在 OnKeyDown 函数的调用上。在此先感谢您。
您不能从某个对象自己的事件处理程序中销毁该对象。当事件处理程序 returns 时,代码继续在您刚刚释放的对象的上下文中执行。这通常会导致像这样的运行时错误。
与其使用此列表框控件的动态生命周期,不如使用窗体设计器以传统方式创建它。当你想隐藏它时,将 Visible
设置为 False
。当你想要它显示时,将 Visible
设置为 True
。
这个问题快把我逼疯了,我有一个编辑框,我可以在其中写一些东西。在编辑框的事件 'change' 中,将创建一个列表框并由 SQL 查询填充。它在写作时用作提示框。 当我在我想要 select 的项目上按下回车键时,列表框应该 'free',但它继续 return 我 'access violation'。这里的代码:
procedure TFTimbra.EditCommessaKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
X, Y, W: Integer;
QSugg: TAdoQuery;
begin
if not Assigned(Suggerimento) then
begin
Suggerimento := TListBox.Create(Self);
Y := EditCommessa.Top + EditCommessa.Height;
X := EditCommessa.Left;
W := EditCommessa.Width;
with Suggerimento do
begin
Top := Y;
Left := X;
Width := W;
Height := 200;
Parent := FTimbra;
BorderStyle := bsNone;
Font.Size := 14;
Font.Style := [fsBold];
end;
end else
Suggerimento.Clear;
if Key = 40 then
Suggerimento.SetFocus;
QSugg := TAdoQuery.Create(nil);
QSugg.ConnectionString := DMMain.DBConnection.ConnectionString;
QSugg.SQL.Text := format('select Codice, Descrizione from Commesse where Descrizione like %s',
[quotedstr('%' + EditCommessa.Text + '%')]);
QSugg.Open;
while not QSugg.Eof do
begin
Suggerimento.Items.Add(QSugg.FieldByName('Descrizione').AsString);
QSugg.Next;
end;
QSugg.Close;
if Assigned(Suggerimento) then Suggerimento.OnKeyDown := SuggerimentoKeyDown;
end;
这是第一部分,这是 "should" 释放列表框的代码:
procedure TFTimbra.SuggerimentoKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = 13 then
begin
Commessa := Suggerimento.Items[Suggerimento.ItemIndex];
EditCommessa.Text := Commessa;
Suggerimento.Free;
end;
end;
我认为问题出在 OnKeyDown 函数的调用上。在此先感谢您。
您不能从某个对象自己的事件处理程序中销毁该对象。当事件处理程序 returns 时,代码继续在您刚刚释放的对象的上下文中执行。这通常会导致像这样的运行时错误。
与其使用此列表框控件的动态生命周期,不如使用窗体设计器以传统方式创建它。当你想隐藏它时,将 Visible
设置为 False
。当你想要它显示时,将 Visible
设置为 True
。