如何只显示 TWinControl 并让其父级处理所有鼠标事件?
Posted
技术标签:
【中文标题】如何只显示 TWinControl 并让其父级处理所有鼠标事件?【英文标题】:How to make a TWinControl display only and let its parent handle all mouse events? 【发布时间】:2012-03-20 05:05:17 【问题描述】:我正在创建一个用户组件,在按钮上添加一些额外的标签(使用代码),但是当点击标签时,按钮的 onClick 事件不会触发。
为这些标签创建所有与鼠标相关的事件并将它们指向按钮的事件是麻烦且无效的。
是否有更简单的方法让按钮处理所有这些鼠标事件,就像那些标签不存在一样?
实际情况要复杂得多,标签是 TJvLinkLabel 用于简单的标记渲染,所以简单地在按钮上绘制文本对我来说不是一个好的选择。
感谢您的热心帮助。
编辑: 更加具体。有一组按钮,每个显示一个表记录的信息。他们每个人都有 2 个 TJvLinkLabel 作为页眉和页脚,其中有简单标记的标题来显示各种字段信息和 1 个 TJvLabel(alClient、shadow、wordwrap)来显示主要描述。每个按钮可以是不同的颜色,甚至可以有背景图片,这就是为什么需要阴影来显示文本的原因。按钮自己的标题始终设置为空。
我其实只需要视觉效果(标记渲染、阴影),不需要那些标签的任何交互。我只是希望按钮的行为就像没有托管其他组件一样。
当我搜索 *** 时,我看到 C# 似乎将 hittest 设置为 false 等,但我在 Delphi 中找不到类似的设置。
编辑2: 更简单地说,有没有办法让父级(在这种情况下为按钮)处理所有鼠标消息并且不传递给它的子级(在这种情况下为标签)。谢谢。
编辑 3: 到目前为止,我已经继承了标签类并将 Click、DblClick、MouseDown、MouseUp 过程路由到按钮并跳过了其他事件。我想知道是否有更好的解决方案。谢谢。
【问题讨论】:
您是否在这些标签上使用了超链接?你想谁来处理那些,按钮或标签。屏幕截图可以帮助我们形象化吗? 如果您不能分配标签的 OnClick .. 可能您可以创建 TJvLinkLabel 后代类,将Click
覆盖为 parent.click
,然后使用它?
@DavidHeffernan 他们没有使用超链接,我只希望标签的视觉效果来替换原来的单个普通标题。
@teran 我曾想过这种方法。这可以通过 mousedown、mouseup、click、dblClick 来完成,但是 mouseenter 和 mouseleave 呢?触发按钮的mouseleave然后再次触发mouseenter(通过标签路由)似乎不好。
【参考方案1】:
将标签的Enabled
属性设置为False
。
【讨论】:
感谢您的帮助。您的建议在 TJvLinkLabel 上效果很好。伟大的!但是,TJvLabel 变成灰色并且仍然不响应 onMouseDown(触发按下效果)。我原本认为会有一个通用的方法来跳过鼠标事件的处理,所以我没有提到 TjvLabel。对不起。【参考方案2】:不要从 TWinControl 派生,或者如果不可能,则处理所有鼠标事件并将它们传递给父级。您可以在下面查看一些链接:
Handling mouse events
你可以看看TWinControl的代码:
TWinControl = class(TControl)
protected
property DefWndProc: Pointer read FDefWndProc write FDefWndProc;
procedure MainWndProc(var Message: TMessage);
public
procedure DefaultHandler(var Message); override;
如果您的控件不是后代,则覆盖 DefWndProc,如果是,则覆盖 MainWndProc。
【讨论】:
感谢您的回答。我的按钮组件来自现有的按钮类,这绝对是 TWinControl 的后代。两个标签控件也是如此。当 MainWndProc 不是虚拟方法时如何覆盖它?以及如何将消息传递给父母?坦率地说,我对消息系统并不熟悉。 您可以访问 DefWndProc 属性(如果您是孩子)。在 TWinControl 的源代码中查找它,并将该属性更改为指向您的函数的指针。以上是关于如何只显示 TWinControl 并让其父级处理所有鼠标事件?的主要内容,如果未能解决你的问题,请参考以下文章