问题描述
我正在使用 Josef Švejk's excellent answer 中的 DrawTextRotatedB
函数来解决问题 How to draw text in a canvas vertical + horizontal with Delphi 10.2
在 TPanel
上垂直绘制文本。
该组件没有公共 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
,然后可能会在绘制过程中稍微更改它(可能以斜体或粗体绘制某些部分或一些不同的颜色)。