Delphi使用画布打印,将文本向右对齐

Delphi使用画布打印,将文本向右对齐,delphi,canvas,printing,Delphi,Canvas,Printing,我正在使用TPrinter.Canvas打印,由于货币显示数字,我正在尝试将文本向右对齐 文本以以下代码打印: Printer.Canvas.Textout(800, 100, 250.00); //charge1 Printer.Canvas.Textout(800, 200, 10.00); //charge2 Printer.Canvas.Textout(800, 300, 260.00); //Total Amount 如何对齐这些行以正确显示?您应该使用Winapi,并选择在给定

我正在使用
TPrinter.Canvas
打印,由于货币显示数字,我正在尝试将文本向右对齐

文本以以下代码打印:

Printer.Canvas.Textout(800, 100, 250.00); //charge1
Printer.Canvas.Textout(800, 200,  10.00); //charge2
Printer.Canvas.Textout(800, 300, 260.00); //Total Amount


如何对齐这些行以正确显示?

您应该使用Winapi,并选择在给定矩形内使用它向右对齐,而不是使用VCL的
文本输出,特别是使用
DT\u right
。例如

DrawText(Canvas.Handle, PChar(T), Length(T), R, DT_SINGLELINE or DT_RIGHT);

您不应该使用VCL的
TextOut
,而应该使用Winapi并选择在给定的矩形内使用它向右对齐,特别是使用
dtu right
。例如

DrawText(Canvas.Handle, PChar(T), Length(T), R, DT_SINGLELINE or DT_RIGHT);

您可以使用较低级别的设备上下文Api来更精确地控制文本输出,如Jerry建议的
DrawText()
。但是,执行此操作需要预先计算/设置文本输出的边界矩形,以便Windows知道任何对齐所对应的区域

有两种可能更简单的选择:

选项1-仅适用于固定宽度字体 这可能适合您,因为您似乎正在使用固定宽度字体

我们在这里所做的就是在输出之前为字符串引入填充。这可能比输出矩形等所需的计算更简单

要做到这一点,请确定要接受输出的最长字符串,然后在每个字符串的左侧添加所需的空格,以确保它们的长度相同。对于固定宽度字体,空格与任何其他字符占用相同的水平空间,因此通过使所有字符串长度相同,您将实现“正确对齐”:

如何处理指定字符串长度超过最大宽度的情况是一个练习

选项2-适用于任何字体 另一种适用于固定宽度或可变宽度字体(如Arial)的方法是选择字符串最右边的位置,并根据为输出的每个字符串计算的设备宽度计算X位置:

procedure PrintRightJustified(const aRightX, aY; aValue: String);
var
  leftX: Integer;
begin
  leftX := aRightX - Printer.Canvas.TextWidth(aValue);

  Printer.Canvas.Textout(leftX, aY, aValue);
end;
您不需要为此版本指定最大宽度,无论使用何种字体,它都可以工作:

PrintRightJustified(900, 100, '250.00'); //charge1
PrintRightJustified(900, 200, '10.00'); //charge2
PrintRightJustified(900, 300, '260.00'); //Total Amount

这确实意味着,如果没有某种机制来检测和处理,文本可能会“出血”到太远的左侧。同样,如果这是一个问题,那么要么将右边缘进一步移动,要么您将不得不想出一种处理方法(左边缘作为练习,因为我们不知道您的确切要求是什么)。

您可以使用较低级别的设备上下文Api来更准确地控制文本输出,例如
DrawText()
如Jerry所建议。但是,执行此操作需要预先计算/设置文本输出的边界矩形,以便Windows知道任何对齐所对应的区域

有两种可能更简单的选择:

选项1-仅适用于固定宽度字体 这可能适合您,因为您似乎正在使用固定宽度字体

我们在这里所做的就是在输出之前为字符串引入填充。这可能比输出矩形等所需的计算更简单

要做到这一点,请确定要接受输出的最长字符串,然后在每个字符串的左侧添加所需的空格,以确保它们的长度相同。对于固定宽度字体,空格与任何其他字符占用相同的水平空间,因此通过使所有字符串长度相同,您将实现“正确对齐”:

如何处理指定字符串长度超过最大宽度的情况是一个练习

选项2-适用于任何字体 另一种适用于固定宽度或可变宽度字体(如Arial)的方法是选择字符串最右边的位置,并根据为输出的每个字符串计算的设备宽度计算X位置:

procedure PrintRightJustified(const aRightX, aY; aValue: String);
var
  leftX: Integer;
begin
  leftX := aRightX - Printer.Canvas.TextWidth(aValue);

  Printer.Canvas.Textout(leftX, aY, aValue);
end;
您不需要为此版本指定最大宽度,无论使用何种字体,它都可以工作:

PrintRightJustified(900, 100, '250.00'); //charge1
PrintRightJustified(900, 200, '10.00'); //charge2
PrintRightJustified(900, 300, '260.00'); //Total Amount

这确实意味着,如果没有某种机制来检测和处理,文本可能会“出血”到太远的左侧。同样,如果这是一个问题,那么要么将右边缘进一步移动,要么您必须想出一种处理方法(左边缘是您的练习,因为我们不知道您的确切要求是什么).

使用这种方法,您应该提到需要计算/设置文本的边框,以获得正确的定位以及正确的对齐方式。@Deltics这一切都取决于所需的内容。大多数情况下,您已经知道要在其中绘制文本的区域(Rect)。显然,它将与给定矩形的右边缘对齐。我希望OP阅读我链接的文档,并自行决定如何使用它。就在几个小时前,我使用
DrawText
编写了代码,不需要计算任何东西-只需传递我需要绘制的区域的
TRect
。OP声明他们正在使用
TextOut
,这不需要任何rect计算。如果您可以依靠OP阅读文档并从中推断出他们需要自己学习的所有内容,那么他们现在就不会在这里问这个问题了,是吗?;)Canvas.TextRect使用drawtextextex,接受TextFormat参数。是的,无论如何,Canvas应该类似于
Printer.Canvas.TextRect(R,T,[tfRight,tfSingleLine])
使用这种方法,您应该提到需要计算/设置文本的边框,以获得正确的定位以及正确的对齐方式。@Deltics这一切都取决于所需的内容。大多数情况下,您已经知道要在其中绘制文本的区域(Rect)。显然,它将与给定矩形的右边缘对齐。我希望OP能够阅读以下文档: