Как нарисовать текст Unicode?

Как нарисовать текст Unicode в TCustomControl? Есть ли другие варианты сделать это без Canvas?


person Little Helper    schedule 30.04.2011    source источник
comment
Извините за мой английский, может DrawTextW будет работать?   -  person Little Helper    schedule 30.04.2011
comment
Вы загрузили набор компонентов TNT? Это проще, чем делать это самостоятельно в версиях delphi без юникода (до 2009 года), и еще проще просто купить Delphi XE, который изначально поддерживает юникод.   -  person Warren P    schedule 01.05.2011


Ответы (1)


Да, вы прямо в точку. Тем не менее, я бы порекомендовал вам перейти на Delphi 2009 или более позднюю версию, в которой VCL имеет полную поддержку Unicode и все намного проще.

Во всяком случае, вы можете сделать

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;

в старых версиях Delphi (я думаю. Код компилируется в Delphi 7 на моей виртуальной машине с Windows 95, но я не вижу текста. Думаю, это потому, что Windows 95 слишком старая.)

Обновить

Если вы хотите поддерживать очень старые операционные системы, такие как Windows 95 и Windows 98, вам нужно использовать TextOutW вместо DrawTextW, так как последний не реализован (источник). TextOut менее мощный, чем DrawText, поэтому вам нужно вычислить положение вручную, если вы хотите, например, центрировать текст внутри прямоугольника.

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;
person Andreas Rejbrand    schedule 30.04.2011
comment
Оба работают, спасибо! Но какой шрифт лучше всего подходит для уставов Unicode? - person Little Helper; 30.04.2011
comment
По моему опыту, лучший шрифт — Arial Unicode MS. Lucida Sans Unicode тоже подходит. Но, конечно, вы не можете полагаться на то, что эти шрифты будут установлены на компьютере конечного пользователя. Бесплатные шрифты DejaVu хороши, и вы можете установить их вместе со своим приложением. - person Andreas Rejbrand; 30.04.2011
comment
Как центрировать текст в TCustomControl? Как очистить Канвас? - person Little Helper; 30.04.2011
comment
@Robrok: DrawText сделает это за вас, если вы укажете только флаги DT_SINGLELINE, DT_CENTER (в центре по горизонтали) и DT_VCENTER (в центре по вертикали), а прямоугольник r - это весь прямоугольник клиента (ClientRect). Таким образом, мой первый фрагмент кода будет отображать текст по центру как по горизонтали, так и по вертикали. Однако при использовании TextOut вам нужно вычислить верхний левый угол текста вручную. Левая координата — (Width - TextWidth) div 2, верхняя — (Height - TextHeight) div 2. Width и Height — ширина и высота элемента управления. Нужно как-то разобраться... - person Andreas Rejbrand; 30.04.2011
comment
(продолжение) ширина и высота выходной строки (переменные TextWidth и TextHeight). Вы можете использовать [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` в Delphi 7, чтобы получить ширину и высоту широкой строки в пикселях перед ее выводом. - person Andreas Rejbrand; 30.04.2011
comment
Холст должен быть очищен, когда вы находитесь в своей Paint процедуре. Но если вы хотите очистить его вручную, сделайте Canvas.Brush.Color := clBtnFace; Canvas.Brush.Style := bsSolid; Canvas.FillRect(ClientRect);. - person Andreas Rejbrand; 30.04.2011
comment
@Robrok: Да, я знаю. Именно поэтому я упомянул так много подробностей о том, как узнать размер текста. (Когда я пишу TextOut и т. д., я имею в виду TextOutW и т. д. в данном случае.) - person Andreas Rejbrand; 30.04.2011