2

TControl(私の場合はTGraphicControl)の制約比率を作成するにはどうすればよいですか?
したがって、変更するとWidthHeight比例関係が変更されます(その逆も同様です)。
また、私が設定した場合BoundsRect、コントロールは比率を維持する必要があります。私のコントロールにはAspectRatio: TPoint、次の設定のプロパティがあります。

AspectRatio.X := 4;
AspectRatio.Y := 3;

だから今私のAspectRatioFactor = 4/3。そして、この比率は常に維持する必要があります。

これはどのように行うことができますか?

4

2 に答える 2

6
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TPanel = Class(ExtCtrls.TPanel)
  private
    FAspectRatio: TPoint;
    procedure SetAspectRatio(const Value: TPoint);
  public
    constructor Create(AOwner: TComponent); override;
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
    property AspectRatio: TPoint read FAspectRatio write SetAspectRatio;
  end;

  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
{ TPanel }

constructor TPanel.Create(AOwner: TComponent);
begin
  inherited;
  FAspectRatio.X := 4;
  FAspectRatio.Y := 3;
end;

procedure TPanel.SetAspectRatio(const Value: TPoint);
begin
  FAspectRatio := Value;
  AdjustSize;
end;

procedure TPanel.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
var
  vh: Double;
begin
  if FAspectRatio.Y <> 0 then
  begin
    vh := FAspectRatio.X / FAspectRatio.Y;
    if Round(AHeight * vh) <> AWidth then
    begin
      if AWidth <> Width then
        AHeight := Round(AWidth / vh)
      else
        AWidth := Round(AHeight * vh);
    end;
  end;
  inherited;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Panel1.Width := 101;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Panel1.Height := 101;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  p: TPoint;
begin
  p.X := 5;
  p.Y := 3;
  Panel1.AspectRatio := p;
end;

end.

Setbounds をオーバーライドすると、指定された AspectRatio が確実に維持されます。
AspectRatio の Setter の AdjustSize は、AspectRatio の変更が一度に適用されることを保証します。
ボタン イベントは、デモ用にのみ実装されています。

于 2012-12-30T18:11:34.480 に答える
4

コントロールの仮想メソッドをオーバーライドCanResizeします。

function TMyControl.CanResize(var NewWidth, NewHeight: Integer): Boolean;
begin
  NewHeight := MulDiv(NewWidth, AspectRatio.Y, AspectRatio.X); 
  Result := True;
end;

これにより、幅がマスター寸法になります。高さを担当させたい場合は、数式を再配置できます。

どのディメンションをマスターにするかを賢く選択することができます。

function TMyControl.CanResize(var NewWidth, NewHeight: Integer): Boolean;
begin
  if abs(NewWidth-Width)>abs(NewHeight-Height) then
    NewHeight := MulDiv(NewWidth, AspectRatio.Y, AspectRatio.X)
  else
    NewWidth := MulDiv(NewHeight, AspectRatio.X, AspectRatio.Y);
  Result := True;
end;

また、プロパティのプロパティ セッターにコードを追加する必要がありAspectRatioます。そのプロパティを変更すると、コントロールのサイズ変更が必要になるためです。

于 2012-12-30T17:55:57.680 に答える