What is the best way to programmatically determine if TLabel is cropped (i.e. Drawn using ellipsis)?

I have TLabelwith EllipsisPositioninstalled on epEndEllipsis, and I need to find out if the text is currently truncated or not. Besides calculating the area needed to display the text and comparing it with the actual size of the label, has anyone come up with a simpler / more elegant way to do this?

In fact, calculating the required area in fail-safe mode also does not seem as straightforward as it seems ... For example, it TCanvas.GetTextHeightdoes not take line breaks into account.

TCustomLabel.DoDrawTextinternally uses either DrawTextWor DrawThemeTextExwith a flag DT_CALCRECTto determine whether to use ellipsis or not. There is a lot of code, all of which are declared private. Just duplicating all of this code will not exactly qualify as "elegant" in my book ...

Any ideas?

(I use Delphi 2010 in case anyone comes up with a solution specific to Delphi)

Update 1: Now I realized that I can simply call TCustomLabel.DoDrawText(lRect, DT_CALCRECT)directly (which is just declared protected) so that the label performs the required size calculation without having to duplicate its code. I just need to either temporarily set EllipsisPositionto epNoneor use an instance of the timestamp in general. This is actually not so bad, and I can just go with it if no one can think of an even simpler solution.

Update 2: I added my solution as a separate answer. This turned out to be more straightforward than I expected, so there probably isn't a simpler / better way to do this, but I will leave this question open for a while longer anyway just in case.

+3
2

FWIW, ( TLabel -):

function TMyLabel.IsTextClipped: Boolean;
const
  EllipsisStr = '...';
var
  lEllipBup: TEllipsisPosition;
  lRect: TRect;
begin
  lRect := ClientRect;
  Dec(lRect.Right, Canvas.TextWidth(EllipsisStr));

  lEllipBup := EllipsisPosition;
  EllipsisPosition := epNone;
  try
    DoDrawText(lRect, DT_CALCRECT or IfThen(WordWrap, DT_WORDBREAK));
  finally
    EllipsisPosition := lEllipBup;
  end;
  Result := ((lRect.Right - lRect.Left) > ClientWidth)
         or ((lRect.Bottom - lRect.Top) > ClientHeight);
end;

, TCustomLabel.DoDrawText ( WordWrap), . , "" " True, TLabel False ".

, , , , , TLabel: , , , , .

+3

function DrawStringEllipsis(const DC: HDC; const ARect: TRect; const AStr: string): boolean;
var
  r: TRect;
  s: PChar;
begin
  r := ARect;
  GetMem(s, length(AStr)*sizeof(char) + 8);
  StrCopy(s, PChar(AStr));
  DrawText(DC, PChar(s), length(AStr), r, DT_LEFT or DT_END_ELLIPSIS or DT_MODIFYSTRING);
  result := not SameStr(AStr, s);
  FreeMem(s);
end;

:

procedure TForm1.FormClick(Sender: TObject);
begin
  Caption := 'Clipped ' + BoolToStr(DrawStringEllipsis(Canvas.Handle, Rect(10, 100, 50, 50), 'This is a text.'), true);
end;

TExtLabel, WasClipped, . , TLabel VCL - .

+2

Source: https://habr.com/ru/post/1777648/


All Articles