《GOF设计模式》—装饰(DECORATOR)—Delphi源码示例:图形用户界面组件

示例:图形用户界面组件

说明:

有时我们希望给某个对象而不是整个类添加一些功能。例如,一个图形用户界面工具箱允许你对任意一个用户界面组件添加一些特性,例如边框,或是一些行为,例如窗口滚动。

代码:

unit uView;

 

interface

 

uses

    Classes,Graphics,Controls,Forms,StdCtrls;

 

type

    TVisualComponent = class

    protected

        function GetCanvas: TCanvas; virtual; abstract;

    public

        procedure Draw(); virtual; abstract;

        //---

        property Canvas: TCanvas read GetCanvas;

    end;

    TDecorator = class(TVisualComponent)

    private

        FComponent: TVisualComponent;

    protected

        function GetCanvas: TCanvas; override;

    public

        constructor Create(AComponent: TVisualComponent);

        destructor Destroy; override;

        //---

        procedure Draw(); override;

    end;

 

    TBorderDecortor = class(TDecorator)

    private

        FBorderWidth: Integer;

        procedure DrawBorder;

    public

        constructor Create(AComponent: TVisualComponent; const ABorderWidth: Integer =

            1);

        //---

        procedure Draw(); override;

    end;

 

    TScrollDecortor = class(TDecorator)

    private

        FScrollBar: TScrollBar;

        FScrollPosition: integer;

        FOnScroll: TNotifyEvent;

        procedure DoScroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos:

            Integer);

        function GetScrollMax: Integer;

        function GetScrollMin: Integer;

        procedure SetScrollMax(const Value: Integer);

        procedure SetScrollMin(const Value: Integer);

    public

        constructor Create(AComponent: TVisualComponent; AParent: TWinControl);

        destructor Destroy; override;

        //---

        procedure Draw(); override;

        //---

        property OnScroll: TNotifyEvent read FOnScroll write FOnScroll;

        property ScrollPosition: integer read FScrollPosition;

        property ScrollMax: Integer read GetScrollMax write SetScrollMax;

        property ScrollMin: Integer read GetScrollMin write SetScrollMin;

    end;

 

    TTextView = class(TVisualComponent)

    private

        FCanvas: TCanvas;

        FLines: TStrings;

        FStartRow: integer;

    protected

        function GetCanvas: TCanvas; override;

    public

        constructor Create(ACanvas: TCanvas);

        destructor Destroy; override;

        //---

        procedure Draw; override;

        //---

        property Lines: TStrings read FLines;

        property StartRow: integer read FStartRow write FStartRow;

    end;

 

implementation

 

constructor TDecorator.Create(aComponent: TVisualComponent);

begin

    inherited Create;

    //---

    FComponent := AComponent;

end;

 

destructor TDecorator.Destroy;

begin

    if Assigned(FComponent) then

        FComponent.Free;

    //---

    inherited;

end;

 

procedure TDecorator.Draw();

begin

    if Assigned(FComponent) then

        FComponent.Draw;

end;

 

function TDecorator.GetCanvas: TCanvas;

begin

    Result := FComponent.Canvas;

end;

 

procedure TBorderDecortor.DrawBorder;

begin

    with Canvas do

    begin

        with Pen do

        begin

            Width := FBorderWidth;

            Color := clRed;

        end;

        Brush.Style := bsClear;

        //---

        Rectangle(ClipRect);

    end;

end;

 

constructor TBorderDecortor.Create(AComponent: TVisualComponent; const

    ABorderWidth: Integer = 1);

begin

    inherited Create(AComponent);

    //---

    FBorderWidth := ABorderWidth;

end;

 

procedure TBorderDecortor.Draw();

begin

    inherited;

    //---

    DrawBorder;

end;

 

constructor TScrollDecortor.Create(AComponent: TVisualComponent;

    AParent: TWinControl);

begin

    inherited Create(AComponent);

    //--

    FScrollBar := TScrollBar.Create(nil);

    with FScrollBar do

    begin

        Parent := AParent;

        Kind := sbVertical;

        OnScroll := self.DoScroll;

    end;

end;

 

destructor TScrollDecortor.Destroy;

begin

    FScrollBar.Free;

    //---

    inherited;

end;

 

procedure TScrollDecortor.Draw();

begin

    with self.Canvas.ClipRect do

    begin

        FScrollBar.Top := Top;

        FScrollBar.Left := Right - FScrollBar.Width;

        FScrollBar.Height := Bottom - Top;

    end;

    //---

    inherited;

end;

 

constructor TTextView.Create(ACanvas: TCanvas);

begin

    inherited Create;

    //---

    FCanvas := ACanvas;

    FLines := TStringList.Create;

end;

 

destructor TTextView.Destroy;

begin

    FLines.Free;

    //---

    inherited;

end;

 

procedure TTextView.Draw;

    //---

    procedure _ClearBack;

    begin

        with FCanvas do

        begin

            with Brush do

            begin

                Color := clBlack;

                Style := bsSolid;

            end;

            FillRect(ClipRect);

        end;

    end;

    //---

    procedure _DrawText;

    const

        CNT_PageRowCount = 3;

    var

        x,y: Integer;

        ARow,AEndRow: integer;

    begin

        AEndRow := FStartRow + CNT_PageRowCount;

        if AEndRow >= FLines.Count then

        begin

            AEndRow := FLines.Count - 1;

            //---

            FStartRow := AEndRow - CNT_PageRowCount;

            if FStartRow < 0 then

                FStartRow := 0;

        end;

        //---

        with FCanvas do

        begin

            Font.Color := clRed;

            //---

            x := 2;

            y := 2;

            //---

            for ARow := FStartRow to AEndRow do

            begin

                TextOut(x,y,FLines[ARow]);

                //---

                y := y + TextHeight(FLines[ARow]) + 20;

            end;

        end;

    end;

begin

    _ClearBack;

    _DrawText;

end;

 

function TTextView.GetCanvas: TCanvas;

begin

    Result := FCanvas;

end;

 

procedure TScrollDecortor.DoScroll(Sender: TObject; ScrollCode: TScrollCode;

    var ScrollPos: Integer);

begin

    FScrollPosition := ScrollPos;

    if Assigned(FOnScroll) then

        FOnScroll(self);

end;

 

function TScrollDecortor.GetScrollMax: Integer;

begin

    Result := FScrollBar.Max;

end;

 

function TScrollDecortor.GetScrollMin: Integer;

begin

    Result := FScrollBar.Min;

end;

 

procedure TScrollDecortor.SetScrollMax(const Value: Integer);

begin

    FScrollBar.Max := Value;

end;

 

procedure TScrollDecortor.SetScrollMin(const Value: Integer);

begin

    FScrollBar.Min := Value;

end;

 

end.

 

unit uForm1;

 

interface

 

uses

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

    ExtCtrls,uView;

 

type

    TForm1 = class(TForm)

        Image1: TImage;

        procedure FormCreate(Sender: TObject);

    private

        FView: TTextView;

        FScroll: TScrollDecortor;

        FBorder: TBorderDecortor;

        procedure DoScroll(Sender: TObject);

    public

    end;

 

var

    Form1: TForm1;

 

implementation

 

{$R *.DFM}

 

procedure TForm1.FormCreate(Sender: TObject);

var

    i,j: integer;

    AText: string;

begin

    FView := TTextView.Create(self.Image1.Canvas);

    for i := 1 to 9 do

    begin

        AText := '';

        for j := 1 to 20 do

            AText := AText + IntToStr(i);

        FView.Lines.Add(AText);

    end;

    //---

    FScroll := TScrollDecortor.Create(FView,self);

    with FScroll do

    begin

        ScrollMin := 0;

        ScrollMax := FView.Lines.Count - 1;

        OnScroll := self.DoScroll;

    end;

    //---

    FBorder := TBorderDecortor.Create(FScroll,2);

    FBorder.Draw;

end;

 

procedure TForm1.DoScroll(Sender: TObject);

begin

    FView.StartRow := FScroll.ScrollPosition;

    FBorder.Draw;

end;

 

end.

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值