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

Delphi控件源码

开发平台:

Delphi

  1. {*****************************************************}
  2. {                                                     }
  3. {     Varian Component Workshop                       }
  4. {                                                     }
  5. {     Varian Software NL (c) 1996-2000                }
  6. {     All Rights Reserved                             }
  7. {                                                     }
  8. {*****************************************************}
  9. unit VrLcd;
  10. {$I VRLIB.INC}
  11. interface
  12. uses
  13.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Dialogs,
  14.   VrConst, VrTypes, VrClasses, VrControls, VrSysUtils, VrThreads;
  15. type
  16.   TVrNumStyle = (ns13x24, ns11x20, ns7x13, ns12x17, ns5x7);
  17.   TVrNumAlignment = (naLeftJustify, naCenter, naRightJustify);
  18.   TVrCustomNum = class(TVrGraphicImageControl)
  19.   private
  20.     FValue: Integer;
  21.     FDigits: Integer;
  22.     FMax: Integer;
  23.     FMin: Integer;
  24.     FSpacing: Integer;
  25.     FStyle: TVrNumStyle;
  26.     FLeadingZero: Boolean;
  27.     FPalette: TVrPalette;
  28.     FAlignment: TVrNumAlignment;
  29.     FZeroBlank: Boolean;
  30.     FAutoSize: Boolean;
  31.     FOnChange: TNotifyEvent;
  32.     Bitmap: TBitmap;
  33.     ImageWidth: Integer;
  34.     ImageHeight: Integer;
  35.     BelowZero: Boolean;
  36.     procedure SetDigits(Value: Integer);
  37.     procedure SetValue(Value: Integer);
  38.     procedure SetSpacing(Value: Integer);
  39.     procedure SetStyle(Value: TVrNumStyle);
  40.     procedure SetLeadingZero(Value: Boolean);
  41.     procedure SetAlignment(Value: TVrNumAlignment);
  42.     procedure SetAutoSize(Value: Boolean);
  43.     procedure SetMin(Value: Integer);
  44.     procedure SetMax(Value: Integer);
  45.     procedure SetZeroBlank(Value: Boolean);
  46.     procedure SetPalette(Value: TVrPalette);
  47.     procedure PaletteModified(Sender: TObject);
  48.   protected
  49.     procedure LoadBitmaps; virtual;
  50.     procedure DrawNum(Num: integer; X,Y: integer);
  51.     procedure ChangeSize(NewWidth, NewHeight: Integer);
  52.     procedure Paint; override;
  53.     procedure Change; dynamic;
  54. {$IFDEF VER110}
  55.     procedure RequestAlign; override;
  56. {$ELSE}
  57.     procedure RequestAlign;
  58. {$ENDIF}
  59.     property Digits: Integer read FDigits write SetDigits default 4;
  60.     property Value: Integer read FValue write SetValue default 0;
  61.     property Spacing: Integer read FSpacing write SetSpacing default 2;
  62.     property Style: TVrNumStyle read FStyle write SetStyle default ns13x24;
  63.     property LeadingZero: Boolean read FLeadingZero write SetLeadingZero default false;
  64.     property Palette: TVrPalette read FPalette write SetPalette;
  65.     property Alignment: TVrNumAlignment read FAlignment write SetAlignment default naCenter;
  66.     property AutoSize: Boolean read FAutoSize write SetAutoSize default false;
  67.     property Max: Integer read FMax write SetMax default 9999;
  68.     property Min: Integer read FMin write SetMin default 0;
  69.     property ZeroBlank: Boolean read FZeroBlank write SetZeroBlank default false;
  70.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  71.   public
  72.     constructor Create(AOwner: TComponent); override;
  73.     destructor Destroy; override;
  74.   end;
  75.   TVrNum = class(TVrCustomNum)
  76.     property Digits;
  77.     property Value;
  78.     property Spacing;
  79.     property Style;
  80.     property LeadingZero;
  81.     property Palette;
  82.     property Alignment;
  83.     property AutoSize;
  84.     property Max;
  85.     property Min;
  86.     property ZeroBlank;
  87.     property Transparent default false;
  88.     property Align;
  89. {$IFDEF VER110}
  90.     property Anchors;
  91.     property Constraints;
  92. {$ENDIF}
  93.     property Color;
  94.     property DragCursor;
  95. {$IFDEF VER110}
  96.     property DragKind;
  97. {$ENDIF}
  98.     property DragMode;
  99.     property Hint;
  100.     property ParentColor;
  101.     property ParentShowHint;
  102.     property PopupMenu;
  103.     property ShowHint;
  104.     property Visible;
  105.     property OnChange;
  106.     property OnClick;
  107. {$IFDEF VER130}
  108.     property OnContextPopup;
  109. {$ENDIF}
  110.     property OnDblClick;
  111.     property OnDragDrop;
  112.     property OnDragOver;
  113. {$IFDEF VER110}
  114.     property OnEndDock;
  115. {$ENDIF}
  116.     property OnEndDrag;
  117.     property OnMouseDown;
  118.     property OnMouseMove;
  119.     property OnMouseUp;
  120. {$IFDEF VER110}
  121.     property OnStartDock;
  122. {$ENDIF}
  123.     property OnStartDrag;
  124.   end;
  125.   TVrClockType = (ctRealTime, ctElapsed, ctCustom);
  126.   TVrTimeZone = (tzPM, tzAM, tzNone);
  127.   TVrClock = class(TVrCustomNum)
  128.   private
  129.     FHours: TVrHoursInt;
  130.     FMinutes: TVrMinutesInt;
  131.     FSeconds: TVrSecondsInt;
  132.     FClockType: TVrClockType;
  133.     FActive: Boolean;
  134.     FShowSeconds: Boolean;
  135.     FBlink: Boolean;
  136.     FBlinkVisible: Boolean;
  137.     FThreaded: Boolean;
  138.     FHours24: Boolean;
  139.     FShowTimeZone: Boolean;
  140.     FHoursInternal: TVrHoursInt;
  141.     FOnHoursChanged: TVrHoursChangeEvent;
  142.     FOnMinutesChanged: TVrMinutesChangeEvent;
  143.     FOnSecondsChanged: TVrSecondsChangeEvent;
  144.     FTimer: TVrTimer;
  145.     ElapsedTime: TDateTime;
  146.     FSeperator: TBitmap;
  147.     FTimeZoneImage: TBitmap;
  148.     procedure SetHours(Value: TVrHoursInt);
  149.     procedure SetMinutes(Value: TVrMinutesInt);
  150.     procedure SetSeconds(Value: TVrSecondsInt);
  151.     procedure SetActive(Value: Boolean);
  152.     procedure SetClockType(Value: TVrClockType);
  153.     procedure SetShowSeconds(Value: Boolean);
  154.     procedure SetBlink(Value: Boolean);
  155.     procedure SetShowTimeZone(Value: Boolean);
  156.     procedure SetThreaded(Value: Boolean);
  157.     procedure OnTimerEvent(Sender: TObject);
  158.   protected
  159.     procedure LoadBitmaps; override;
  160.     procedure Paint; override;
  161.     procedure DrawTimeZone(Hrs: Integer; X, Y: integer);
  162.     procedure Loaded; override;
  163.     procedure HoursChanged; virtual;
  164.     procedure MinutesChanged; virtual;
  165.     procedure SecondsChanged; virtual;
  166.   public
  167.     constructor Create(AOwner: TComponent); override;
  168.     destructor Destroy; override;
  169.   published
  170.     property Threaded: Boolean read FThreaded write SetThreaded default True;
  171.     property Hours: TVrHoursInt read FHours write SetHours default 0;
  172.     property Minutes: TVrMinutesInt read FMinutes write SetMinutes default 0;
  173.     property Seconds: TVrSecondsInt read FSeconds write SetSeconds default 0;
  174.     property ClockType: TVrClockType read FClockType write SetClockType default ctRealTime;
  175.     property Active: Boolean read FActive write SetActive default false;
  176.     property ShowSeconds: Boolean read FShowSeconds write SetShowSeconds default false;
  177.     property Blink: Boolean read FBlink write SetBlink default false;
  178.     property Hours24: Boolean read FHours24 write FHours24 default True;
  179.     property ShowTimeZone: Boolean read FShowTimeZone write SetShowTimeZone default false;
  180.     property Transparent default false;
  181.     property OnHoursChanged: TVrHoursChangeEvent read FOnHoursChanged write FOnHoursChanged;
  182.     property OnMinutesChanged: TVrMinutesChangeEvent read FOnMinutesChanged write FOnMinutesChanged;
  183.     property OnSecondsChanged: TVrSecondsChangeEvent read FOnSecondsChanged write FOnSecondsChanged;
  184.     property Palette;
  185.     property Spacing;
  186.     property Style;
  187.     property AutoSize;
  188.     property Align;
  189. {$IFDEF VER110}
  190.     property Anchors;
  191.     property Constraints;
  192. {$ENDIF}
  193.     property Color;
  194.     property DragCursor;
  195. {$IFDEF VER110}
  196.     property DragKind;
  197. {$ENDIF}
  198.     property DragMode;
  199.     property Hint;
  200.     property ParentColor;
  201.     property ParentShowHint;
  202.     property PopupMenu;
  203.     property ShowHint;
  204.     property Visible;
  205.     property OnClick;
  206. {$IFDEF VER130}
  207.     property OnContextPopup;
  208. {$ENDIF}    
  209.     property OnDblClick;
  210.     property OnDragDrop;
  211.     property OnDragOver;
  212. {$IFDEF VER110}
  213.     property OnEndDock;
  214. {$ENDIF}
  215.     property OnEndDrag;
  216.     property OnMouseDown;
  217.     property OnMouseMove;
  218.     property OnMouseUp;
  219. {$IFDEF VER110}
  220.     property OnStartDock;
  221. {$ENDIF}
  222.     property OnStartDrag;
  223.   end;
  224. implementation
  225. {$R VRLCD.D32}
  226. const
  227.   ResNumId: array[TVrNumStyle] of PChar =
  228.     ('NUM13x24', 'NUM11x20', 'NUM7x13', 'NUM12x17', 'NUM5x7');
  229.   ResClockId: array[TVrNumStyle] of PChar =
  230.     ('CLOCKSEP1', 'CLOCKSEP2', 'CLOCKSEP3', 'CLOCKSEP4', 'CLOCKSEP5');
  231.   ResTimeZoneId: array[TVrNumStyle] of PChar =
  232.     ('AMPM13x24', 'AMPM11x20', 'AMPM7x13', 'AMPM12x17', 'AMPM5x7');
  233. {TVrCustomNum}
  234. constructor TVrCustomNum.Create(AOwner: TComponent);
  235. begin
  236.   inherited Create(AOwner);
  237.   ControlStyle := ControlStyle + [csOpaque, csReplicatable];
  238.   Width := 100;
  239.   Height := 26;
  240.   ParentColor := false;
  241.   Color := clBlack;
  242.   FDigits := 4;
  243.   FValue := 0;
  244.   FSpacing := 2;
  245.   FLeadingZero := false;
  246.   FPalette := TVrPalette.Create;
  247.   FPalette.OnChange := PaletteModified;
  248.   FStyle := ns13x24;
  249.   FAlignment := naCenter;
  250.   FAutoSize := false;
  251.   FMin := 0;
  252.   FMax := 9999;
  253.   FZeroBlank := false;
  254.   BelowZero := false;
  255.   Bitmap := TBitmap.Create;
  256.   LoadBitmaps;
  257. end;
  258. destructor TVrCustomNum.Destroy;
  259. begin
  260.   FPalette.Free;
  261.   Bitmap.Free;
  262.   inherited Destroy;
  263. end;
  264. procedure TVrCustomNum.LoadBitmaps;
  265. begin
  266.   Bitmap.Handle := LoadBitmap(hInstance, ResNumId[Style]);
  267.   FPalette.ToBMP(Bitmap, ResColorLow, ResColorHigh);
  268.   ImageWidth := Bitmap.Width div 13;
  269.   ImageHeight := Bitmap.Height;
  270. end;
  271. procedure TVrCustomNum.PaletteModified(Sender: TObject);
  272. begin
  273.   LoadBitmaps;
  274.   UpdateControlCanvas;
  275. end;
  276. procedure TVrCustomNum.SetDigits(Value: Integer);
  277. begin
  278.   if (FDigits <> Value) and (Value > 0) and (Value < 16) then
  279.   begin
  280.     FDigits := Value;
  281.     UpdateControlCanvas;
  282.   end;
  283. end;
  284. procedure TVrCustomNum.SetValue(Value: Integer);
  285. begin
  286.   AdjustRange(Value, FMin, FMax);
  287.   if FValue <> Value then
  288.   begin
  289.     FValue := Value;
  290.     UpdateControlCanvas;
  291.     Change;
  292.   end;
  293. end;
  294. procedure TVrCustomNum.SetMin(Value: Integer);
  295. begin
  296.   if (FMin <> Value) and (Value < FMax) then
  297.   begin
  298.     FMin := Value;
  299.     BelowZero := FMin < 0;
  300.     UpdateControlCanvas;
  301.   end;
  302. end;
  303. procedure TVrCustomNum.SetMax(Value: Integer);
  304. begin
  305.   if (FMax <> Value) and (Value > FMin) then
  306.   begin
  307.     FMax := Value;
  308.     UpdateControlCanvas;
  309.   end;
  310. end;
  311. procedure TVrCustomNum.SetSpacing(Value: Integer);
  312. begin
  313.   if FSpacing <> Value then
  314.   begin
  315.     FSpacing := Value;
  316.     UpdateControlCanvas;
  317.   end;
  318. end;
  319. procedure TVrCustomNum.SetStyle(Value: TVrNumStyle);
  320. begin
  321.   if FStyle <> Value then
  322.   begin
  323.     FStyle := Value;
  324.     LoadBitmaps;
  325.     UpdateControlCanvas;
  326.   end;
  327. end;
  328. procedure TVrCustomNum.SetLeadingZero(Value: Boolean);
  329. begin
  330.   if FLeadingZero <> Value then
  331.   begin
  332.     FLeadingZero := Value;
  333.     UpdateControlCanvas;
  334.   end;
  335. end;
  336. procedure TVrCustomNum.SetAlignment(Value: TVrNumAlignment);
  337. begin
  338.   if FAlignment <> Value then
  339.   begin
  340.     FAlignment := Value;
  341.     UpdateControlCanvas;
  342.   end;
  343. end;
  344. procedure TVrCustomNum.SetAutoSize(Value: Boolean);
  345. begin
  346.   if (FAutoSize <> Value) then
  347.   begin
  348.     FAutoSize := Value;
  349.     UpdateControlCanvas;
  350.   end;
  351. end;
  352. procedure TVrCustomNum.SetZeroBlank(Value: Boolean);
  353. begin
  354.   if FZeroBlank <> Value then
  355.   begin
  356.     FZeroBlank := Value;
  357.     UpdateControlCanvas;
  358.   end;
  359. end;
  360. procedure TVrCustomNum.SetPalette(Value: TVrPalette);
  361. begin
  362.   FPalette.Assign(Value);
  363. end;
  364. procedure TVrCustomNum.Change;
  365. begin
  366.   if Assigned(FOnChange) then FOnChange(self);
  367. end;
  368. procedure TVrCustomNum.RequestAlign;
  369. begin
  370.   inherited;
  371.   if Align = alNone then UpdateControlCanvas;
  372. end;
  373. procedure TVrCustomNum.ChangeSize(NewWidth, NewHeight: Integer);
  374. begin
  375.   if (Align = alNone) then
  376.     if (NewWidth <> Width) or (NewHeight <> Height) then
  377.     begin
  378.       Self.Width := NewWidth;
  379.       Self.Height := NewHeight;
  380.     end;
  381. end;
  382. procedure TVrCustomNum.DrawNum(Num: integer; X, Y: integer);
  383. var
  384.   R, D: TRect;
  385. begin
  386.   with BitmapCanvas do
  387.   begin
  388.     D := Bounds(X, Y, ImageWidth, ImageHeight);
  389.     R := Bounds(Num * ImageWidth, 0, ImageWidth, ImageHeight);
  390.     Brush.Style := bsClear;
  391.     BrushCopy(D, Bitmap, R, clBlack);
  392.   end;
  393. end;
  394. procedure TVrCustomNum.Paint;
  395. var
  396.   I, X, Y, W: Integer;
  397.   S: string;
  398.   Num, Chars: Integer;
  399.   function PadLeft(str: string; Ch: Char; MaxWidth: Integer): string;
  400.   begin
  401.     while Length(str) < MaxWidth do
  402.       str := Ch + str;
  403.     Result := str;
  404.   end;
  405. begin
  406.   ClearBitmapCanvas;
  407.   Num := FValue;
  408.   if Num < 0 then Num := -Num;
  409.   Chars := FDigits;
  410.   S := Format('%d', [Num]);
  411.   if (FValue = 0) and (FZeroBlank) then S := '';
  412.   if FLeadingZero then S := PadLeft(S, '0', Chars)
  413.   else S := PadLeft(S, #32, Chars);
  414.   if (BelowZero) then Inc(Chars);
  415.   W := (Chars * ImageWidth) + (Pred(Chars) * FSpacing);
  416.   if FAutoSize then
  417.     ChangeSize(W, ImageHeight);
  418.   case FAlignment of
  419.     naLeftJustify: X := 0;
  420.     naRightJustify: X := ClientWidth - W;
  421.     else X := (ClientWidth - W) div 2;
  422.   end;
  423.   Y := (Self.Height - ImageHeight) div 2;
  424.   if BelowZero then
  425.   begin
  426.     if (FValue >= 0) then
  427.       DrawNum(11, X, Y) else DrawNum(12, X, Y);
  428.     Inc(X, ImageWidth + FSpacing);
  429.   end;
  430.   for I := 1 to Length(S) do
  431.   begin
  432.     if (S[I] = #32) then DrawNum(10, X, Y)
  433.     else DrawNum(StrToInt(S[I]), X, Y);
  434.     Inc(X, ImageWidth + FSpacing);
  435.   end;
  436.   inherited Paint;
  437. end;
  438. {TVrClock}
  439. constructor TVrClock.Create(AOwner: TCOmponent);
  440. begin
  441.   inherited Create(AOwner);
  442.   Width := 140;
  443.   FHours := 0;
  444.   FMinutes := 0;
  445.   FSeconds := 0;
  446.   FShowSeconds := false;
  447.   FBlink := false;
  448.   FHours24 := True;
  449.   FShowTimeZone := false;
  450.   FThreaded := True;
  451.   FTimer := TVrTimer.Create(Self);
  452.   FTimer.Enabled := false;
  453.   FTimer.OnTimer := OnTimerEvent;
  454. end;
  455. destructor TVrClock.Destroy;
  456. begin
  457.   FTimer.Free;
  458.   FSeperator.Free;
  459.   FTimeZoneImage.Free;
  460.   inherited Destroy;
  461. end;
  462. procedure TVrClock.Loaded;
  463. begin
  464.   inherited Loaded;
  465.   if (FClockType = ctRealTime) and (not Designing) then
  466.     OnTimerEvent(Self);
  467. end;
  468. procedure TVrClock.LoadBitmaps;
  469. begin
  470.   inherited LoadBitmaps;
  471.   if not Assigned(FSeperator) then
  472.   begin
  473.     FSeperator := TBitmap.Create;
  474.     FSeperator.Transparent := True;
  475.   end;
  476.   if not Assigned(FTimeZoneImage) then
  477.     FTimeZoneImage := TBitmap.Create;
  478.   FSeperator.Handle := LoadBitmap(hInstance, ResClockId[Style]);
  479.   FPalette.ToBMP(FSeperator, ResColorLow, ResColorHigh);
  480.   FTimeZoneImage.Handle := LoadBitmap(hInstance, ResTimeZoneId[Style]);
  481.   FPalette.ToBMP(FTimeZoneImage, ResColorLow, ResColorHigh);
  482. end;
  483. procedure TVrClock.HoursChanged;
  484. begin
  485.   if Assigned(FOnHoursChanged) then
  486.     FOnHoursChanged(Self, FHours);
  487. end;
  488. procedure TVrClock.MinutesChanged;
  489. begin
  490.   if Assigned(FOnMinutesChanged) then
  491.     FOnMinutesChanged(Self, FMinutes);
  492. end;
  493. procedure TVrClock.SecondsChanged;
  494. begin
  495.   if Assigned(FOnSecondsChanged) then
  496.     FOnSecondsChanged(Self, FSeconds);
  497. end;
  498. procedure TVrClock.SetHours(Value: TVrHoursInt);
  499. begin
  500.   if FHours <> Value then
  501.   begin
  502.     FHours := Value;
  503.     UpdateControlCanvas;
  504.     HoursChanged;
  505.   end;
  506. end;
  507. procedure TVrClock.SetMinutes(Value: TVrMinutesInt);
  508. begin
  509.   if FMinutes <> Value then
  510.   begin
  511.     FMinutes := Value;
  512.     UpdateControlCanvas;
  513.     MinutesChanged;
  514.   end;
  515. end;
  516. procedure TVrClock.SetSeconds(Value: TVrSecondsInt);
  517. begin
  518.   if FSeconds <> Value then
  519.   begin
  520.     FSeconds := Value;
  521.     UpdateControlCanvas;
  522.     SecondsChanged;
  523.   end;
  524. end;
  525. procedure TVrClock.SetActive(Value: Boolean);
  526. begin
  527.   if (Value) and (FClockType = ctCustom) then
  528.     Value := false;
  529.   if (FActive <> Value) then
  530.   begin
  531.     FActive := Value;
  532.     FBlinkVisible := True;
  533.     UpdateControlCanvas;
  534.     if Designing then Exit;
  535.     if FActive then ElapsedTime := Now;
  536.     FTimer.Enabled := FActive;
  537.   end;
  538. end;
  539. procedure TVrClock.SetClockType(Value: TVrClockType);
  540. begin
  541.   if (FClockType <> Value) then
  542.   begin
  543.     FClockType := Value;
  544.     if FClockType <> ctCustom then
  545.     begin
  546.       FHours := 0;
  547.       FMinutes := 0;
  548.       FSeconds := 0;
  549.     end
  550.    else
  551.     if Active then Active := false;
  552.     UpdateControlCanvas;
  553.   end;
  554. end;
  555. procedure TVrClock.SetShowSeconds(Value: Boolean);
  556. begin
  557.   if FShowSeconds <> Value then
  558.   begin
  559.     FShowSeconds := Value;
  560.     UpdateControlCanvas;
  561.   end;
  562. end;
  563. procedure TVrClock.SetBlink(Value: Boolean);
  564. begin
  565.   if FBlink <> Value then
  566.   begin
  567.     FBlink := Value;
  568.     FBlinkVisible := True;
  569.     UpdateControlCanvas;
  570.   end;
  571. end;
  572. procedure TVrClock.SetShowTimeZone(Value: Boolean);
  573. begin
  574.   if FShowTimeZone <> Value then
  575.   begin
  576.     FShowTimeZone := Value;
  577.     UpdateControlCanvas;
  578.   end;
  579. end;
  580. procedure TVrClock.SetThreaded(Value: Boolean);
  581. begin
  582.   if FThreaded <> Value then
  583.   begin
  584.     FThreaded := Value;
  585.     if Value then FTimer.TimerType := ttThread
  586.     else FTimer.TimerType := ttSystem;
  587.   end;
  588. end;
  589. procedure TVrClock.DrawTimeZone(Hrs: Integer; X, Y: integer);
  590. var
  591.   R, D: TRect;
  592.   W, H, Index: Integer;
  593. begin
  594.   with BitmapCanvas do
  595.   begin
  596.     Index := 0;
  597.     if Hrs < 12 then Index := 1;
  598.     W := FTimeZoneImage.Width div 2;
  599.     H := FTimeZoneImage.Height;
  600.     D := Bounds(X, Y, W, H);
  601.     R := Bounds(Index * W, 0, W, H);
  602.     Brush.Style := bsClear;
  603.     BrushCopy(D, FTimeZoneImage, R, clBlack);
  604.   end;
  605. end;
  606. procedure TVrClock.OnTimerEvent(Sender: TObject);
  607. var
  608.   H, M, S, S100: Word;
  609.   Ho, Mo, So: Word;
  610.   T: TDateTime;
  611.   SecsChanged: Boolean;
  612. begin
  613.   //store old values
  614.   Ho := FHours;
  615.   Mo := FMinutes;
  616.   So := FSeconds;
  617.   case FClockType of
  618.     ctRealTime: T := Now;
  619.     ctElapsed: T := Now - ElapsedTime;
  620.     else
  621.       T := 0; //This should never occure
  622.   end;
  623.   DecodeTime(T, H, M, S, S100);
  624.   FHoursInternal := H;
  625.   FHours := H;
  626.   if not FHours24 then
  627.   begin
  628.     FHours := FHours mod 12;
  629.     if FHours = 0 then FHours := 12;
  630.   end;
  631.   FMinutes := M;
  632.   FSeconds := S;
  633.   FBlinkVisible := not FBlinkVisible;
  634.   SecsChanged := (FShowSeconds) and (So <> FSeconds);
  635.   if (SecsChanged) or (FBlink) or (FMinutes <> Mo) then
  636.     UpdateControlCanvas;
  637.   if (FHours <> Ho) then HoursChanged;
  638.   if (FMinutes <> Mo) then MinutesChanged;
  639.   if (FSeconds <> So) then SecondsChanged;
  640. end;
  641. procedure TVrClock.Paint;
  642. var
  643.   I, X, Y, W: Integer;
  644.   NumDigits: Integer;
  645.   NumSpacing: Integer;
  646.   S: string;
  647. begin
  648.   ClearBitmapCanvas;
  649.   NumDigits := 4;
  650.   NumSpacing := 4;
  651.   if FShowSeconds then
  652.   begin
  653.     Inc(NumDigits, 2);
  654.     Inc(NumSpacing, 3);
  655.   end;
  656.   W := (NumDigits * ImageWidth);
  657.   W := W + (FSeperator.Width * (ord(FShowSeconds) + 1));
  658.   W := W + (NumSpacing * FSpacing);
  659.   if (ShowTimeZone) and (ClockType = ctRealTime) then
  660.     Inc(W, FSpacing + FTimeZoneImage.Width div 2);
  661.   if FAutoSize then
  662.     ChangeSize(W, ImageHeight);
  663.   X := (Width - W) div 2;
  664.   Y := (Self.Height - ImageHeight) div 2;
  665.   S := Format('%.2d:%.2d', [FHours, FMinutes]);
  666.   if FShowSeconds then
  667.     S := S + Format(':%.2d', [FSeconds]);
  668.   for I := 1 to Length(S) do
  669.   begin
  670.     if (S[I] = ':') then
  671.     begin
  672.       if (FClockType = ctCustom) or
  673.          (not FBlink) or (FBlink and FBlinkVisible) then
  674.         BitmapCanvas.Draw(X, Y, FSeperator);
  675.       Inc(X, FSeperator.Width + FSpacing);
  676.     end
  677.    else
  678.     begin
  679.       DrawNum(StrToInt(S[I]), X, Y);
  680.       Inc(X, ImageWidth + FSpacing);
  681.     end;
  682.   end;
  683.   if (ShowTimeZone) and (ClockType = ctRealTime) then
  684.     DrawTimeZone(FHoursInternal, X, Y);
  685.   with inherited Canvas do
  686.     Draw(0, 0, BitmapImage);
  687. end;
  688. end.