📄 rxpickdate.pas
字号:
if (FMaxDate <> NullDate) and (TmpDate > FMaxDate) then DecodeDate(FMaxDate, TYear, TMonth, ADay)
}
//<Polaris
end else Exit;
3: if (Value <= DaysThisMonth) and (Value <> ADay) then begin
//>Polaris
TmpDate := EncodeDate(AYear, AMonth, Value);
if (FMinDate <> NullDate) and (TmpDate < FMinDate) then DecodeDate(FMinDate, TYear, TMonth, iValue);
if (FMaxDate <> NullDate) and (TmpDate > FMaxDate) then DecodeDate(FMaxDate, TYear, TMonth, iValue);
//<Polaris
ADay := iValue
end
else Exit;
else Exit;
end;
FDate := EncodeDate(AYear, AMonth, ADay);
FUseCurrentDate := False;
CalendarUpdate(Index = 3);
Change;
end;
end;
procedure TRxCalendar.SetWeekendColor(Value: TColor);
begin
if Value <> FWeekendColor then begin
FWeekendColor := Value;
Invalidate;
end;
end;
procedure TRxCalendar.SetWeekends(Value: TDaysOfWeek);
begin
if Value <> FWeekends then begin
FWeekends := Value;
UpdateCalendar;
end;
end;
function TRxCalendar.IsWeekend(ACol, ARow: Integer): Boolean;
begin
Result := TDayOfWeekName((Integer(StartOfWeek) + ACol) mod 7) in FWeekends;
end;
procedure TRxCalendar.SetStartOfWeek(Value: TDayOfWeekName);
begin
if Value <> FStartOfWeek then begin
FStartOfWeek := Value;
UpdateCalendar;
end;
end;
procedure TRxCalendar.SetUseCurrentDate(Value: Boolean);
begin
if Value <> FUseCurrentDate then begin
FUseCurrentDate := Value;
if Value then begin
FDate := Date; { use the current date, then }
UpdateCalendar;
end;
end;
end;
{ Given a value of 1 or -1, moves to Next or Prev month accordingly }
procedure TRxCalendar.ChangeMonth(Delta: Integer);
var
AYear, AMonth, ADay: Word;
NewDate: TDateTime;
CurDay: Integer;
begin
DecodeDate(FDate, AYear, AMonth, ADay);
CurDay := ADay;
if Delta > 0 then ADay := DaysPerMonth(AYear, AMonth)
else ADay := 1;
NewDate := EncodeDate(AYear, AMonth, ADay);
NewDate := NewDate + Delta;
DecodeDate(NewDate, AYear, AMonth, ADay);
if DaysPerMonth(AYear, AMonth) > CurDay then ADay := CurDay
else ADay := DaysPerMonth(AYear, AMonth);
CalendarDate := EncodeDate(AYear, AMonth, ADay);
end;
procedure TRxCalendar.PrevMonth;
begin
ChangeMonth(-1);
end;
procedure TRxCalendar.NextMonth;
begin
ChangeMonth(1);
end;
procedure TRxCalendar.NextYear;
begin
if IsLeapYear(Year) and (Month = 2) and (Day = 29) then Day := 28;
Year := Year + 1;
end;
procedure TRxCalendar.PrevYear;
begin
if IsLeapYear(Year) and (Month = 2) and (Day = 29) then Day := 28;
Year := Year - 1;
end;
procedure TRxCalendar.CalendarUpdate(DayOnly: Boolean);
var
AYear, AMonth, ADay: Word;
FirstDate: TDateTime;
begin
FUpdating := True;
try
DecodeDate(FDate, AYear, AMonth, ADay);
FirstDate := EncodeDate(AYear, AMonth, 1);
FMonthOffset := 2 - ((DayOfWeek(FirstDate) - Ord(StartOfWeek) + 7) mod 7);
{ day of week for 1st of month }
if FMonthOffset = 2 then FMonthOffset := -5;
MoveColRow((ADay - FMonthOffset) mod 7, (ADay - FMonthOffset) div 7 + 1,
False, False);
if DayOnly then Update else Invalidate;
finally
FUpdating := False;
end;
end;
procedure TRxCalendar.UpdateCalendar;
begin
CalendarUpdate(False);
end;
procedure TRxCalendar.WMSize(var Message: TWMSize);
var
GridLinesH, GridLinesW: Integer;
begin
GridLinesH := 6 * GridLineWidth;
if (goVertLine in Options) or (goFixedVertLine in Options) then
GridLinesW := 6 * GridLineWidth
else GridLinesW := 0;
DefaultColWidth := (Message.Width - GridLinesW) div 7;
DefaultRowHeight := (Message.Height - GridLinesH) div 7;
end;
{ TLocCalendar }
type
TLocCalendar = class(TRxCalendar)
private
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
public
constructor Create(AOwner: TComponent); override;
procedure MouseToCell(X, Y: Integer; var ACol, ARow: Longint);
property GridLineWidth;
property DefaultColWidth;
property DefaultRowHeight;
end;
constructor TLocCalendar.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := [csCaptureMouse, csClickEvents, csDoubleClicks];
ControlStyle := ControlStyle + [csReplicatable];
Ctl3D := False;
Enabled := False;
BorderStyle := bsNone;
ParentColor := True;
CalendarDate := Trunc(Now);
UseCurrentDate := False;
FixedColor := Self.Color;
Options := [goFixedHorzLine];
TabStop := False;
end;
procedure TLocCalendar.CMParentColorChanged(var Message: TMessage);
begin
inherited;
if ParentColor then FixedColor := Self.Color;
end;
procedure TLocCalendar.CMEnabledChanged(var Message: TMessage);
begin
if HandleAllocated and not (csDesigning in ComponentState) then
EnableWindow(Handle, True);
end;
procedure TLocCalendar.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
Style := Style and not (WS_BORDER or WS_TABSTOP or WS_DISABLED);
end;
procedure TLocCalendar.MouseToCell(X, Y: Integer; var ACol, ARow: Longint);
var
Coord: TGridCoord;
begin
Coord := MouseCoord(X, Y);
ACol := Coord.X;
ARow := Coord.Y;
end;
procedure TLocCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect;
AState: TGridDrawState);
var
D, M, Y: Word;
begin
inherited DrawCell(ACol, ARow, ARect, AState);
DecodeDate(CalendarDate, Y, M, D);
D := StrToIntDef(CellText[ACol, ARow], 0);
if (D > 0) and (D <= DaysPerMonth(Y, M)) then begin
if (EncodeDate(Y, M, D) = SysUtils.Date) then
Frame3D(Canvas, ARect, clBtnShadow, clBtnHighlight, 1);
end;
end;
{ TPopupCalendar }
type
TPopupCalendar = class(TPopupWindow)
private
FCalendar: TRxCalendar;
FTitleLabel: TLabel;
FFourDigitYear: Boolean;
FBtns: array[0..3] of TRxSpeedButton;
procedure CalendarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PrevMonthBtnClick(Sender: TObject);
procedure NextMonthBtnClick(Sender: TObject);
procedure PrevYearBtnClick(Sender: TObject);
procedure NextYearBtnClick(Sender: TObject);
procedure CalendarChange(Sender: TObject);
procedure TopPanelDblClick(Sender: TObject);
//>Polaris
// function GetDate(Index: Integer): TDate;
procedure SetDate(Index: Integer; Value: TDateTime);
//<Polaris
protected
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
function GetValue: Variant; override;
procedure SetValue(const Value: Variant); override;
//>Polaris
procedure CheckButton;
//<Polaris
public
constructor Create(AOwner: TComponent); override;
//>Polaris
procedure Invalidate; override;
procedure Update; override;
property MinDate: TDateTime index 0 {read GetDate} write SetDate;
property MaxDate: TDateTime index 1 {read GetDate} write SetDate;
//<Polaris
end;
function CreatePopupCalendar(AOwner: TComponent;
{$IFDEF RX_D4} ABiDiMode: TBiDiMode = bdLeftToRight; {$ENDIF}
MinDate: TDateTime{$IFDEF RX_D4}= 0{$ENDIF};
MaxDate: TDateTime{$IFDEF RX_D4}= 0{$ENDIF}
): TWinControl;
begin
Result := TPopupCalendar.Create(AOwner);
if (AOwner <> nil) and not (csDesigning in AOwner.ComponentState) and
(Screen.PixelsPerInch <> 96) then
begin { scale to screen res }
Result.ScaleBy(Screen.PixelsPerInch, 96);
{ The ScaleBy method does not scale the font well, so set the
font back to the original info. }
TPopupCalendar(Result).FCalendar.ParentFont := True;
TPopupCalendar(Result).FCalendar.MinDate := MinDate;
TPopupCalendar(Result).FCalendar.MaxDate := MaxDate;
FontSetDefault(TPopupCalendar(Result).Font);
{$IFDEF RX_D4}
Result.BiDiMode := ABiDiMode;
{$ENDIF}
end;
end;
procedure SetupPopupCalendar(PopupCalendar: TWinControl;
AStartOfWeek: TDayOfWeekName; AWeekends: TDaysOfWeek;
AWeekendColor: TColor; BtnHints: TStrings; FourDigitYear: Boolean;
MinDate: TDateTime;
MaxDate: TDateTime
);
var
I: Integer;
begin
if (PopupCalendar = nil) or not (PopupCalendar is TPopupCalendar) then
Exit;
// Polaris
if not (csDesigning in PopupCalendar.Owner.ComponentState) then begin
TPopupCalendar(PopupCalendar).SetDate(0, MinDate);
TPopupCalendar(PopupCalendar).SetDate(1, MaxDate);
end;
// Polaris
// TPopupCalendar(PopupCalendar).MaxDate := MaxDate;
TPopupCalendar(PopupCalendar).FFourDigitYear := FourDigitYear;
if TPopupCalendar(PopupCalendar).FCalendar <> nil then begin
with TPopupCalendar(PopupCalendar).FCalendar do begin
StartOfWeek := AStartOfWeek;
WeekendColor := AWeekendColor;
Weekends := AWeekends;
end;
if (BtnHints <> nil) then
for I := 0 to Min(BtnHints.Count - 1, 3) do begin
if BtnHints[I] <> '' then
TPopupCalendar(PopupCalendar).FBtns[I].Hint := BtnHints[I];
end;
end;
end;
constructor TPopupCalendar.Create(AOwner: TComponent);
const
BtnSide = 14;
var
Control, BackPanel: TWinControl;
begin
inherited Create(AOwner);
FFourDigitYear := FourDigitYear;
Height := Max(PopupCalendarSize.Y, 120);
Width := Max(PopupCalendarSize.X, 180);
Color := clBtnFace;
FontSetDefault(Font);
if AOwner is TControl then ShowHint := TControl(AOwner).ShowHint
else ShowHint := True;
if (csDesigning in ComponentState) then Exit;
BackPanel := TPanel.Create(Self);
with BackPanel as TPanel do begin
Parent := Self;
Align := alClient;
ParentColor := True;
ControlStyle := ControlStyle + [csReplicatable];
end;
Control := TPanel.Create(Self);
with Control as TPanel do begin
Parent := BackPanel;
Align := alTop;
Width := Self.Width - 4;
Height := 18;
BevelOuter := bvNone;
ParentColor := True;
ControlStyle := ControlStyle + [csReplicatable];
end;
FCalendar := TLocCalendar.Create(Self);
with TLocCalendar(FCalendar) do begin
Parent := BackPanel;
Align := alClient;
OnChange := CalendarChange;
OnMouseUp := CalendarMouseUp;
end;
FBtns[0] := TRxTimerSpeedButton.Create(Self);
with FBtns[0] do begin
Parent := Control;
SetBounds(-1, -1, BtnSide, BtnSide);
Glyph.Handle := LoadBitmap(hInstance, SBtnGlyphs[0]);
OnClick := PrevYearBtnClick;
Hint := LoadStr(SPrevYear);
end;
FBtns[1] := TRxTimerSpeedButton.Create(Self);
with FBtns[1] do begin
Parent := Control;
SetBounds(BtnSide - 2, -1, BtnSide, BtnSide);
Glyph.Handle := LoadBitmap(hInstance, SBtnGlyphs[1]);
OnClick := PrevMonthBtnClick;
Hint := LoadStr(SPrevMonth);
end;
FTitleLabel := TLabel.Create(Self);
with FTitleLabel do begin
Parent := Control;
AutoSize := False;
Alignment := taCenter;
SetBounds(BtnSide * 2 + 1, 1, Control.Width - 4 * BtnSide - 2, 14);
Transparent := True;
OnDblClick := TopPanelDblClick;
ControlStyle := ControlStyle + [csReplicatable];
end;
FBtns[2] := TRxTimerSpeedButton.Create(Self);
with FBtns[2] do begin
Parent := Control;
SetBounds(Control.Width - 2 * BtnSide + 2, -1, BtnSide, BtnSide);
Glyph.Handle := LoadBitmap(hInstance, SBtnGlyphs[2]);
OnClick := NextMonthBtnClick;
Hint := LoadStr(SNextMonth);
end;
FBtns[3] := TRxTimerSpeedButton.Create(Self);
with FBtns[3] do begin
Parent := Control;
SetBounds(Control.Width - BtnSide + 1, -1, BtnSide, BtnSide);
Glyph.Handle := LoadBitmap(hInstance, SBtnGlyphs[3]);
OnClick := NextYearBtnClick;
Hint := LoadStr(SNextYear);
end;
//Polaris
CheckButton;
end;
//>Polaris
procedure TPopupCalendar.CheckButton;
var
// CurDate: TDate;
AYear, AMonth, ADay: Word;
begin
if not Assigned(FCalendar) then Exit;
// CurDate := TLocCalendar(FCalendar).CalendarDate;
if TLocCalendar(FCalendar).MinDate = NullDate
then for AYear := 0 to 1 do FBtns[AYear].Enabled := True
else begin
DecodeDate(TLocCalendar(FCalendar).MinDate, AYear, AMonth, ADay);
FBtns[0].Enabled := TLocCalendar(FCalendar).Year > AYear;
FBtns[1].Enabled := (TLocCalendar(FCalendar).Year > AYear) or ((TLocCalendar(FCalendar).Year = AYear) and (TLocCalendar(FCalendar).Month > AMonth));
end;
if TLocCalendar(FCalendar).MaxDate = NullDate
then for AYear := 2 to 3 do FBtns[AYear].Enabled := True
else begin
DecodeDate(TLocCalendar(FCalendar).MaxDate, AYear, AMonth, ADay);
FBtns[2].Enabled := (TLocCalendar(FCalendar).Year < AYear) or ((TLocCalendar(FCalendar).Year = AYear) and (TLocCalendar(FCalendar).Month < AMonth));
FBtns[3].Enabled := TLocCalendar(FCalendar).Year < AYear;
end;
end;
procedure TPopupCalendar.Invalidate;
begin
CheckButton;
inherited Invalidate;
end;
procedure TPopupCalendar.Update;
begin
CheckButton;
inherited Update;
end;
{
function TPopupCalendar.GetDate(Index: Integer): TDateTime;
begin
FCalendar.Min
case Index of
0: Result := TLocCalendar(FCalendar).FMinDate;
1: Result := TLocCalendar(FCalendar).FMaxDate;
else Result := NullDate;
end;
end;
}
procedure TPopupCalendar.SetDate(Index: Integer; Value: TDateTime);
begin
case Index of
0: TLocCalendar(FCalendar).FMinDate := Value;
1: TLocCalendar(FCalendar).FMaxDate := Value;
end;
end;
//<Polaris
procedure TPopupCalendar.CalendarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Col, Row: Longint;
begin
if (Button = mbLeft) and (Shift = []) then begin
TLocCalendar(FCalendar).MouseToCell(X, Y, Col, Row);
if (Row > 0) and (FCalendar.CellText[Col, Row] <> '') then
CloseUp(True);
end;
end;
procedure TPopupCalendar.TopPanelDblClick(Sender: TObject);
begin
FCalendar.CalendarDate := Trunc(Now);
end;
procedure TPopupCalendar.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if FCalendar <> nil then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -