【问题标题】:Setting the fontsize of a Paintbox causes OnPaint to be called设置 Paintbox 的字体大小会导致调用 OnPaint
【发布时间】:2011-03-11 22:34:57
【问题描述】:

我需要将一些文本写入画框,并在 OnPaint 事件中完成。当我在方法中设置 fontsize twice 时,OnPaint-event 被重复调用。

要亲眼看看,试试这个:

  1. 创建一个新的 VCL Forms 应用程序
  2. 在表单上放置一个颜料盒
  3. 在 OnPaint-event 中加入以下代码:
过程 TForm1.PaintBox1Paint(发送者:TObject); 开始 PaintBox1.Canvas.MoveTo(random(PaintBox1.Width),random(PaintBox1.Height)); PaintBox1.Canvas.LineTo(random(PaintBox1.Width),random(PaintBox1.Height)); PaintBox1.Font.Size := 10; PaintBox1.Font.Size := 12; 结尾;

当您运行应用程序时,您会看到画框上“跳跃”了一条线。但是,如果您删除设置字体大小的一条或两条线,您将看到一条固定的线。

为什么会发生这种情况,我可以做些什么来解决它?

【问题讨论】:

    标签: delphi graphics onpaint


    【解决方案1】:

    设置PaintBox1.Canvas.Font.Size而不是PaintBox1.Font.Size,你的问题就会得到解决。

    至于为什么会发生:更改控件的字体属性会导致它无效并重绘,并且在重绘的情况下这样做会导致无限循环。幸运的是,绘制事件是合成的,并且优先级低于其他消息,否则您的程序会挂起。

    【讨论】:

    • 全部正确,但我不明白为什么不使用简单的“如果字段 值然后”。这将防止在字体未更改时重新绘制针头。 VCL 应该在几乎所有的 setter 中使用这样的比较。
    • @Runner:但是字体已经改变了,实际上是两次。在这两种情况下,对不等式的检查都评估为True。立即撤销更改并不重要,因为这超出了 setter 的范围。你所要求的对我来说似乎是不可能的。
    • @mghhie:我知道在他的代码中必须进行更改。我说的是 VCL 是如何工作的。例如,如果您将字体大小更改为 10 并且大小已经是 10,如果没有真正改变,您将触发一个字体更改事件事件。一个简单的比较就可以解决问题。在我看来,这是草率的编程。是的,我知道如果大小相同,我不应该分配大小。但是 VCL 应该检查这些简单的条件。而 TFont 类只是众多具有此弱点的类之一。更糟糕的是,他们会在设置字体名称时检查值。
    • 如果不小心分配给Paintbox1.Font.Style属性,而不是Paintbox1.Canvas.Font.Style,也会出现问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 2017-06-01
    • 2020-03-01
    • 1970-01-01
    • 2020-06-12
    • 2017-04-29
    相关资源
    最近更新 更多