11

The VCL form designer offers pink guidelines for aligning controls at their respective text base lines: Guidelines in form designer
But as far as I can tell this doesn't work for labels and checkboxes. Update: It works for labels if you place the controls exactly, e.g. by Ctrl-arrow. It kind of works for checkboxes - see screenshot.

Now, on some forms I'm creating controls in code, e.g.

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

etc. How can I ensure that their text base lines are aligned? I'd like to have this for edits, comboboxes, labels and checkboxes. The result should look like this (without the red line, of course :-)): base line aligned

Edit: My current approach is to call something like AlignTop(8, [Edit1, ComboBox1], [CheckBox1, Label1]); with

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;

My goal is to replace it with something more robust and less hacky.

4

4 回答 4

5

这些指南是在设计时代码中实现的,该许可证禁止您随应用程序一起发布,因此您只能使用它来学习它,然后自己重​​新实现它。抬头

DesignIntf.TBaseComponentGuidelines
DesignEditors.TComponentGuidelines
VCLEditors.TControlGuidelines

类(在“{RADStudio\version}\source\ToolsAPI 目录”中)。也许它归结为一些简单的事情

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

其中GetMagicConstant类似于TControlGuidelines.GetTextBaseline()

于 2011-08-03T09:30:28.813 回答
2

我认为这个逻辑不会以任何方式暴露给你在运行时调用。我相信这只是设计时间。

为了处理这个问题,我将在设计器中创建一个虚拟表单,其中包含您使用的每个控件之一。将它们与屏幕截图中的所有方式对齐。在运行时实例化此表单,但不显示它并读出Top每种控件类型的属性。最后,您可以计算出Top属性从每种类型的控件到其他类型的控件的垂直偏移量。

于 2011-08-03T10:42:30.493 回答
1

我想将标签与它的编辑框对齐。站在@ain 的肩膀上,我用了这个:

  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;
于 2011-08-08T16:55:11.310 回答
0

如果您使两个控件的高度相同,则对齐顶部并垂直对齐文本,即使您更改字体大小和字体,基线也会对齐

于 2016-03-25T15:00:11.417 回答