为什么 TPanel.Canvas.Font 属性通过受保护的黑客访问与 TPanel.Font 属性不同?

问题描述

我正在使用 Josef Švejk's excellent answer 中的 DrawTextRotatedB 函数来解决问题 How to draw text in a canvas vertical + horizontal with Delphi 10.2TPanel 上垂直绘制文本。
该组件没有公共 Canvas 属性,因此我使用受保护的 hack 来访问它:

type
   THackPanel = class(TPanel);

DrawTextRotated(THackPanel(PnlLeftLeft).Canvas,90,PnlLeftLeft.Width DIV 2,cVertDrawOffset,FLeftVertText)

with definition

procedure DrawTextRotated(ACanvas: TCanvas; Angle,X,Y: Integer; AText: String);

该过程使用 ACanvas.Font 属性使用 ACanvas.TextOut 绘制文本。
我注意到在程序内部这些属性不是我所期望的,例如

PnlLeftLeft.Font.Size = 20
PnlLeftLeft.Font.Ttyle = [fsBold]

THackPanel(PnlLeftLeft).Canvas.Font.Size = 10
THackPanel(PnlLeftLeft).Canvas.Font.Ttyle = []

似乎我可以在过程调用之前轻松地“修复”这个THackPanel(PnlLeftLeft).Canvas.Font := PnlLeftLeft.Font;, 但我仍然有疑问:

为什么 TPanel.Canvas.Font 属性不反映 TPanel.Font 属性?

解决方法

这是设计使然。

一个复杂的控件可能会在不同的时间和位置用不同的字体写入文本,因此 Canvas.Font – 决定了下一个文本绘制操作的字体 – 即使在绘制单个“框架”期间也可能发生变化.

另一方面,

Self.Font 是控件的“主要字体”,通常显示在对象检查器中(作为已发布的属性)并受 ParentFont 属性的影响。

例如,控件的绘制代码可能会在每次调用开始时将 Self.Font 分配给 Canvas.Font,然后可能会在绘制过程中稍微更改它(可能以斜体或粗体绘制某些部分或一些不同的颜色)。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...