Как нарисовать текст на холсте по вертикали + по горизонтали с Delphi 10.2 - PullRequest
0 голосов
/ 21 октября 2018

Я хочу нарисовать на холсте слово вертикально, а рядом с ним слово горизонтально.Я использовал старое предложение вроде этого:

в событии создания maiForm:

GetObject(MainForm.Font.Handle,SizeOf(TLogFont),@LogFont);
NewLogFont := LogFont;
NewLogFont.lfEscapement := 900;
NewFont := CreateFontIndirect(NewLogFont);
OldFont := MainForm.Font.Handle;

где

LogFont,NewLogFont  : TLogFont;
NewFont,OldFont     : HFont;

и в процедуре рисования:

fontTemp := TFont.Create;
fontTemp.Assign(aCanvas.Font);
......
aCanvas.Font.Handle := newFont; // if i coment this line the two strings drawn verically else both drawn horizonatlly
aCanvas.Font.Size := 8;
h := textHeight('1');
aCanvas.textOut(x,y,aString);
aCanvas.Font.Assign(fontTemp);
aCanvas.textOut(x+20,y,bString);
.....
fontTemp.Free;

В моем старом приложении (D2007) все работало нормально, но в Delphi 10.2 смена ориентации (с вершины на горизонт) меняет обе строки на горизонт.Любая помощь, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Нет, как вы сказали, это не абсолютно редкий код.Этот подход позволяет вращать текст без , используя свойства холста VCL.

Чистый WinAPI для вывода текста с вращением

Приведенный ниже код не использует возможности VCL для вывода повернутого текста в предоставленный контекст устройства (HDC).

procedure TForm1.DrawTextRotatedA(ADC: HDC; AFontHandle: HFONT; 
  Angle, X, Y: Integer; AColor: COLORREF; AText: String);
var
  LogFont: tagLOGFONT;
  OldFontHandle: HFONT;
  NewFontHandle: HFONT;
begin
  if (ADC = 0) or (AFontHandle = 0) then
    Exit;

  if GetObject(AFontHandle, SizeOf(LogFont), @LogFont) = 0 then
    Exit;

  // Set color of text and its rotation angle
  SetTextColor(ADC, AColor);
  if Angle > 360 then
    Angle := 0;
  LogFont.lfEscapement := Angle * 10;
  LogFont.lfCharset := 1;
  LogFont.lfOutPrecision := OUT_TT_PRECIS;
  LogFont.lfQuality := PROOF_QUALITY;

  // Create new font
  NewFontHandle := CreateFontIndirect(LogFont);
  try
    OldFontHandle := SelectObject(ADC, NewFontHandle);
    try
      // Output result
      SetBKMode(ADC, TRANSPARENT);
      try
        TextOut(ADC, X, Y, LPCWSTR(AText), Length(AText));
      finally
        SetBKMode(ADC, OPAQUE);
      end;
    finally
      // Restore font handle
      NewFontHandle := SelectObject(ADC, OldFontHandle);
    end;
  finally
    // Delete font handle
    DeleteObject(NewFontHandle);
  end;
end;

Есть места для улучшений, но это всего лишь пример, доказывающий, что вы ошибаетесь, называя такой код редко .В этом примере ожидается, что HFONT будет одним из аргументов для выполнения всех действий над ним.Вы, вероятно, могли бы получить дескриптор шрифта из TControl, используя сообщение WM_GETFONT, но большинство компонентов VCL не поддерживают это сообщение (это работает, например, с TListView, который возвращает правильный дескриптор шрифта).Попытка получить дескриптор шрифта из HDC возвращает шрифт System, который вообще не поддерживает вращение.Возможно, я сделал что-то не так, но я действовал в соответствии с microsoft.docs.

Использование VCL для вывода текста с вращением

Я не понял, какой код вы должны предоставить в своем вопросе, что нужно сделать(он не может быть скомпилирован), поэтому я переписал его, чтобы показать вам, как выводить повернутый текст с использованием возможностей VCL .

procedure TForm1.DrawTextRotatedB(ACanvas: TCanvas; Angle, X, Y: Integer; 
  ATextColor: TColor; AText: String);
var
  NewX: Integer;
  NewY: integer;
  Escapement: Integer;
  LogFont: TLogFont;
  NewFontHandle: HFONT;
  OldFontHandle: HFONT;
begin
  if not Assigned(ACanvas) then
    Exit;

  // Get handle of font and prepare escapement
  GetObject(ACanvas.Font.Handle, SizeOf(LogFont), @LogFont);
  if Angle > 360 then
    Angle := 0;
  Escapement := Angle * 10;

  // We must initialise all fields of the record structure
  LogFont.lfWidth := 0;
  LogFont.lfHeight := ACanvas.Font.Height;
  LogFont.lfEscapement := Escapement;
  LogFont.lfOrientation := 0;
  if fsBold in ACanvas.Font.Style then
    LogFont.lfWeight := FW_BOLD
  else
    LogFont.lfWeight := FW_NORMAL;
  LogFont.lfItalic := Byte(fsItalic in ACanvas.Font.Style);
  LogFont.lfUnderline := Byte(fsUnderline in ACanvas.Font.Style);
  LogFont.lfStrikeOut := Byte(fsStrikeOut in ACanvas.Font.Style);
  LogFont.lfCharSet := ACanvas.Font.Charset;
  LogFont.lfOutPrecision := OUT_DEFAULT_PRECIS;
  LogFont.lfClipPrecision := CLIP_DEFAULT_PRECIS;
  LogFont.lfQuality := DEFAULT_QUALITY;
  LogFont.lfPitchAndFamily := DEFAULT_PITCH;
  StrPCopy(LogFont.lfFaceName, ACanvas.Font.Name);

  // Create new font with rotation
  NewFontHandle := CreateFontIndirect(LogFont);
  try
    // Set color of text
    ACanvas.Font.Color := ATextColor;

    // Select the new font into the canvas
    OldFontHandle := SelectObject(ACanvas.Handle, NewFontHandle);
    try
      // Output result
      ACanvas.Brush.Style := VCL.Graphics.bsClear;
      try
        ACanvas.TextOut(X, Y, AText);
      finally
        ACanvas.Brush.Style := VCL.Graphics.bsSolid;
      end;
    finally
      // Restore font handle
      NewFontHandle := SelectObject(ACanvas.Handle, OldFontHandle);
    end;
  finally
    // Delete the deselected font object
    DeleteObject(NewFontHandle);
  end;
end;

Использование регистра

Вот код, показывающий, как использовать процедуры для поворота текста.

procedure TForm1.aButton1Click(Sender: TObject);
var
  DC: HDC;
begin
  Repaint;

  DC := GetDC(Handle);
  try
    DrawTextRotatedA(DC, Canvas.Font.Handle, TrackBar1.Position, 100, 100, clNavy, 'String');
  finally
    ReleaseDC(Handle, DC);
  end;

  DrawTextRotatedB(Canvas, TrackBar1.Position, 200, 100, clNavy, 'String');
end;

Иногда быстрее выводить повернутый текст на DC без VCL.Это может быть полезно, если вы пытаетесь справиться с контролем, который не имеет доступа к холсту.Например, если вы попытаетесь нарисовать tooltip (tooltip_class32) в своем собственном стиле, вы, возможно, захотите использовать первый метод для вывода текста (повернутый или нет).

Информация

Вот ссылки с docs.microsoft.они описывают как и почему использовалась та или иная функция.

0 голосов
/ 21 октября 2018

Это просто!TFont имеет свойство ориентации, которая делает работу!Все эти вещи, которые я использовал, абсолютно редки.

...