Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi - Draw text multiline in the centre of a rect

Tags:

text

delphi

In Delphi i wish to draw text inside a TRect. I am hoping for the following functionality:

  1. Draw the text centred vertically within the TRect
  2. Draw the text centred horizontally within the TRect
  3. If there is space for more than 1 line of text (using TRect's height), draw the text multiline
  4. If the text does not fit in the TRect (either on a single or mult line) then append ellipsis to the text.

I can see the Windows.DrawText() function almost covers this functionality, however when writing text, multiline and vertically centred are mutually exclusive.

I was wondering if this functionality is built into windows (2000+)? If not is there a way to do this without writing my own function?

like image 568
Simon Avatar asked Aug 10 '11 07:08

Simon


People also ask

How do I add a multi line caption in Delphi?

7 Best Answer 9 Votes Unfortunately, TPanel does not support multi-line captions, at least not in the newer versions of Delphi. To be able to display the caption of the panel with several lines, you have to write a custom component derived from TPanel and rewrite the OnPaint event.

What is the rect command in Delphi?

Delphi Basics : rect command DelphiBasics rect Function Create a TRect value from 2 points or 4 coordinates Classesunit 1 function rect( Left, Top, Right, Bottom : Integer ) : TRect; 2 function rect ( TopLeft, BottomRight : TPoint ) : TRect;

How to add multi-line text to a Delphi TLabel?

A TLabel Delphi component has a WordWrap property you can set to true in order for the text in the Caption property appear wrapped (multi-lined) when it is too long for the width of the label. However, you *cannot* specify multi-line text for a TLabel at design-time, using Object Inspector.

What is the use of drawtext function in Python?

DrawText function. The DrawText function draws formatted text in the specified rectangle. It formats the text according to the specified method (expanding tabs, justifying characters, breaking lines, and so forth).


2 Answers

Sorry, this is a combination of all previous answers and comments. But it seems OP needs more assistance.

function DrawTextCentered(Canvas: TCanvas; const R: TRect; S: String): Integer;
var
  DrawRect: TRect;
  DrawFlags: Cardinal;
  DrawParams: TDrawTextParams;
begin
  DrawRect := R;
  DrawFlags := DT_END_ELLIPSIS or DT_NOPREFIX or DT_WORDBREAK or
    DT_EDITCONTROL or DT_CENTER;
  DrawText(Canvas.Handle, PChar(S), -1, DrawRect, DrawFlags or DT_CALCRECT);
  DrawRect.Right := R.Right;
  if DrawRect.Bottom < R.Bottom then
    OffsetRect(DrawRect, 0, (R.Bottom - DrawRect.Bottom) div 2)
  else
    DrawRect.Bottom := R.Bottom;
  ZeroMemory(@DrawParams, SizeOf(DrawParams));
  DrawParams.cbSize := SizeOf(DrawParams);
  DrawTextEx(Canvas.Handle, PChar(S), -1, DrawRect, DrawFlags, @DrawParams);
  Result := DrawParams.uiLengthDrawn;
end;

procedure TForm1.FormPaint(Sender: TObject);
const
  S = 'This is a very long text as test case for my paint routine.';
var
  R: TRect;
begin
  SetRect(R, 100, 100, 200, 140);
  Canvas.Rectangle(R);
  InflateRect(R, -1, -1);
  Caption := Format('%d characters drawn', [DrawTextCentered(Canvas, R, S)]);
end;
like image 147
NGLN Avatar answered Sep 24 '22 02:09

NGLN


Measure the text first using DT_CALCRECT. Pass DT_WORDBREAK to specify that word wrapping is enabled. This will allow you to find the required height for your text. Then you can, in your code, calculate the vertical offset that gives you vertically centred text, and draw to that offset.

like image 45
David Heffernan Avatar answered Sep 24 '22 02:09

David Heffernan