我遇到以下示例的问题。我有一个按钮,用于创建包含更多组件的运行时面板:
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;
当你点击它时,虽然我的组件被删除但是当它弹出消息时,地址上的访问冲突...为什么?
谢谢:)
答案 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
事件处理程序中释放按钮。这根本不允许。该按钮由此面板拥有,因此,当您释放面板时,它还会释放此按钮 - 在其事件处理程序完成执行之前。