gpt4 book ai didi

delphi - 子控件在 TCustomControl 后代的大小调整期间闪烁

转载 作者:行者123 更新时间:2023-12-03 15:47:46 25 4
gpt4 key购买 nike

很长一段时间,我在我的应用程序中使用了 TCustomPanel 类的后代,称为 MyContainer。我可以说是其他视觉控件的典型容器。一切都很好。有一天,我意识到我根本不使用面板功能,因此我可以直接从 TCustomControl 派生 MyContainer。

这样做之后,当使用鼠标调整 MyContainer 的大小时,我会遇到子控件(例如对齐的 TMemo)可怕的闪烁问题。这太可怕了 - 看起来整个 TMemo 暂时消失了,所以我可以看到背景。 MyContainer 本身画得很好 - 这只是子控件的问题。

当 MyContainer 从 TCustomPanel 派生时,不会发生这种情况。我缺少什么以及在哪里?子控件是双缓冲的,MyContainer 也是。我使用Delphi 7个人版,所以我没有VCL源代码,所以我无法将TCustomPanel与TCustomControl实现进行比较。处理 WM_EXITSIZEMOVEWM_ENTERSIZEMOVE 消息(启用/禁用子对齐)没有帮助。

我相信我的问题与删除控制背景有关。作为“迁移”到 TCustomControl 的一部分,我将以下代码添加到 Paint 方法中:

Canvas.Font.Assign(Font);
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := Color;
PatBlt(Canvas.Handle, Canvas.ClipRect.Left, Canvas.ClipRect.Top, Canvas.ClipRect.Right, Canvas.ClipRect.Bottom, PATCOPY);

如果没有此代码,子控件将不再闪烁,但父控件的绘制会被破坏。

最佳答案

TCustomPanelTCustomControl 之间影响此行为的区别在于,TCustomPanelcsAcceptControls 样式添加到构造函数中的ControlStyle。这反过来会影响 TWinControl 基类中的行为,从而将 WS_CLIPCHILDREN 样式添加到具有该样式集的控件的窗口中。

因此,您可以通过以下两种方式之一获得相同的结果:

  1. 重写构造函数并将csAcceptsControls添加到容器控件的ControlStyle

或者

  • 重写CreateParams并直接将WS_CLIPCHILDREN标志添加到容器控件的窗口Style
  • 代码

    选项 1:

    constructor TMyContainer.Create(Owner: TComponent);
    begin
    inherited;
    ControlStyle := ControlStyle + [csAcceptsControls];
    end;

    请注意,这意味着您的容器控件现在可以接受在设计时放置在其上的控件。即使没有此 ControlStyle,您也可以通过设置 Parent 属性在运行时向容器添加控件。

    选项 2:

    procedure TMyContainer.CreateParams(var aParams: TCreateParams);
    begin
    inherited;
    aParams.Style := aParams.Style or WS_CLIPCHILDREN;
    end;

    这实现了您所追求的绘画行为的特定变化,但不影响控件在设计时接受控件的能力。

    关于delphi - 子控件在 TCustomControl 后代的大小调整期间闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38086143/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com