DELPHI - 有没有办法释放在运行时创建的对象而不会出现“访问冲突”?

Mat*_*ias -1 delphi pascal runtime

这个问题让我发疯,我有一个编辑框,我可以在其中写一些东西。在编辑框发生“更改”事件时,将创建一个 ListBox,并由 SQL 查询填充。它在写作时用作提示框。当我在要选择的项目上按 Enter 键时,列表框应该“空闲”,但它继续向我返回“访问冲突”。这里的代码:

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;
Run Code Online (Sandbox Code Playgroud)

这是第一部分,这是“应该”释放列表框的代码:

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;
Run Code Online (Sandbox Code Playgroud)

我认为问题出在 OnKeyDown 函数的调用上。在此先感谢您。

Dav*_*nan 6

您不能从该对象自己的事件处理程序之一中销毁该对象。当事件处理程序返回时,代码继续在您刚刚释放的对象的上下文中执行。这通常会导致像这样的运行时错误。

不是为此列表框控件使用动态生命周期,而是使用表单设计器以传统方式创建它。当你想隐藏它时,设置VisibleFalse。当你想要它显示时,设置VisibleTrue