Шаг 26.
Класс TControl. Положение, размеры и выравнивание элементов управления

    На этом шаге мы продолжим изучение некоторых событий и методов класса TControl. Полный перечень свойств, методов и событий приведен на шаге 16.

    О каждом визуальном компоненте должно быть известно, где он будет показан и какой будет иметь размер. Свойство:

   property BoundsRect: TRect; 

определяет прямоугольник, содержащий координаты верхнего левого и правого нижнего углов компонента в системе координат клиентской области родительского элемента. Для формы верхний левый угол выражен в системе координат экрана.

    Также можно установить положение и размер компонента, изменяя координаты верхнего левого угла, длины и ширины методом:

   procedure setBounds (ALeft, ATop, AWidth, AHeight: Integer);.

    К каждой из этих величин есть и раздельный доступ во время разработки с помощью свойств:

   property Left: Integer;
   property Top: Integer;
   property Width: Integer;
   property Height: Integer;         .

    Другое свойство задает прямоугольник, определяющий положение и размеры клиентской области окна элемента управления:

   property ClientRect: TRect;     .  

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

   property ClientHeight: Integer;
   property ClientWidth: Integer;           .

    Свойство ClientOrigin задает положение начала клиентской области относительно экрана:

   property ClientOrigin: TPoint;   .

    Если же нужно связать с координатной системой экрана произвольную точку, пользуйтесь парой методов (не путать с одноименными функциями Windows API):

   function ClientToScreen (const Point: TPoint): TPoint;
   function ScreenToClient (const Point: TPoint): TPoint;    .

    Очень важную часть работы по управлению размерами и расположением элементов выполняет свойство:

   property Align: TAlign;  . 

    Оно определяет выравнивание компонента относительно границ родителя. Может принимать одно из предопределенных значений:

   TAlign = (alNone, alTop, alBottom, alLeft, alRight, alClient);:

    Выравнивание гарантирует, что при изменении размеров родителя относительная позиция дочернего элемента не меняется. Это свойство имеет приоритет над простым изменением положения и размеров. Если новые координаты элемента противоречат способу его выравнивания (например, перемещение вверх при alBottom), изменения отвергаются и элемент возвращается к первоначальным координатам. Свойство Align незаменимо при организации панелей инструментов и строк состояния: они могут перемещаться и видоизменяться вместе с содержащей их формой.

    Для временного отключения действия свойства Align предназначены методы:

   procedure DisableAlign;
   procedure EnableAlign;       .

    Эти методы управляют возможностью выравнивания потомков данного элемента, они должны вызываться в паре. Для восстановления выравнивания элементов в соответствии с Align есть метод:

   procedure Realign;    .

    В следующем примере использование методов DisableAlign и EnableAlign позволяет настроить выравнивание панели (компонента TPanel) по тому краю формы, на который пользователь перетащит ее мышью.

    Внешний вид приложения показан на рисунке 1:


Рис.1. Внешний вид приложения

    Приведем текст модуля:

unit Un_Al;

interface

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

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
     				Shift: TShiftState; X, Y: Integer);
    procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
      				Y: Integer);
    procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
      				Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Moving: Boolean; //Флаг разрешения/запрещения перетаскивания.
  
implementation

{$R *.dfm}

//Задание начальных значений.
procedure TForm1.FormCreate(Sender: TObject);
begin
    Panel1.Align := alBottom;//Выравнивание по умолчанию.
    Moving := False;//Перетаскивания нет.
end;

//Начало перетаскивания.
procedure TForm1.Panel1MouseDown(Sender: TObject; Button:
 TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
   if not Moving then
     begin
       Form1.DisableAlign; //Запретить выравнивание.
       Moving := True; //Перетаскивание началось.
     end;
end;

//Процесс перетаскивания.
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; 
                         X, Y: Integer);
begin
    if Moving then
       with Panel1 do
       begin
        //Вычисление новых координат панели.
         Left := Left + X - Width div 2; 
         Top := Top + Y - Height div 2;
	//Их вывод.
         Panel1.Caption := Format('%d,%d',[Left, Top]);
       end;
end;

//Завершение перетаскивания.
procedure TForm1.Panel1MouseUp(Sender: TObject; 
Button: 
TMouseButton;   Shift: TShiftState; X, Y: Integer);
var
   LastPos : TPoint;
   r0, rl, r2 : real;
begin
   if Moving then
   begin
     Moving := False;
     Panel1.Caption := ' ';
     //Вычисление новых координат.
     LastPos := Point(Panel1.Left + X, Panel1.Top + Y) ;
     if LastPos.X <= 0 then LastPos.X := 1;
     if LastPos.X >= ClientWidth then
        LastPos.X := ClientWidth-1;
     if LastPos.Y<=0 then LastPos.Y := 1;
     if LastPos.Y>=ClientHeight then
        LastPos.Y := ClientHeight-1;
     r0 := ClientWidth / ClientHeight;
     rl := LastPos.X / LastPos.Y;
     r2 := LastPos.X / (ClientHeight - LastPos.Y);
     //Определение того, какое выравнивание задать панели.
     with Panel1 do
       if rl < r0 then
         if r2 < r0 then Align := alLeft
         else Align := alBottom
       else if r2 < r0 then Align := alTop
            else Align := alRight;
     Form1.EnableAlign; //Включить выравнивание.
   end;
end;

end.

    Текст этого примера можно взять здесь.

    На следующем шаге мы рассмотрим активность и видимость элементов управления.




Предыдущий шаг Содержание Следующий шаг