【问题标题】:How to let Parent component get click events of child components?如何让父组件获取子组件的点击事件?
【发布时间】:2026-01-07 03:55:01
【问题描述】:

我有一个 FireMonkey 应用程序,上面有多个按钮(实际上是矩形)。除了每个按钮的特定操作之外,我还希望在表单上的任何一次点击中调用一个过程。

由于每个子组件的HitTest都设置为True,所以父组件的HitTest自动为false。

那么处理这个问题的正确方法是什么?

一个愚蠢的解决方法是将此过程分配给每个按钮的OnClick 事件,但是当我有一个包含数百个按钮的表单时,这将没有任何意义。

【问题讨论】:

  • 在 VCL 中,使用 TApplication.OnMessage 事件将非常容易。但这在 FMX 中不存在。因此,除非您在表单的底层窗口上使用特定于平台的消息/鼠标挂钩,否则我不知道如何在 FMX 中解决这个问题。
  • 你的问题有点不清楚。当您说您不想将 OnClick 事件分配给每个按钮时,您打算如何在单击这些按钮时触发所需的代码?还有为什么你需要数百个按钮?
  • @codeGood "我已经为每个按钮实现了 OnClick,将相同的过程复制并粘贴到所有这些 onClick 事件中是无稽之谈" - 你不需要多个程序。您可以将单个过程分配给多个事件,然后使用其Sender 参数来区分每次单击哪个按钮。
  • @codeGood "我实际上只为 Windows 编译" - 那你为什么使用 FMX 而不是 VCL? “我可以使用 TApplication.OnMessage 吗?”——不能在 FMX 中使用。但在 VCL 中,是的。鼠标事件是基于queued messages 和VCL 的TApplication.OnMessage 事件在它被分派到其目标窗口之前为每个排队的消息调用。您可以根据需要处理WM_LBUTTON(DOWN|UP) 消息。在 FMX 中并非不可能,但您必须将消息队列与 SetWindowsHookEx() 挂钩。
  • 正确的方法是编写一个OnClick 事件处理程序并将该处理程序分配给每个矩形,然后在调用事件时使用Sender 参数以区分单击了哪个矩形。您根本不需要跳过任何类型的障碍或做您的问题标题所要求的事情。同样的方法也适用于 VCL 和 FMX。

标签: delphi components parent-child firemonkey


【解决方案1】:

我找到了 vcl 的解决方案。 您可以通过此代码找到鼠标位置的组件基础:

var
  ctrl : TWinControl;
begin

 ctrl := FindVCLWindow(Mouse.CursorPos);
 if ctrl.Name = '' then
   ShowMessage(ctrl.Owner.Name);

对于 FireMonkey 没有建立结果,但您可以在表单上获取鼠标位置并根据该点的结果分析组件并找到它的名称,然后继续处理该组件的事件库。

【讨论】:

    【解决方案2】:

    TRectangle 的简单拦截器/插入器类完成了这项工作! 感谢大家的意见。

    【讨论】:

      最近更新 更多