【问题标题】:How to free control inside its event handler?如何在其事件处理程序中释放控制权?
【发布时间】:2010-03-23 18:24:40
【问题描述】:

有谁知道诀​​窍,如何在其事件处理程序中释放控制?根据delphi的帮助,这是不可能的......

当 Self.Text='' 时,我想释放动态创建的 TEdit。

TAmountEdit = class (TEdit)
.
.
public
  procedure KeyUp(var Key: Word; Shift :TShiftState);
end;

procedure TAmountEdit.KeyUp(var Key: Word; Shift :TShiftState);
begin
inherited;
if Text='' then Free; // after calling free, an exception arises
end;

应该怎么做才能达到同样的效果?

感谢

【问题讨论】:

  • 您是否尝试过启动一个计时器来释放编辑,然后自行禁用?
  • 嗯...好问题。如果这是一个表单,我会调用 Release,但这是在 TCustomForm 上声明的,而不是在 TControl 或 TComponent 上。
  • 好问题。过去我多次需要这样的东西。

标签: delphi


【解决方案1】:

解决方案是将排队的消息发布到控件,它通过销毁自身来响应。 Ny 约定我们使用CM_RELEASE,这是TForm 在执行类似任务的Release 方法的实现中使用的私人消息。

interface

type
  TAmountEdit = class (TEdit)
    ...
    procedure KeyUp(var Key: Word; Shift :TShiftState); override;
    procedure HandleRelease(var Msg: TMessage); message CM_RELEASE;
    ...
  end;

implementation

procedure TAmountEdit.KeyUp(var Key: Word; Shift :TShiftState);
begin
  inherited;
  if Text = '' then
    PostMessage(Handle, CM_RELEASE, 0, 0);
end;

procedure TAmountEdit.HandleRelease(var Msg: TMessage);
begin
  Free;
end;

当应用程序下一次抽出它的消息队列时,控件被销毁。

【讨论】:

  • 无需声明新的消息ID。查看 CM_RELEASE,它专为表单执行此操作而设计。但基本思想是正确的。 +1
  • 我会将此方法称为 hack,因为它不是 100% 安全的。尝试在此处使用 Release: TForm2 = class(TForm) S:string;过程 WndProc(var Msg:TMessage);覆盖;公共构造函数 Create(Aown​​er:TComponent);override; //... 构造函数 TForm2.Create(AOwner:TComponent);开始 S:='abc';继承结束;过程 TForm2.WndProc(var Msg:TMessage);开始继承; S[2]:='x' {*} 结束;
【解决方案2】:

在实施之前,我会停下来问“这真的是最好的方法吗?

您真的想要一个编辑控件类,当按键输入导致 Text 属性变为空字符串时,它总是会自行销毁?

您是否更有可能拥有需要此行为的特定表单/对话框?在这种情况下,没有问题...您可以在表单处理的 KeyUp 事件中释放编辑控件,而不会导致 Access Violation

【讨论】:

  • 是的,我知道。问题是,我有一个(我自己的)基于 TCustomControl 的组件,其中包含 TAmountEdit 控件(未指定有多少)。这就是为什么我必须动态创建它们,然后根据我的规则释放它们......它类似于 IE 或 FireFox 上的选项卡,我关闭选项卡并消失......(释放?我不知道...... :-) )
  • 我明白了。但是,如果您的组件创建了控件,那么在我看来,它也应该负责释放它们。这些规则似乎是由包含 TAmountEdit 控件的控件设置的,而不是由TAmountEdit 控件本身设置的。您的自定义控件将创建一个 TAmountEdit 然后将一个事件处理程序(它实现)分配给 TAmountEditOnKeyUp() 事件(请注意从技术上讲,您最初的问题不是关于处理事件,而是拦截一个!)。
  • :-) 我不关心释放 TAmountEdit,而它们被添加到容器控件的组件数组中(它拥有它们)。因此,当 containercontrol 即将被销毁时,它们会被自动释放。无论如何,我都会拦截 TAmountEdit 的 OnKeyUp() 事件,以便轻松浏览它们。释放 TAmountEdit 是它的可选属性,我想在控件本身内部实现它。此外,由于拦截 OnKeyUp 事件,我在从父级释放控制权方面遇到了一些具体困难......
  • 父母释放孩子的问题和风险远小于任何物体释放自己的风险。但这是你的葬礼。 :)
  • 我制作了用于显示消息的控件。它是带有用户名、日期和消息标签的面板,以及两个用于编辑和删除的按钮。我有两个事件:onEdit 和 onDelete。我想在单击“删除”按钮时删除组件。我从 onDelete 事件处理程序中的父表单执行此操作,但仍然遇到访问冲突。我使用了这里提出的解决方案,但我不太喜欢它。任何建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2010-11-20
  • 1970-01-01
相关资源
最近更新 更多