17.4. ПОЛОЖЕНИЕ, РАЗМЕРЫ И ОФОРМЛЕНИЕ КОМПОНЕНТОВ

Положение и размеры компонента определяются четырьмя его свойствами (в пикселях):

property Height: Integer; // Высота

property Left: Integer;// Положение левой кромки

property Top: Integer;// Положение верхней кромки

property Width: Integer;// Ширина

Для всех компонентов, кроме форм, эти свойства задаются в координатах клиентской части родительского компонента. Для формы - в координатах экрана. Клиентская часть компонента - это внутренняя его область за исключением заголовка, рамки и меню. Свойства обычно определяются на стадии конструирования формы, но они доступны также и на этапе прогона программы. Изменение любого из них приводит к немедленному изменению положения или размера компонента как на этапе конструирования, так и при прогоне программы. Все четыре числовые величины содержатся также в единственном свойстве

property BoundsRect: TRect;

type

TPoint = record X: Longint;

Y: Longint;

end;

TRect = record case Integer of

0: (Left, Top, Right, Bottom: Integer);

1: (TopLeft, BottomRight: TPoint);

end;

Это свойство удобно использовать при прорисовке компонента методом TCanvas . FrameRect.

В некоторых случаях бывает необходимо пересчитать относительные координаты точки внутри клиентской части в абсолютные координаты экрана и наоборот. Эта задача решается двумя методами Control:

function ClientToScreen(const Point: TPoint): TPoint;

function ScreenToClient(const Point: TPoint): TPoint;

Важную роль играет свойство Align, определяющее выравнивание положения компонента относительно границ своего родителя:

type TAlign = (aINone, alTop, alBottom, alLeft, alRight, alClient) ;

property Align: TAlign;

Если это свойство не равно aiNone, компонент прижимается к верхней (alTop), нижней (alBottom), левой (alLeft) или правой (alRight) границе своего родителя. При этом размеры компонента по соседним с границей измерениям игнорируются, и компонент “растекается” по границе. Например, если Align=alTop, значения свойств компонента Left и width игнорируются и его прямоугольник будет занимать всю верхнюю часть клиентской области родителя высотой Height пикселей; если Align=alLeft, свойства тор и Height игнорируются и прямоугольник занимает левую часть родителя шириной width пикселей и т. д. Если несколько компонентов имеют одинаковое выравнивание, они последовательно прижимаются друг к другу в порядке их перечисления в свойстве controls: первый прижимается к границе родителя, второй - к границе первого и т. д. Вся не заполненная другими компонентами клиентская область родителя заполняется компонентами со свойствами Align=alClient, которые в этом случае накладываются друг на друга. Замечательной особенностью свойства является его постоянство при изменении размеров клиентской части родителя. Если, например, компонент прижат к верхней границе формы, он будет неизменно занимать верхнюю часть клиентской области при любых изменениях размеров окна. Таким способом можно легко реализовать панели с инструментальными кнопками, панели статуса и т. п. Временное отключение и затем включение эффекта от свойства Align обеспечивается методами

procedure DisableAlign;

procedure EnableAlign;

Любой видимый компонент можно спрятать или показать с помощью свойства visible или методами Hide и show:

property Visible: Boolean; // True - показывает

procedure Hide; // Прячет компонент

procedure Show; // Показывает компонент

Спрятанный компонент не реагирует на события от мыши или клавиатуры, он не участвует в дележе клиентской области родителя, ему нельзя передать фокус ввода клавишей Tab.

Если компонент частично или полностью перекрывается другими компонентами, его можно расположить над всеми компонентами и убрать обратно с помощью методов

procedure BringToFront; // Сделать верхним

procedure SendToBack; // Сделать нижним

Свойство

property Enabled: Boolean;

определяет возможность активизации компонента. Если оно имеет значение False, компонент запрещен для выбора. Такие компоненты (точнее, надписи на них) обычно отображаются серым цветом.

Некоторые компоненты имеют плоское изображение (например, метка TLabel), другие - всегда объемное (например, кнопка TButton).

Для остальных элементов объемность изображения регулируется свойством

property Ctl3D: Boolean;

С каждым управляющим компонентом связывается текстовая строка, которая становится доступна либо через свойство Caption, либо через свойство Text (альтернативой свойству Text, которое имеет тип string, является свойство TControi.windowsText типа pchar). Независимо от того, какое свойство хранит эту строку, ее можно установить и получить соответственно методами setTextBuf и GetTextBuf, при этом метод GetTextLen возвращает длину строки:

procedure SetTextBuf(Buffer: PChar);

function GetTextBuf(Buffer: PChar; BufSize: Integer): Integers;

function GetTextLen: Integer;

Если эта строка выводится в компоненте, используется шрифт, задаваемый свойством Font:

property Font: TFont;

В этом случае свойство

type TAlignment = (taLeftJustify, taRightJustify, taCenter);

property Alignment: TAlignment;

регулирует расположение текста относительно границ компонента:

taLeftJustify - прижать к левой границе; taRightJustify - прижать к правой границе; taCenter - расположить по центру.

С помощью придания свойству

property DesktopFont: Boolean;

значения True можно потребовать от компонента, чтобы он выводил текст системным шрифтом Windows.

Видимая часть элемента заливается цветом Color:

property Color: TColor;

Обычно значение этого свойства выбирается из таблицы стандартных цветов Windows в виде константы clxxxx (перечень этих констант содержит раскрывающийся список свойства). В некоторых случаях может потребоваться залить компонент нестандартным цветом. В этом случае учтите, что свойство Color хранит четырехбайтное значение, каждый байт которого (слева направо, т. е. от старшего к младшему) имеет следующее назначение:

- 1 - указатель формата цвета (см. ниже);
- 2, 3, 4 - интенсивность соответственно синей, зеленой и красной

составляющих.

Например, значение $00000000 определяет черный цвет, $00ff0000 -чистый синий цвет, $00ffffff - белый цвет и т. д.

Старший байт указывает, как используются остальные байты значения. Если он равен нулю, они определяют RGB-цвет так, как это описано выше. Если старший байт равен 1, три оставшихся байта определяют номер одной из 65536 возможных логических палитр (второй байт в этом случае игнорируется). Наконец, если старший байт равен 2, младшие определяют относительный цвет: в этом случае Windows отыскивает в текущей логической палитре ближайший к указанному цвет и использует его для заливки компонента. Другие значения старшего байта игнорируются (точнее, игнорируются старшие 5 разрядов этого байта; самый старший бит, если он равен 1, определяет черный цвет независимо от значений остальных 31 разрядов).

Чтобы разнообразить унылые серые окна программы, соответствующие стандартным формам Delphi, я иногда использую значение $00AAffff, определяющее бледно-желтый цвет (в свойство color можно вводить значения в виде десятичных или шестнадцатеричных чисел). Получить шестнадцатеричное значение того или иного цвета вам поможет несложная программа, окно которой показано на рис. 17.1. С ее помощью можно выбрать цвет в окне компонента TColor-Dialog (см. дальше п. 17.5.4) и получить его шестнадцатеричное представление или ввести шестнадцатеричное число и увидеть соответствующий ему цвет.

Рис. 17.1. Окно програлшы для определения цветовых констант

1. Положите на пустую форму две панели - они будут наглядно демонстрировать цвет, выбранный с помощью TCoiorDialog (левая панель), и цвет, заданный с помощью 16-ричной константы (правая панель). Установите в свойство Align панели Panel1. Значение alRight, а в такое же свойство Рапе12 - alClient.
2. На левую панель положите кнопку TButtcni и диалог TCoiorDialog (этот компонент находится на странице Dialogs палитры компонентов). В значение caption кнопки поместите строку. Выбор цвета.
3. На правую панель положите редактор TEdit и кнопку TButton. В свойство charCase редактора поместите значение ecupper-case - это заставит компонент преобразовывать вводимые в нем буквы к заглавным и упростит дальнейший их анализ. В Caption кнопки поместите Ввод константы.
4. Напишите такой обработчик события OnClick кнопки Button1 (в нем открывается диалоговое окно компонента ColorDialog1, закрашивается выбранным цветом левая панель panel 1, в заголовок окна помещается десятичное представление цветовой константы, а в редактор Editi - ее 16-ричное представление:

procedure TFormI.ButtonlClick(Sender: TObject) ;

begin

{Вызываем диалог CoiorDiaiogi и контролируем его результат:

если его метод Execute возвращает True, пользователь выбрал нужный цвет:}

if CoiorDiaiogi.Execute then begin

//В заголовок окна помещаем iu-чное представление цвета:

Caption := IntToStr(CoiorDiaiogi.Color);

//Закрашиваем левую панель выбранным цветом:

Рапе12.Color := CoiorDiaiogi.Color;

//Помещаем в Edit1 и в заголовок левой панели 16-ричное

// представление цвета:

Editl.Text := IntToHex(ColorDialogl.Color,8);

Panel2.Caption := Editl.Text

end

end;

5. В обработчике события нажатия правой кнопки нужно преобразовать введенное в редакторе 16-ричное представление цветовой константы в целое число и поместить его в свойство caption правой панели. Поскольку нет стандартной функции преобразования символьного представления 16-ричной константы в число, обработчик использует вспомогательную функцию HexStrToInt:

function HexStrToint(S: String): Integer;

(Функция преобразует 16-ричное представление S целого числа в тип Integer} function HDigitaKC: Char): Byte;

//Преобразует 16-ричную цифру С в число

begin

case С of 'О'..'9': Result := ord(C)-ord('0');

'A'..'F': Result := ord(C)-ord('A')+10;

else

{Если очередной символ не относится к допустимым для представления 16-ричной цифры, возбуждаем исключительную ситуацию, которая блокирует преобразование и сообщает пользователю об ошибке:}

raise EConvertError.Create

('Недопустимое представление 16-ричного числа');

end;

end; //HDigital

var

k: Integer;

begin //HexStrToInt

Result := 0;

//Удаляем возможный символ-указатель 16-ричного числа:

if S[1]='$' then delete(S,1,1) ;

//Цикл преобразования строки:

for k := 1 to Length (S) do

Result := Result*16+HDigital(S[k]);

end; //HexStrToInt

procedure TForml.Button2Click(Sender: TObject);

begin

Panell.Color := StrToHex(Editl.Text);

Panell.Caption := Edit1.Text

end;

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

property ParentColor: Boolean;

property ParentCtl3d: Boolean;

property ParentFont: Boolean;

property ParentHint: Boolean;

Если, например, цвет компонента не задан явно свойством color и его свойство ParentColor имеет значение True, компонент будет использовать при прорисовке цвет своего родителя, а изменение цвета родителя приведет к немедленному изменению цвета дочернего компонента. Явная установка значений свойств color, Cti3D, Font или Hint приводит к автоматической установке значений False в соответствующие свойства ParentXXX.

Некоторые компоненты очерчиваются двойной кромкой - внешней и внутренней. В класс TWinControl Delphi 4 введены специальные свойства, управляющие трехмерным эффектом, создаваемым такими кромками:

type TBevelEdge = (beLeft, beTop, oeRight, beBottom) ; TBevelEdges = set of TBevelEdge; property BevelEdges: TBevelEdges; | Определяет стороны компонента, которые будут содержать кромки: beLeft -левая; bеТор - верхняя; beRight - правая; beBot tom - нижняя
type TBevelCut = (bvNone, bvLow- ered, bvRaised, bvSpace) ; property Bevellnner: TBevelCut; | Определяет тип внутренней кромки: bvNone- нет рамки; bvLowered. - вдавленная кром ка; bvRaised - выпуклая кромка; bvSpace -кромки нет, но для нее отводится место толщиной 1 пиксель
type TBevelKind = (bkNone, okTile, bkSoft, bkFlat) ; property BevelStyle: TBevelKind; | Указывает тип кромок: bkNone - нет кромок; bkTile - есть внутренняя и внешняя кромка; bksoft - то же, что и bkTile, но менее контрастная внешняя кромка; bkFlat - есть только внешняя кромка толщиной 1пиксель
property BevelOuter: TBevelCut; | Определяет тип внешней кромки
type TBevelWidth = l..MaxInt; property BevelWidth: TBevelWidth; | Задает толщину линий кромки
type TBorderWidth = O..MaxInt; property BorderWidth: TBorder Width; | Определяет расстояние в пикселях от внешней кромки до внутренней

В версиях Delphi 4 ... 6 в класс TControl введено свойство

property Anchors: TAnchors;

type TAnchors = set of TAnchorKind;

type TAnchorKind = (akTop, akLeft, akRight, akBottom);

определяющее способ фиксирования дочернего компонента относительно границ контейнера, в котором он размещен. По умолчанию это свойство имеет значение [akTop, akLeft], что означает фиксацию компонента относительно левого верхнего угла контейнера. В результате возможные изменения размеров контейнера никак не скажутся на изменении положения и/или размеров компонента. Если установить значение [akRight, akBottom], правая и нижняя кромки компонента всегда будут располагаться на одном и том же расстоянии от соответствующих кромок контейнера. Так как положение левого верхнего угла компонента при этом не фиксируется, он будет “плавать” внутри контейнера, всегда располагаясь на одном и том же расстоянии от его правой и нижней кромки. Однако, если установлено значение [akTop, akLeft, akRight, akBottom], левый верхний угол будет зафиксирован, и компонент будет пытаться отслеживать расстояние до правого нижнего угла контейнера с помощью изменения своих размеров. Поместите на пустую форму редактор TEdit и поэксперименти-руйте с его свойством Anchors, каждый раз изменяя мышью размеры формы (не обязательно запускать программу - свойство Anchors работает и на этапе конструирования). В Delphi 4... 6 введено свойство

property Constraints: TSizeConstraints;

Оно используется для ограничения максимальных и минимальных размеров управляющих элементов по высоте и ширине. Объект класса TSizeConstraint имеет четыре следующих свойства: Max-Height, MaxWidth, MinHeight, MinWidth типа O..MaxInt, которые и определяют предельные значения указанных параметров. По умолчанию эти свойства имеют нулевые значения, что эквивалентно снятию каких бы то ни было ограничений.

Свойство

property AutoSize: Boolean;

также впервые введено в Delphi 4. Оно связано, в основном, с интерфейсом Drag&Dock (см.п. 17.8) и разрешает (True) или запрещает (False) оконному компоненту автоматически изменять свои размеры в зависимости от количества и размеров содержащихся в нем неоконных компонентов.