Эквивалент дизайнерских рекомендаций в коде

Конструктор форм VCL предлагает розовые рекомендации по выравниванию элементов управления на соответствующих текстовых базовых линиях: Guidelines in form designer
Но насколько я могу сказать, это не работает для меток и флажков. Обновление:. Он работает с метками, если вы размещаете элементы управления точно, например. на Ctrl - arrow. Это работает для флажков - см. Снимок экрана.

Теперь, в некоторых формах я создаю элементы управления в коде, например.

ed := TEdit.Create(Self);
ed.SetBounds(...);
ed.Parent := SomePanel;

и т.д.. Как я могу обеспечить, чтобы их текстовые базовые строки были выровнены? Я хотел бы иметь это для редактирования, comboboxes, label и checkboxes. Результат должен выглядеть так (без красной линии, конечно:-)): base line aligned

Изменить: Мой текущий подход - вызвать что-то вроде AlignTop(8, [Edit1, ComboBox1], [CheckBox1, Label1]); с помощью

procedure ControlArray_SetTop(const AControls: array of TControl; ATop: Integer);
var
  i: Integer;
begin
  for i := Low(AControls) to High(AControls) do
    AControls[i].Top := ATop;
end;

procedure AlignTop(ATop: Integer; const AControls: array of TControl; const ALabelLikeControls: array of TControl);
begin
  ControlArray_SetTop(AControls, ATop);
  ControlArray_SetTop(ALabelLikeControls, ATop + 3);
end;

Моя цель - заменить его чем-то более надежным и менее взломанным.

Ответ 1

Рекомендации внедрены в коде времени разработки, лицензия которого запрещает вам отправлять с вашим приложением, поэтому вы можете использовать его только для изучения, а затем переопределить его самостоятельно. Посмотрите

DesignIntf.TBaseComponentGuidelines
DesignEditors.TComponentGuidelines
VCLEditors.TControlGuidelines

(в "{RADStudio\version}\source\ToolsAPI directory" ). Возможно, это сводится к чему-то простому, поскольку

Label1.Top := (Edit1.Top + Edit1.Height) - Label1.Height + GetMagicConstant;  

где GetMagicConstant аналогично TControlGuidelines.GetTextBaseline().

Ответ 2

Я не думаю, что эта логика каким-либо образом подвергается вызову во время выполнения. Я считаю, что это только время разработки.

Чтобы справиться с этим, я бы создал фиктивную форму в дизайнере, в которой был один из каждого элемента управления, с которым вы работали. Выровняйте их так же, как на скриншотах. Во время выполнения создайте экземпляр этой формы, но не показывайте ее и не читайте свойство Top для каждого типа элемента управления. Наконец, вы можете выработать вертикальное смещение свойства Top для каждого типа управления для каждого типа управления.

Ответ 3

Мне захотелось выровнять ярлык с ним в поле редактирования. стоя на плечах @, я использовал это:

  Label1.Top := edit1.Top + _GetTextBaseline(edit1, tlBottom) - _GetTextBaseline(Label1, tlTop);


  // lifted from TControlGuidelines.GetTextBaseline(AControl: TControl; Align: TTextLayout): Integer;
  function _GetTextBaseline(AControl: TControl; Align: TTextLayout): Integer;
  var
    Canvas: TControlCanvas;
    tm: TTextMetric;
    ClientRect: TRect;
    Ascent, Height: Integer;
  begin
    Canvas := TControlCanvas.Create;
    try
      ClientRect := AControl.ClientRect;
      Canvas.Control := AControl;
      Canvas.Font := TControlFriend(AControl).Font;
      GetTextMetrics(Canvas.Handle, tm);
      Ascent := tm.tmAscent + 1;
      Height := tm.tmHeight;
      case Align of
        tlTop: Result := ClientRect.Top + Ascent;
        tlCenter: Result := (ClientRect.Top + (ClientRect.Bottom - Height) div 2) + Ascent;
        tlBottom: Result := (ClientRect.Bottom - Height) + Ascent;
      else
        Result := 0;
      end;
    finally
      Canvas.Free;
    end;
  end;

Ответ 4

Если вы сделаете два элемента управления с одинаковой высотой, выровняйте вершины и выравнивайте текст по вертикали, как правило, базовая линия будет выровнена даже при изменении размера шрифта и шрифтов