Почему я получил другой размер компонента в IDE? - PullRequest
4 голосов
/ 25 января 2012

Использование Delphi 6 Prof.

Я создал скос для разделения.

Поскольку я использовал проставки с 8 пикселями (ширина х высота), я подумал,создать этот компонент, и когда я помещаю его в форму, мне нужно только установить Align - и все.

type
  TSSpacer = class(TBevel)
  public
    constructor Create(aOwner: TComponent); override;
  published
    //property Width default 8;
    //property Height default 8;
    property Shape default bsSpacer;
end;

constructor TSSpacer.Create(aOwner : TComponent);
begin
  inherited Create(aOwner);
  Shape := bsSpacer;
  Width := 8;
  Height := 8;
end;

Но когда я использую этот код (с или без "по умолчанию"), результат140 х 41 пиксель в IDE.

Так почему же он не имеет размер 8 х 8?И что также интересно: TBevel по умолчанию равен 50 x 50.

Что вызывает это изменение размера?

Ответы [ 2 ]

2 голосов
/ 26 января 2012

TLama ударил по гвоздю в своих комментариях: так или иначе, дизайнер препятствует тому, чтобы компоненты стали слишком маленькими. Странно, однако, что разработчик не устанавливает этот минимальный размер (10 x 10), а вместо этого, кажется, произвольно устанавливает размер на произвольные значения: 140 x 41 в D6, как указано в OP, и 100 x 41 здесь, в D7.

Ну, так как TBevel не использует и не публикует свойство AutoSize, а имя этого свойства относится к желаемому поведению, я решил расширить его использование:

type
  TSSPacer = class(TBevel)
  protected
    procedure SetParent(AParent: TWinControl); override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
  published
    property Shape default bsSpacer;
  end;

constructor TSSPacer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Shape := bsSpacer;
end;

procedure TSSPacer.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
  if AutoSize then
    inherited SetBounds(ALeft, ATop, 8, 8)
  else
    inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;

procedure TSSPacer.SetParent(AParent: TWinControl);
begin
  AutoSize := (csDesigning in ComponentState) and (Parent = nil) and
    (AParent <> nil);
  inherited SetParent(AParent);
end;

Это работает здесь, в D7, но более надежная реализация может быть:

  private
    FFixDesignSize: Boolean;

procedure TSSPacer.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
  if FFixDesignSize then
  begin
    inherited SetBounds(ALeft, ATop, 8, 8);
    FFixDesignSize := False;
  end
  else
    inherited SetBounds(ALeft, ATop, AWidth, AHeight);
end;

procedure TSSPacer.SetParent(AParent: TWinControl);
begin
  FFixDesignSize := (csDesigning in ComponentState) and (Parent = nil) and
    (AParent <> nil);
  inherited SetParent(AParent);
end;

И чтобы завершить этот ответ стеком вызовов, сбросив этот элемент управления в конструкторе на форме:

- Before SetBounds
- After SetBounds
- Before SetBounds
- After SetBounds
- Before SetParent
    - Before SetBounds
    - After SetBounds
- After SetParent
- Before SetBounds
- After SetBounds
- Before SetParent
- After SetParent

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

0 голосов
/ 25 января 2012

Нашел статью, которая должна объяснить это .. Я думаю, вам нужно переопределить TCBontrol SetBounds.

Подробнее здесь http://www.delphidabbler.com/tips/77

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...