Справочник по компонентам Delphi. Часть 1
Страница 18. Оконные элементы управления


Оконные элементы управления

Понятие окна Windows инкапсулировано в потомке TControl — классе TWinControl. Такой компонент получает соответствующий атрибут _ дескриптор окна, определяемый свойством:

(Ro) property Handle: HWnd;

С помощью этого дескриптора вы можете вызывать функции API Windows, если средств VCL вам недостаточно для решения задачи. Компоненты-потомки TWinControl — в дальнейшем будем называть оконными элементами управ­ления, а элементы управления, не имеющие дескриптора окна, — неоконными.

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

function HandleAllocated:Boolean;
procedure HandleNeeded;

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

Важным свойством TWinControl является то, что он может содержать другие — дочерние — элементы управления. Они упорядочены в виде списка. Если быть точным, то списков на самом деле два — для неоконных и оконных дочерних элементов. Но "видны" они как один объединенный — сначала первый, потом второй. Методы и свойства для работы с этим списком приведены в таблице:


(Ro) property Controls[Index: Integer]: TControl;

Содержит список дочерних элементов.

(Ro) property ControlCount: Integer;

Содержит число элементов в списке.

function ContainsControl(Control: TControl): Boolean;

Проверяет наличие элемента в списке.

function ControlAtPos(const Pos: TPoint; AllowDisabled: Boolean): TControl ;

Отыскивает в списке элемент, которому принадлежит заданная точка (в системе координат собственной клиентской облас­ти). Флаг AllowDisabled показывает, раз­решен ли поиск среди пассивных (свойство Enabled которых равно False) элементов.

procedure InsertControl(AControl: TControl) ;

Вставляет элемент в конец списка.

procedure RemoveControl(AControl: TControl);

Удаляет элемент из списка.

procedure Broadcast(var Message);

Рассылает всем дочерним элементам из списка сообщение Message.

С каждым оконным компонентом можно связать контекстную помощь. Кон­текст помощи — это индекс, указывающий на определенную информацию в файле справочной системы, связанном с приложением:

property HelpContext: THelpContext;

Когда компонент находится в фокусе, то при нажатии клавиши загру­жается система контекстной помощи, и пользователь сразу получает инфор­мацию, связанную с заданным контекстом. Если контекст равен нулю, то система пытается отыскать в цепочке родительских компонентов первый, имеющий ненулевой контекст.

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

Прокрутку (скроллинг) элементов на интервал DeltaX, DeltaY осуществляет метод:

procedure ScrollBy(DeltaX, DeltaY: Integer);

Прибегая к вызову этой процедуры, можно при желании осуществить про­крутку нестандартным способом, т. е. без привлечения полос прокрутки. При­веденный ниже фрагмент кода — составная часть примера IMGSCROL на дискете— позволяет "тащить" изображение Imagel вслед за мышью с нажатой кнопкой:

type
TMouseState = (msNormal, msDragging);
var
OldPos, NewPos, MaxShift: TPoint;
PMouseState : TMouseState;
procedure TFormI.ScrollMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integers-begin
MaxShift.X := Imagel.Parent.Width - Imagel.Width;
MaxShift.Y := Imagel.Parent.Height - Imagel.Height;
if (MaxShift.X > 0) and (MaxShift.Y > 0) then Exit;
FMouseState := msDragging;
OldPos := Point(X, Y) ;
Screen.Cursor := crDrag;
end;
procedure TFormI.ScrollMouseMove(Sender : TObject;
Shift: TShiftState; X, Y: Integers-begin
if FMouseState = msDragging then begin
NewPos := Point(X - OldPos.X, Y - OldPos.Y) ;
if Imagel.Left + NewPos.X > 0 then NewPos.X := - Imagel.Left;
if Imagel.Left + NewPos.X < MaxShift.X
then NewPos.X := MaxShift.X - Imagel.Left;
if Imagel.Top + NewPos.Y > 0 then NewPos.Y := - Imagel.Top;
if Imagel.Top + NewPos.Y < MaxShift.Y
then NewPos.Y := MaxShift.Y - Imagel.Top;
Imagel.Parent.ScrollBy(NewPos.X, NewPos. Y) ;
end;
end;
procedure TFormI.ScrollMouseUp(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FMouseState -.= msNormal;
Screen.Cursor := crDefault;
end;

Обратите внимание, что прокрутка неоконного компонента Imagel осуществ­ляется посредством вызова Image l.Parent.ScrollBy. Это свидетельствует о том, что конкретный родительский тип для этого безразличен. В примере изобра­жение помещено на панель (TPanel). Впрочем, метод ScrollBy используется также и полосами прокрутки, которые есть в компоненте TScrollingWinControl и его потомках, например, в TForm.

В VCL предусмотрена возможность написания приложений, которые будут сохранять относительный размер и положение при всех разрешениях дисплея. Более подробно эти механизмы описаны в разделе, посвященном формам; для TWinControl упомянем лишь метод

procedure ScaleBy(M, D: Integer);

который изменяет масштаб элемента управления в M/D раз, при этом верхний левый угол остается неподвижным. Так же изменяются и размеры всех дочерних элементов. Соответственно изменяется и масштаб шрифта (свойство Font). Флаги csFixedWidth и csFixedHeight в свойстве ControlStyle предотвращают изменение ширины или высоты.

При изображении большинства оконных элементов управления используют эффект "трехмерности", создающий иллюзию приподнятости или вдавленное™ за счет подбора внешнего вида обрамления. Наличие "трехмерности" задается свойством:

(РЙ property Ctl3D: Boolean;

Нужно уточнить, что это свойство есть не у всех компонентов. Для части компонентов трехмерность реализована средствами VCL; другая же часть (радиокнопки, флажки и др.) требует для создания трехмерного эффекта до­ступа к библиотеке CTL3DV2.DLL.

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

property Font: TFont;

Кисть, используемая для закрашивания рабочей области оконного элемента управления, представлена свойством:

(Ro) property Brush: TBrush;

Она имеет цвет, содержащийся в свойстве Color (по умолчанию clWindow). На уровне TControl оно доступно только по чтению:

property Color: TColor;

Подробно о последних двух типах см. в разделе "Графическая подсистема".

 
« Предыдущая статья   Следующая статья »