Delphi - 销毁组件

时间:2015-07-28 13:50:06

标签: delphi components destroy

我遇到以下示例的问题。我有一个按钮,用于创建包含更多组件的运行时面板:

Panel := TPanel.Create(self);
Panel.Parent := FlowPanel;
Panel.Align := alTop;
Panel.Height := 24;
Panel.Width := FlowPanel.Width;

Text := TLabel.Create(self);
Text.Parent := Panel;
Text.Align := alLeft;
Text.Caption := Query.FieldByName('Nazev').AsString;
Text.AlignWithMargins := True;
Text.Tag := Data_Id;
Text.Width := 100;

Button := TButton.Create(self);
Button.Parent := Panel;
Button.Caption := 'Odstranit';
Button.Align := alRight;
Button.Margins.Top := 0;
Button.Margins.Bottom := 0;
Button.AlignWithMargins := True;
Button.OnClick := DeleteFlowPanelItem;

Button在DeleteFlowPanelItem上有OnClick事件;

procedure TAdminTypyPlochy.DeleteFlowPanelItem(Sender: TObject);
var
  myPanel: TPanel;
begin
  myPanel := TPanel(TButton(Sender).Parent);
  myPanel.Free;
end;

当你点击它时,虽然我的组件被删除但是当它弹出消息时,地址上的访问冲突...为什么?

谢谢:)

2 个答案:

答案 0 :(得分:3)

调用按钮OnClick事件处理程序的函数是同一按钮的方法。您的OnClick事件删除了该按钮,因此当事件处理程序返回时,您现在正在一个已被销毁的对象的实例方法中执行。

您需要推迟按钮的销毁,直到按钮单击事件处理完成。使用PostMessage发布自定义消息,以标识要销毁的按钮。通过销毁指定的按钮处理该消息。例如,按钮可以在lParam中传递。

我个人会使用AllocateHWnd创建一个可以作为这些消息的目标的窗口。这样您就可以确保避免窗口重新创建的问题。

答案 1 :(得分:1)

这是因为您从按钮的DECLARE @regex INT,@string varchar(100) SET @string='india!@#$%^&*()_+<>?:"{}| indian' SET @regex = PATINDEX('%[^a-zA-Z0-9 ]%', @string) WHILE @regex > 0 BEGIN SET @string = STUFF(@string, @regex, 1, ' ' ) SET @regex = PATINDEX('%[^a-zA-Z0-9 ]%', @string) END SELECT @string 事件处理程序中释放按钮。这根本不允许。该按钮由此面板拥有,因此,当您释放面板时,它还会释放此按钮 - 在其事件处理程序完成执行之前。