《GOF设计模式》—桥接(BRIDGE)—Delphi源码示例:可移植的用户界面

来源:互联网 发布:mysql cluster 索引 编辑:程序博客网 时间:2024/04/28 09:29

示例:可移植的用户界面

说明:

 

代码:

 

unit uWindow;

 

interface

 

uses

Windows,SysUtils,Classes,Graphics;

 

type

   TWindow = class;

   TWindowImp = class;

 

   {窗口视图}

   TView = class

   public

       //---

       procedure Draw(const AWindow: TWindow);

   end;

 

   {窗口抽象类}

   TWindow = class

   private

       FCanvas: TCanvas;

       FContents: TView;

       FImp: TWindowIMP;

       function GetView(): TView;

       function GetWindowIMP: TWindowIMP;

       procedure SetOrigin(const Value: TPoint);

       procedure SetExtent(const Value: TPoint);

   protected

       procedure DrawLine(const p1,p2: TPoint);

       procedure DrawRect(const p1,p2: TPoint);

       procedure DrawPolygon(const Points: array of TPoint);

       procedure DrawText(const text: string; position: TPoint);

       //---

       property WindowIMP: TWindowIMP read GetWindowIMP;

       property View: TView read GetView;

   public

       constructor Create(ACanvas: TCanvas; contents: TView);

       //---

       procedure Open; virtual;

       procedure Close(); virtual;

       procedure Iconify(); virtual;

       procedure Deiconfy(); virtual;

       //---

       procedure Raised(); virtual;

       procedure Lower(); virtual;

       //---

       procedure DrawContents; virtual; abstract;

       //---

       property Origin: TPoint write SetOrigin;

       property Extent: TPoint write SetExtent;

   end;

 

   TApplicationWindow = class(TWindow)

   public

       procedure DrawContents(); override;

       procedure DrawCloseBox;

   end;

 

   TIconWindow = class(Twindow)

   private

       FBitmapName: string;

   public

       procedure DrawContents; override;

       procedure DrawBorder;

       //---

       property BitmapName: string write FBitmapName;

   end;

 

   {窗口实现类}

   TWindowImp = class

   protected

       procedure SetOrigin(const Value: TPoint); virtual;

       procedure SetExtent(const Value: TPoint); virtual;

   public

       constructor Create;

       //---

       procedure DeviceDrawLine(const p1,p2: TPoint); virtual; abstract;

       procedure DeviceDrawPolygon(const Points: array of TPoint); virtual; abstract;

       procedure DeviceDrawRect(const x1,y1,x2,y2: integer); virtual; abstract;

       procedure DeviceDrawText(const Text: string; x1,y1: integer); virtual; abstract;

       procedure DeviceDrawBitmap(const ABitmapName: string; x1,y1: integer); virtual; abstract;

       //---

       property Origin: TPoint write SetOrigin;

       property Extent: TPoint write SetExtent;

   end;

 

   TXWindowImp = class(TWindowImp)

   private

       FCanvas: TCanvas;

   public

       constructor Create(ACanvas: TCanvas);

       //---

       procedure DeviceDrawLine(const p1,p2: TPoint); override;

       procedure DeviceDrawRect(const x1,y1,x2,y2: integer); override;

       procedure DeviceDrawText(const Text: string; x1,y1: integer); override;

       procedure DeviceDrawBitmap(const ABitmapName: string; x1,y1: integer); override;

       procedure DeviceDrawPolygon(const Points: array of TPoint); override;

   end;

 

   TPMWindowImp = class(TWindowImp)

   private

       FCanvas: TCanvas;

   public

       constructor Create(ACanvas: TCanvas);

       //---

       procedure DeviceDrawLine(const p1,p2: TPoint); override;

       procedure DeviceDrawRect(const x1,y1,x2,y2: integer); override;

       procedure DeviceDrawText(const Text: string; x1,y1: integer); override;

       procedure DeviceDrawBitmap(const ABitmapName: string; x1,y1: integer); override;

       procedure DeviceDrawPolygon(const Points: array of TPoint); override;

   end;

 

   TWindowSystemFactory = class

   public

       constructor Create;

       destructor Destroy; override;

       //---

       class function Instance(): TWindowSystemFactory;

       function MakeWindowImp(ACanvas: TCanvas): TWindowImp;

   end;

 

implementation

 

var

   FFactory: TWindowSystemFactory;

 

procedure TView.Draw(const AWindow: TWindow);

begin

   AWindow.DrawText('abc',Point(12,12));

end;

 

constructor TWindow.Create(ACanvas: TCanvas; contents: TView);

begin

   FCanvas := ACanvas;

   FContents := contents;

end;

 

procedure TWindow.Open;

begin

end;

 

procedure TWindow.Close();

begin

end;

 

procedure TWindow.Iconify();

begin

end;

 

procedure TWindow.Deiconfy();

begin

end;

 

procedure TWindow.SetExtent(const Value: TPoint);

begin

   self.WindowIMP.Extent := Value;

end;

 

procedure TWindow.Raised();

begin

end;

 

procedure TWindow.Lower();

begin

end;

 

procedure TWindow.DrawLine(const p1,p2: TPoint);

begin

   self.WindowIMP.DeviceDrawLine(p1,p2);

end;

 

procedure TWindow.DrawRect(const p1,p2: TPoint);

begin

   self.WindowIMP.DeviceDrawRect(p1.x,p1.y,p2.x,p2.y);

end;

 

procedure TWindow.DrawPolygon(const Points: array of TPoint);

begin

   self.WindowIMP.DeviceDrawPolygon(Points);

end;

 

procedure TWindow.DrawText(const text: string; position: TPoint);

begin

   self.WindowIMP.DeviceDrawText(text,position.X,position.Y);

end;

 

function TWindow.GetWindowIMP: TWindowIMP;

begin

   if FImp = nil then

       FImp := TWindowSystemFactory.Instance.MakeWindowImp(FCanvas);

   //---

   Result := FImp;

end;

 

function TWindow.GetView(): TView;

begin

   Result := FContents;

end;

 

procedure TWindow.SetOrigin(const Value: TPoint);

begin

   self.WindowIMP.Origin := Value;

end;

 

constructor TWindowSystemFactory.Create;

begin

   if FFactory = nil then

       FFactory := Self

   else

       abort;

end;

 

destructor TWindowSystemFactory.Destroy;

begin

   FFactory := nil;

   //---

   inherited;

end;

 

class function TWindowSystemFactory.Instance(): TWindowSystemFactory;

begin

   if FFactory = nil then

       FFactory := TWindowSystemFactory.Create;

   //---

   Result := FFactory;

end;

 

function TWindowSystemFactory.MakeWindowImp(ACanvas: TCanvas): TWindowImp;

   //---

   function GetImpNameByIni: string;

   begin

       Result := 'PM';

   end;

var

   AImpName: string;

begin

   AImpName := GetImpNameByIni;

   //---

   if AImpName = 'PM' then

       Result := TPMWindowImp.Create(ACanvas)

   else if AImpName = 'X' then

       Result := TXWindowImp.Create(ACanvas)

   else

       Result := TPMWindowImp.Create(ACanvas);

end;

 

constructor TWindowImp.Create;

begin

end;

 

procedure TWindowImp.SetExtent(const Value: TPoint);

begin

end;

 

procedure TWindowImp.SetOrigin(const Value: TPoint);

begin

end;

 

procedure TApplicationWindow.DrawCloseBox;

begin

   self.DrawRect(Point(10,10),Point(50,50));

end;

 

procedure TApplicationWindow.DrawContents();

begin

   self.View.Draw(self);

end;

 

procedure TIconWindow.DrawBorder;

begin

   self.DrawRect(Point(10,10),Point(50,50));

   self.DrawText('123',Point(12,12));

end;

 

procedure TIconWindow.DrawContents();

begin

   if FBitmapName <> '' then

       self.WindowIMP.DeviceDrawBitmap(FBitmapName,0,0);

   //----

   self.WindowIMP.DeviceDrawLine(Point(10,10),Point(50,50));

end;

 

constructor TXWindowImp.Create(ACanvas: TCanvas);

begin

   inherited Create;

   //---

   FCanvas := ACanvas;

end;

 

procedure TXWindowImp.DeviceDrawBitmap(const ABitmapName: string; x1,y1:

   integer);

   //---

   procedure _XDrawBitmap;

   var

       AGraphic: TBitmap;

   begin

       AGraphic := TBitmap.Create;

       try

           AGraphic.LoadFromFile(ABitmapName);

           FCanvas.Draw(0,0,AGraphic);

       finally

           AGraphic.Free;

       end;

   end;

begin

   _XDrawBitmap;

end;

 

procedure TXWindowImp.DeviceDrawLine(const p1,p2: TPoint);

   //---

   procedure _XDrawLine;

   begin

       with FCanvas do

       begin

           with Pen do

           begin

               Color := clRed;

               Width := 1;

               Style := psSolid;

           end;

           //---

           MoveTo(p1.X,p1.X);

           LineTo(p2.X,p2.X);

       end;

   end;

begin

   _XDrawLine;

end;

 

procedure TXWindowImp.DeviceDrawPolygon(const Points: array of TPoint);

   //---

   procedure _XDrawPolygon;

   begin

       with FCanvas do

       begin

           with Pen do

           begin

               Color := clRed;

               Width := 1;

               Style := psSolid;

           end;

           Brush.Color := clWhite;

           //---

           Polygon(Points);

       end;

   end;

begin

   _XDrawPolygon;

end;

 

procedure TXWindowImp.DeviceDrawRect(const x1,y1,x2,y2: integer);

   //---

   procedure _XDrawRect;

   begin

       with FCanvas do

       begin

           with Pen do

           begin

               Color := clRed;

               Width := 1;

               Style := psSolid;

           end;

           Brush.Color := clWhite;

           //---

           Rectangle(x1,y1,x2,y2);

       end;

   end;

begin

   _XDrawRect;

end;

 

procedure TXWindowImp.DeviceDrawText(const Text: string; x1,y1: integer);

   //---

   procedure _XDrawString;

   begin

       with FCanvas do

       begin

           with Font do

           begin

               Name := '宋体';

               Size := 11;

               Color := clRed;

           end;

           TextOut(x1,y1,Text);

       end;

   end;

begin

   _XDrawString;

end;

 

constructor TPMWindowImp.Create(ACanvas: TCanvas);

begin

   inherited Create;

   //---

   FCanvas := ACanvas;

end;

 

procedure TPMWindowImp.DeviceDrawBitmap(const ABitmapName: string; x1,y1:

   integer);

   //---

   procedure _PMDrawBitmap;

   var

       AGraphic: TBitmap;

   begin

       AGraphic := TBitmap.Create;

       try

           AGraphic.LoadFromFile(ABitmapName);

           FCanvas.StretchDraw(Rect(0,0,AGraphic.Width div 2,AGraphic.Height div 2),AGraphic);

       finally

           AGraphic.Free;

       end;

   end;

begin

   _PMDrawBitmap;

end;

 

procedure TPMWindowImp.DeviceDrawLine(const p1,p2: TPoint);

   //---

   procedure _PMDrawLine;

   begin

       with FCanvas do

       begin

           with Pen do

           begin

               Color := clBlue;

               Width := 1;

               Style := psDot;

           end;

           //---

           MoveTo(p1.X,p1.X);

           LineTo(p2.X,p2.X);

       end;

   end;

begin

   _PMDrawLine;

end;

 

procedure TPMWindowImp.DeviceDrawPolygon(const Points: array of TPoint);

   //---

   procedure _PMDrawPolygon;

   begin

       with FCanvas do

       begin

           with Pen do

           begin

               Color := clBlue;

               Width := 1;

               Style := psDot;

           end;

           Brush.Color := clWhite;

           //---

           Polygon(Points);

       end;

   end;

begin

   _PMDrawPolygon;

end;

 

procedure TPMWindowImp.DeviceDrawRect(const x1,y1,x2,y2: integer);

   //---

   procedure _PMDrawRect;

   begin

       with FCanvas do

       begin

           with Pen do

           begin

               Color := clBlue;

               Width := 1;

               Style := psDot;

           end;

           Brush.Color := clYellow;

           //---

           Rectangle(x1,y1,x2,y2);

       end;

   end;

begin

   _PMDrawRect;

end;

 

procedure TPMWindowImp.DeviceDrawText(const Text: string; x1,y1: integer);

   //---

   procedure _PMDrawString;

   begin

       with FCanvas do

       begin

           with Font do

           begin

               Name := '宋体';

               Size := 11;

               Color := clBlue;

           end;

           TextOut(x1,y1,Text);

       end;

   end;

begin

   _PMDrawString;

end;

 

end.

procedure TForm1.Button1Click(Sender: TObject);

var

   AWindow: TWindow;

   AView: TView;

begin

   AView := TView.Create;

   AWindow := TApplicationWindow.Create(self.Canvas,AView);

   try

       AWindow.DrawContents;

   finally

       AWindow.Free;

       AView.Free;

   end;

end;

0 0