VrMatrix.pas
上传用户:hbszzs
上传日期:2008-08-20
资源大小:628k
文件大小:40k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*****************************************************}
  2. {                                                     }
  3. {     Varian Component Workshop                       }
  4. {                                                     }
  5. {     Varian Software NL (c) 1996-2000                }
  6. {     All Rights Reserved                             }
  7. {                                                     }
  8. {*****************************************************}
  9. unit VrMatrix;
  10. {$I VRLIB.INC}
  11. interface
  12. uses
  13.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  14.   VrConst, VrTypes, VrClasses, VrControls, VrSysUtils, VrThreads;
  15. type
  16.   TVrMatrixTextStyle = (tsUpperCase, tsLowerCase, tsAsIs, tsProperCase);
  17.   TVrMatrixData = class
  18.   private
  19.     FOrigin: string;
  20.     FData: string;
  21.     FColors: string;
  22.     FCurrColor: Char;
  23.     FStyle: TVrMatrixTextStyle;
  24.     procedure DecodeColorCode(var S: string);
  25.     procedure InsertChar(var S: string);
  26.   public
  27.     constructor Create;
  28.     procedure Decode(S: string);
  29.     procedure SetStyle(Value: TVrMatrixTextStyle);
  30.     procedure MoveLeft;
  31.     procedure MoveRight;
  32.     procedure Reset;
  33.     property Data: string read FData;
  34.     property Colors: string read FColors;
  35.   end;
  36.   TVrMatrixScrollDirection = (msdRightToLeft, msdLeftToRight);
  37.   TVrMatrixLedStyle = (ls9x13, ls14x20, ls19x27);
  38.   TVrMatrix = class(TVrGraphicImageControl)
  39.   private
  40.     FLeds: Integer;
  41.     FSpacing: Integer;
  42.     FAlignment: TAlignment;
  43.     FPalette: TVrPalette;
  44.     FTextStyle: TVrMatrixTextStyle;
  45.     FAutoScroll: Boolean;
  46.     FBevel: TVrBevel;
  47.     FScrollDirection: TVrMatrixScrollDirection;
  48.     FLedStyle: TVrMatrixLedStyle;
  49.     FLedsVisible: Boolean;
  50.     FThreaded: Boolean;
  51.     FOrientation: TVrOrientation;
  52.     FCharIndex: Integer;
  53.     FOnScrollDone: TNotifyEvent;
  54.     Bitmap: TBitMap;
  55.     FTimer: TVrTimer;
  56.     ScrollInit: Boolean;
  57.     Initialized: Boolean;
  58.     FStartLed: Integer;
  59.     FImageRect: TRect;
  60.     FString: TVrMatrixData;
  61.     function GetTimeInterval: Integer;
  62.     procedure SetLeds(Value: Integer);
  63.     procedure SetSpacing(Value: Integer);
  64.     procedure SetAlignment(Value: TAlignment);
  65.     procedure SetTextStyle(Value: TVrMatrixTextStyle);
  66.     procedure SetAutoScroll(Value: Boolean);
  67.     procedure SetTimeInterval(Value: Integer);
  68.     procedure SetLedStyle(Value: TVrMatrixLedStyle);
  69.     procedure SetLedsVisible(Value: Boolean);
  70.     procedure SetPalette(Value: TVrPalette);
  71.     procedure SetBevel(Value: TVrBevel);
  72.     procedure SetThreaded(Value: Boolean);
  73.     procedure SetOrientation(Value: TVrOrientation);
  74.     procedure PaletteModified(Sender: TObject);
  75.     procedure BevelChanged(Sender: TObject);
  76.     procedure TimerEvent(Sender: TObject);
  77.     procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  78.   protected
  79.     procedure LoadBitmaps; virtual;
  80.     procedure DestroyBitmaps;
  81.     procedure UpdateLed(Index: Integer; Ch: Char; Color: TColor);
  82.     procedure UpdateLeds(Redraw: Boolean);
  83.     procedure Paint; override;
  84.     procedure Loaded; override;
  85.     procedure GetItemRect(Index: Integer; var R: TRect);
  86.     procedure CalcPaintParams;
  87.     procedure FormatText(Value: string);
  88.   public
  89.     constructor Create(AOwner: TComponent); override;
  90.     destructor Destroy; override;
  91.   published
  92.     property Threaded: Boolean read FThreaded write SetThreaded default True;
  93.     property Leds: Integer read FLeds write SetLeds default 15;
  94.     property Spacing: Integer read FSpacing write SetSpacing default 2;
  95.     property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
  96.     property Palette: TVrPalette read FPalette write SetPalette;
  97.     property Bevel: TVrBevel read FBevel write SetBevel;
  98.     property TextStyle: TVrMatrixTextStyle read FTextStyle write SetTextStyle default tsUpperCase;
  99.     property AutoScroll: Boolean read FAutoScroll write SetAutoScroll default false;
  100.     property TimeInterval: Integer read GetTimeInterval write SetTimeInterval default 500;
  101.     property ScrollDirection: TVrMatrixScrollDirection read FScrollDirection write FScrollDirection default msdRightToLeft;
  102.     property LedStyle: TVrMatrixLedStyle read FLedStyle write SetLedStyle default ls14x20;
  103.     property LedsVisible: Boolean read FLedsVisible write SetLedsVisible default True;
  104.     property Orientation: TVrOrientation read FOrientation write SetOrientation default voHorizontal;
  105.     property OnScrollDone: TNotifyEvent read FOnScrollDone write FOnScrollDone;
  106. {$IFDEF VER110}
  107.     property Anchors;
  108.     property Constraints;
  109. {$ENDIF}
  110.     property Color;
  111.     property DragCursor;
  112. {$IFDEF VER110}
  113.     property DragKind;
  114. {$ENDIF}
  115.     property DragMode;
  116.     property Hint;
  117.     property ParentColor;
  118.     property ParentShowHint;
  119.     property PopupMenu;
  120.     property ShowHint;
  121.     property Text;
  122.     property Visible;
  123.     property OnClick;
  124. {$IFDEF VER130}
  125.     property OnContextPopup;
  126. {$ENDIF}
  127.     property OnDblClick;
  128.     property OnDragDrop;
  129.     property OnDragOver;
  130. {$IFDEF VER110}
  131.     property OnEndDock;
  132. {$ENDIF}
  133.     property OnEndDrag;
  134.     property OnMouseDown;
  135.     property OnMouseMove;
  136.     property OnMouseUp;
  137. {$IFDEF VER110}
  138.     property OnStartDock;
  139. {$ENDIF}
  140.     property OnStartDrag;
  141.   end;
  142.   TVrMatrixGroup = class(TVrGraphicImageControl)
  143.   private
  144.     FCols: TVrColInt;
  145.     FRows: TVrRowInt;
  146.     FAutoScroll: Boolean;
  147.     FPalette: TVrPalette;
  148.     FBevel: TVrBevel;
  149.     FCharSpacing: Integer;
  150.     FLineSpacing: Integer;
  151.     FPixelSize: Integer;
  152.     FPixelSpacing: Integer;
  153.     FLines: TStrings;
  154.     FTimer: TVrTimer;
  155.     FThreaded: Boolean;
  156.     FLedImage: TBitmap;
  157.     FMatrixImage: TBitmap;
  158.     FColorChanged: Boolean;
  159.     FScrollDirection: TVrScrollDirection;
  160.     FViewPort: TRect;
  161.     FAlignment: TAlignment;
  162.     FTextStyle: TVrMatrixTextStyle;
  163.     FInitialized: Boolean;
  164.     FList: TList;
  165.     function GetTimeInterval: Integer;
  166.     procedure SetCols(Value: TVrColInt);
  167.     procedure SetRows(Value: TVrRowInt);
  168.     procedure SetCharSpacing(Value: Integer);
  169.     procedure SetLineSpacing(Value: Integer);
  170.     procedure SetPixelSize(Value: Integer);
  171.     procedure SetPixelSpacing(Value: Integer);
  172.     procedure SetLines(Value: TStrings);
  173.     procedure SetPalette(Value: TVrPalette);
  174.     procedure SetBevel(Value: TVrBevel);
  175.     procedure SetThreaded(Value: Boolean);
  176.     procedure SetAutoScroll(Value: Boolean);
  177.     procedure SetAlignment(Value: TAlignment);
  178.     procedure SetTextStyle(Value: TVrMatrixTextStyle);
  179.     procedure SetTimeInterval(Value: Integer);
  180.     procedure PaletteModified(Sender: TObject);
  181.     procedure BevelChanged(Sender: TObject);
  182.     procedure LinesChanged(Sender: TObject);
  183.     procedure TimerEvent(Sender: TObject);
  184.     procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
  185.   protected
  186.     procedure Paint; override;
  187.     procedure CalcPaintParams;
  188.     procedure Loaded; override;
  189.     procedure CreateLedImage;
  190.     procedure UpdateLed(Index: Integer; Ch: Char; Color: TColor);
  191.     procedure UpdateRow(ARow: Integer);
  192.     procedure FormatStrings;
  193.     function GetItemRect(Index: Integer): TRect;
  194.     procedure CreateDataList;
  195.     procedure ClearDataList(FreeList: Boolean);
  196.   public
  197.     constructor Create(AOwner: TComponent); override;
  198.     destructor Destroy; override;
  199.     procedure Reset;
  200.   published
  201.     property Threaded: Boolean read FThreaded write SetThreaded default True;
  202.     property Cols: TVrColInt read FCols write SetCols default 15;
  203.     property Rows: TVrRowInt read FRows write SetRows default 7;
  204.     property AutoScroll: Boolean read FAutoScroll write SetAutoScroll default false;
  205.     property CharSpacing: Integer read FCharSpacing write SetCharSpacing default 1;
  206.     property LineSpacing: Integer read FLineSpacing write SetLineSpacing default 1;
  207.     property PixelSize: Integer read FPixelSize write SetPixelSize default 1;
  208.     property PixelSpacing: Integer read FPixelSpacing write SetPixelSpacing default 1;
  209.     property Lines: TStrings read FLines write SetLines;
  210.     property ScrollDirection: TVrScrollDirection read FScrollDirection write FScrollDirection default sdRightToLeft;
  211.     property Palette: TVrPalette read FPalette write SetPalette;
  212.     property Bevel: TVrBevel read FBevel write SetBevel;
  213.     property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
  214.     property TextStyle: TVrMatrixTextStyle read FTextStyle write SetTextStyle default tsUpperCase;
  215.     property TimeInterval: Integer read GetTimeInterval write SetTimeInterval default 500;
  216. {$IFDEF VER110}
  217.     property Anchors;
  218.     property Constraints;
  219. {$ENDIF}
  220.     property Color default clBlack;
  221.     property DragCursor;
  222. {$IFDEF VER110}
  223.     property DragKind;
  224. {$ENDIF}
  225.     property DragMode;
  226.     property Hint;
  227.     property ParentColor default false;
  228.     property ParentShowHint;
  229.     property PopupMenu;
  230.     property ShowHint;
  231.     property Text;
  232.     property Visible;
  233.     property OnClick;
  234. {$IFDEF VER130}
  235.     property OnContextPopup;
  236. {$ENDIF}
  237.     property OnDblClick;
  238.     property OnDragDrop;
  239.     property OnDragOver;
  240. {$IFDEF VER110}
  241.     property OnEndDock;
  242. {$ENDIF}
  243.     property OnEndDrag;
  244.     property OnMouseDown;
  245.     property OnMouseMove;
  246.     property OnMouseUp;
  247. {$IFDEF VER110}
  248.     property OnStartDock;
  249. {$ENDIF}
  250.     property OnStartDrag;
  251.   end;
  252. implementation
  253. {$R VRMATRIX.D32}
  254. const
  255.   CharState: array[0..895] of byte = { all ASCII according to Hewlett Packard HDSP 2470 }
  256.               ($02, $06, $0e, $1e, $0e, $06, $02,     { NUL }
  257.                $04, $00, $04, $08, $11, $11, $0e,     { SOH }
  258.                $1f, $00, $11, $0a, $04, $0a, $11,     { STX }
  259.                $1f, $00, $11, $19, $15, $13, $11,     { ETX }
  260.                $1f, $00, $16, $19, $11, $11, $11,     { EOT }
  261.                $00, $00, $0d, $12, $12, $12, $0d,     { ENQ }
  262.                $1c, $12, $12, $16, $11, $16, $10,     { ACK }
  263.                $06, $08, $04, $0e, $11, $11, $0e,     { BEL }
  264.                $00, $00, $00, $04, $0a, $11, $1f,     { BS }
  265.                $00, $10, $1c, $12, $12, $02, $01,     { HT }
  266.                $0e, $11, $11, $1f, $11, $11, $0e,     { LF }
  267.                $00, $10, $08, $04, $0a, $11, $11,     { VT }
  268.                $00, $00, $09, $09, $09, $0e, $10,     { FF }
  269.                $00, $01, $0e, $1a, $0a, $0a, $0a,     { CR }
  270.                $00, $00, $0f, $12, $12, $12, $0c,     { SO }
  271.                $1f, $08, $04, $02, $04, $08, $1f,     { SI }
  272.                $00, $00, $01, $0e, $14, $04, $04,     { DLE }
  273.                $00, $04, $0e, $15, $15, $0e, $04,     { DC1 }
  274.                $0e, $11, $11, $11, $11, $0a, $1b,     { DC2 }
  275.                $04, $00, $0e, $11, $1f, $11, $11,     { DC3 }
  276.                $04, $00, $0e, $12, $12, $12, $0d,     { DC4 }
  277.                $0a, $00, $0e, $11, $1f, $11, $11,     { NAK }
  278.                $0a, $00, $0e, $12, $12, $12, $0d,     { SYN }
  279.                $0a, $0e, $11, $11, $11, $11, $0e,     { ETB }
  280.                $0a, $00, $0e, $11, $11, $11, $0e,     { CAN }
  281.                $0a, $00, $11, $11, $11, $11, $0e,     { EM }
  282.                $00, $0a, $00, $11, $11, $11, $0e,     { SUB }
  283.                $00, $04, $02, $1f, $02, $04, $00,     { ESC }
  284.                $00, $0f, $08, $08, $08, $18, $08,     { FS }
  285.                $0c, $12, $04, $08, $1e, $00, $00,     { GS }
  286.                $06, $09, $08, $1c, $08, $08, $1f,     { RS }
  287.                $11, $0a, $04, $04, $0e, $04, $04,     { US }
  288.                $00, $00, $00, $00, $00, $00, $00,     { Space }
  289.                $08, $08, $08, $08, $08, $00, $08,     { ! }
  290.                $0a, $0a, $00, $00, $00, $00, $00,     { " }
  291.                $0a, $0a, $1f, $0a, $1f, $0a, $0a,     { # }
  292.                $04, $0f, $14, $0e, $05, $1e, $04,     { $ }
  293.                $18, $19, $02, $04, $08, $13, $03,     { % }
  294.                $08, $14, $14, $08, $15, $12, $0d,     { & }
  295.                $0c, $0c, $04, $08, $00, $00, $00,     { ' }
  296.                $02, $04, $04, $04, $04, $04, $02,     { ( }
  297.                $08, $04, $04, $04, $04, $04, $08,     { ) }
  298.                $00, $0a, $04, $1f, $04, $0a, $00,     { * }
  299.                $00, $04, $04, $1f, $04, $04, $00,     { + }
  300.                $00, $00, $00, $0c, $0c, $04, $08,     { , }
  301.                $00, $00, $00, $1f, $00, $00, $00,     { - }
  302.                $00, $00, $00, $00, $0c, $0c, $00,     { . }
  303.                $00, $01, $02, $04, $08, $10, $00,     { / }
  304.                $0e, $11, $13, $15, $19, $11, $0e,     { 0 }
  305.                $04, $0c, $04, $04, $04, $04, $0e,     { 1 }
  306.                $0e, $11, $01, $06, $08, $10, $1f,     { 2 }
  307.                $0e, $11, $01, $06, $01, $11, $0e,     { 3 }
  308.                $02, $06, $0a, $12, $1f, $02, $02,     { 4 }
  309.                $1f, $10, $1e, $01, $01, $11, $0e,     { 5 }
  310.                $06, $08, $10, $1e, $11, $11, $0e,     { 6 }
  311.                $1f, $01, $02, $04, $08, $08, $08,     { 7 }
  312.                $0e, $11, $11, $0e, $11, $11, $0e,     { 8 }
  313.                $0e, $11, $11, $0f, $01, $02, $0c,     { 9 }
  314.                $00, $0c, $0c, $00, $0c, $0c, $00,     { : }
  315.                $0c, $0c, $00, $0c, $0c, $04, $08,     { ; }
  316.                $01, $02, $04, $08, $04, $02, $01,     { < }
  317.                $00, $00, $1f, $00, $1f, $00, $00,     { = }
  318.                $10, $08, $04, $02, $04, $08, $10,     { > }
  319.                $0e, $11, $01, $02, $04, $00, $04,     { ? }
  320.                $0e, $11, $17, $15, $17, $10, $0e,     { @ }
  321.                $0e, $11, $11, $1f, $11, $11, $11,     { A }
  322.                $1e, $11, $11, $1e, $11, $11, $1e,     { B }
  323.                $0e, $11, $10, $10, $10, $11, $0e,     { C }
  324.                $1e, $11, $11, $11, $11, $11, $1e,     { D }
  325.                $1f, $10, $10, $1e, $10, $10, $1f,     { E }
  326.                $1f, $10, $10, $1e, $10, $10, $10,     { F }
  327.                $0e, $11, $10, $10, $13, $11, $0f,     { G }
  328.                $11, $11, $11, $1f, $11, $11, $11,     { H }
  329.                $0e, $04, $04, $04, $04, $04, $0e,     { I }
  330.                $01, $01, $01, $01, $01, $11, $0e,     { J }
  331.                $11, $12, $14, $18, $14, $12, $11,     { K }
  332.                $10, $10, $10, $10, $10, $10, $1f,     { L }
  333.                $11, $1b, $15, $15, $11, $11, $11,     { M }
  334.                $11, $11, $19, $15, $13, $11, $11,     { N }
  335.                $0e, $11, $11, $11, $11, $11, $0e,     { O }
  336.                $1e, $11, $11, $1e, $10, $10, $10,     { P }
  337.                $0e, $11, $11, $11, $15, $12, $0d,     { Q }
  338.                $1e, $11, $11, $1e, $14, $12, $11,     { R }
  339.                $0e, $11, $10, $0e, $01, $11, $0e,     { S }
  340.                $1f, $04, $04, $04, $04, $04, $04,     { T }
  341.                $11, $11, $11, $11, $11, $11, $0e,     { U }
  342.                $11, $11, $11, $11, $11, $0a, $04,     { V }
  343.                $11, $11, $11, $15, $15, $1b, $11,     { W }
  344.                $11, $11, $0a, $04, $0a, $11, $11,     { X }
  345.                $11, $11, $0a, $04, $04, $04, $04,     { Y }
  346.                $1f, $01, $02, $04, $08, $10, $1f,     { Z }
  347.                $07, $04, $04, $04, $04, $04, $07,     { [ }
  348.                $00, $10, $08, $04, $02, $01, $00,     {  }
  349.                $1c, $04, $04, $04, $04, $04, $1c,     { ] }
  350.                $04, $0e, $15, $04, $04, $04, $04,     { ^ }
  351.                $00, $00, $00, $00, $00, $00, $1f,     { _ }
  352.                $0c, $0c, $08, $04, $00, $00, $00,     { ` }
  353.                $00, $00, $0e, $12, $12, $12, $0d,     { a }
  354.                $10, $10, $16, $19, $11, $11, $1e,     { b }
  355.                $00, $00, $0e, $10, $10, $11, $0e,     { c }
  356.                $01, $01, $0d, $13, $11, $11, $0f,     { d }
  357.                $00, $00, $0e, $11, $1e, $10, $0e,     { e }
  358.                $04, $0a, $08, $1c, $08, $08, $08,     { f }
  359.                $00, $00, $0f, $11, $0f, $01, $06,     { g }
  360.                $10, $10, $16, $19, $11, $11, $11,     { h }
  361.                $04, $00, $0c, $04, $04, $04, $0e,     { i }
  362.                $02, $00, $06, $02, $02, $12, $0c,     { j }
  363.                $08, $08, $09, $0a, $0c, $0a, $09,     { k }
  364.                $0c, $04, $04, $04, $04, $04, $0e,     { l }
  365.                $00, $00, $0a, $15, $15, $11, $11,     { m }
  366.                $00, $00, $16, $19, $11, $11, $11,     { n }
  367.                $00, $00, $0e, $11, $11, $11, $0e,     { o }
  368.                $00, $00, $1e, $11, $19, $16, $10,     { p }
  369.                $00, $00, $0e, $12, $16, $0a, $03,     { q }
  370.                $00, $00, $0b, $0c, $08, $08, $08,     { r }
  371.                $00, $00, $0e, $10, $0e, $01, $1e,     { s }
  372.                $00, $08, $1c, $08, $08, $0a, $04,     { t }
  373.                $00, $00, $11, $11, $11, $13, $0d,     { u }
  374.                $00, $00, $11, $11, $11, $0a, $04,     { v }
  375.                $00, $00, $11, $11, $15, $15, $0a,     { w }
  376.                $00, $00, $11, $0a, $04, $0a, $11,     { x }
  377.                $00, $00, $11, $0a, $04, $04, $08,     { y }
  378.                $00, $00, $1f, $02, $04, $08, $1f,     { z }
  379.                $02, $04, $04, $08, $04, $04, $02,     (* { *)
  380.                $04, $04, $04, $00, $04, $04, $04,     { | }
  381.                $08, $04, $04, $02, $04, $04, $08,     (* } *)
  382.                $00, $00, $08, $15, $02, $00, $00,     { ~ }
  383.                $0a, $15, $0a, $15, $0a, $15, $0a);    { DEL }
  384.   SegSize: array[TVrMatrixLedStyle] of Integer = (1, 2, 3);
  385.   SegX = 5;
  386.   SegY = 7;
  387.   ColorCmd = '%';
  388.   ColorArray: array[1..16] of TColor = (
  389.     clBlack, clMaroon, clGreen, clOlive, clNavy, clPurple,
  390.     clTeal, clGray, clSilver, clRed, clLime, clYellow,
  391.     clBlue, clFuchsia, clAqua, clWhite);
  392.   //Each color code is made out of a percentage charater and a combination
  393.   //of a digit or a letter: for example "%CHello" will display all characters in clYellow.
  394.   //Combinations are also possible: %CH%0ello. This will only display the
  395.   //"H" in a different color.
  396.   //Codes are as follows:
  397.   //1 = clBlack       A = clRed
  398.   //2 = clMaroon      B = clLime
  399.   //3 = clGreen       C = clYellow
  400.   //4 = clOlive       D = clBlue
  401.   //5 = clNavy        E = clFuchsia
  402.   //6 = clPurple      F = clAqua
  403.   //7 = clTeal        G = clWhite
  404.   //8 = clGray
  405.   //9 = clSilver
  406.   //Note: in order to reset to the default palette color use "%0", or
  407.   //to display a % character use %%.
  408. function CountChars(const S: string): Integer;
  409. var
  410.   I: Integer;
  411. begin
  412.   I := 1;
  413.   Result := 0;
  414.   while I <= Length(S) do
  415.   begin
  416.     if S[I] = ColorCmd then
  417.     begin
  418.       Inc(I);
  419.       if (I <= Length(S)) and (S[I] = ColorCmd) then
  420.       begin
  421.         Inc(Result);
  422.         Inc(I);
  423.       end else Inc(I);
  424.     end
  425.     else
  426.     begin
  427.       Inc(Result);
  428.       Inc(I);
  429.     end;
  430.   end;
  431. end;
  432. { TVrMatrixData }
  433. constructor TVrMatrixData.Create;
  434. begin
  435.   inherited Create;
  436.   FStyle := tsAsIs;
  437. end;
  438. procedure TVrMatrixData.DecodeColorCode(var S: string);
  439. begin
  440.   FCurrColor := '-';
  441.   if S <> '' then
  442.   begin
  443.     if Upcase(S[1]) in ['0'..'9', 'A'..'G'] then
  444.       FCurrColor := S[1];
  445.     Delete(S, 1, 1);
  446.   end;
  447. end;
  448. procedure TVrMatrixData.InsertChar(var S: string);
  449. begin
  450.   if S <> '' then
  451.   begin
  452.     FData := FData + S[1];
  453.     FColors := FColors + FCurrColor;
  454.     Delete(S, 1, 1);
  455.   end;
  456. end;
  457. procedure TVrMatrixData.Decode(S: string);
  458. begin
  459.   FOrigin := S;
  460.   FData := '';
  461.   FColors := '';
  462.   FCurrColor := '-';
  463.   while Length(S) > 0 do
  464.   begin
  465.     if S[1] = ColorCmd then
  466.     begin
  467.       Delete(S, 1, 1);
  468.       if (S <> '') and (S[1] = ColorCmd) then
  469.         InsertChar(S)
  470.       else DecodeColorCode(S);
  471.     end else InsertChar(S);
  472.   end;
  473. end;
  474. procedure TVrMatrixData.MoveLeft;
  475. begin
  476.   FData := Copy(FData, 2, Length(FData) - 1) + Copy(FData, 1, 1);
  477.   FColors := Copy(FColors, 2, Length(FColors) - 1) + Copy(FColors, 1, 1);
  478. end;
  479. procedure TVrMatrixData.MoveRight;
  480. begin
  481.   FData := Copy(FData, Length(FData), 1) + Copy(FData, 0, Length(FData) - 1);
  482.   FColors := Copy(FColors, Length(FColors), 1) + Copy(FColors, 0, Length(FColors) - 1);
  483. end;
  484. procedure TVrMatrixData.Reset;
  485. begin
  486.   Decode(FOrigin);
  487.   SetStyle(FStyle);
  488. end;
  489. procedure TVrMatrixData.SetStyle(Value: TVrMatrixTextStyle);
  490. begin
  491.   FStyle := Value;
  492.   case FStyle of
  493.     tsUpperCase: FData := AnsiUpperCase(FData);
  494.     tsLowerCase: FData := AnsiLowerCase(FData);
  495.     tsProperCase:
  496.       begin
  497.         FData := AnsiLowerCase(FData);
  498.         if FData <> '' then
  499.           FData[1] := Upcase(FData[1]);
  500.       end;
  501.     tsAsIs:; //do nothing
  502.   end;
  503. end;
  504. {TVrMatrix}
  505. constructor TVrMatrix.Create(AOwner: TComponent);
  506. begin
  507.   inherited Create(AOwner);
  508.   ControlStyle := ControlStyle + [csOpaque] - [csSetCaption];
  509.   Width := 245;
  510.   Height := 30;
  511.   ParentColor := false;
  512.   Color := clBlack;
  513.   FLeds := 15;
  514.   FSpacing := 2;
  515.   FAlignment := taLeftjustify;
  516.   FTextStyle := tsUpperCase;
  517.   FAutoScroll := false;
  518.   FCharIndex := 1;
  519.   FScrollDirection := msdRightToLeft;
  520.   FLedStyle := ls14x20;
  521.   FLedsVisible := True;
  522.   FOrientation := voHorizontal;
  523.   FPalette := TVrPalette.Create;
  524.   FPalette.OnChange := PaletteModified;
  525.   FBevel := TVrBevel.Create;
  526.   with FBevel do
  527.   begin
  528.     InnerStyle := bsLowered;
  529.     InnerWidth := 2;
  530.     InnerColor := clBlack;
  531.     OnChange := BevelChanged;
  532.   end;
  533.   Bitmap := TBitMap.Create;
  534.   LoadBitmaps;
  535.   FThreaded := True;
  536.   FTimer := TVrTimer.Create(Self);
  537.   FTimer.Enabled := false;
  538.   FTimer.Interval := 500;
  539.   FTimer.OnTimer := TimerEvent;
  540.   FString := TVrMatrixData.Create;
  541. end;
  542. destructor TVrMatrix.Destroy;
  543. begin
  544.   DestroyBitmaps;
  545.   FString.Free;
  546.   FBevel.Free;
  547.   FPalette.Free;
  548.   FTimer.Free;
  549.   inherited Destroy;
  550. end;
  551. procedure TVrMatrix.Loaded;
  552. begin
  553.   inherited Loaded;
  554.   CalcPaintParams;
  555. end;
  556. procedure TVrMatrix.LoadBitmaps;
  557. const
  558.   ResNames: array[TVrMatrixLedStyle] of PChar =
  559.     ('9x13', '14x20', '19x27');
  560. begin
  561.   Bitmap.Handle := LoadBitmap(hInstance, PChar('VRMATRIXLED' + ResNames[FLedStyle]));
  562.   FPalette.ToBMP(Bitmap, ResColorLow, ResColorHigh);
  563.   FImageRect := Bounds(0, 0, Bitmap.Width, Bitmap.Height);
  564. end;
  565. procedure TVrMatrix.DestroyBitmaps;
  566. begin
  567.   Bitmap.Free;
  568. end;
  569. procedure TVrMatrix.PaletteModified(Sender: TObject);
  570. begin
  571.   LoadBitmaps;
  572.   UpdateControlCanvas;
  573. end;
  574. procedure TVrMatrix.BevelChanged(Sender: TObject);
  575. begin
  576.   UpdateControlCanvas;
  577. end;
  578. procedure TVrMatrix.SetLeds(Value: Integer);
  579. begin
  580.   if FLeds <> Value then
  581.   begin
  582.     FLeds := Value;
  583.     FormatText(Text);
  584.     UpdateControlCanvas;
  585.   end;
  586. end;
  587. procedure TVrMatrix.SetSpacing(Value: Integer);
  588. begin
  589.   if FSpacing <> Value then
  590.   begin
  591.     FSpacing := Value;
  592.     UpdateControlCanvas;
  593.   end;
  594. end;
  595. procedure TVrMatrix.FormatText(Value: string);
  596. begin
  597.   FString.Decode(Value);
  598.   FString.SetStyle(FTextStyle);
  599. end;
  600. procedure TVrMatrix.SetTextStyle(Value: TVrMatrixTextStyle);
  601. begin
  602.   if FTextStyle <> Value then
  603.   begin
  604.     FTextStyle := Value;
  605.     FormatText(Text);
  606.     UpdateLeds(True);
  607.   end;
  608. end;
  609. procedure TVrMatrix.SetAlignment(Value: TAlignment);
  610. begin
  611.   if FAlignment <> Value then
  612.   begin
  613.     FAlignment := Value;
  614.     if (Designing) or (not FAutoScroll) then
  615.       UpdateControlCanvas;
  616.   end;
  617. end;
  618. procedure TVrMatrix.SetAutoScroll(Value: Boolean);
  619. begin
  620.   if FAutoScroll <> Value then
  621.   begin
  622.     FAutoScroll := Value;
  623.     FCharIndex := 1;
  624.     UpdateControlCanvas;
  625.     if not (Designing or Loading) then
  626.     begin
  627.       ScrollInit := True;
  628.       FTimer.Enabled := Value;
  629.     end;
  630.   end;
  631. end;
  632. procedure TVrMatrix.SetLedStyle(Value: TVrMatrixLedStyle);
  633. begin
  634.   if FLedStyle <> Value then
  635.   begin
  636.     FLedStyle := Value;
  637.     LoadBitmaps;
  638.     UpdateControlCanvas;
  639.   end;
  640. end;
  641. procedure TVrMatrix.SetLedsVisible(Value: Boolean);
  642. begin
  643.   if FLedsVisible <> Value then
  644.   begin
  645.     FLedsVisible := Value;
  646.     UpdateControlCanvas;
  647.   end;
  648. end;
  649. procedure TVrMatrix.SetThreaded(Value: Boolean);
  650. begin
  651.   if FThreaded <> Value then
  652.   begin
  653.     FThreaded := Value;
  654.     if Value then FTimer.TimerType := ttThread
  655.     else FTimer.TimerType := ttSystem;
  656.   end;
  657. end;
  658. procedure TVrMatrix.SetOrientation(Value: TVrOrientation);
  659. begin
  660.   if FOrientation <> Value then
  661.   begin
  662.     FOrientation := Value;
  663.     UpdateControlCanvas;
  664.   end;
  665. end;
  666. procedure TVrMatrix.SetTimeInterval(Value: Integer);
  667. begin
  668.   FTimer.Interval := Value;
  669. end;
  670. function TVrMatrix.GetTimeInterval: Integer;
  671. begin
  672.   Result := FTimer.Interval;
  673. end;
  674. procedure TVrMatrix.SetPalette(Value: TVrPalette);
  675. begin
  676.   FPalette.Assign(Value);
  677. end;
  678. procedure TVrMatrix.SetBevel(Value: TVrBevel);
  679. begin
  680.   FBevel.Assign(Value);
  681. end;
  682. procedure TVrMatrix.CMTextChanged(var Message: TMessage);
  683. begin
  684.   inherited;
  685.   FormatText(Text);
  686.   UpdateControlCanvas;
  687. end;
  688. procedure TVrMatrix.UpdateLed(Index: Integer; Ch: Char; Color: TColor);
  689. var
  690.   R, ItemRect: TRect;
  691.   I, J, Idx, W: Integer;
  692. begin
  693.   with BitmapCanvas do
  694.   begin
  695.     GetItemRect(Index, ItemRect);
  696.     Brush.Style := bsSolid;
  697.     Brush.Color := Self.Color;
  698.     FillRect(ItemRect);
  699.     if FLedsVisible then
  700.     begin
  701.       Brush.Style := bsClear;
  702.       BrushCopy(ItemRect, Bitmap, FImageRect, clBlack);
  703.     end;
  704.     if Ch = #32 then Exit;
  705.     Brush.Color := Color;
  706.     Idx := ord(Ch) * 7;
  707.     for I := 0 to 6 do
  708.       for J := 0 to 4 do
  709.       begin
  710.         if CharState[Idx + I] and (1 shl J) > 0 then
  711.         begin
  712.           W := SegSize[FLedStyle];
  713.           R := Bounds(ItemRect.Left + Bitmap.Width - W - (J * Succ(W)),
  714.                       ItemRect.Top + (I * Succ(W)), W, W);
  715.           FillRect(R);
  716.         end;
  717.       end;
  718.   end;
  719. end;
  720. procedure TVrMatrix.UpdateLeds(Redraw: Boolean);
  721. var
  722.   I: Integer;
  723.   Data, Colors: string;
  724.   Idx: Integer;
  725.   Color: TColor;
  726.   function GetColorValue(Ch: Char): TColor;
  727.   var
  728.     ColorIndex: Integer;
  729.   begin
  730.     ColorIndex := 0;
  731.     case Upcase(Ch) of
  732.       '0'..'9' : ColorIndex := ord(Ch) - 48;    // 48 = ord('0')
  733.       'A'..'G' : ColorIndex := ord(Ch) - 55;   // 'A' = 41h = 65d  ; minus 10 = 55d
  734.     end;
  735.     if (ColorIndex < 1) or (ColorIndex > 16) then
  736.          Result := FPalette.High
  737.       else Result := ColorArray[ColorIndex];
  738.   end;
  739. begin
  740.   for I := 0 to FLeds - 1 do
  741.     UpdateLed(I, #32, FPalette.High);
  742.   Data := FString.Data;
  743.   Colors := FString.Colors;
  744.   Idx := FStartLed;
  745.   for I := FCharIndex to Length(Data) do
  746.   begin
  747.     Color := GetColorValue(Colors[I]);
  748.     UpdateLed(Idx, Data[I], Color);
  749.     Inc(Idx);
  750.     if Idx >= FLeds then Break;
  751.   end;
  752.   if not Loading then
  753.     if Redraw then inherited Paint;
  754. end;
  755. procedure TVrMatrix.Paint;
  756. var
  757.   R: TRect;
  758. begin
  759.   CalcPaintParams;
  760.   ClearBitmapCanvas;
  761.   R := ClientRect;
  762.   FBevel.Paint(BitmapCanvas, R);
  763.   FCharIndex := 1;
  764.   case FAlignment of
  765.     taCenter: FStartLed := MaxIntVal(0, ((FLeds - Length(FString.Data)) div 2));
  766.     taRightJustify: FStartLed := MaxIntVal(0, (FLeds - Length(FString.Data)));
  767.     else FStartLed := 0;
  768.   end;
  769.   UpdateLeds(True);
  770.   //Make sure we first display the control
  771.   if (not Initialized) and (AutoScroll) then
  772.   begin
  773.     Initialized := True;
  774.     ScrollInit := True;
  775.     FTimer.Enabled := True;
  776.   end;
  777. end;
  778. procedure TVrMatrix.CalcPaintParams;
  779. var
  780.   R: TRect;
  781.   Gap, NewWidth, NewHeight: Integer;
  782. begin
  783.   R := ClientRect;
  784.   FBevel.GetVisibleArea(R);
  785.   Gap := (FLeds - 1) * FSpacing;
  786.   if Orientation = voHorizontal then
  787.   begin
  788.     NewWidth := (R.Left * 2) + Gap + (FLeds * Bitmap.Width);
  789.     NewHeight := (R.Top * 2) + Bitmap.Height;
  790.   end
  791.   else
  792.   begin
  793.     NewWidth := (R.Left * 2) + Bitmap.Width;
  794.     NewHeight := (R.Top * 2) + Gap + (FLeds * Bitmap.Height);
  795.   end;
  796.   BoundsRect := Bounds(Left, Top, NewWidth, NewHeight);
  797. end;
  798. procedure TVrMatrix.GetItemRect(Index: Integer; var R: TRect);
  799. var
  800.   X, Y: Integer;
  801. begin
  802.   R := ClientRect;
  803.   FBevel.GetVisibleArea(R);
  804.   X := R.Left;
  805.   Y := R.Top;
  806.   if Orientation = voHorizontal then
  807.     X := X + (Index * Bitmap.Width) + (Index * FSpacing)
  808.   else Y := Y + (Index * Bitmap.Height) + (Index * FSpacing);
  809.   R := Bounds(X, Y, Bitmap.Width, Bitmap.Height);
  810. end;
  811. procedure TVrMatrix.TimerEvent(Sender: TObject);
  812. begin
  813.   if (ScrollInit) then
  814.   begin
  815.     FCharIndex := 1;
  816.     ScrollInit := false;
  817.   end;
  818.   if FScrollDirection = msdRightToLeft then
  819.   begin
  820.     if FStartLed > 0 then Dec(FStartLed)
  821.     else if FCharIndex <= Length(FString.Data) then Inc(FCharIndex)
  822.     else
  823.     begin
  824.       if Assigned(FOnScrollDone) then
  825.         FOnScrollDone(Self);
  826.       FCharIndex := 1;
  827.       FStartLed := FLeds - 1;
  828.     end;
  829.   end
  830.   else
  831.   begin
  832.     if (FCharIndex = 1) and (FStartLed < FLeds-1) then Inc(FStartLed)
  833.     else
  834.     if FCharIndex > 1 then
  835.     begin
  836.       Dec(FCharIndex);
  837.       FStartLed := 0;
  838.     end
  839.     else
  840.     begin
  841.       if Assigned(FOnScrollDone) then
  842.         FOnScrollDone(Self);
  843.       FCharIndex := Length(FString.Data);
  844.       FStartLed := 0;
  845.     end;
  846.   end;
  847.   UpdateLeds(True);
  848. end;
  849. { TVrMatrixGroup }
  850. constructor TVrMatrixGroup.Create(AOwner: TComponent);
  851. begin
  852.   inherited Create(AOwner);
  853.   ControlStyle := ControlStyle + [csOpaque];
  854.   Width := 200;
  855.   Height := 100;
  856.   Color := clBlack;
  857.   ParentColor := false;
  858.   FCols := 15;
  859.   FRows := 7;
  860.   FCharSpacing := 1;
  861.   FLineSpacing := 1;
  862.   FPixelSize := 1;
  863.   FPixelSpacing := 1;
  864.   FScrollDirection := sdRightToLeft;
  865.   FAutoScroll := false;
  866.   FAlignment := taLeftjustify;
  867.   FTextStyle := tsUpperCase;
  868.   FPalette := TVrPalette.Create;
  869.   FPalette.OnChange := PaletteModified;
  870.   FBevel := TVrBevel.Create;
  871.   with FBevel do
  872.   begin
  873.     InnerStyle := bsLowered;
  874.     InnerWidth := 2;
  875.     InnerColor := clBlack;
  876.     OnChange := BevelChanged;
  877.   end;
  878.   FThreaded := True;
  879.   FTimer := TVrTimer.Create(Self);
  880.   with FTimer do
  881.   begin
  882.     FTimer.Enabled := false;
  883.     FTimer.Interval := 500;
  884.     FTimer.OnTimer := TimerEvent;
  885.   end;
  886.   FLines := TStringList.Create;
  887.   TStringList(FLines).OnChange := LinesChanged;
  888.   FLedImage := TBitmap.Create;
  889.   FLedImage.Transparent := false;
  890.   FMatrixImage := TBitmap.Create;
  891.   FMatrixImage.Transparent := false;
  892.   CreateLedImage;
  893.   CreateDataList;
  894. end;
  895. destructor TVrMatrixGroup.Destroy;
  896. begin
  897.   ClearDataList(True);
  898.   FBevel.Free;
  899.   FPalette.Free;
  900.   FTimer.Free;
  901.   FLines.Free;
  902.   FLedImage.Free;
  903.   FMatrixImage.Free;
  904.   inherited Destroy;
  905. end;
  906. procedure TVrMatrixGroup.Loaded;
  907. begin
  908.   inherited Loaded;
  909.   FColorChanged := True;
  910.   CreateLedImage;
  911. end;
  912. procedure TVrMatrixGroup.CreateDataList;
  913. var
  914.   I: Integer;
  915. begin
  916.   if not Assigned(FList) then
  917.     FList := TList.Create;
  918.   ClearDataList(false);
  919.   for I := 0 to (Rows * 2) - 1 do
  920.     FList.Add(TVrMatrixData.Create);
  921. end;
  922. procedure TVrMatrixGroup.ClearDataList(FreeList: Boolean);
  923. var
  924.   I: Integer;
  925. begin
  926.   for I := 0 to FList.Count - 1 do
  927.     TVrMatrixData(FList[I]).Free;
  928.   FList.Clear;
  929.   if FreeList then
  930.     FList.Free;
  931. end;
  932. procedure TVrMatrixGroup.Reset;
  933. var
  934.   I: Integer;
  935. begin
  936.   AutoScroll := false;
  937.   for I := 0 to FList.Count - 1 do
  938.     TVrMatrixData(FList[I]).Reset;
  939.   UpdateControlCanvas;
  940. end;
  941. procedure TVrMatrixGroup.CreateLedImage;
  942. var
  943.   R: TRect;
  944.   X, Y: Integer;
  945. begin
  946.   with FLedImage do
  947.   begin
  948.     Width := ((PixelSize + PixelSpacing) * SegX) - PixelSpacing;
  949.     Height := ((PixelSize + PixelSpacing) * SegY) - PixelSpacing;
  950.     Canvas.Brush.Color := Self.Color;
  951.     Canvas.FillRect(Bounds(0, 0, Width, Height));
  952.     X := 0;
  953.     while X <= Width do
  954.     begin
  955.       Y := 0;
  956.       while Y <= Height do
  957.       begin
  958.         R := Bounds(X, Y, PixelSize, PixelSize);
  959.         Canvas.Brush.Color := FPalette.Colors[0];
  960.         Canvas.FillRect(R);
  961.         Inc(Y, PixelSize + PixelSpacing);
  962.       end;
  963.       Inc(X, PixelSize + PixelSpacing);
  964.     end;
  965.   end;
  966.   with FMatrixImage do
  967.   begin
  968.     Width := ((FLedImage.Width + FCharSpacing + 1) * FCols) - FCharSpacing;
  969.     Height := ((FLedImage.Height + FLineSpacing + 1) * FRows) - FLineSpacing;
  970.     Canvas.Brush.Color := Self.Color;
  971.     Canvas.FillRect(Bounds(0, 0, Width, Height));
  972.     X := 0;
  973.     while X <= Width do
  974.     begin
  975.       Y := 0;
  976.       while Y <= Height do
  977.       begin
  978.         Canvas.Draw(X, Y, FLedImage);
  979.         Inc(Y, FLedImage.Height + LineSpacing + 1);
  980.       end;
  981.       Inc(X, FLedImage.Width + CharSpacing + 1);
  982.     end;
  983.   end;
  984. end;
  985. function TVrMatrixGroup.GetItemRect(Index: Integer): TRect;
  986. var
  987.   X, Y: Integer;
  988. begin
  989.   X := (Index mod FCols) * (FLedImage.Width + CharSpacing + 1);
  990.   Y := (Index div FCols) * (FLedImage.Height + LineSpacing + 1);
  991.   Result := Bounds(FViewPort.Left + X, FViewPort.Top + Y, FLedImage.Width, FLedImage.Height);
  992. end;
  993. procedure TVrMatrixGroup.UpdateLed(Index: Integer; Ch: Char; Color: TColor);
  994. var
  995.   R, ItemRect: TRect;
  996.   I, J, Idx, W: Integer;
  997. begin
  998.   if Ch = #32 then Exit;
  999.   with BitmapCanvas do
  1000.   begin
  1001.     ItemRect := GetItemRect(Index);
  1002.     Brush.Color := Color;
  1003.     Idx := ord(Ch) * 7;
  1004.     W := PixelSize;
  1005.     for I := 0 to SegY - 1 do
  1006.       for J := 0 to SegX - 1 do
  1007.       begin
  1008.         if CharState[Idx + I] and (1 shl J) > 0 then
  1009.         begin
  1010.           R := Bounds(ItemRect.Left + FLedImage.Width - W - (J * Succ(PixelSpacing)),
  1011.                       ItemRect.Top + (I * Succ(PixelSpacing)), W, W);
  1012.           FillRect(R);
  1013.         end;
  1014.       end;
  1015.   end;
  1016. end;
  1017. procedure TVrMatrixGroup.UpdateRow(ARow: Integer);
  1018. var
  1019.   Idx, I: Integer;
  1020.   Color: TColor;
  1021.   Data, Colors: string;
  1022.   function GetColorValue(Ch: Char): TColor;
  1023.   var
  1024.     ColorIndex: Integer;
  1025.   begin
  1026.     ColorIndex := 0;
  1027.     case Upcase(Ch) of
  1028.       '0'..'9' : ColorIndex := ord(Ch) - 48;    // 48 = ord('0')
  1029.       'A'..'G' : ColorIndex := ord(Ch) - 55;   // 'A' = 41h = 65d  ; minus 10 = 55d
  1030.     end;
  1031.     if (ColorIndex < 1) or (ColorIndex > 16) then
  1032.          Result := FPalette.High
  1033.       else Result := ColorArray[ColorIndex];
  1034.   end;
  1035. begin
  1036.   if ARow > Rows - 1 then
  1037.     Exit;
  1038.   Data := TVrMatrixData(FList[ARow]).Data;
  1039.   Colors := TVrMatrixData(FList[ARow]).Colors;
  1040.   Idx := ARow * Cols;
  1041.   for I := 1 to Length(Data) do
  1042.   begin
  1043.     Color := GetColorValue(Colors[I]);
  1044.     UpdateLed(Idx, Data[I], Color);
  1045.     Inc(Idx);
  1046.     if Idx >= (ARow * FCols) + FCols then Break;
  1047.   end;
  1048. end;
  1049. procedure TVrMatrixGroup.Paint;
  1050. var
  1051.   I: Integer;
  1052. begin
  1053.   CalcPaintParams;
  1054.   FViewPort := ClientRect;
  1055.   FBevel.Paint(BitmapCanvas, FViewPort);
  1056.   with BitmapCanvas do
  1057.     Draw(FViewPort.Left, FViewPort.Top, FMatrixImage);
  1058.   for I := 0 to Rows - 1 do UpdateRow(I);
  1059.   inherited Paint;
  1060.   //Make sure we first display the control
  1061.   if (not FInitialized) and (AutoScroll) then
  1062.   begin
  1063.     FInitialized := True;
  1064.     FTimer.Enabled := True;
  1065.   end;
  1066. end;
  1067. procedure TVrMatrixGroup.CalcPaintParams;
  1068. var
  1069.   R: TRect;
  1070.   NewWidth, NewHeight: Integer;
  1071. begin
  1072.   R := ClientRect;
  1073.   Bevel.GetVisibleArea(R);
  1074.   NewWidth := FMatrixImage.Width + (R.Left * 2);
  1075.   NewHeight := FMatrixImage.Height + (R.Top * 2);
  1076.   BoundsRect := Bounds(Left, Top, NewWidth, NewHeight);
  1077. end;
  1078. procedure TVrMatrixGroup.TimerEvent(Sender: TObject);
  1079. var
  1080.   I: Integer;
  1081. begin
  1082.   if (FScrollDirection in [sdRightToLeft, sdLeftToRight]) then
  1083.   begin
  1084.     for I := 0 to Rows - 1 do
  1085.         case FScrollDirection of
  1086.           sdRightToLeft: TVrMatrixData(FList[I]).MoveLeft;
  1087.           sdLeftToRight: TVrMatrixData(FList[I]).MoveRight;
  1088.         end;
  1089.   end
  1090.   else
  1091.   if FScrollDirection = sdTopToBottom then
  1092.   begin
  1093.     FList.Add(FList[0]);
  1094.     FList.Delete(0);
  1095.   end
  1096.   else
  1097.   begin
  1098.     FList.Insert(0, FList[FList.Count - 1]);
  1099.     FList.Delete(FList.Count - 1);
  1100.   end;
  1101.   UpdateControlCanvas;
  1102. end;
  1103. procedure TVrMatrixGroup.FormatStrings;
  1104. var
  1105.   S: string;
  1106.   I, MaxLen, Count: Integer;
  1107.   Strings: TStringList;
  1108.   function Center(S: string; Width: Integer): string;
  1109.   var
  1110.     Append: Boolean;
  1111.     Cnt: Integer;
  1112.   begin
  1113.     Result := S;
  1114.     Cnt := CountChars(S);
  1115.     Append := True;
  1116.     while Cnt < Width do
  1117.     begin
  1118.       if Append then Result := Result + #32 else Result := #32 + Result;
  1119.       Append := not Append;
  1120.       Inc(Cnt);
  1121.     end;
  1122.   end;
  1123.   function RightJustify(S: string; Width: Integer): string;
  1124.   var
  1125.     Cnt: Integer;
  1126.   begin
  1127.     Result := S;
  1128.     Cnt := CountChars(S);
  1129.     while Cnt < Width do
  1130.     begin
  1131.       Result := #32 + Result;
  1132.       Inc(Cnt);
  1133.     end;
  1134.   end;
  1135. begin
  1136.   Strings := TStringList.Create;
  1137.   try
  1138.     for I := 0 to Lines.Count - 1 do
  1139.       case Alignment of
  1140.         taCenter: Strings.Add(Center(Lines[I], Cols));
  1141.         taRightJustify: Strings.Add(RightJustify(Lines[I], Cols));
  1142.         else Strings.Add(Lines[I]);
  1143.       end;
  1144.     while Strings.Count < Rows * 2 do Strings.Add(#32);
  1145.     MaxLen := Cols;
  1146.     for I := 0 to Strings.Count - 1 do
  1147.       MaxLen := MaxIntVal(MaxLen, CountChars(Strings[I]));
  1148.     for I := 0 to Strings.Count - 1 do
  1149.     begin
  1150.       S := Strings[I];
  1151.       Count := CountChars(S);
  1152.       while Count < MaxLen + Cols do
  1153.       begin
  1154.         S := S + #32;
  1155.         Inc(Count);
  1156.       end;
  1157.       TVrMatrixData(FList[I]).Decode(S);
  1158.       TVrMatrixData(FList[I]).SetStyle(FTextStyle);
  1159.     end;
  1160.   finally
  1161.     Strings.Free;
  1162.   end;
  1163. end;
  1164. procedure TVrMatrixGroup.PaletteModified(Sender: TObject);
  1165. begin
  1166.   CreateLedImage;
  1167.   UpdateControlCanvas;
  1168. end;
  1169. procedure TVrMatrixGroup.BevelChanged(Sender: TObject);
  1170. begin
  1171.   UpdateControlCanvas;
  1172. end;
  1173. procedure TVrMatrixGroup.LinesChanged(Sender: TObject);
  1174. begin
  1175.   FormatStrings;
  1176.   UpdateControlCanvas;
  1177. end;
  1178. procedure TVrMatrixGroup.SetPalette(Value: TVrPalette);
  1179. begin
  1180.   FPalette.Assign(Value);
  1181. end;
  1182. procedure TVrMatrixGroup.SetBevel(Value: TVrBevel);
  1183. begin
  1184.   FBevel.Assign(Value);
  1185. end;
  1186. procedure TVrMatrixGroup.SetLines(Value: TStrings);
  1187. begin
  1188.   FLines.Assign(Value);
  1189. end;
  1190. procedure TVrMatrixGroup.SetCols(Value: TVrColInt);
  1191. begin
  1192.   if FCols <> Value then
  1193.   begin
  1194.     FCols := Value;
  1195.     CreateLedImage;
  1196.     FormatStrings;
  1197.     UpdateControlCanvas;
  1198.   end;
  1199. end;
  1200. procedure TVrMatrixGroup.SetRows(Value: TVrRowInt);
  1201. begin
  1202.   if FRows <> Value then
  1203.   begin
  1204.     FRows := Value;
  1205.     CreateDataList;
  1206.     CreateLedImage;
  1207.     FormatStrings;
  1208.     UpdateControlCanvas;
  1209.   end;
  1210. end;
  1211. procedure TVrMatrixGroup.SetCharSpacing(Value: Integer);
  1212. begin
  1213.   if FCharSpacing <> Value then
  1214.   begin
  1215.     FCharSpacing := Value;
  1216.     CreateLedImage;
  1217.     UpdateControlCanvas;
  1218.   end;
  1219. end;
  1220. procedure TVrMatrixGroup.SetLineSpacing(Value: Integer);
  1221. begin
  1222.   if FLineSpacing <> Value then
  1223.   begin
  1224.     FLineSpacing := Value;
  1225.     CreateLedImage;
  1226.     UpdateControlCanvas;
  1227.   end;
  1228. end;
  1229. procedure TVrMatrixGroup.SetPixelSize(Value: Integer);
  1230. begin
  1231.   if FPixelSize <> Value then
  1232.   begin
  1233.     FPixelSize := Value;
  1234.     CreateLedImage;
  1235.     UpdateControlCanvas;
  1236.   end;
  1237. end;
  1238. procedure TVrMatrixGroup.SetPixelSpacing(Value: Integer);
  1239. begin
  1240.   if FPixelSpacing <> Value then
  1241.   begin
  1242.     FPixelSpacing := Value;
  1243.     CreateLedImage;
  1244.     UpdateControlCanvas;
  1245.   end;
  1246. end;
  1247. procedure TVrMatrixGroup.SetAutoScroll(Value: Boolean);
  1248. begin
  1249.   if FAutoScroll <> Value then
  1250.   begin
  1251.     FAutoScroll := Value;
  1252.     UpdateControlCanvas;
  1253.     if not (Designing or Loading) then
  1254.       FTimer.Enabled := Value;
  1255.   end;
  1256. end;
  1257. procedure TVrMatrixGroup.SetAlignment(Value: TAlignment);
  1258. begin
  1259.   if FAlignment <> Value then
  1260.   begin
  1261.     FAlignment := Value;
  1262.     FormatStrings;
  1263.     if (Designing) or (not FAutoScroll) then
  1264.       UpdateControlCanvas;
  1265.   end;
  1266. end;
  1267. procedure TVrMatrixGroup.SetTextStyle(Value: TVrMatrixTextStyle);
  1268. begin
  1269.   if FTextStyle <> Value then
  1270.   begin
  1271.     FTextStyle := Value;
  1272.     FormatStrings;
  1273.     UpdateControlCanvas;
  1274.   end;
  1275. end;
  1276. procedure TVrMatrixGroup.SetThreaded(Value: Boolean);
  1277. begin
  1278.   if FThreaded <> Value then
  1279.   begin
  1280.     FThreaded := Value;
  1281.     if Value then FTimer.TimerType := ttThread
  1282.     else FTimer.TimerType := ttSystem;
  1283.   end;
  1284. end;
  1285. procedure TVrMatrixGroup.SetTimeInterval(Value: Integer);
  1286. begin
  1287.   FTimer.Interval := Value;
  1288. end;
  1289. function TVrMatrixGroup.GetTimeInterval: Integer;
  1290. begin
  1291.   Result := FTimer.Interval;
  1292. end;
  1293. procedure TVrMatrixGroup.CMColorChanged(var Message: TMessage);
  1294. begin
  1295.   inherited;
  1296.   if FColorChanged then
  1297.   begin
  1298.     CreateLedImage;
  1299.     UpdateControlCanvas;
  1300.   end;
  1301. end;
  1302. end.