Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на Pascal / Delphi / Справочник по компонентам Delphi.doc
Скачиваний:
148
Добавлен:
02.05.2014
Размер:
1 Mб
Скачать

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

Понятие окна 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;

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

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

Прокрутку (скроллинг) элементов на интервал 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;

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

Реакция на события от мыши и клавиатуры

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

(р^ property OnMouseDown: TMouseEvent;

(Pb) property OnMouseUp: TMouseEvent;

TMouseEvent = procedure(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer) of object;

Параметры:

Sender — элемент-источник сообщения (обычно равен Self);

Button — идентификатор одной из кнопок;

TMouseButton = (mbLeft, mbRight, mbMiddle);

Shift — множество, которое может содержать элементы:

ssAlt, ssCtrl, ssShift — в зависимости от состояния этих клавиш;

ssLeft, ssRight, ssMiddle, ssDouble — в зависимости от нажатия кнопок мыши (ssDouble — нажать! и правая, и левая кнопки);

X, Y — координаты нажатия (в системе координат клиентской области получателя).

При перемещении мыши возникает событие:

(Pb) property OnMouseMove: TMouseMoveEvent ;

TMouseMoveEvent = procedure(Sender: TObject; Shift: TShiftState;

X, Y: Integer) of object;

Использование сообщений от мьшш уже встречалось в примерах, приведенных вьппе (например, см. разд. "Положение, размеры и выравнивание элементов управления").

Два события извещают о щелчке и двойном щелчке левой кнопкой мыши над компонентом:

(pt) property OnClick: TNotifyEvent;

(Pb) property OnDblClick: TNotifyEvent;

Отменить генерацию этих событий можно, удалив флаг csClickEvents из слова состояния элемента (ControlStyle). Для некоторых компонентов (например, кно­пок) OnClick возникает еще и при нажатии определенных клавиш на клавиатуре, а также вследствие вызова метода Click.

События, связанные с мышью, могут быть получены потомками TControl. В отличие от них, реакцию на события от клавиатуры могут иметь только оконные элементы управления ("могут", т. к. на уровне TControl и TWinControl эти события только описаны, но не опубликованы). Таким образом, есть компоненты (в том числе в Палитре компонентов), не имеющие связи с этими событиями из-за ее ненадобности. Впрочем, их меньшинство, и материал в этом разделе обобщен вполне обоснованно.

Нажатие и отпускание клавиш клавиатуры могут инициировать следующие события:

§ property OnKeyDown: TKeyEvent;

property OnKeyUp: TKeyEvent;

eyEvent = procedure(Sender: TObject; var Key: Word;

Shift: TShiftState) of object;

Генерация этих событий встроена в обработчики сообщений Windows WMJCEYDOWN, WMJSYSKEYDOWN и WM_KEYUP, WM_SYSKEYUP соответст­венно. Обработчику передаются:

Sender — источник сообщения;

Shift — состояние специальных клавиш и кнопок мыши во время нажатия (отпускания);

Key — код нажатой клавиши, представляющий собой виртуальный код клавиши Windows (константы вида VK_XX, например, VK_F1, VK_ESCAPE и т. п.). Обратите внимание, что Key является var-параметром; т. е. его значение может быть изменено программистом.

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

property OnKeyPress :. TKeyPressEvent;

TKeyPressEvent = procedure(Sender: TObject; var Key: Char) of object;

Это событие возникает при вводе с клавиатуры символа ASCII, т. е. оно не ге­нерируется, например, при нажатии функциональных клавиш или <CapsLock>. Обработчик события вызывается при нажатии буквенных (в т. ч. вместе с <Shift>), цифровых клавиш, комбинаций <Ctri>+<A> .. <Ctd>+<Z> (коды ASCII #1..#26), <Enter>, <Esc>, <Backspace>, <Ctrl>+<Break> (код #3) и некоторых других. Также код ASCII можно сгенерировать, нажав <А11>+<десятичньш код символа> на числовой клавиатуре (Numeric Pad).

Событие OnKeyPress соответствует сообщению Windows WM_CHAR.

Все сообщения клавиатуры поступают тому элементу управления, который в данный момент имеет фокус ввода. Однако из этого правила возможно одно исключение. Если у формы, которая содержит этот элемент управления, свойство

(Pb) property KeyPreview: boolean;

установлено в True, то сначала все три вида сообщений поступают к ее обработчикам, и только потом — к элементу управления. Если при этом в них обнулить параметр Key, то в элемент сообщение не поступит вообще. В приведенном ниже примере клавиша <F5> резервируется для изменения со­стояния формы:

procedure TFormI.FormCreate(Sender: TObject);

begin KeyPreview := True;

end;

procedure TFonnl.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin if Key = VK_F5 then

begin

if ssCtrl in Shift then WindowState := wsNormal

else if Shift = [] then

WindowState := wsMaximized;

Key : = 0 ;

end;

end;

Соседние файлы в папке Delphi