📄 jvqclock.pas
字号:
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.SetShowMode(Value: TShowClock);
begin
if FShowMode <> Value then
begin
FShowMode := 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
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);
Canvas.Brush.Color := Canvas.Pen.Color;
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.DrawSecondHand(Pos: Integer);
var
Radius: Longint;
SaveMode: TPenMode;
begin
Radius := (FClockRadius * SecondTip) div 100;
SaveMode := Canvas.Pen.Mode;
Canvas.Pen.Mode := pmNot;
try
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;
DrawFatHand(HourHandPos(FDisplayTime), True);
DrawFatHand(FDisplayTime.Minute, False);
Pen.Color := Brush.Color;
if ShowSeconds then
DrawSecondHand(FDisplayTime.Second);
end;
end
else
begin
with Canvas do
begin
Pen.Color := Brush.Color;
GetTime(NewTime);
if NewTime.Hour >= 12 then
Dec(NewTime.Hour, 12);
if (NewTime.Second <> FDisplayTime.Second) then
if ShowSeconds then
DrawSecondHand(FDisplayTime.Second);
if ((NewTime.Minute <> FDisplayTime.Minute) or
(NewTime.Hour <> FDisplayTime.Hour)) then
begin
DrawFatHand(FDisplayTime.Minute, False);
DrawFatHand(HourHandPos(FDisplayTime), True);
Pen.Color := Self.Font.Color;
DrawFatHand(NewTime.Minute, False);
DrawFatHand(HourHandPos(NewTime), True);
end;
Pen.Color := Brush.Color;
if (NewTime.Second <> FDisplayTime.Second) then
begin
if ShowSeconds then
DrawSecondHand(NewTime.Second);
FDisplayTime := NewTime;
end;
end;
end;
end;
procedure TJvClock.PaintTimeStr(var Rect: TRect; FullTime: Boolean);
var
FontHeight, FontWidth, FullWidth, I, L, H: Integer;
TimeStr, 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, QWindows.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';
with NewTime do
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);
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;
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}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$RCSfile: JvQClock.pas,v $';
Revision: '$Revision: 1.15 $';
Date: '$Date: 2005/02/06 14:06:02 $';
LogPath: 'JVCL\run'
);
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -