У меня проблема с DrawTextEx. При использовании Align = DT_RIGHT и шрифта «Arial» текст выходит за пределы прямоугольника.
Это код, который я использовал для воспроизведения проблемы:
procedure TForm2.FormShow(Sender: TObject);
var
LRect: TRect;
LString : string;
LMetaCanvas: TMetafileCanvas;
LAlign: integer;
LParams: TDrawTextParams;
begin
LMetaCanvas := TMetafileCanvas.Create(Image1.Picture.Metafile, 0);
LRect := Rect(10, 10, 200, 200);
LMetaCanvas.Brush.Color := clWhite;
LMetaCanvas.Brush.style := bsSolid;
LMetaCanvas.Rectangle(LRect.Left, LRect.Top, LRect.Right, LRect.Bottom);
LMetaCanvas.Font.Name := 'Arial';
LMetaCanvas.Font.Size := 10;
LMetaCanvas.Brush.Color := clBlack;
LMetaCanvas.Brush.Style := bsClear;
LString := '111111111111111112';
LParams.cbSize := SizeOf(LParams);
LParams.iTabLength := 0;
LParams.iLeftMargin := 0;
LParams.iRightMargin := 0;
LParams.uiLengthDrawn := Length(LString);
LAlign := DT_RIGHT or DT_NOPREFIX or DT_EDITCONTROL or DT_EXPANDTABS or DT_NOCLIP;
DrawTextEx(
LMetaCanvas.Handle,
PChar(LString),
Length(LString),
LRect,
LAlign,
@LParams);
LMetaCanvas.Free;
end;
Без DT_NOCLIP символы, находящиеся за пределами прямоугольника, даже не отображаются.
Я использую Delphi 10.2 в Windows 10 Pro, но сталкивался с этой проблемой также в Delphi XE3 и Delphi 2007.
Редактировать: я пытался использовать DT_CALCRECT, но я не уверен, что это правильный способ… Вот код, который я использовал:
LAlign := DT_RIGHT or DT_NOPREFIX or DT_EDITCONTROL or DT_EXPANDTABS or DT_NOCLIP or DT_CALCRECT;
DrawTextEx(
LMetaCanvas.Handle,
PChar(LString),
Length(LString),
LRect,
LAlign,
@LParams);
LAlign := DT_RIGHT or DT_NOPREFIX or DT_EDITCONTROL or DT_EXPANDTABS or DT_NOCLIP;
DrawTextEx(
LMetaCanvas.Handle,
PChar(LString),
Length(LString),
LRect,
LAlign,
@LParams);
LMetaCanvas.Free;
end;
После первого вызова DrawTextEx LRect стал (10, 10, 120, 26), что делает его меньше, чем я настроил его вначале (10, 10, 200, 200). Текст выровнен по левому краю (я думаю, это потому, что LRect был изменен, чтобы соответствовать тексту), и все равно без DT_NOCLIP я не вижу последние цифры.
Редактировать: проект, в котором возникла эта проблема, требует TMetaFileCanvas
(для других целей) и использует DrawTextEx
для отображения сумм (которые должны быть выровнены по правому краю), поэтому, к сожалению, я не могу изменить тип холста, выравнивание или текст. Использование другого шрифта, такого как Arial Unicode MS (который, похоже, не имеет проблем), означало бы изменение огромного количества существующих отчетов, поэтому я бы предпочел избегать этого решения.
LString := StringReplace(LString, '1', '1'#$200B, [rfReplaceAll]);
(не знаю, будут ли проблемы с D2007). Также может помочь воспроизведение проблемы только с вызовами API и пометка вопроса с помощью winapi. - person Sertac Akyuz   schedule 23.08.2019LString := LString + #$200B;
Возможно, это заставляет обойти какую-то оптимизацию. Или кто знает что... - person Sertac Akyuz   schedule 24.08.2019LString
сработало, спасибо! - person Marina Finetti   schedule 26.08.2019