Delphi 使表单失效会使表单中的所有控件失效吗?

Delphi 使表单失效会使表单中的所有控件失效吗?,delphi,Delphi,我正在使用delphixe3。使表单失效会使表单中的所有控件失效吗?根据我的测试,它不会。但根据我的理解,既然表单需要作废,那么它的所有控件也应该作废 更新 实际上,我尝试对表单重新绘制、更新、失效,发现所有这些都不会导致表单中的控件被重新绘制、更新或失效。我必须调用相应控件的函数来执行任务。通常是的,我相信是这样 根据MSDN-: 子窗口的更新和可见区域受子窗口的父窗口的影响;对于其他样式的窗口,情况并非如此系统在设置父窗口的更新区域时,通常会设置子窗口的更新区域,当父窗口接收WM_PAINT

我正在使用delphixe3。使表单失效会使表单中的所有控件失效吗?根据我的测试,它不会。但根据我的理解,既然表单需要作废,那么它的所有控件也应该作废

更新


实际上,我尝试对表单重新绘制、更新、失效,发现所有这些都不会导致表单中的控件被重新绘制、更新或失效。我必须调用相应控件的函数来执行任务。

通常是的,我相信是这样

根据MSDN-:

子窗口的更新和可见区域受子窗口的父窗口的影响;对于其他样式的窗口,情况并非如此系统在设置父窗口的更新区域时,通常会设置子窗口的更新区域,当父窗口接收WM_PAINT消息时,使子窗口接收WM_PAINT消息。系统将子窗口可见区域的位置限制在父窗口的客户端区域内,并剪辑移动到父窗口外的子窗口的任何部分

当父窗口的更新区域的一部分包括子窗口的一部分时,系统为子窗口设置更新区域。在这种情况下,系统首先向父窗口发送WM_PAINT消息,然后向子窗口发送消息,允许子窗口恢复父窗口可能已绘制的任何部分

通过在创建父窗口时指定WS_CLIPCHILDREN样式,应用程序可以防止在设置父窗口时设置子窗口的更新区域。设置此样式时,系统会将子窗口从父窗口的可见区域中排除,因此会忽略更新区域中可能包含子窗口的任何部分。当应用程序在父窗口中绘制时,会剪裁覆盖子窗口的任何图形,不需要向子窗口发送后续WM_PAINT消息

如果VCL
TWinControl
在其
ControlStyle
属性中设置了
CSAcceptsControl
标志,则它将自己启用
WS\u CLIPCHILDREN
样式。但是,默认情况下,
TForm
(它是
TWinControl
的后代)没有启用
csacceptsControl
,这意味着当
TForm
的窗口无效时,它的子控件不会被排除在无效之外


默认情况下,各种类似容器的控件为自己启用
csaccepts控件。例如
t组框
t面板
t控件栏
,等等。但不是
t表单

调用表单上的
Invalidate
不会使表单上的控件失效,因为它是不需要的。另外,
invalidate
不会立即开始
paint
循环,它只是将表单标记为“脏”,即“需要重新绘制”。这将在消息que变为空时触发绘制循环,并绘制窗体及其上的任何控件。这就是为什么不需要使表单上的组件无效。据我从源代码中看到的,如果启用了样式服务,则具有csParentBackground控件样式的表单的控件将随表单一起无效。框架和面板就是例子。答案与你的主张相冲突。我建议你提供一个(1)当你测试这一点时,你是否考虑了窗口控件和图形控件之间的根本区别?(2) 正如@TomBrunberg所写,请注意,
Invalidate
只是设置“需要重新绘制”标志,这将导致稍后(可能是一毫秒或两毫秒后)生成
WM_PAINT
消息<代码>更新
将立即重新绘制任何无效区域<代码>重新绘制或
刷新
立即重新绘制(因此,本质上,
Repaint=Invalidate+Update
)。通常只有一个表单是无效的。您是如何得出这样的结论的:使表单无效最终不会导致表单中的控件被重新绘制的?请提供演示这一点的代码。默认VCL表单在TCustomForm.InitializeNewForm中设置了CsAcceptsControl,因此表单的窗口设置了ws_clipchildren。@SertacAkyuz
TCustomForm.InitializeNewForm()
存在于FMX中,但不存在于VCL中。当我写我的答案时,我正在看VCL源代码。在VCL中,我没有看到默认情况下在
TForm
上启用
csaccepts控件的代码。也许当时的设计已经改变了。我在看XE2源代码,TCustomForm.InitializeNewForm在Vcl.Forms.pas的3586行。@SertacAkyuz我在看XE3。我明天会看XE2。