销毁调用 onKeyDown 事件的元素

Destroy the element that called the onKeyDown event

我目前正在使用 Free Pascal,但在处理 onKeyDown 事件时遇到问题。事情是,每当我尝试使用 onKeyDown 事件来销毁(例如:element.Free)元素(包括调用该事件的元素)时,我都会收到 SIGSEV 异常。我尝试在执行 "Free" 过程之前更改元素焦点,但无济于事。

有没有一种方法可以在不出现 "SIGSEV" 异常的情况下顺利删除(免费)元素?我已经成功地使用按钮执行了相同的方法,但现在我需要将其设置为与 onKeyDown 事件一起使用,因此需要设置的元素之一 "Free" 恰好具有焦点onKeyDown 事件被触发的那一刻。

希望这是清楚的,如果您需要其他信息,请告诉我,

奥斯卡

原因:

据我了解,您正在尝试

procedure TElement.OnKeyPress(...);
begin
  Free;
end;

为什么不能在事件处理程序中销毁对象,这里有几个答案。简而言之:该对象可能想在调用您的事件处理程序之后做一些事情,如果它已经被您销毁 - 在这种情况下您将拥有 SIGSEGV。

解决方案:

您必须推迟销毁对象。有几种情况:使用PostMessage,使用Application.QueueAsyncCall等等。

有一个简单的例子:

type
    TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
    private
        procedure FreeButton(Data: PtrInt);
    public
    end;

var
    Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
    Application.QueueAsyncCall(@FreeButton, PtrInt(Button1));
end;

procedure TForm1.FreeButton(Data: PtrInt);
begin
    TButton(Data).Free;
end;

Read more about Application.QueueAsyncCall.