?? pickdate.pas
字號:
{*******************************************************}
{ }
{ Delphi VCL Extensions (RX) }
{ }
{ Copyright (c) 1995, 1996 AO ROSNO }
{ Copyright (c) 1997, 1998 Master-Bank }
{ }
{*******************************************************}
unit PickDate;
{$I RX.INC}
{$S-}
interface
uses Windows, Classes, Variants, Controls, SysUtils, Graphics, DateUtil;
{ Calendar dialog }
function SelectDate(var Date: TDateTime; const DlgCaption: TCaption;
AStartOfWeek: TDayOfWeekName; AWeekends: TDaysOfWeek;
AWeekendColor: TColor; BtnHints: TStrings): Boolean;
function SelectDateStr(var StrDate: string; const DlgCaption: TCaption;
AStartOfWeek: TDayOfWeekName; AWeekends: TDaysOfWeek;
AWeekendColor: TColor; BtnHints: TStrings): Boolean;
function PopupDate(var Date: TDateTime; Edit: TWinControl): Boolean;
{ Popup calendar }
function CreatePopupCalendar(AOwner: TComponent
{$IFDEF RX_D4}; ABiDiMode: TBiDiMode = bdLeftToRight {$ENDIF}): TWinControl;
procedure SetupPopupCalendar(PopupCalendar: TWinControl;
AStartOfWeek: TDayOfWeekName; AWeekends: TDaysOfWeek;
AWeekendColor: TColor; BtnHints: TStrings; FourDigitYear: Boolean);
const
PopupCalendarSize: TPoint = (X: 187; Y: 124);
implementation
uses Messages, Consts, Forms, Buttons, StdCtrls, Grids, ExtCtrls, RXCtrls,
RXCConst, ToolEdit, VCLUtils, MaxMin, rxStrUtils;
{$IFDEF WIN32}
{$R *.R32}
{$ELSE}
{$R *.R16}
{$ENDIF}
const
SBtnGlyphs: array[0..3] of PChar = ('PREV2', 'PREV1', 'NEXT1', 'NEXT2');
procedure FontSetDefault(AFont: TFont);
{$IFDEF WIN32}
var
NonClientMetrics: TNonClientMetrics;
{$ENDIF}
begin
{$IFDEF WIN32}
NonClientMetrics.cbSize := SizeOf(NonClientMetrics);
if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0) then
AFont.Handle := CreateFontIndirect(NonClientMetrics.lfMessageFont)
else
{$ENDIF}
with AFont do begin
Color := clWindowText;
Name := 'MS Sans Serif';
Size := 8;
Style := [];
end;
end;
{ TRxTimerSpeedButton }
type
TRxTimerSpeedButton = class(TRxSpeedButton)
public
constructor Create(AOwner: TComponent); override;
published
property AllowTimer default True;
property Style default bsWin31;
end;
constructor TRxTimerSpeedButton.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Style := bsWin31;
AllowTimer := True;
{$IFDEF WIN32}
ControlStyle := ControlStyle + [csReplicatable];
{$ENDIF}
end;
{ TRxCalendar }
{ TRxCalendar implementation copied from Borland CALENDAR.PAS sample unit
and modified }
type
TDayOfWeek = 0..6;
TRxCalendar = class(TCustomGrid)
private
FDate: TDateTime;
FMonthOffset: Integer;
FOnChange: TNotifyEvent;
FReadOnly: Boolean;
FStartOfWeek: TDayOfWeekName;
FUpdating: Boolean;
FUseCurrentDate: Boolean;
FWeekends: TDaysOfWeek;
FWeekendColor: TColor;
function GetCellText(ACol, ARow: Integer): string;
function GetDateElement(Index: Integer): Integer;
procedure SetCalendarDate(Value: TDateTime);
procedure SetDateElement(Index: Integer; Value: Integer);
procedure SetStartOfWeek(Value: TDayOfWeekName);
procedure SetUseCurrentDate(Value: Boolean);
procedure SetWeekendColor(Value: TColor);
procedure SetWeekends(Value: TDaysOfWeek);
function IsWeekend(ACol, ARow: Integer): Boolean;
procedure CalendarUpdate(DayOnly: Boolean);
function StoreCalendarDate: Boolean;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure Change; dynamic;
procedure ChangeMonth(Delta: Integer);
procedure Click; override;
function DaysThisMonth: Integer;
procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
function SelectCell(ACol, ARow: Longint): Boolean; override;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
public
constructor Create(AOwner: TComponent); override;
procedure NextMonth;
procedure NextYear;
procedure PrevMonth;
procedure PrevYear;
procedure UpdateCalendar; virtual;
property CellText[ACol, ARow: Integer]: string read GetCellText;
published
property CalendarDate: TDateTime read FDate write SetCalendarDate
stored StoreCalendarDate;
property Day: Integer index 3 read GetDateElement write SetDateElement stored False;
property Month: Integer index 2 read GetDateElement write SetDateElement stored False;
property ReadOnly: Boolean read FReadOnly write FReadOnly default False;
property StartOfWeek: TDayOfWeekName read FStartOfWeek write SetStartOfWeek default Mon;
property UseCurrentDate: Boolean read FUseCurrentDate write SetUseCurrentDate default True;
property WeekendColor: TColor read FWeekendColor write SetWeekendColor default clRed;
property Weekends: TDaysOfWeek read FWeekends write SetWeekends default [Sun];
property Year: Integer index 1 read GetDateElement write SetDateElement stored False;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
constructor TRxCalendar.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FUseCurrentDate := True;
FStartOfWeek := Mon;
FWeekends := [Sun];
FWeekendColor := clRed;
FixedCols := 0;
FixedRows := 1;
ColCount := 7;
RowCount := 7;
ScrollBars := ssNone;
Options := Options - [goRangeSelect] + [goDrawFocusSelected];
ControlStyle := ControlStyle + [csFramed];
FDate := Date;
UpdateCalendar;
end;
procedure TRxCalendar.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or WS_BORDER;
{$IFDEF WIN32}
Params.ExStyle := Params.ExStyle and not WS_EX_CLIENTEDGE;
{$ENDIF}
{$IFDEF RX_D4}
AddBiDiModeExStyle(Params.ExStyle);
{$ENDIF}
end;
procedure TRxCalendar.Change;
begin
if Assigned(FOnChange) then FOnChange(Self);
end;
procedure TRxCalendar.Click;
var
TheCellText: string;
begin
inherited Click;
TheCellText := CellText[Col, Row];
if TheCellText <> '' then Day := StrToInt(TheCellText);
end;
function TRxCalendar.DaysThisMonth: Integer;
begin
Result := DaysPerMonth(Year, Month);
end;
procedure TRxCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
TheText: string;
begin
TheText := CellText[ACol, ARow];
with ARect, Canvas do begin
if IsWeekend(ACol, ARow) and not (gdSelected in AState) then
Font.Color := WeekendColor;
TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2,
Top + (Bottom - Top - TextHeight(TheText)) div 2, TheText);
end;
end;
function TRxCalendar.GetCellText(ACol, ARow: Integer): string;
var
DayNum: Integer;
begin
if ARow = 0 then { day names at tops of columns }
Result := ShortDayNames[(Ord(StartOfWeek) + ACol) mod 7 + 1]
else begin
DayNum := FMonthOffset + ACol + (ARow - 1) * 7;
if (DayNum < 1) or (DayNum > DaysThisMonth) then Result := ''
else Result := IntToStr(DayNum);
end;
end;
procedure TRxCalendar.KeyDown(var Key: Word; Shift: TShiftState);
begin
if Shift = [] then
case Key of
VK_LEFT, VK_SUBTRACT:
begin
if (Day > 1) then Day := Day - 1
else CalendarDate := CalendarDate - 1;
Exit;
end;
VK_RIGHT, VK_ADD:
begin
if (Day < DaysThisMonth) then Day := Day + 1
else CalendarDate := CalendarDate + 1;
Exit;
end
end;
inherited KeyDown(Key, Shift);
end;
procedure TRxCalendar.KeyPress(var Key: Char);
begin
if Key in ['T', 't'] then begin
CalendarDate := Trunc(Now);
Key := #0;
end;
inherited KeyPress(Key);
end;
function TRxCalendar.SelectCell(ACol, ARow: Longint): Boolean;
begin
if ((not FUpdating) and FReadOnly) or (CellText[ACol, ARow] = '') then
Result := False
else Result := inherited SelectCell(ACol, ARow);
end;
procedure TRxCalendar.SetCalendarDate(Value: TDateTime);
begin
if FDate <> Value then begin
FDate := Value;
UpdateCalendar;
Change;
end;
end;
function TRxCalendar.StoreCalendarDate: Boolean;
begin
Result := not FUseCurrentDate;
end;
function TRxCalendar.GetDateElement(Index: Integer): Integer;
var
AYear, AMonth, ADay: Word;
begin
DecodeDate(FDate, AYear, AMonth, ADay);
case Index of
1: Result := AYear;
2: Result := AMonth;
3: Result := ADay;
else Result := -1;
end;
end;
procedure TRxCalendar.SetDateElement(Index: Integer; Value: Integer);
var
AYear, AMonth, ADay: Word;
begin
if Value > 0 then begin
DecodeDate(FDate, AYear, AMonth, ADay);
case Index of
1: if AYear <> Value then AYear := Value else Exit;
2: if (Value <= 12) and (Value <> AMonth) then begin
AMonth := Value;
if ADay > DaysPerMonth(Year, Value) then
ADay := DaysPerMonth(Year, Value);
end else Exit;
3: if (Value <= DaysThisMonth) and (Value <> ADay) then
ADay := Value
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);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -