git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.jvcl@19 7f62d464-2af8-f54e-996c-e91b33f51cbe
1253 lines
35 KiB
ObjectPascal
1253 lines
35 KiB
ObjectPascal
{-----------------------------------------------------------------------------
|
|
The contents of this file are subject to the Mozilla Public License
|
|
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
|
the specific language governing rights and limitations under the License.
|
|
|
|
The Original Code is: JvClock.PAS, released on 2002-07-04.
|
|
|
|
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 2001,2002 SGB Software
|
|
All Rights Reserved.
|
|
|
|
Contributor(s):
|
|
Polaris Software
|
|
|
|
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
|
located at http://jvcl.delphi-jedi.org
|
|
|
|
Known Issues:
|
|
-----------------------------------------------------------------------------}
|
|
// $Id: JvClock.pas 12461 2009-08-14 17:21:33Z obones $
|
|
|
|
unit JvClock;
|
|
|
|
{$I jvcl.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF UNITVERSIONING}
|
|
JclUnitVersioning,
|
|
{$ENDIF UNITVERSIONING}
|
|
Windows, Messages, Classes, Graphics, Controls,
|
|
JvJCLUtils, JvTimer, JvExtComponent, JvExControls;
|
|
|
|
type
|
|
TShowClock = (scDigital, scAnalog);
|
|
TPaintMode = (pmPaintAll, pmHandPaint);
|
|
|
|
TJvClockTime = packed record
|
|
Hour: Word;
|
|
Minute: Word;
|
|
Second: Word;
|
|
end;
|
|
|
|
TJvGetTimeEvent = procedure(Sender: TObject; var ATime: TDateTime) of object;
|
|
TJvGetDateEvent = TJvGetTimeEvent;
|
|
|
|
TJvClock = class(TJvCustomPanel, IJvDenySubClassing)
|
|
private
|
|
FTimer: TJvTimer;
|
|
FAutoSize: Boolean;
|
|
FShowMode: TShowClock;
|
|
FTwelveHour: Boolean;
|
|
FLeadingZero: Boolean;
|
|
FShowSeconds: Boolean;
|
|
FAlarm: TDateTime;
|
|
FAlarmEnabled: Boolean;
|
|
FHooked: Boolean;
|
|
FDotsColor: TColor;
|
|
FAlarmWait: Boolean;
|
|
FDisplayTime: TJvClockTime;
|
|
FClockRect: TRect;
|
|
FClockRadius: Longint;
|
|
FClockCenter: TPoint;
|
|
FOnGetTime: TJvGetTimeEvent;
|
|
FOnAlarm: TNotifyEvent;
|
|
FShowDate: Boolean;
|
|
FOnGetDate: TJvGetDateEvent;
|
|
FDateFormat: string;
|
|
FFixedTime: TDateTime;
|
|
FFixedTimeStored: Boolean;
|
|
FSecondsHandColor: TColor;
|
|
FMinutesHandColor: TColor;
|
|
FHoursHandColor: TColor;
|
|
procedure TimerExpired(Sender: TObject);
|
|
procedure GetTime(var T: TJvClockTime);
|
|
function IsAlarmTime(ATime: TDateTime): Boolean;
|
|
procedure SetShowMode(Value: TShowClock);
|
|
function GetAlarmElement(Index: Integer): Byte;
|
|
procedure SetAlarmElement(Index: Integer; Value: Byte);
|
|
procedure SetDotsColor(Value: TColor);
|
|
procedure SetTwelveHour(Value: Boolean);
|
|
procedure SetLeadingZero(Value: Boolean);
|
|
procedure SetShowSeconds(Value: Boolean);
|
|
procedure PaintAnalogClock(PaintMode: TPaintMode);
|
|
procedure Paint3DFrame(var Rect: TRect);
|
|
procedure DrawAnalogFace;
|
|
procedure CircleClock(MaxWidth, MaxHeight: Integer);
|
|
procedure DrawSecondHand(Pos: Integer);
|
|
procedure DrawFatHand(Pos: Integer; HourHand: Boolean);
|
|
procedure PaintTimeStr(var Rect: TRect; FullTime: Boolean);
|
|
procedure ResizeFont(const Rect: TRect);
|
|
procedure ResetAlarm;
|
|
procedure CheckAlarm;
|
|
procedure SetFixedTime(const Value: TDateTime);
|
|
function FormatSettingsChange(var Msg: TMessage): Boolean;
|
|
procedure CMCtl3DChanged(var Msg: TMessage); message CM_CTL3DCHANGED;
|
|
procedure WMTimeChange(var Msg: TMessage); message WM_TIMECHANGE;
|
|
procedure SetShowDate(const Value: Boolean);
|
|
procedure SetDateFormat(const Value: string);
|
|
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
|
|
procedure SetHoursHandColor(const Value: TColor);
|
|
procedure SetMinutesHandColor(const Value: TColor);
|
|
procedure SetSecondsHandColor(const Value: TColor);
|
|
protected
|
|
procedure TextChanged; override;
|
|
procedure FontChanged; override;
|
|
procedure SetAutoSize(Value: Boolean); override;
|
|
procedure Alarm; dynamic;
|
|
procedure AlignControls(AControl: TControl; var Rect: TRect); override;
|
|
procedure CreateWnd; override;
|
|
procedure DestroyWindowHandle; override;
|
|
procedure Loaded; override;
|
|
procedure Paint; override;
|
|
function GetSystemTime: TDateTime; virtual;
|
|
function GetSystemDate: TDateTime; virtual;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure SetAlarmTime(AlarmTime: TDateTime);
|
|
procedure UpdateClock;
|
|
published
|
|
property AlarmEnabled: Boolean read FAlarmEnabled write FAlarmEnabled default False;
|
|
property AlarmHour: Byte index 1 read GetAlarmElement write SetAlarmElement default 0;
|
|
property AlarmMinute: Byte index 2 read GetAlarmElement write SetAlarmElement default 0;
|
|
property AlarmSecond: Byte index 3 read GetAlarmElement write SetAlarmElement default 0;
|
|
property AutoSize: Boolean read FAutoSize write SetAutoSize default False;
|
|
property BevelInner default bvLowered;
|
|
property BevelOuter default bvRaised;
|
|
property DotsColor: TColor read FDotsColor write SetDotsColor default clTeal;
|
|
property DateFormat: string read FDateFormat write SetDateFormat;
|
|
property FixedTime: TDateTime read FFixedTime write SetFixedTime stored FFixedTimeStored;
|
|
property HoursHandColor: TColor read FHoursHandColor write SetHoursHandColor default clBlack;
|
|
property MinutesHandColor: TColor read FMinutesHandColor write SetMinutesHandColor default clBlack;
|
|
property SecondsHandColor: TColor read FSecondsHandColor write SetSecondsHandColor default clBlack;
|
|
property ShowMode: TShowClock read FShowMode write SetShowMode default scDigital;
|
|
property ShowSeconds: Boolean read FShowSeconds write SetShowSeconds default True;
|
|
property ShowDate: Boolean read FShowDate write SetShowDate default False;
|
|
property TwelveHour: Boolean read FTwelveHour write SetTwelveHour default False;
|
|
property LeadingZero: Boolean read FLeadingZero write SetLeadingZero default True;
|
|
property Align;
|
|
property BevelWidth;
|
|
property BorderWidth;
|
|
property BorderStyle;
|
|
property Anchors;
|
|
property Constraints;
|
|
property UseDockManager default True;
|
|
property DockSite;
|
|
property DragKind;
|
|
property DragCursor;
|
|
property FullRepaint;
|
|
property Color;
|
|
property Cursor;
|
|
property DragMode;
|
|
property Enabled;
|
|
property Font;
|
|
property ParentColor;
|
|
property ParentFont;
|
|
property ParentShowHint;
|
|
property PopupMenu;
|
|
property ShowHint;
|
|
property Visible;
|
|
property OnAlarm: TNotifyEvent read FOnAlarm write FOnAlarm;
|
|
property OnGetTime: TJvGetTimeEvent read FOnGetTime write FOnGetTime;
|
|
property OnGetDate: TJvGetDateEvent read FOnGetDate write FOnGetDate;
|
|
property OnClick;
|
|
property OnDblClick;
|
|
property OnMouseMove;
|
|
property OnMouseDown;
|
|
property OnMouseUp;
|
|
property OnDragOver;
|
|
property OnDragDrop;
|
|
property OnEndDrag;
|
|
property OnResize;
|
|
property OnContextPopup;
|
|
property OnStartDrag;
|
|
property OnConstrainedResize;
|
|
property OnCanResize;
|
|
property OnDockDrop;
|
|
property OnDockOver;
|
|
property OnEndDock;
|
|
property OnGetSiteInfo;
|
|
property OnStartDock;
|
|
property OnUnDock;
|
|
end;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
const
|
|
UnitVersioning: TUnitVersionInfo = (
|
|
RCSfile: '$URL: https://jvcl.svn.sourceforge.net/svnroot/jvcl/tags/JVCL3_39/run/JvClock.pas $';
|
|
Revision: '$Revision: 12461 $';
|
|
Date: '$Date: 2009-08-14 19:21:33 +0200 (ven., 14 août 2009) $';
|
|
LogPath: 'JVCL\run'
|
|
);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
implementation
|
|
|
|
uses
|
|
RTLConsts,
|
|
{$IFDEF COMPILER7_UP}
|
|
SysConst,
|
|
{$ENDIF COMPILER7_UP}
|
|
SysUtils, Forms, ExtCtrls, Consts,
|
|
JvThemes;
|
|
|
|
var
|
|
Registered: Boolean = False;
|
|
|
|
type
|
|
PPointArray = ^TPointArray;
|
|
TPointArray = array [0..60 * 2 - 1] of TSmallPoint;
|
|
|
|
const
|
|
ClockData: array [0..60 * 4 - 1] of Byte = (
|
|
$00, $00, $C1, $E0, $44, $03, $EC, $E0, $7F, $06, $6F, $E1,
|
|
$A8, $09, $48, $E2, $B5, $0C, $74, $E3, $9F, $0F, $F0, $E4,
|
|
$5E, $12, $B8, $E6, $E9, $14, $C7, $E8, $39, $17, $17, $EB,
|
|
$48, $19, $A2, $ED, $10, $1B, $60, $F0, $8C, $1C, $4B, $F3,
|
|
$B8, $1D, $58, $F6, $91, $1E, $81, $F9, $14, $1F, $BC, $FC,
|
|
$40, $1F, $00, $00, $14, $1F, $44, $03, $91, $1E, $7F, $06,
|
|
$B8, $1D, $A8, $09, $8C, $1C, $B5, $0C, $10, $1B, $A0, $0F,
|
|
$48, $19, $5E, $12, $39, $17, $E9, $14, $E9, $14, $39, $17,
|
|
$5E, $12, $48, $19, $9F, $0F, $10, $1B, $B5, $0C, $8C, $1C,
|
|
$A8, $09, $B8, $1D, $7F, $06, $91, $1E, $44, $03, $14, $1F,
|
|
$00, $00, $3F, $1F, $BC, $FC, $14, $1F, $81, $F9, $91, $1E,
|
|
$58, $F6, $B8, $1D, $4B, $F3, $8C, $1C, $60, $F0, $10, $1B,
|
|
$A2, $ED, $48, $19, $17, $EB, $39, $17, $C7, $E8, $E9, $14,
|
|
$B8, $E6, $5E, $12, $F0, $E4, $9F, $0F, $74, $E3, $B5, $0C,
|
|
$48, $E2, $A8, $09, $6F, $E1, $7F, $06, $EC, $E0, $44, $03,
|
|
$C1, $E0, $00, $00, $EC, $E0, $BC, $FC, $6F, $E1, $81, $F9,
|
|
$48, $E2, $58, $F6, $74, $E3, $4B, $F3, $F0, $E4, $60, $F0,
|
|
$B8, $E6, $A2, $ED, $C7, $E8, $17, $EB, $17, $EB, $C7, $E8,
|
|
$A2, $ED, $B8, $E6, $61, $F0, $F0, $E4, $4B, $F3, $74, $E3,
|
|
$58, $F6, $48, $E2, $81, $F9, $6F, $E1, $BC, $FC, $EC, $E0);
|
|
|
|
const
|
|
AlarmSecDelay = 60; { seconds for try alarm event after alarm time occured }
|
|
MaxDotWidth = 25; { maximum Hour-marking dot width }
|
|
MinDotWidth = 2; { minimum Hour-marking dot width }
|
|
MinDotHeight = 1; { minimum Hour-marking dot height }
|
|
|
|
{ distance from the center of the clock to... }
|
|
HourSide = 7; { ...either side of the Hour hand }
|
|
MinuteSide = 5; { ...either side of the Minute hand }
|
|
HourTip = 60; { ...the tip of the Hour hand }
|
|
MinuteTip = 80; { ...the tip of the Minute hand }
|
|
SecondTip = 80; { ...the tip of the Second hand }
|
|
HourTail = 15; { ...the tail of the Hour hand }
|
|
MinuteTail = 20; { ...the tail of the Minute hand }
|
|
|
|
{ conversion factors }
|
|
CirTabScale = 8000; { circle table values scale down value }
|
|
MmPerDm = 100; { millimeters per decimeter }
|
|
|
|
{ number of hand positions on... }
|
|
HandPositions = 60; { ...entire clock }
|
|
SideShift = (HandPositions div 4); { ...90 degrees of clock }
|
|
TailShift = (HandPositions div 2); { ...180 degrees of clock }
|
|
|
|
var
|
|
CircleTab: PPointArray;
|
|
HRes: Integer; { width of the display (in pixels) }
|
|
VRes: Integer; { height of the display (in raster lines) }
|
|
AspectH: Longint; { number of pixels per decimeter on the display }
|
|
AspectV: Longint; { number of raster lines per decimeter on the display }
|
|
|
|
{ Exception routine }
|
|
|
|
procedure InvalidTime(Hour, Min, Sec: Word);
|
|
var
|
|
sTime: string;
|
|
begin
|
|
sTime := IntToStr(Hour) + TimeSeparator + IntToStr(Min) +
|
|
TimeSeparator + IntToStr(Sec);
|
|
raise EConvertError.CreateResFmt(@SInvalidTime, [sTime]);
|
|
end;
|
|
|
|
function VertEquiv(L: Integer): Integer;
|
|
begin
|
|
VertEquiv := Longint(L) * AspectV div AspectH;
|
|
end;
|
|
|
|
function HorzEquiv(L: Integer): Integer;
|
|
begin
|
|
HorzEquiv := Longint(L) * AspectH div AspectV;
|
|
end;
|
|
|
|
function LightColor(Color: TColor): TColor;
|
|
var
|
|
L: Longint;
|
|
C: array [1..3] of Byte;
|
|
I: Byte;
|
|
begin
|
|
L := ColorToRGB(Color);
|
|
C[1] := GetRValue(L);
|
|
C[2] := GetGValue(L);
|
|
C[3] := GetBValue(L);
|
|
for I := 1 to 3 do
|
|
begin
|
|
if C[I] = $FF then
|
|
begin
|
|
Result := clBtnHighlight;
|
|
Exit;
|
|
end;
|
|
if C[I] <> 0 then
|
|
if C[I] = $C0 then
|
|
C[I] := $FF
|
|
else
|
|
C[I] := C[I] + $7F;
|
|
end;
|
|
Result := TColor(RGB(C[1], C[2], C[3]));
|
|
end;
|
|
|
|
procedure ClockInit;
|
|
var
|
|
Pos: Integer; { hand position Index into the circle table }
|
|
vSize: Integer; { height of the display in millimeters }
|
|
hSize: Integer; { width of the display in millimeters }
|
|
DC: HDC;
|
|
begin
|
|
DC := GetDC(HWND_DESKTOP);
|
|
try
|
|
VRes := GetDeviceCaps(DC, VERTRES);
|
|
HRes := GetDeviceCaps(DC, HORZRES);
|
|
vSize := GetDeviceCaps(DC, VERTSIZE);
|
|
hSize := GetDeviceCaps(DC, HORZSIZE);
|
|
finally
|
|
ReleaseDC(HWND_DESKTOP, DC);
|
|
end;
|
|
AspectV := (Longint(VRes) * MmPerDm) div Longint(vSize);
|
|
AspectH := (Longint(HRes) * MmPerDm) div Longint(hSize);
|
|
CircleTab := PPointArray(@ClockData);
|
|
for Pos := 0 to HandPositions - 1 do
|
|
CircleTab[Pos].Y := VertEquiv(CircleTab[Pos].Y);
|
|
end;
|
|
|
|
function HourHandPos(T: TJvClockTime): Integer;
|
|
begin
|
|
// When drawing the hour hand, only 12 hours are shown, hence the need
|
|
// to adjust the time if it goes above, or the hand would not be drawn
|
|
// correctly.
|
|
if T.Hour >= 12 then
|
|
Dec(T.Hour, 12);
|
|
|
|
Result := (T.Hour * 5) + (T.Minute div 12);
|
|
end;
|
|
|
|
{ Digital clock font routine }
|
|
|
|
procedure SetNewFontSize(Canvas: TCanvas; const Text: string;
|
|
MaxH, MaxW: Integer);
|
|
const
|
|
FHeight = 1000;
|
|
var
|
|
Font: TFont;
|
|
NewH: Integer;
|
|
begin
|
|
Font := Canvas.Font;
|
|
{ empiric calculate character height by cell height }
|
|
MaxH := MulDiv(MaxH, 4, 5);
|
|
with Font do
|
|
begin
|
|
Height := -FHeight;
|
|
NewH := MulDiv(FHeight, MaxW, Canvas.TextWidth(Text));
|
|
if NewH > MaxH then
|
|
NewH := MaxH;
|
|
Height := -NewH;
|
|
end;
|
|
end;
|
|
|
|
constructor TJvClock.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
if not Registered then
|
|
begin
|
|
ClockInit;
|
|
Registered := True;
|
|
end;
|
|
Caption := TimeToStr(Time);
|
|
ControlStyle := ControlStyle - [csSetCaption] - [csReplicatable];
|
|
IncludeThemeStyle(Self, [csNeedsBorderPaint, csParentBackground]);
|
|
BevelInner := bvLowered;
|
|
BevelOuter := bvRaised;
|
|
FFixedTimeStored := False;
|
|
FTimer := TJvTimer.Create(nil);
|
|
FTimer.Interval := 450; { every second }
|
|
FTimer.OnTimer := TimerExpired;
|
|
FDotsColor := clTeal;
|
|
FHoursHandColor := clBlack;
|
|
FMinutesHandColor := clBlack;
|
|
FSecondsHandColor := clBlack;
|
|
FShowSeconds := True;
|
|
FLeadingZero := True;
|
|
FShowDate := False;
|
|
FDateFormat := ShortDateFormat;
|
|
GetTime(FDisplayTime);
|
|
if FDisplayTime.Hour >= 12 then
|
|
Dec(FDisplayTime.Hour, 12);
|
|
FAlarmWait := True;
|
|
FAlarm := EncodeTime(0, 0, 0, 0);
|
|
end;
|
|
|
|
destructor TJvClock.Destroy;
|
|
begin
|
|
if FHooked then
|
|
begin
|
|
Application.UnhookMainWindow(FormatSettingsChange);
|
|
FHooked := False;
|
|
end;
|
|
FTimer.Enabled := True;
|
|
FTimer.Free;
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TJvClock.Loaded;
|
|
begin
|
|
inherited Loaded;
|
|
ResetAlarm;
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvClock.CreateWnd;
|
|
begin
|
|
inherited CreateWnd;
|
|
if not (csDesigning in ComponentState) and not (IsLibrary or FHooked) then
|
|
begin
|
|
Application.HookMainWindow(FormatSettingsChange);
|
|
FHooked := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.DestroyWindowHandle;
|
|
begin
|
|
if FHooked then
|
|
begin
|
|
Application.UnhookMainWindow(FormatSettingsChange);
|
|
FHooked := False;
|
|
end;
|
|
inherited DestroyWindowHandle;
|
|
end;
|
|
|
|
procedure TJvClock.CMCtl3DChanged(var Msg: TMessage);
|
|
begin
|
|
inherited;
|
|
if ShowMode = scAnalog then
|
|
Invalidate;
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvClock.TextChanged;
|
|
begin
|
|
{ Skip this message, no repaint }
|
|
end;
|
|
|
|
procedure TJvClock.FontChanged;
|
|
begin
|
|
inherited FontChanged;
|
|
Invalidate;
|
|
if AutoSize then
|
|
Realign;
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvClock.WMTimeChange(var Msg: TMessage);
|
|
begin
|
|
inherited;
|
|
Invalidate;
|
|
CheckAlarm;
|
|
end;
|
|
|
|
function TJvClock.FormatSettingsChange(var Msg: TMessage): Boolean;
|
|
begin
|
|
Result := False;
|
|
case Msg.Msg of
|
|
WM_WININICHANGE:
|
|
begin
|
|
Invalidate;
|
|
if AutoSize then
|
|
Realign;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
function TJvClock.GetSystemTime: TDateTime;
|
|
begin
|
|
if Enabled then
|
|
Result := SysUtils.Time
|
|
else
|
|
Result := FixedTime;
|
|
if Assigned(FOnGetTime) then
|
|
FOnGetTime(Self, Result);
|
|
end;
|
|
|
|
function TJvClock.GetSystemDate: TDateTime;
|
|
begin
|
|
Result := SysUtils.Date;
|
|
if Assigned(FOnGetDate) then
|
|
FOnGetDate(Self, Result);
|
|
end;
|
|
|
|
procedure TJvClock.GetTime(var T: TJvClockTime);
|
|
var
|
|
MSec: Word;
|
|
begin
|
|
with T do
|
|
DecodeTime(GetSystemTime, Hour, Minute, Second, MSec);
|
|
end;
|
|
|
|
procedure TJvClock.UpdateClock;
|
|
begin
|
|
Invalidate;
|
|
if AutoSize then
|
|
Realign;
|
|
Update;
|
|
end;
|
|
|
|
procedure TJvClock.ResetAlarm;
|
|
begin
|
|
FAlarmWait := (FAlarm > GetSystemTime) or (FAlarm = 0);
|
|
end;
|
|
|
|
function TJvClock.IsAlarmTime(ATime: TDateTime): Boolean;
|
|
var
|
|
Hour, Min, Sec, MSec: Word;
|
|
AHour, AMin, ASec: Word;
|
|
begin
|
|
DecodeTime(FAlarm, Hour, Min, Sec, MSec);
|
|
DecodeTime(ATime, AHour, AMin, ASec, MSec);
|
|
Result := {FAlarmWait and} (Hour = AHour) and (Min = AMin) and
|
|
(ASec >= Sec) and (ASec <= Sec + AlarmSecDelay);
|
|
end;
|
|
|
|
procedure TJvClock.ResizeFont(const Rect: TRect);
|
|
var
|
|
H, W: Integer;
|
|
DC: HDC;
|
|
TimeStr: string;
|
|
begin
|
|
H := Rect.Bottom - Rect.Top - 4;
|
|
W := (Rect.Right - Rect.Left - 30);
|
|
if (H <= 0) or (W <= 0) then
|
|
Exit;
|
|
DC := GetDC(HWND_DESKTOP);
|
|
try
|
|
Canvas.Handle := DC;
|
|
Canvas.Font := Font;
|
|
TimeStr := '88888';
|
|
if FShowSeconds then
|
|
TimeStr := TimeStr + '888';
|
|
if FTwelveHour then
|
|
begin
|
|
if Canvas.TextWidth(TimeAMString) > Canvas.TextWidth(TimePMString) then
|
|
TimeStr := TimeStr + ' ' + TimeAMString
|
|
else
|
|
TimeStr := TimeStr + ' ' + TimePMString;
|
|
end;
|
|
SetNewFontSize(Canvas, TimeStr, H, W);
|
|
Font := Canvas.Font;
|
|
finally
|
|
Canvas.Handle := 0;
|
|
ReleaseDC(HWND_DESKTOP, DC);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.AlignControls(AControl: TControl; var Rect: TRect);
|
|
var
|
|
InflateWidth: Integer;
|
|
begin
|
|
inherited AlignControls(AControl, Rect);
|
|
FClockRect := Rect;
|
|
InflateWidth := BorderWidth + 1;
|
|
if BevelOuter <> bvNone then
|
|
Inc(InflateWidth, BevelWidth);
|
|
if BevelInner <> bvNone then
|
|
Inc(InflateWidth, BevelWidth);
|
|
InflateRect(FClockRect, -InflateWidth, -InflateWidth);
|
|
with FClockRect do
|
|
CircleClock(Right - Left, Bottom - Top);
|
|
if AutoSize then
|
|
ResizeFont(Rect);
|
|
end;
|
|
|
|
procedure TJvClock.Alarm;
|
|
begin
|
|
if Assigned(FOnAlarm) then
|
|
FOnAlarm(Self);
|
|
end;
|
|
|
|
procedure TJvClock.SetAutoSize(Value: Boolean);
|
|
begin
|
|
inherited SetAutoSize(Value);
|
|
FAutoSize := Value;
|
|
if FAutoSize then
|
|
begin
|
|
Invalidate;
|
|
Realign;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetTwelveHour(Value: Boolean);
|
|
begin
|
|
if FTwelveHour <> Value then
|
|
begin
|
|
FTwelveHour := Value;
|
|
Invalidate;
|
|
if AutoSize then
|
|
Realign;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetLeadingZero(Value: Boolean);
|
|
begin
|
|
if FLeadingZero <> Value then
|
|
begin
|
|
FLeadingZero := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetMinutesHandColor(const Value: TColor);
|
|
begin
|
|
if FMinutesHandColor <> Value then
|
|
begin
|
|
FMinutesHandColor := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetShowSeconds(Value: Boolean);
|
|
begin
|
|
if FShowSeconds <> Value then
|
|
begin
|
|
{if FShowSeconds and (ShowMode = scAnalog) then
|
|
DrawSecondHand(FDisplayTime.Second);}
|
|
FShowSeconds := Value;
|
|
Invalidate;
|
|
if AutoSize then
|
|
Realign;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetDotsColor(Value: TColor);
|
|
begin
|
|
if Value <> FDotsColor then
|
|
begin
|
|
FDotsColor := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetFixedTime(const Value: TDateTime);
|
|
begin
|
|
if FFixedTime <> Value then
|
|
begin
|
|
// Fixed time is stored if not zero
|
|
FFixedTime := Value;
|
|
FFixedTimeStored := FFixedTime <> 0;
|
|
|
|
// Disable us and ensure the display time is accurate
|
|
Enabled := False;
|
|
GetTime(FDisplayTime);
|
|
|
|
// Force entire redraw.
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetHoursHandColor(const Value: TColor);
|
|
begin
|
|
if FHoursHandColor <> Value then
|
|
begin
|
|
FHoursHandColor := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetShowMode(Value: TShowClock);
|
|
begin
|
|
if FShowMode <> Value then
|
|
begin
|
|
FShowMode := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetSecondsHandColor(const Value: TColor);
|
|
begin
|
|
if FSecondsHandColor <> Value then
|
|
begin
|
|
FSecondsHandColor := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetShowDate(const Value: Boolean);
|
|
begin
|
|
if FShowDate <> Value then
|
|
begin
|
|
FShowDate := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetDateFormat(const Value: string);
|
|
begin
|
|
if FDateFormat <> Value then
|
|
begin
|
|
FDateFormat := Value;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
function TJvClock.GetAlarmElement(Index: Integer): Byte;
|
|
var
|
|
Hour, Min, Sec, MSec: Word;
|
|
begin
|
|
DecodeTime(FAlarm, Hour, Min, Sec, MSec);
|
|
case Index of
|
|
1:
|
|
Result := Hour;
|
|
2:
|
|
Result := Min;
|
|
3:
|
|
Result := Sec;
|
|
else
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.SetAlarmElement(Index: Integer; Value: Byte);
|
|
var
|
|
Hour, Min, Sec, MSec: Word;
|
|
begin
|
|
DecodeTime(FAlarm, Hour, Min, Sec, MSec);
|
|
case Index of
|
|
1:
|
|
Hour := Value;
|
|
2:
|
|
Min := Value;
|
|
3:
|
|
Sec := Value;
|
|
else
|
|
Exit;
|
|
end;
|
|
if (Hour < 24) and (Min < 60) and (Sec < 60) then
|
|
begin
|
|
FAlarm := EncodeTime(Hour, Min, Sec, 0);
|
|
ResetAlarm;
|
|
end
|
|
else
|
|
InvalidTime(Hour, Min, Sec);
|
|
end;
|
|
|
|
procedure TJvClock.SetAlarmTime(AlarmTime: TDateTime);
|
|
var
|
|
Hour, Min, Sec, MSec: Word;
|
|
begin
|
|
DecodeTime(FAlarm, Hour, Min, Sec, MSec);
|
|
if (Hour < 24) and (Min < 60) and (Sec < 60) then
|
|
begin
|
|
FAlarm := Frac(AlarmTime);
|
|
ResetAlarm;
|
|
end
|
|
else
|
|
InvalidTime(Hour, Min, Sec);
|
|
end;
|
|
|
|
procedure TJvClock.TimerExpired(Sender: TObject);
|
|
var
|
|
DC: HDC;
|
|
Rect: TRect;
|
|
InflateWidth: Integer;
|
|
begin
|
|
DC := GetDC(Handle);
|
|
try
|
|
Canvas.Handle := DC;
|
|
Canvas.Brush.Color := Color;
|
|
Canvas.Font := Font;
|
|
Canvas.Pen.Color := Font.Color;
|
|
if FShowMode = scAnalog then
|
|
PaintAnalogClock(pmHandPaint)
|
|
else
|
|
begin
|
|
Rect := GetClientRect;
|
|
InflateWidth := BorderWidth;
|
|
if BevelOuter <> bvNone then
|
|
Inc(InflateWidth, BevelWidth);
|
|
if BevelInner <> bvNone then
|
|
Inc(InflateWidth, BevelWidth);
|
|
InflateRect(Rect, -InflateWidth, -InflateWidth);
|
|
PaintTimeStr(Rect, False);
|
|
end;
|
|
finally
|
|
Canvas.Handle := NullHandle;
|
|
ReleaseDC(Handle, DC);
|
|
end;
|
|
CheckAlarm;
|
|
end;
|
|
|
|
procedure TJvClock.CheckAlarm;
|
|
begin
|
|
if FAlarmEnabled and IsAlarmTime(GetSystemTime) then
|
|
begin
|
|
if FAlarmWait then
|
|
begin
|
|
FAlarmWait := False;
|
|
Alarm;
|
|
end;
|
|
end
|
|
else
|
|
ResetAlarm;
|
|
end;
|
|
|
|
procedure TJvClock.DrawAnalogFace;
|
|
var
|
|
Pos, DotHeight, DotWidth: Integer;
|
|
DotCenter: TPoint;
|
|
R: TRect;
|
|
SaveBrush, SavePen: TColor;
|
|
MinDots: Boolean;
|
|
begin
|
|
DotWidth := (MaxDotWidth * Longint(FClockRect.Right - FClockRect.Left)) div HRes;
|
|
DotHeight := VertEquiv(DotWidth);
|
|
if DotHeight < MinDotHeight then
|
|
DotHeight := MinDotHeight;
|
|
if DotWidth < MinDotWidth then
|
|
DotWidth := MinDotWidth;
|
|
DotCenter.X := DotWidth div 2;
|
|
DotCenter.Y := DotHeight div 2;
|
|
InflateRect(FClockRect, -DotCenter.Y, -DotCenter.X);
|
|
FClockRadius := ((FClockRect.Right - FClockRect.Left) div 2);
|
|
FClockCenter.X := FClockRect.Left + FClockRadius;
|
|
FClockCenter.Y := FClockRect.Top + ((FClockRect.Bottom - FClockRect.Top) div 2);
|
|
InflateRect(FClockRect, DotCenter.Y, DotCenter.X);
|
|
SaveBrush := Canvas.Brush.Color;
|
|
SavePen := Canvas.Pen.Color;
|
|
try
|
|
Canvas.Brush.Color := Canvas.Pen.Color;
|
|
MinDots := ((DotWidth > MinDotWidth) and (DotHeight > MinDotHeight));
|
|
for Pos := 0 to HandPositions - 1 do
|
|
begin
|
|
R.Top := (CircleTab[Pos].Y * FClockRadius) div CirTabScale + FClockCenter.Y;
|
|
R.Left := (CircleTab[Pos].X * FClockRadius) div CirTabScale + FClockCenter.X;
|
|
if (Pos mod 5) <> 0 then
|
|
begin
|
|
if MinDots then
|
|
begin
|
|
if Ctl3D then
|
|
begin
|
|
Canvas.Brush.Color := clBtnShadow;
|
|
OffsetRect(R, -1, -1);
|
|
R.Right := R.Left + 2;
|
|
R.Bottom := R.Top + 2;
|
|
Canvas.FillRect(R);
|
|
Canvas.Brush.Color := clBtnHighlight;
|
|
OffsetRect(R, 1, 1);
|
|
Canvas.FillRect(R);
|
|
Canvas.Brush.Color := Self.Color;
|
|
end;
|
|
R.Right := R.Left + 1;
|
|
R.Bottom := R.Top + 1;
|
|
DrawThemedBackground(Self, Canvas, R);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
R.Right := R.Left + DotWidth;
|
|
R.Bottom := R.Top + DotHeight;
|
|
OffsetRect(R, -DotCenter.X, -DotCenter.Y);
|
|
if Ctl3D and MinDots then
|
|
with Canvas do
|
|
begin
|
|
Brush.Color := FDotsColor;
|
|
Brush.Style := bsSolid;
|
|
DrawThemedBackground(Self, Canvas, R);
|
|
Frame3D(Canvas, R, LightColor(FDotsColor), clWindowFrame, 1);
|
|
end;
|
|
Canvas.Brush.Color := Canvas.Pen.Color;
|
|
if not (Ctl3D and MinDots) then
|
|
DrawThemedBackground(Self, Canvas, R);
|
|
end;
|
|
end;
|
|
finally
|
|
Canvas.Brush.Color := SaveBrush;
|
|
Canvas.Pen.Color := SavePen;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.CircleClock(MaxWidth, MaxHeight: Integer);
|
|
var
|
|
ClockHeight: Integer;
|
|
ClockWidth: Integer;
|
|
begin
|
|
if MaxWidth > HorzEquiv(MaxHeight) then
|
|
begin
|
|
ClockWidth := HorzEquiv(MaxHeight);
|
|
FClockRect.Left := FClockRect.Left + ((MaxWidth - ClockWidth) div 2);
|
|
FClockRect.Right := FClockRect.Left + ClockWidth;
|
|
end
|
|
else
|
|
begin
|
|
ClockHeight := VertEquiv(MaxWidth);
|
|
FClockRect.Top := FClockRect.Top + ((MaxHeight - ClockHeight) div 2);
|
|
FClockRect.Bottom := FClockRect.Top + ClockHeight;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.CMEnabledChanged(var Message: TMessage);
|
|
begin
|
|
if FTimer.Enabled <> Enabled then
|
|
begin
|
|
FTimer.Enabled := Enabled;
|
|
if not Enabled and not FFixedTimeStored then
|
|
FFixedTime := Now;
|
|
|
|
// Ensure the display time is accurate and force redraw
|
|
GetTime(FDisplayTime);
|
|
Invalidate;
|
|
end;
|
|
|
|
inherited;
|
|
end;
|
|
|
|
procedure TJvClock.DrawSecondHand(Pos: Integer);
|
|
var
|
|
Radius: Longint;
|
|
SaveMode: TPenMode;
|
|
begin
|
|
Radius := (FClockRadius * SecondTip) div 100;
|
|
SaveMode := Canvas.Pen.Mode;
|
|
try
|
|
Canvas.Pen.Mode := pmCopy;
|
|
Canvas.MoveTo(FClockCenter.X, FClockCenter.Y);
|
|
Canvas.LineTo(FClockCenter.X + ((CircleTab[Pos].X * Radius) div
|
|
CirTabScale), FClockCenter.Y + ((CircleTab[Pos].Y * Radius) div
|
|
CirTabScale));
|
|
finally
|
|
Canvas.Pen.Mode := SaveMode;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.DrawFatHand(Pos: Integer; HourHand: Boolean);
|
|
var
|
|
ptSide, ptTail, ptTip: TPoint;
|
|
Index, Hand: Integer;
|
|
Scale: Longint;
|
|
SaveMode: TPenMode;
|
|
begin
|
|
if HourHand then
|
|
Hand := HourSide
|
|
else
|
|
Hand := MinuteSide;
|
|
|
|
Scale := (FClockRadius * Hand) div 100;
|
|
Index := (Pos + SideShift) mod HandPositions;
|
|
ptSide.Y := (CircleTab[Index].Y * Scale) div CirTabScale;
|
|
ptSide.X := (CircleTab[Index].X * Scale) div CirTabScale;
|
|
if HourHand then
|
|
Hand := HourTip
|
|
else
|
|
Hand := MinuteTip;
|
|
Scale := (FClockRadius * Hand) div 100;
|
|
ptTip.Y := (CircleTab[Pos].Y * Scale) div CirTabScale;
|
|
ptTip.X := (CircleTab[Pos].X * Scale) div CirTabScale;
|
|
if HourHand then
|
|
Hand := HourTail
|
|
else
|
|
Hand := MinuteTail;
|
|
Scale := (FClockRadius * Hand) div 100;
|
|
Index := (Pos + TailShift) mod HandPositions;
|
|
ptTail.Y := (CircleTab[Index].Y * Scale) div CirTabScale;
|
|
ptTail.X := (CircleTab[Index].X * Scale) div CirTabScale;
|
|
with Canvas do
|
|
begin
|
|
SaveMode := Pen.Mode;
|
|
Pen.Mode := pmCopy;
|
|
try
|
|
MoveTo(FClockCenter.X + ptSide.X, FClockCenter.Y + ptSide.Y);
|
|
LineTo(FClockCenter.X + ptTip.X, FClockCenter.Y + ptTip.Y);
|
|
MoveTo(FClockCenter.X - ptSide.X, FClockCenter.Y - ptSide.Y);
|
|
LineTo(FClockCenter.X + ptTip.X, FClockCenter.Y + ptTip.Y);
|
|
MoveTo(FClockCenter.X + ptSide.X, FClockCenter.Y + ptSide.Y);
|
|
LineTo(FClockCenter.X + ptTail.X, FClockCenter.Y + ptTail.Y);
|
|
MoveTo(FClockCenter.X - ptSide.X, FClockCenter.Y - ptSide.Y);
|
|
LineTo(FClockCenter.X + ptTail.X, FClockCenter.Y + ptTail.Y);
|
|
finally
|
|
Pen.Mode := SaveMode;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.PaintAnalogClock(PaintMode: TPaintMode);
|
|
var
|
|
NewTime: TJvClockTime;
|
|
begin
|
|
Canvas.Pen.Color := Font.Color;
|
|
Canvas.Brush.Color := Color;
|
|
SetBkMode(Canvas.Handle, TRANSPARENT);
|
|
if PaintMode = pmPaintAll then
|
|
begin
|
|
with Canvas do
|
|
begin
|
|
DrawThemedBackground(Self, Canvas, FClockRect);
|
|
Pen.Color := Self.Font.Color;
|
|
DrawAnalogFace;
|
|
Pen.Color := HoursHandColor;
|
|
DrawFatHand(HourHandPos(FDisplayTime), True);
|
|
Pen.Color := MinutesHandColor;
|
|
DrawFatHand(FDisplayTime.Minute, False);
|
|
Pen.Color := Brush.Color;
|
|
if ShowSeconds then
|
|
begin
|
|
Pen.Color := SecondsHandColor;
|
|
DrawSecondHand(FDisplayTime.Second);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
with Canvas do
|
|
begin
|
|
GetTime(NewTime);
|
|
|
|
if NewTime.Hour >= 12 then
|
|
Dec(NewTime.Hour, 12);
|
|
|
|
// Erase seconds if needed
|
|
Pen.Color := Brush.Color;
|
|
if (NewTime.Second <> FDisplayTime.Second) then
|
|
if ShowSeconds then
|
|
DrawSecondHand(FDisplayTime.Second);
|
|
|
|
// Erase minutes and hours if needed
|
|
if ((NewTime.Minute <> FDisplayTime.Minute) or
|
|
(NewTime.Hour <> FDisplayTime.Hour)) then
|
|
begin
|
|
DrawFatHand(FDisplayTime.Minute, False);
|
|
DrawFatHand(HourHandPos(FDisplayTime), True);
|
|
end;
|
|
|
|
// Draw minutes and hours if at least something changed so that we avoid
|
|
// drawing on top of the seconds hand if it has not changed position.
|
|
if ((NewTime.Minute <> FDisplayTime.Minute) or
|
|
(NewTime.Hour <> FDisplayTime.Hour) or
|
|
(NewTime.Second <> FDisplayTime.Second)) then
|
|
begin
|
|
Pen.Color := MinutesHandColor;
|
|
DrawFatHand(NewTime.Minute, False);
|
|
Pen.Color := HoursHandColor;
|
|
DrawFatHand(HourHandPos(NewTime), True);
|
|
end;
|
|
|
|
// Draw seconds if required
|
|
Pen.Color := Brush.Color;
|
|
if (NewTime.Second <> FDisplayTime.Second) then
|
|
begin
|
|
if ShowSeconds then
|
|
begin
|
|
Pen.Color := SecondsHandColor;
|
|
DrawSecondHand(NewTime.Second);
|
|
end;
|
|
FDisplayTime := NewTime;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.PaintTimeStr(var Rect: TRect; FullTime: Boolean);
|
|
var
|
|
FontHeight, FontWidth, FullWidth, I, L, H: Integer;
|
|
TimeStr, DateStr, SAmPm: string;
|
|
NewTime: TJvClockTime;
|
|
|
|
function IsPartSym(Idx, Num: Byte): Boolean;
|
|
var
|
|
TwoSymHour: Boolean;
|
|
begin
|
|
TwoSymHour := (H >= 10) or FLeadingZero;
|
|
case Idx of
|
|
1: {hours}
|
|
Result := True;
|
|
2: {minutes}
|
|
if TwoSymHour then
|
|
Result := (Num in [4, 5])
|
|
else
|
|
Result := (Num in [3, 4]);
|
|
3: {seconds}
|
|
if TwoSymHour then
|
|
Result := FShowSeconds and (Num in [7, 8])
|
|
else
|
|
Result := FShowSeconds and (Num in [6, 7]);
|
|
else
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
procedure DrawSym(Sym: Char; Num: Byte);
|
|
begin
|
|
if FullTime or
|
|
((NewTime.Second <> FDisplayTime.Second) and IsPartSym(3, Num)) or
|
|
((NewTime.Minute <> FDisplayTime.Minute) and IsPartSym(2, Num)) or
|
|
(NewTime.Hour <> FDisplayTime.Hour) then
|
|
begin
|
|
DrawThemedBackground(Self, Canvas, Rect);
|
|
SetBkMode(Canvas.Handle, Windows.TRANSPARENT);
|
|
DrawText(Canvas, Sym, 1, Rect, DT_EXPANDTABS or
|
|
DT_VCENTER or DT_CENTER or DT_NOCLIP or DT_SINGLELINE);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
GetTime(NewTime);
|
|
H := NewTime.Hour;
|
|
if NewTime.Hour >= 12 then
|
|
Dec(NewTime.Hour, 12);
|
|
if FTwelveHour then
|
|
begin
|
|
if H > 12 then
|
|
Dec(H, 12)
|
|
else
|
|
if H = 0 then
|
|
H := 12;
|
|
end;
|
|
if (not FullTime) and (NewTime.Hour <> FDisplayTime.Hour) then
|
|
begin
|
|
Repaint;
|
|
Exit;
|
|
end;
|
|
if FLeadingZero then
|
|
TimeStr := 'hh:mm'
|
|
else
|
|
TimeStr := 'h:mm';
|
|
if FShowSeconds then
|
|
TimeStr := TimeStr + ':ss';
|
|
if FTwelveHour then
|
|
TimeStr := TimeStr + ' ampm';
|
|
TimeStr := FormatDateTime(TimeStr, GetSystemTime);
|
|
if (H >= 10) or FLeadingZero then
|
|
L := 5
|
|
else
|
|
L := 4;
|
|
if FShowSeconds then
|
|
Inc(L, 3);
|
|
SAmPm := Copy(TimeStr, L + 1, MaxInt);
|
|
with Canvas do
|
|
begin
|
|
Font := Self.Font;
|
|
FontHeight := TextHeight('8');
|
|
FontWidth := TextWidth('8');
|
|
FullWidth := TextWidth(SAmPm) + (L * FontWidth);
|
|
if ShowDate then
|
|
FullWidth := FullWidth + (Length(DateFormat) + 1) * FontWidth;
|
|
with Rect do
|
|
begin
|
|
Left := ((Right + Left) - FullWidth) div 2;
|
|
Right := Left + FullWidth;
|
|
Top := ((Bottom + Top) - FontHeight) div 2;
|
|
Bottom := Top + FontHeight;
|
|
end;
|
|
Brush.Color := Color;
|
|
if ShowDate then
|
|
begin
|
|
DateStr := FormatDateTime(DateFormat + ' ', GetSystemDate);
|
|
DrawText(Canvas, PChar(DateStr), Length(DateStr), Rect,
|
|
DT_EXPANDTABS or DT_VCENTER or DT_NOCLIP or DT_SINGLELINE);
|
|
Inc(Rect.Left, Length(DateFormat) * FontWidth);
|
|
end;
|
|
for I := 1 to L do
|
|
begin
|
|
Rect.Right := Rect.Left + FontWidth;
|
|
DrawSym(TimeStr[I], I);
|
|
Inc(Rect.Left, FontWidth);
|
|
end;
|
|
if FullTime or (NewTime.Hour <> FDisplayTime.Hour) then
|
|
begin
|
|
Rect.Right := Rect.Left + TextWidth(SAmPm);
|
|
DrawText(Canvas, @SAmPm[1], Length(SAmPm), Rect, // DO NOT CHANGE @SAmPm[1], it is used to get a PChar to the string
|
|
DT_EXPANDTABS or DT_VCENTER or DT_NOCLIP or DT_SINGLELINE);
|
|
end;
|
|
end;
|
|
FDisplayTime := NewTime;
|
|
end;
|
|
|
|
procedure TJvClock.Paint3DFrame(var Rect: TRect);
|
|
var
|
|
TopColor, BottomColor: TColor;
|
|
|
|
procedure AdjustColors(Bevel: TPanelBevel);
|
|
begin
|
|
TopColor := clBtnHighlight;
|
|
if Bevel = bvLowered then
|
|
TopColor := clBtnShadow;
|
|
BottomColor := clBtnShadow;
|
|
if Bevel = bvLowered then
|
|
BottomColor := clBtnHighlight;
|
|
end;
|
|
|
|
begin
|
|
Rect := GetClientRect;
|
|
with Canvas do
|
|
begin
|
|
Brush.Color := Color;
|
|
DrawThemedBackground(Self, Canvas, Rect);
|
|
end;
|
|
if BevelOuter <> bvNone then
|
|
begin
|
|
AdjustColors(BevelOuter);
|
|
Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
|
|
end;
|
|
InflateRect(Rect, -BorderWidth, -BorderWidth);
|
|
if BevelInner <> bvNone then
|
|
begin
|
|
AdjustColors(BevelInner);
|
|
Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
|
|
end;
|
|
end;
|
|
|
|
procedure TJvClock.Paint;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
Paint3DFrame(R);
|
|
case FShowMode of
|
|
scDigital:
|
|
PaintTimeStr(R, True);
|
|
scAnalog:
|
|
PaintAnalogClock(pmPaintAll);
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF UNITVERSIONING}
|
|
initialization
|
|
RegisterUnitVersion(HInstance, UnitVersioning);
|
|
|
|
finalization
|
|
UnregisterUnitVersion(HInstance);
|
|
{$ENDIF UNITVERSIONING}
|
|
|
|
end.
|