Главная » Delphi » Компонент контейнер  TddgButtonEdit

0

Иногда требуется создать  компонент, состоящий из одного  или  нескольких других компонентов. Компонент Delphi  TDBNavigator —  отличный пример таких  компонен тов,  поскольку  он состоит из компонента TPanel и нескольких компонентов TSpeed- Button. Данный раздел  посвящен созданию компонента,  являющегося комбинацией компонентов TEdit и TSpeedButton. Назовем этот компонент TddgButtonEdit.

Проектные решения

Ввиду того,  что  язык  Object Pascal  обладает объектной моделью  с наследованием лишь  от  одного  предка, компонент TddgButtonEdit должен  быть  самостоятельным компонентом, включающим компоненты TEdit и TSpeedButton. Более того,  посколь ку этот  компонент должен  содержать оконные элементы управления, он и сам долженбыть  оконным элементом управления. Поэтому  TddgButtonEdit необходимо сделать потомком  класса   TWinControl.  В  этом   случае  экземпляры  компонентов  TEdit и TSpeedButton следует  создавать  в  конструкторе компонента  TddgButtonEdit, ис пользуя следующий код:

constructor TddgButtonEdit.Create(AOwner: TComponent);

begin

inherited Create(AOwner);

FEdit             := TEdit.Create(Self);

FEdit.Parent := self;

FEdit.Height := 21;

FSpeedButton := TSpeedButton.Create(Self); FSpeedButton.Left := FEdit.Width;

// На два пикселя меньше вертикального размера TEdit

FSpeedButton.Height := 19;

FSpeedButton.Width      := 19;

FSpeedButton.Caption := ‘…';

FSpeedButton.Parent := Self;

Width       := FEdit.Width+FSpeedButton.Width; Height := FEdit.Height;

end;

При создании компонента, содержащего другие компоненты, определенную трудность представляет выделение свойств внутренних компонентов из свойств компонента контейнера. Например, компоненту TddgButtonEdit потребуется свойство Text. Для изменения шрифта этого  текста  понадобится свойство Font. Наконец, кнопке элемента необходимо событие OnClick. Естественно, не стоит  пытаться самостоятельно реализо вать эти свойства в компоненте контейнере, если они уже существуют во внутренних ком понентах. Наша задача — вывести необходимые свойства внутренних элементов управле ния на поверхность контейнера, не переписывая их интерфейса.

Предоставление свойств вложенных объектов

Эта задача сводится к простой, но трудоемкой процедуре создания методов записи и чтения для каждого  из свойств внутренних компонентов, предоставляемых компо ненту контейнеру. Например, компонент TddgButtonEdit можно  снабдить свойст вом Text с соответствующими методами доступа следующим образом:

TddgButtonEdit = class(TWinControl)

private

FEdit: TEdit;

protected

procedure SetText(Value: String);

function       GetText: String;

published

property Text: String read GetText write SetText;

end;

Методы  SetText() и  GetText() получают  прямой  доступ  к  свойству  Text вло

женного элемента TEdit:function TddgButtonEdit.GetText: String;

begin

Result := FEdit.Text;

end;

procedure TddgButtonEdit.SetText(Value: String);

begin

FEdit.Text := Value;

end;

Предоставление событий

Помимо свойств, контейнеру необходимо предоставить события внутренних компо нентов. Например, если  пользователь щелкает  мышью  на элементе TSpeedButton, то придется обработать его событие OnClick. Предоставление событий ничем  не отличает ся от предоставления свойств; ведь, в конце концов, события — это тоже свойства.

Для начала  необходимо снабдить компонент TddgButtonEdit собственным собы тием  OnClick. Для удобства  назовем его  OnButtonClick. И тогда  методы  записи и чтения этого  события просто перенаправят назначенный обработчик событию On- Click внутреннего компонента TSpeedButton.

В листинге 11.14 приведен исходный код компонента контейнера TddgButtonEdit.

Листинг 11.14. Компонент контейнер TddgButtonEdit

unit ButtonEdit;

interface uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, Buttons;

type

TddgButtonEdit = class(TWinControl)

private

FSpeedButton: TSpeedButton;

FEdit: TEdit;

protected

procedure WMSize(var Message: TWMSize); message WM_SIZE;

procedure SetText(Value: String);

function         GetText: String;

function GetFont: TFont;

procedure SetFont(Value: TFont);

function GetOnButtonClick: TNotifyEvent;

procedure SetOnButtonClick(Value: TNotifyEvent);

public

constructor Create(AOwner: TComponent); override;

destructor         Destroy; override;

published

property Text: String read GetText write SetText;property Font: TFont read GetFont write SetFont;

property OnButtonClick: TNotifyEvent read GetOnButtonClick

write SetOnButtonClick;

end;

implementation

procedure TddgButtonEdit.WMSize(var Message: TWMSize);

begin

inherited;

FEdit.Width := Message.Width-FSpeedButton.Width;

FSpeedButton.Left := FEdit.Width;

end;

constructor TddgButtonEdit.Create(AOwner: TComponent);

begin

inherited Create(AOwner);

FEdit             := TEdit.Create(Self);

FEdit.Parent := self;

FEdit.Height := 21;

FSpeedButton := TSpeedButton.Create(Self); FSpeedButton.Left := FEdit.Width;

// На два пикселя меньше высоты TEdit FSpeedButton.Height := 19; FSpeedButton.Width  := 19; FSpeedButton.Caption := ‘…'; FSpeedButton.Parent := Self;

Width       := FEdit.Width+FSpeedButton.Width; Height := FEdit.Height;

end;

destructor     TddgButtonEdit.Destroy;

begin

FSpeedButton.Free;

FEdit.Free;

inherited Destroy;

end;

function TddgButtonEdit.GetText: String;

begin

Result := FEdit.Text;

end;

procedure TddgButtonEdit.SetText(Value: String);

begin

FEdit.Text := Value;

end;

function TddgButtonEdit.GetFont: TFont;

begin

Result := FEdit.Font;end;

procedure TddgButtonEdit.SetFont(Value: TFont);

begin

if Assigned(FEdit.Font) then

FEdit.Font.Assign(Value);

end;

function TddgButtonEdit.GetOnButtonClick: TNotifyEvent;

begin

Result := FSpeedButton.OnClick;

end;

procedure TddgButtonEdit.SetOnButtonClick(Value: TNotifyEvent);

begin

FSpeedButton.OnClick := Value;

end;

end.

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии