2010-03-22 2 views
2

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

ответ

2

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

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} 
{ ---------------------------------------------------------------------------- } 

Подробнее:

@Ulrich и другие: Я сожалею, я уже забыл пару вещей. Простой пример следующим образом:

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

  2. Объявляет следующий вид: PRIVATE поле

    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

использует UArtDefs, можете ли вы предложить, где я могу это получить? –

+0

@Tofig: Удалить UArtDefs и добавить следующее: 'float = Single; TFloatPoint = запись x, y: float; конец; TFloatRect = запись case Integer 0: (Слева, Верх, Вправо, Внизу: поплавок); 1: (TopLeft, BottomRight: TFloatPoint); конец; '. По крайней мере, это компилируется. :-) –

+0

@Brian: Я сделал простое тестовое приложение (создав TARTPercentageWireGrid в конструкторе формы), но элементы управления в форме не изменяются. Как это должно работать? –

3

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

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

+0

+1 но это не будет * растягивать * размер шрифта. –

+0

И я думаю, что это тоже не изменит размеры компонентов. –

+0

Он изменит размеры компонентов, но вы оба правы, это не совсем то, что задается ... Это не изменяет размер шрифтов. Я уйду на пенсию, чтобы рассмотреть лучший ответ! – Nat

0

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

+0

Я не знаю, как это сделать, в коде я вручную вводим координаты и размеры каждого компонента. Как эта функция автоматически настраивается в любой форме? –

+0

точно ... создайте настраиваемый компонент, который наследует TForm, и все формы должны наследовать компонент. И поместите код из события OnResize в метод, например ResizeControls. Проблема заключается в том, как автоматически вызывать этот метод при возникновении события OnResize. Вернемся к вам по этому вопросу: D Или сделайте это не изящным способом и для каждой формы в OnResize вызовите метод. – AlexRednic

+0

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

0

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

1

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

procedure Register; 

    implementation 

    procedure Register; 
    begin 
     RegisterComponents('ComponentName', [TARTPercentageWireGrid]); 
    end;