如何捕捉父控件调整大小的时刻?
我有一个源自 TWinControl 的可视化组件。当组件的父控件大小调整后,我需要在组件中做一些工作。一般情况下,我的组件的“对齐”属性是 alNone。
如何捕获调整父控件大小的事件?是否可以?
I have a visual component derived from TWinControl. I need to do some work in my component when its parent control has been resized. In general case, the "Align" property of my component is alNone.
How to catch the event of resizing the parent control? Is it possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果 TWinControl(父级)的大小发生更改,则在
WM_SIZE
处理程序中调用TWinControl.Realign
。此过程通过 TWinControl.AlignControls 冒泡,迭代所有将 Align 属性设置为除alNone
之外的任何值的子控件。当设置为alCustom
时,将使用不变的参数调用子控件的SetBounds
,即使它们的大小由于锚点的参与而发生或未发生变化。因此,将 Align 设置为
alCustom
,您就会收到父级调整大小的通知:目前我能想到的唯一缺点是 Align 属性永远不能是
alNone
,这可能会让组件的用户感到困惑。当内部继承属性仍设置为alCustom
时,很容易显示或返回alNone
,但这不是建议,只会更加混乱。只需将alCustom
设置视为该组件的一项功能即可。注意:通过这种结构,组件的用户仍然能够自己实现自定义对齐。
这是我的测试代码。也许您想为自己添加一些测试。
If a TWinControl (the parent) is changed in size, then
TWinControl.Realign
is called in theWM_SIZE
handler. This bubbles viaTWinControl.AlignControls
into iterating over all the child controls which have the Align property set to anything else thenalNone
. When set toalCustom
,SetBounds
of the child controls will be called with unchanged arguments, even if their size has or has not changed due to anchor involvement.So, set Align to
alCustom
and you have the notification of the parent's resize:The only drawback I can think of for now is that the Align property can never be
alNone
, which could confuse the user of your component. It is easily possible to show or returnalNone
when the internal inherited property is still set toalCustom
, but that is not an advice and would confuse only more. Just consider thealCustom
setting as a feature of this component.Note: with this construction, the user of your component is still able to implement custom alignment himself.
And here is my test code. Maybe you want add some testing for yourself.
是的,安德鲁,我认为将您的组件附加到父级的消息循环(子类化它)是可行的方法。为此,您可以使用
TControl.WindowProc
属性。 doc 解释说您必须保存原始文件并稍后恢复(在组件的析构函数中)并将消息传递给原始处理程序,即您的替换应该看起来像如果您想以“旧学校”方式进行操作,请使用 SetWindowLongPtr API 与
GWLP_WNDPROC 但据我所知,
WindowProc
的引入正是为了更容易子类化组件,即使用它没有任何问题。Yes, Andrew, I think attaching your component to parent's message loop (subclassing it) is the way to go. For that you can use
TControl.WindowProc
property. The doc explains that you have to save the original and restore it later (in the destructor of your component) and also to pass the messages to the original handler, ie your replacement should look likeIf you want to do it "old shool" way, use the SetWindowLongPtr API with
GWLP_WNDPROC
but AFAIK theWindowProc
was introduced exactly for the reason to make it easier to subclass components, ie there is nothing wrong using it.警告:完全重写。谢谢罗布!!
使用 SetWindowSubClass 的示例。
WARNING: Full rewrite. Thanks Rob!!
Example using SetWindowSubClass.
我正在寻找类似问题的解决方案。但就我而言,我不能对对齐有这样的限制,并且子类化似乎太过分了(对齐的东西看起来也太过分了,现在我看看它)
所以我想出了以下想法:
添加或替换 FParentLastWidth 为您想要的任何大小跟踪(我只需要在父宽度发生变化时做出反应。您可以将其视为一种优化,这样就不会对各种变化做出反应,这对您的组件没有影响)
I was looking for a solution to a similar problem. But in my case I cannot have such restrictions on alignment, and subclassing seemed overkill (the alignment thingie looks overkill too, now that I look at it)
So I came up with the following idea:
Add or replace the FParentLastWidth with whatever size you are tracking (I only needed reaction when the parent width changed. You can take it as an optimization so to not react to all kinds of changes which makes no difference for your component)
这是可以帮助您的示例:
Here is exapmle to help you: