How do I draw Unicode text?
Asked Answered
O

1

7

How to draw Unicode text on TCustomControl? Are there other options to make it without the Canvas?

Oud answered 30/4, 2011 at 9:1 Comment(2)
Sorry for my english, maybe DrawTextW will work?Oud
Have you downloaded the TNT component set? It's easier than doing it yourself in non-unicode delphi versions (prior to 2009) and easier still is to just buy Delphi XE which is natively unicode.Simmer
R
11

Yes, you are right on spot. Still, I would recommend you to upgrade to Delphi 2009 or later in which the VCL has full Unicode support and everything is much easier.

Anyhow, you can do

procedure TMyControl.Paint;
var
  S: WideString;
  r: TRect;
begin
  inherited;
  r := ClientRect;
  S := 'This is the integral sign: '#$222b;
  DrawTextW(Canvas.Handle, PWideChar(S), length(S), r, DT_SINGLELINE or
    DT_CENTER or DT_VCENTER or DT_END_ELLIPSIS);
end;

in old versions of Delphi (I think. The code compiles in Delphi 7 in my virtual Windows 95 machine, but I see no text. That is because Windows 95 is too old, I think.)

Update

If you want to support very old operating systems, like Windows 95 and Windows 98, you need to use TextOutW instead of DrawTextW, since the latter isn't implemented (source). TextOut is less powerful then DrawText, so you need to compute the position manually if you want to center the text inside a rectangle, for instance.

procedure TMyControl.Paint;
var
  S: WideString;
begin
  inherited;
  S := 'This is the integral sign: '#$222b;
  TextOutW(Canvas.Handle, 0, 0, PWideChar(S), length(S));
end;
Reprobation answered 30/4, 2011 at 11:4 Comment(7)
Both work, thanks! But what is the best font for unicode charters?Oud
In my experience, the best font is Arial Unicode MS. Lucida Sans Unicode is also OK. But of course, you cannot rely on these font's being installed on the end user's computer. The free DejaVu fonts are good, and you can install them together with your application.Reprobation
How to center text in TCustomControl? How to clean Canvas?Oud
@Robrok: DrawText does it for you, if you only specify the flags DT_SINGLELINE, DT_CENTER (center horizontally), and DT_VCENTER (center vertically) and the r rect is the entire client rect (ClientRect). Thus, my first code snippet will draw the text centered both horizontally and vertically. Using TextOut, however, you need to compute the top-left corner of the text manually. The left coordinate is (Width - TextWidth) div 2 and the top coordinate is (Height - TextHeight) div 2. Width and Height are the width and height of the control. You need somehow to figure out...Reprobation
(cont.) the width and height of the output string (the TextWidth and TextHeight variables). You can use the [GetTextExtentPoint32W](msdn.microsoft.com/en-us/library/dd144938(VS.85).aspx) function for this. It is easy. If you want code sample, please post a new question asking exactly how to use GetTextExtentPoint32W` in Delphi 7 to get the pixel width and height of a wide string before it is output.Reprobation
The canvas should be cleaned when you are in your Paint procedure. But if you want to clean it manually, do Canvas.Brush.Color := clBtnFace; Canvas.Brush.Style := bsSolid; Canvas.FillRect(ClientRect);.Reprobation
@Robrok: Yes, I know. That is why I mentioned so many details about how to find out the text size. (When I write TextOut etc. I mean TextOutW etc. in this case.)Reprobation

© 2022 - 2024 — McMap. All rights reserved.