Какой лучший бесплатный способ сделать форму изменяемой размера в Delphi 7? - PullRequest
2 голосов
/ 22 марта 2010

Мне нужно, чтобы моя форма в Delphi изменялась в размерах, а все компоненты и элементы управления должны пропорционально растягиваться вместе с размерами шрифта и т. Д. Сейчас, чтобы изменить размеры компонентов, я пишу код внутри события «OnResize» и вручную вычисляю все компоненты Размеры и шрифты. Я хотел бы иметь более простое решение, которое я могу применить к различным приложениям, не переписывая этот код для каждой формы. Я нашел некоторые компоненты в Интернете, но они являются условно-бесплатными. Можете ли вы предложить что-то?

Ответы [ 5 ]

3 голосов
/ 22 марта 2010

Вы можете использовать свойство Anchor для каждого элемента управления. Это позволяет «привязать» стороны элемента управления к определенной стороне формы.

Например, если вы хотите, чтобы TMemo заполнял середину формы по мере ее изменения, установите для свойства Anchor значение [akLeft,akTop,akRight,akBottom]. Или, если вы хотите, чтобы кнопка следовала за нижней частью формы при изменении ее размера, установите для свойства Anchor значение [akLeft,akBottom]

2 голосов
/ 22 марта 2010

Вы можете использовать мой компонент 'TArtPercentageWireGrid'. Я использовал это в течение многих лет. Перетащите его на форму, разместите любой компонент там, где вам нравится, и затем, по мере изменения размера формы, размер компонента будет пропорционально изменен. Brian

unit UArtWireGrids;

interface


uses
  Windows,
  Messages,
  SysUtils,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs;

type

  float = double;

  TFloatPoint = record X, Y : float end;

  TFloatRect = record
    case Integer of
     0: (Left, Top, Right, Bottom: float);
     1: (TopLeft, BottomRight: TFloatPoint);
  end;



  TARTSimpleWireGrid = class(TGraphicControl)
  private
    { Private declarations }
    FGridSpacing : integer;
    FPen         : TPen;
    FBrush       : TBrush;
    procedure SetGridSpacing( AValue : integer );
    procedure SetBrush( AValue : TBrush );
    procedure SetPen( AValue : TPen );
  protected
    { Protected declarations }
    procedure Paint; override;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
  published
    { Published declarations }
    property  Align;
    property  Brush : TBrush read FBrush write SetBrush;
    property  Pen : TPen read FPen write SetPen;
    property  GridSpacing : integer read FGridSpacing write SetGridSpacing;
    procedure StyleChanged(Sender : TObject);
    property  Visible;
  end;



  TGridStyle = ( gsLines, gsPoints );



  TARTPercentageWireGrid = class(TGraphicControl)
  private
    { Private declarations }
    FLineSpacing : double;
    FPen         : TPen;
    FBrush       : TBrush;
    FGridVisible : boolean;
    FGridStyle   : TGridStyle;
    procedure SetLineSpacing( AValue : double );
    procedure SetBrush( AValue : TBrush );
    procedure SetPen( AValue : TPen );
    function  GetLineSpacingPixelX : integer;
    function  GetLineSpacingPixelY : integer;
    procedure SetGridVisible( AState : boolean );
    procedure SetGridStyle( AValue : TGridStyle );
    function  RoundToGrid( AValue : float ) : float;
  protected
    { Protected declarations }
    procedure Paint; override;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
    procedure   DrawPointsOnCanvas( ACanvas : TCanvas );
    function    GridXToPixel( const AGridX : float ) : integer;
    function    GridYToPixel( const AGridY : float ) : integer;
    function    GridPointToPixel( const APoint : TFloatPoint ) : TPoint;
    function    GridRectToPixel( const ARect : TFloatRect ) : TRect;
    function    PixelXToGrid( AValue : integer ) : float;
    function    PixelYToGrid( AValue : integer ) : float;
    function    PixelPointToGrid( const APoint : TPoint ) : TFloatPoint;
    function    PixelRectToGrid( const ARect : TRect ) : TFloatRect;
    function    GridAlignPixelX( AValue : integer ) : integer;
    function    GridAlignPixelY( AValue : integer ) : integer;
    function    GridAlignPixelPoint( const APoint : TPoint ) : TPoint;
    function    GridAlignPixelRect( const ARect : TRect ) : TRect;
    function    MoveGridRect( const ARect : TFloatRect;
                              const ADeltaX, ADeltaY : float ) : TFloatRect;
    function    ScaleGridRect( const ARect  : TFloatRect;
                               const AScale : float ) : TFloatRect;
    function    GridLineXToPixel( AValue : integer ) : integer;
    function    GridLineYToPixel( AValue : integer ) : integer;
    function    GridLinePointToPixel( const APoint : TPoint ) : TPoint;
    function    GridLineRectToPixel( const ARect : TRect ) : TRect;
    function    PixelXToGridLine( AValue : integer ) : integer;
    function    PixelYToGridLine( AValue : integer ) : integer;
    function    PixelPointToGridLine( const APoint : TPoint ) : TPoint;
    function    PixelRectToGridLine( const ARect : TRect ) : TRect;
  published
    { Published declarations }
    property  Align;
    property  Brush : TBrush read FBrush write SetBrush;
    property  Pen : TPen read FPen write SetPen;
    property  LineSpacing : double read FLineSpacing write SetLineSpacing;
    property  LineSpacingPixelX : integer read GetLineSpacingPixelX;
    property  LineSpacingPixelY : integer read GetLineSpacingPixelY;
    procedure StyleChanged(Sender : TObject);
    property  Visible;
    property  GridVisible : boolean read FGridVisible write SetGridVisible;
    property  GridStyle   : TGridStyle read FGridStyle write SetGridSTyle;
  end;



implementation


{TARTSimpleWireGrid}
{ ---------------------------------------------------------------------------- }



constructor TARTSimpleWireGrid.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FPen            := TPen.Create;
  FPen.OnChange   := StyleChanged;
  FBrush          := TBrush.Create;
  FBrush.OnChange := StyleChanged;
  GridSpacing     := 20;
  Height          := 100;
  Width           := 100;
end;



destructor  TARTSimpleWireGrid.Destroy;
begin
  FPen.Free;
  FBrush.Free;
  Inherited Destroy;
end;


procedure TARTSimplewireGrid.SetGridSpacing( AValue : integer );
begin
  If AValue <> FGridSpacing then
    begin
    FGridSpacing := AValue;
    Invalidate;
    end;
end;

procedure TARTsimpleWireGrid.Paint;
var
 I : integer;
begin
   Inherited Paint;

   If FGridspacing < 20 then
    GridSpacing := 20;

   Canvas.Brush.Assign( FBrush );
   Canvas.Pen.Assign( FPen );

   // Vertical bars
   I := 0;
   While I < ClientWidth do
    begin
    Canvas.MoveTo( I,0 );
    Canvas.LineTo( I,ClientHeight);
    Inc(I,FGridSpacing);
    end;

   // Horiz bars
   I := 0;
   While I < ClientHeight do
    begin
    Canvas.MoveTo( 0,I );
    Canvas.LineTo( ClientWidth,I);
    Inc(I,FGridSpacing);
    end;
end;



procedure TARTSimplewireGrid.SetBrush( AValue : TBrush );
begin
  FBrush.Assign( AValue );
end;

procedure TARTSimplewireGrid.SetPen( AValue : TPen );
begin
  FPen.Assign( AValue );
end;


procedure TARTSimplewireGrid.StyleChanged(Sender : TObject);
begin
  Invalidate;
end;


//End TARTSimpleWireGrid

end.













{TARTPercentageWireGrid}
{ ---------------------------------------------------------------------------- }



constructor TARTPercentageWireGrid.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  If AOwner is TForm then
    begin
    OnMouseDown := Tform(AOwner).OnMouseDown;
    OnMouseUp   := Tform(AOwner).OnMouseUp;
    OnMouseMove := Tform(AOwner).OnMouseMove;
    end;
  FPen            := TPen.Create;
  FPen.OnChange   := StyleChanged;
  FBrush          := TBrush.Create;
  FBrush.OnChange := StyleChanged;
  FGridVisible    := True;
  LineSpacing     := 10;
  Height          := 100;
  Width           := 100;
end;



destructor  TARTPercentageWireGrid.Destroy;
begin
  FPen.Free;
  FBrush.Free;
  Inherited Destroy;
end;


procedure TARTPercentagewireGrid.SetLineSpacing( AValue : double );
begin
  If AValue <> FLineSpacing then
    begin
    FLineSpacing := AValue;
    If FLineSpacing < 1.0 then
     FLineSpacing := 1.0;
    Invalidate;
    end;
end;



procedure TARTPercentagewireGrid.DrawPointsOnCanvas( ACanvas : TCanvas );
var
 X, Y   : integer;
 FX, FY : float;
  begin
   FY := 0.0;
   Repeat
    FY := FY + FLineSpacing;
    FX := 0.0;
    Y := GridYToPixel(FY);
    Repeat
     FX := FX + FLineSpacing;
     X := GridXToPixel(FX);
     ACanvas.Pixels[ X, Y ] := clBlack;
    until FX >= 100;
   until FY >= 100;
end;




procedure TARTPercentageWireGrid.Paint;

  procedure DrawLines;

    procedure LinesVert;
    var
     X : integer;
     F : double;
    begin
      F := 0.0;
      Repeat
       F := F + FLineSpacing;
       X := GridXToPixel(F);
       Canvas.MoveTo( X, 0 );
       Canvas.LineTo( X, Height );
      until X >= ClientWidth;
    end;

    procedure LinesHorz;
    var
     F : double;
     Y : integer;
    begin
      F := 0.0;
      Repeat
       F := F + FLineSpacing;
       Y := GridYToPixel(F);
       Canvas.MoveTo( 0, Y );
       Canvas.LineTo( Width, Y );
      until Y >= ClientHeight;
    end;

  begin
     LinesVert;
     LinesHorz;
  end;









begin
   Inherited Paint;

   If FGridVisible then
     begin
     Canvas.Brush.Assign( FBrush );
     Canvas.Pen.Assign( FPen );

     Case FGridStyle of
       gsLines  : DrawLines;
       gsPoints : DrawPointsOnCanvas( Canvas );
     end;
     end;

end;



procedure TARTPercentagewireGrid.SetBrush( AValue : TBrush );
begin
  FBrush.Assign( AValue );
end;

procedure TARTPercentagewireGrid.SetPen( AValue : TPen );
begin
  FPen.Assign( AValue );
end;


procedure TARTPercentagewireGrid.StyleChanged(Sender : TObject);
begin
  Invalidate;
end;



function TARTPercentageWireGrid.GridXToPixel( const AGridX : float ) : integer;
begin
  Result  := Round(AGridX * Width / 100);
end;


function TARTPercentageWireGrid.GridYToPixel( const AGridY : float ) : integer;
begin
  Result  := Round(AGridY * Height / 100);
end;



function TARTPercentageWireGrid.GetLineSpacingPixelX : integer;
begin
  Result := GridXToPixel( FLineSpacing );
end;

function TARTPercentageWireGrid.GetLineSpacingPixelY : integer;
begin
  Result := GridYToPixel( FLineSpacing );
end;


function TARTPercentageWireGrid.GridPointToPixel( const APoint : TFloatPoint ) : TPoint;
begin
  Result.X := GridXToPixel( APoint.X );
  Result.Y := GridYToPixel( APoint.Y );
end;


function TARTPercentageWireGrid.GridRectToPixel( const ARect : TFloatRect ) : TRect;
begin
  Result.TopLeft     := GridPointToPixel( ARect.TopLeft );
  Result.BottomRight := GridPointToPixel( ARect.BottomRight );
end;


function TARTPercentageWireGrid.PixelXToGrid( AValue : integer ) : float;
begin
  Result  := (Trunc(AValue) * 100) / Width;
end;


function TARTPercentageWireGrid.PixelYToGrid( AValue : integer ) : float;
begin
  Result  := (Trunc(AValue) * 100) / Height;
end;





function TARTPercentageWireGrid.PixelPointToGrid( const APoint : TPoint ) : TFloatPoint;
begin
  Result.X := PixelXToGrid( APoint.X );
  Result.Y := PixelYToGrid( APoint.Y );
end;

function TARTPercentageWireGrid.PixelRectToGrid( const ARect : TRect ) : TFloatRect;
begin
  Result.TopLeft     := PixelPointToGrid( ARect.TopLeft );
  Result.BottomRight := PixelPointToGrid( ARect.BottomRight );
end;


function TARTPercentageWireGrid.RoundToGrid( AValue : float ) : float;
begin
    Result := LineSpacing * Round( AValue / LineSpacing );
end;



function TARTPercentageWireGrid.GridAlignPixelX( AValue : integer ) : integer;
begin
  Result := GridXToPixel( RoundToGrid( PixelXToGrid( AValue )));
end;


function TARTPercentageWireGrid.GridAlignPixelY( AValue : integer ) : integer;
begin
  Result := GridYToPixel( RoundToGrid( PixelYToGrid( AValue )));
end;



function TARTPercentageWireGrid.GridAlignPixelPoint( const APoint : TPoint ) : TPoint;
begin
  Result.X := GridAlignPixelX( APoint.X );
  Result.Y := GridAlignPixelY( APoint.Y );
end;


function TARTPercentageWireGrid.GridAlignPixelRect( const ARect : TRect ) : TRect;
begin
  Result.TopLeft     := GridAlignPixelPoint( ARect.TopLeft );
  Result.BottomRight := GridAlignPixelPoint( ARect.BottomRight );

  // Its possible that aligning may have collapsed a width or height to
  // zero. If so, make it at least 1 unit in size
  If Result.Top = Result.Bottom then
    Result.Bottom := Result.Top + LineSpacingPixelY;
  If Result.Left = Result.Right then
    Result.Right := Result.Left + LineSpacingPixelX;

end;


procedure TARTPercentageWireGrid.SetGridVisible( AState : boolean );
begin
  If AState <> FGridVisible then
    begin
    FGridVisible := AState;
    Invalidate;
    end;
end;


function TARTPercentageWireGrid.MoveGridRect( const ARect : TFloatRect;
                                              const ADeltaX, ADeltaY : float ) : TFloatRect;
begin
  Result.Left   := ARect.Left + ADeltaX;
  Result.right  := ARect.Right + ADeltaX;
  Result.Top    := ARect.Top  + ADeltaY;
  Result.Bottom := ARect.Bottom + ADeltaY;
end;


function TARTPercentageWireGrid.ScaleGridRect( const ARect  : TFloatRect;
                                               const AScale : float ) : TFloatRect;
begin
  Result.Left   := ARect.Left * AScale;
  Result.right  := ARect.Right * Ascale;
  Result.Top    := ARect.Top  * AScale;
  Result.Bottom := ARect.Bottom * AScale;
end;


procedure TARTPercentageWireGrid.SetGridStyle( AValue : TGridStyle );
begin
   If AValue <> FGridStyle then
     begin
     FGridStyle := AValue;
     Invalidate;
     end;
end;


function TARTPercentageWireGrid.GridLineXToPixel( AValue : integer ) : integer;
begin
  Result  := GridXToPixel(Trunc(AValue) * LineSpacing);
end;

function TARTPercentageWireGrid.GridLineYToPixel( AValue : integer ) : integer;
begin
  Result  := GridYToPixel(Trunc(AValue) * LineSpacing);
end;



function TARTPercentageWireGrid.GridLinePointToPixel( const APoint : TPoint ) : TPoint;
begin
  Result.X   := GridLineXToPixel( APoint.X );
  Result.Y   := GridLineYToPixel( APoint.Y );
end;


function TARTPercentageWireGrid.GridLineRectToPixel( const ARect : TRect ) : TRect;
begin
  Result.TopLeft     := GridLinePointToPixel( ARect.TopLeft );
  Result.BottomRight := GridLinePointToPixel( ARect.BottomRight );
end;


function TARTPercentageWireGrid.PixelXToGridLine( AValue : integer ) : integer;
begin
  Result  := Round(PixelXToGrid( AValue ) / FLineSpacing);
end;


function TARTPercentageWireGrid.PixelYToGridLine( AValue : integer ) : integer;
begin
  Result  := Round(PixelYToGrid( AValue ) / FLineSpacing);
end;


function TARTPercentageWireGrid.PixelPointToGridLine( const APoint : TPoint ) : TPoint;
begin
  Result.X := PixelXToGridLine( APoint.X );
  Result.Y := PixelYToGridLine( APoint.Y );
end;

function TARTPercentageWireGrid.PixelRectToGridLine( const ARect : TRect ) : TRect;
begin
  Result.TopLeft     := PixelPointToGridLine( ARect.TopLeft );
  Result.BottomRight := PixelPointToGridLine( ARect.BottomRight );
end;


{End TARTPercentageWireGrid}
{ ---------------------------------------------------------------------------- }

Подробнее:

@ Ульрих и другие: извините, я забыл пару вещей. Вот простой пример:

  1. Получите сетку, работающую - установите ее Align = alClient, и когда форма будет изменена, вы должны увидеть, как сетка изменяет размер вместе с ней.

  2. Объявите следующее поле ЧАСТНОЕ поле:

    FBounds: массив TFloatRect;

  3. Предположим, вы хотите, чтобы изменялась только одна кнопка Button1. Поместите в FormCreate следующее:

    SetLength (FBounds, 1); FBounds [0]: = ARTPercentageWireGrid1.PixelRectToGrid (Button1.BoundsRect);

  4. Наконец, добавьте в FormResize следующее:

    Button1.BoundsRect: = ARTPercentageWireGrid1.GridRectToPixel (FBounds [0]);

Когда вы изменяете размер формы, кнопка будет отслеживать форму пропорционально. Для работы со всеми элементами управления выполните:

procedure TForm1.FormResize(Sender: TObject);
var
   I : integer;
begin
  //Button1.BoundsRect := ARTPercentageWireGrid1.GridRectToPixel( FBounds[0] );

  For I := 0 to ComponentCount-1 do
    If Components[I] is TControl then
      With Components[I] as TControl do
        If Align <> alClient then
          BoundsRect := ARTPercentageWireGrid1.GridRectToPixel( FBounds[I] );

end;

procedure TForm1.FormCreate(Sender: TObject);
var
  I : integer;
begin
  //SetLength( FBounds, 1 );
  //FBounds[0] := ARTPercentageWireGrid1.PixelRectToGrid( Button1.BoundsRect );

  SetLength( FBounds, ComponentCount );
  For I := 0 to ComponentCount-1 do
    If Components[I] is TControl then
      With Components[I] as TControl do
        If Align <> alClient then
          FBounds[I] := ARTPercentageWireGrid1.PixelRectToGrid( BoundsRect );
end;

Извинения за небрежный код. Брайан.

1 голос
/ 08 октября 2013

Полезный блок кода (после всех внесенных изменений), но, поскольку он размещен сейчас 3 года спустя, он не работает, так как компонент не зарегистрирован.Вам нужно добавить следующий код вокруг оператора implementation в модуле, прежде чем вы сможете добавить компонент.

    procedure Register;

    implementation

    procedure Register;
    begin
      RegisterComponents('ComponentName', [TARTPercentageWireGrid]);
    end;
0 голосов
/ 23 марта 2010

Проверка ResizeKit компонент для Delphi. Может изменять размеры компонентов и шрифтов.
Существует бесплатная пробная загрузка.

0 голосов
/ 22 марта 2010

Если вас устраивает код, который вы использовали в событии OnResize, возможно, стоит создать свои собственные пользовательские компоненты, включающие этот код. Это упростит использование этих компонентов в будущем.

...