Главная » Delphi » Создание расширенного компонента VCL

0

Псевдовизуальные компоненты

Читатель уже знаком с визуальными компонентами, наподобие TButton и TEdit, и с невизуальными — такими как TTable и TTimer. В настоящем разделе рассматриваются компоненты, занимающие промежуточное положение между визуальными и невизуаль ными, — назовем их псевдовизуальными компонентами (pseudo visual components).

Расширенные подсказки

Примером псевдовизуального компонента, рассматриваемого в этом разделе, является расширение всплывающего окна подсказки (hint) Delphi. Этот компонент назван  псевдови зуальным,  поскольку  палитра компонентов во время  разработки не воспринимает его как визуальный объект, но во время  выполнения данный компонент отображается как всплы вающее окно подсказки.

Замена обычного стиля  окна подсказки новым  требует  выполнения следующих действий.

1.  Создать потомок класса THintWindow.

2.  Удалить старый класс окна подсказки.

3.  Назначить новый  класс окна подсказки.

4.  Создать новый  класс окна подсказки.

Создание потомка класса THintWindow

Прежде чем приступить к написанию кода потомка класса  THintWindow, следует решить, чем поведение нового класса окна  подсказки будет отличаться от поведения обычного окна  подсказки. В данном  случае  вместо  обычного прямоугольного окна подсказки будет создано эллиптическое. Попутно можно  ознакомиться с интересной методикой —  созданием непрямоугольных окон.  В листинге 12.1 приводится код мо дуля RndHint.pas, содержащего компонент TDDGHintWindow, который является по томком  класса THintWindow.

Листинг 12.1. RndHint.pas — пример эллиптического окна подсказки

unit RndHint;

interface

uses Windows, Classes, Controls, Forms, Messages, Graphics;type

TddgHintWindow = class(THintWindow)

private

FRegion: THandle;

procedure FreeCurrentRegion;

public

destructor Destroy; override;

procedure ActivateHint(Rect: TRect;

const AHint: string); override;

procedure Paint; override;

procedure CreateParams(var Params: TCreateParams); override;

end;

implementation

destructor TddgHintWindow.Destroy;

begin

FreeCurrentRegion;

inherited Destroy;

end;

procedure TddgHintWindow.CreateParams(var Params: TCreateParams);

{ Необходимо удалить стандартную границу (border), созданную на

уровне API Windows при создании окна. }

begin

inherited CreateParams(Params);

// Удалить границу

Params.Style := Params.Style and not ws_Border;

end;

procedure TddgHintWindow.FreeCurrentRegion;

{ Области окна, подобно другим объектам API, должны быть

освобождены по завершении их использования. Запомните, что нельзя

удалить в окне область, являющуюся текущей, поэтому в данном методе

перед удалением объекта области текущей областью назначают

нулевую.}

if FRegion <> 0 then begin

//

Если область существует, то

SetWindowRgn(Handle, 0, Tru

); //

сделать текущей нулевую,

DeleteObject(FRegion);

//

удалить заданную область

 

begin

e

FRegion := 0;                      // и обнулить поле Fregion. end;

end;

procedure TddgHintWindow.ActivateHint(Rect: TRect;

const AHint: string);

{ Вызывается при активизации подсказки (при помещении курсора мыши

поверх соответствующего элемента управления). }

begin

with Rect do                        // добавить немного пространства

Right := Right + Canvas.TextWidth(‘WWWW’);

BoundsRect := Rect;

FreeCurrentRegion;{ Создание прямоугольной области со скругленными углами для отображения окна подсказки. }

FRegion := CreateRoundRectRgn(0, 0, Width, Height, Width, Height);

if FRegion <> 0 then

SetWindowRgn(Handle, FRegion, True); // Установка области окна

inherited ActivateHint(Rect, AHint);       // Вызов унаслед. метода

end;

procedure TddgHintWindow.Paint;

{ Этот метод вызывается обработчиком события WM_PAINT. Он отвечает

за прорисовку окна подсказки. }

var

R: TRect;

begin

R := ClientRect;               // Получить размер прямоугольника,

Inc(R.Left, 1);                // немного сдвинуть левую сторону

Canvas.Brush.Color := clInfoBk;      // установить цвет фона области

FillRgn(Canvas.Handle, FRegion, Canvas.Brush.Handle);

Canvas.Font.Color := clInfoText; // установить цвет текста

{ Вывести строку в центре скругленного прямоугольника }

DrawText(Canvas.Handle, PChar(Caption), Length(Caption), R,

DT_NOPREFIX or DT_WORDBREAK or DT_CENTER or DT_VCENTER);

end;

var

OldHintClass: THintWindowClass;

function SetNewHintClass(AClass:

THintWindowClass): THintWindowClass;

var

DoShowHint: Boolean;

begin

// Возвращаемое значение – старое окно подсказки

Result := HintWindowClass;

DoShowHint := Application.ShowHint;

if DoShowHint then

Application.ShowHint := False;// удалить старое окно подсказки

HintWindowClass := AClass;         // назначить новое окно подсказки

if DoShowHint then

Application.ShowHint := True; // создать новое окно подсказки

end;

initialization

OldHintClass := SetNewHintClass(TddgHintWindow);

finalization

SetNewHintClass(OldHintClass);

end.Организация  переопределенных  методов CreateParams() и  Paint() очевидна. Метод CreateParams() позволяет настроить структуру стилей окна перед  тем, как оно будет создано  на уровне API. В этом методе  с помощью операции not удаляется  по маске стиль WS_BORDER для того,  чтобы  вокруг окна не прорисовывалась прямоугольная грани ца. Метод  Paint() отвечает за прорисовку окна.  В данном  случае метод  должен  помес тить  свойство подсказки Caption в центр заголовка окна.  Для  текста  установлен  цвет clInfoText, который является определенным системой цветом подсказки.

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

По теме:

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