Главная » Delphi » Ссылки на компоненты и список ImageList

0

Следующий  компонент, TddgImgListSpinner, расширяет функции компонента TddgDesignSpinner. В нем реализовано свойство, значением которого является ссыл ка на компонент ImageList, что  позволяет использовать вместо  символов “+” и “ ” на кнопках инкремента и декремента изображения из списка ImageList (рис. 13.6).

Рис. 13.6. Компонент TddgImgList- Spinner может  использоваться   для  кно пок изображения из списка ImageList

В листинге 13.3  представлен исходный код  модуля  QddgILSpin.pas, в котором реализован компонент TddgImgListSpinner. В отличие от компонента Tddg- DesignSpinner, при его переносе в CLX, требуется совсем немного изменений.

Листинг 13.3. QddgILSpin.pas — исходный  код компонента

TddgImgListSpinner

unit QddgILSpin;

interface uses

Classes, Types, QddgSpin, QddgDsnSpn, QImgList;

(*

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

ddgSpin, ddgDsnSpn, ImgList;

*)

type

TddgImgListSpinner = class( TddgDesignSpinner )

private

FImages: TCustomImageList;

FImageIndexes: array[ 1..2 ] of Integer;

FImageChangeLink: TChangeLink;

// Внутренние обработчики событий

procedure ImageListChange( Sender: TObject );

protected

procedure Notification( AComponent : TComponent;

Operation : TOperation ); override;

procedure DrawButton( Button: TddgButtonType; Down: Boolean; Bounds: TRect ); override;

procedure CalcCenterOffsets( Bounds: TRect;

var L, T: Integer);

procedure CheckMinSize;

// Методы доступа к свойствамprocedure SetImages( Value: TCustomImageList ); virtual;

function GetImageIndex( PropIndex: Integer ): Integer;

virtual;

procedure SetImageIndex( PropIndex: Integer;

Value: Integer ); virtual;

public

constructor Create( AOwner: TComponent ); override;

destructor Destroy; override;

published

property Images: TCustomImageList

read FImages

write SetImages;

property ImageIndexMinus: Integer index 1

read GetImageIndex write SetImageIndex;

property ImageIndexPlus: Integer index 2

read GetImageIndex write SetImageIndex;

end;

implementation uses

QGraphics;  // VCL->CLX:      Добавлено для поддержки CLX{======================================}

{== Методы класса TddgImgListSpinner ==}

{======================================}

constructor TddgImgListSpinner.Create( AOwner: TComponent );

begin

inherited Create( AOwner );

FImageChangeLink := TChangeLink.Create; FImageChangeLink.OnChange := ImageListChange;

// Примечание: пользователи компонента не имеют прямого доступа

// к объекту типа TChangeLink, поэтому они не могут использовать

// собственные обработчики событий.

FImageIndexes[ 1 ] := -1; FImageIndexes[ 2 ] := -1;

end;

destructor TddgImgListSpinner.Destroy;

begin

FImageChangeLink.Free;

inherited Destroy;

end;

procedure TddgImgListSpinner.Notification( AComponent: TComponent; Operation: TOperation );

begin

inherited Notification( AComponent, Operation );

if ( Operation = opRemove ) and ( AComponent = FImages ) then

SetImages( nil );                 // Вызов метода доступа

end;function TddgImgListSpinner.GetImageIndex( PropIndex:

Integer ): Integer;

begin

Result := FImageIndexes[ PropIndex ];

end;

procedure TddgImgListSpinner.SetImageIndex( PropIndex: Integer; Value: Integer );

begin

if FImageIndexes[ PropIndex ] <> Value then begin

FImageIndexes[ PropIndex ] := Value;

Invalidate;

end;

end;procedure TddgImgListSpinner.SetImages( Value: TCustomImageList );

begin

if FImages <> nil then

FImages.UnRegisterChanges( FImageChangeLink );

FImages := Value;

if FImages <> nil then begin FImages.RegisterChanges( FImageChangeLink ); FImages.FreeNotification( Self ); CheckMinSize;

end; Invalidate;

end;

procedure TddgImgListSpinner.ImageListChange( Sender: TObject );

begin

if Sender = Images then begin

CheckMinSize;

// Для предотвращения мерцания экрана вместо

// метода Invalidate вызывается метод Update

Update;

end;

end;

procedure TddgImgListSpinner.CheckMinSize;

begin// В области кнопки изображение должно отображаться полностью

if FImages.Width > ButtonWidth then

ButtonWidth := FImages.Width;

if FImages.Height > Height then

Height := FImages.Height;

end;procedure TddgImgListSpinner.DrawButton( Button: TddgButtonType; Down: Boolean;

Bounds: TRect );

var

L, T: Integer;

begin

with Canvas do begin

Brush.Color := ButtonColor;

Pen.Color := clBtnShadow;

Rectangle( Bounds.Left, Bounds.Top,

Bounds.Right, Bounds.Bottom );

if Button = btMinus then               // Прорисовка кнопки "-" begin

if ( Images <> nil ) and ( ImageIndexMinus <> -1 ) then begin

(*

// VCL->CLX: Свойство DrawingStyle в классе CLX TImageList

//                     отсутствует, а вместо него используется

//                     свойство BkColor.

if Down then

FImages.DrawingStyle := dsSelected

else

FImages.DrawingStyle := dsNormal;

*)

if Down then

FImages.BkColor := clBtnShadow

else

FImages.BkColor := clBtnFace;

CalcCenterOffsets( Bounds, L, T ); (*

// VCL->CLX:            TImageList.Draw в CLX имеет другой синтаксис

FImages.Draw( Canvas, L, T, ImageIndexMinus, Enabled );

*)

FImages.Draw( Canvas, L, T, ImageIndexMinus, itImage,

Enabled );

end else

inherited DrawButton( Button, Down, Bounds );

end

else                                  // Прорисовка кнопки "+"

begin

if ( Images <> nil ) and ( ImageIndexPlus <> -1 ) thenbegin

(*

// VCL->CLX: Свойство DrawingStyle в классе CLX TImageList

//                     отсутствует. Вместо него используется

//                     свойство BkColor.

if Down then

FImages.DrawingStyle := dsSelected

else

FImages.DrawingStyle := dsNormal;

*)

if Down then

FImages.BkColor := clBtnShadow

else

FImages.BkColor := clBtnFace;

CalcCenterOffsets( Bounds, L, T ); (*

// VCL->CLX:            TImageList.Draw в CLX имеет другой синтаксис

FImages.Draw( Canvas, L, T, ImageIndexPlus, Enabled );

*)

FImages.Draw( Canvas, L, T, ImageIndexPlus, itImage,

Enabled );

end else

inherited DrawButton( Button, Down, Bounds );

end;

end;

end; {= TddgImgListSpinner.DrawButton =}procedure TddgImgListSpinner.CalcCenterOffsets( Bounds: TRect;

var L, T: Integer );

begin

if FImages <> nil then begin

L := Bounds.Left + ( Bounds.Right – Bounds.Left ) div 2 -

( FImages.Width div 2 );

T := Bounds.Top + ( Bounds.Bottom – Bounds.Top ) div 2 -

( FImages.Height div 2 );

end;

end;

end.Как обычно, в раздел uses нужно включить модули, имеющие отношение к CLX, и удалить модули, относящиеся к VCL. В частности, ссылка  на модуль ImgList заменя ется  ссылкой на модуль QImgList. Это  важно,  потому  что  в VCL класс  TImageList является производным от класса  TCustomImageList, реализованного в библиотеке ComCtl32.dll. Компания  Borland создала   версию  класса   TCustomImageList для CLX, которая вместо  библиотеки ComCtl32.dll использует графические примитивы библиотеки Qt.Преимущества такого  подхода  очевидны из объявления класса. Объявление класса TddgImgListSpinner версии CLX идентично объявлению версии VCL. Более  того, идентичными являются реализации всех методов, кроме  одного.

Некоторые изменения, конечно же, нужно внести в переопределенный метод прорисовки DrawButton(). При  этом  необходимо решить две задачи.  Для решения первой из них необходимо провести сравнительную характеристику классов,  сущест вующих как в VCL, так и с CLX. Действительно, одному из классов  VCL может  соот ветствовать один из классов  CLX, однако  это не означает, что в классе CLX будут реа лизованы все функции класса VCL.

В случае с классом  TCustomImageList в версии VCL реализовано свойство Draw- ingStyle, которое использовалось в версии VCL класса  TddgImgListSpinner для прорисовки изображения на кнопке. Но свойство DrawingStyle отсутствует в классе TCustomImageList версии CLX, потому в реализации компонента должен  использо ваться другой подход.

Вторая модификация в методе  DrawButton() связана с тем,  что  метод  TCusto- mImageList.Draw() в архитектуре VCL работает не так, как в архитектуре CLX.

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

По теме:

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