DateDialog.pas
DateDialogUnit.pasunit DateDialog;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
DateDialogUnit;
type
TDateDialog = class(TComponent)
private
{ Private declarations }
DYear : integer;
DMonth : integer;
DDay : integer;
DUseToday : boolean;
DStartDate: TDateTime;
DPosition : TPosition;
DTop : integer;
DLeft : integer;
DCaption : string;
function ShowNormal (Index : integer) : integer;
procedure UpdateDate (Index : integer; Value : integer);
protected
{ Protected declarations }
public
{ Public declarations }
ResultDate : TDateTime;
constructor Create(AOwner : TComponent); override;
function Execute : boolean;
function GetADate(ADate : TDateTime): TDateTime;
published
{ Published declarations }
property Year : integer index 1 read ShowNormal write UpdateDate;
property Month : integer index 2 read ShowNormal write UpdateDate;
property Day : integer index 3 read ShowNormal write UpdateDate;
property UseToday : boolean read DUseToday write DUseToday;
property DialogPosition : TPosition read DPosition write DPosition;
property DialogTop : integer read DTop write DTop;
property DialogLeft : integer read DLeft write Dleft;
property DialogCaption : string read DCaption write DCaption;
property Tag;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Dialogs', [TDateDialog]);
end;
constructor TDateDialog.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
DStartDate:=Date;
DTop:=0;
DLeft:=0;
DCaption:='Select a date';
DUseToday:=True;
DPosition:=poScreenCenter;
end;
function TDateDialog.GetADate(ADate : TDateTime): TDateTime;
begin
if ADate<>0 then
begin
DStartDate:=ADate;
UseToday:=False;
end
else
begin
DStartDate:=Date;
UseToday:=true;
end;
Execute;
GetADate:=ResultDate;
end;
function TDateDialog.ShowNormal(Index : integer) : integer;
var AYear, AMonth, ADay : word;
begin
DecodeDate(DStartDate,AYear,AMonth,ADay);
case Index of
1: Result:=AYear;
2: Result:=AMonth;
3: Result:=ADay;
else Result:=-1;
end;
end;
procedure TDateDialog.UpdateDate(Index : integer; Value : integer);
var AYear, AMonth, ADay : word;
begin
if Value>0 then
begin
DecodeDate(DStartDate,AYear,AMonth,ADay);
case Index of
1: if (Value>0)and(Value<9999) then AYear:=Value;
2: if (Value>0)and(Value<13) then AMonth:=Value;
3: if (Value>0)and(Value<31) then ADay:=Value;
else Exit;
end;
DStartDate:=EncodeDate(AYear,AMonth,ADay);
end;
end;
function TDateDialog.Execute : boolean;
begin
DateDialogForm:=TDateDialogForm.Create(Application);
try
if not DUseToday then
DateDialogForm.StartDate:=DStartDate;
with DateDialogForm do
begin
Top:=DTop;
Left:=DLeft;
Position:=DPosition;
Caption:=DCaption;
end;
DateDialogForm.UseToday:=DUseToday;
DateDialogForm.Icon:=Application.Icon;
DateDialogForm.ShowModal;
Execute:=(DateDialogForm.ModalResult=mrOK);
finally
ResultDate:=DateDialogForm.ResultDate;
DateDialogForm.Free;
end;
end;
end.
{-----------------------------------------------------------------------------}
{ DateDialogUnit }
{ }
{ (C) 1996 Hans Luijten }
{ Version 1.1 }
{ Compiler: Delphi 2.02 }
{ }
{ This unit can be used seperately, or as part of the TDateDialog component }
{ This unit does not require any TCalendar component-stuff }
{ The form for the dialog is derivated from the Time/Date Properties of Win95 }
{ This is my first component ever... }
{-----------------------------------------------------------------------------}
unit DateDialogUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, Grids, ComCtrls;
type
TDateDialogForm = class(TForm)
DataGroupbox: TGroupBox;
DateLabel: TLabel;
MonthSelector: TComboBox;
YearUpDown: TUpDown;
MonthGrid: TStringGrid;
YearSelector: TEdit;
OKButton: TBitBtn;
CancelButton: TBitBtn;
procedure FormActivate(Sender: TObject);
procedure YearUpDownClick(Sender: TObject; Button: TUDBtnType);
procedure MonthSelectorChange(Sender: TObject);
procedure MonthGridClick(Sender: TObject);
procedure OKButtonClick(Sender: TObject);
procedure CancelButtonClick(Sender: TObject);
private
{ Private declarations }
Day, Month, Year : word; { Storing vars in humanformat }
procedure DrawDialog; { Redraw routine for Dialog }
procedure UpdateCurrentDate; { Sync TDateTime and Day..Year}
function IsLeapYear(AYear : integer) : boolean; {Checks if year is leapyear}
public
{ Public declarations }
StartDate : TDateTime; { given by user }
CurrentDate : TDateTime; { used while active }
ResultDate : TDateTime; { result after active }
UseToday : Boolean; { let dialog determine date, Startdate or Today }
end;
var
DateDialogForm: TDateDialogForm;
implementation
{$R *.DFM}
{---------------------------------- Syncs CurrentDate with Day Month and Year -}
procedure TDateDialogForm.UpdateCurrentDate;
begin
{ beware of user who selected day 29, 30 or 31,...}
if ((Month=4)or(Month=6)or(Month=9)or(Month=11))and(Day>30) then
Day:=30; { April, June, Spetember, November }
if (Month=2) then { Februari }
begin
if (IsLeapYear(Year))and(Day>29) then { with and without leapyear }
Day:=29;
if (not IsLeapYear(Year))and(Day>28) then
Day:=28;
end;
CurrentDate:=EncodeDate(Year,Month,Day);{ adapt CurrentDate to year change }
end;
{-----------------------------------------------------------------------------}
{--------------------------------------------- Determine if year is leapyear -}
function TDateDialogForm.IsLeapYear(AYear : integer):boolean;
begin
IsLeapYear:=(AYear mod 4 = 0) and ((Year mod 100 <> 0) or (AYear mod 400 = 0));
{ Years dividable by 4 or 400 are leap-years }
end;
{-----------------------------------------------------------------------------}
{--------------------------------------------- Redraw all data on dialogform -}
procedure TDateDialogForm.DrawDialog;
var DayCounter : TDateTime; { for counting the days of the month }
Column, Row : integer; { for grid-cell positioning }
ThisMonth : word; { for comparing this month }
ThisDay : word; { for comparing today with drawn day }
Dummy : word; { dummy for conversion purposes }
TodayColumn : integer; { for saving the position of selected day nr }
TodayRow : integer; { for saving the position of selected day nr }
begin
DecodeDate(CurrentDate,Year,Month,Day); { decode currently used day }
DayCounter:=EncodeDate(Year,Month,1); { set counter to first of month }
{ set txt label }
DateLabel.Caption:=FormatDateTime(LongDateFormat,CurrentDate);
for Row:=1 to 6 do { clear the displayed month-grid }
for Column:=0 to 6 do { don't clear row 0 }
MonthGrid.Cells[Column,Row]:='';
ThisMonth:=Month; { copy this month }
Column:=DayOfWeek(DayCounter)-1; { column to start day 1 }
Row:=1; { row to start day 1 }
ThisDay:=1; { Start with day 1 }
while ThisMonth=Month do { while we're in the samen month }
begin
MonthGrid.Cells[Column,Row]:=IntToStr(ThisDay); { fill cell with day nr }
if ThisDay=Day then { if this is the selected day nr }
begin
TodayColumn:=Column; { Save the new day nr position }
TodayRow:=Row;
end; { if day }
inc(ThisDay); { goto next day nr }
inc(Column); { goto next cell }
DayCounter:=DayCounter+1; { set counter to next day }
if Column>6 then { end of row ? = end of this week ? }
begin
Column:=0; { goto first day of the week }
inc(Row); { goto next week }
end; { if Column }
DecodeDate(DayCounter,Dummy,ThisMonth,Dummy); { determine current month }
end; { while month }
MonthGrid.Col:=TodayColumn; { reset selection to the }
MonthGrid.Row:=TodayRow; { 'old' selected day nr }
YearSelector.Text:=IntToStr(Year); { fill-in year }
end;
{-----------------------------------------------------------------------------}
{-------------------------------------------- On Activation, Do all settings -}
procedure TDateDialogForm.FormActivate(Sender: TObject);
var DaysOfWeek : integer; { counters for Day- and Month-names }
MonthsOfYear : integer;
begin
if UseToday then
StartDate:=Date; { set StartDate to Today }
CurrentDate:=StartDate; { set current to startdate }
DecodeDate(CurrentDate,Year,Month,Day);
for DaysOfWeek:=1 to 7 do { fill row 0 with day names }
MonthGrid.Cells[DaysOfWeek-1,0]:=ShortDayNames[DaysOfWeek];
with MonthSelector do
begin
Items.Clear; { clear all list-items of the combobox }
for MonthsOfYear:=1 to 12 do { copy monthnames to dropdown list }
Items.Add(LongMonthNames[MonthsOfYear]);
ItemIndex:=Month-1; { make current month the selected one }
end; { with Month }
DrawDialog; { let's make things visible for the user }
end;
{-----------------------------------------------------------------------------}
{-------------------------------------------------- Up & Down click for Year -}
procedure TDateDialogForm.YearUpDownClick(Sender: TObject;
Button: TUDBtnType);
begin
if (Button=btNext)and(Year<9999) then { don't exceed the year 9999 }
inc(Year) { Up pressed: increase year }
else if Year>0 then { don't go below the year zero }
dec(Year); { Down pressed: decrease year }
UpdateCurrentDate; { adapt CurrentDate to year change }
DrawDialog; { make it so mister Laforge }
end;
{-----------------------------------------------------------------------------}
{---------------------------------------------- User selected an other month -}
procedure TDateDialogForm.MonthSelectorChange(Sender: TObject);
begin
Month:=MonthSelector.ItemIndex+1; { ItemIndex - 1 = selected month nr }
UpdateCurrentDate;
DrawDialog;
end;
{-----------------------------------------------------------------------------}
{----------------------------------------------- User clicked on a new daynr -}
procedure TDateDialogForm.MonthGridClick(Sender: TObject);
begin
{ did user select a valid field (with a day-nr in cell) ? }
if MonthGrid.Cells[MonthGrid.Col,MonthGrid.Row]<>'' then
begin { Yes: Update Day and CurrentDate }
Day:=StrToInt(MonthGrid.Cells[MonthGrid.Col,MonthGrid.Row]);
UpdateCurrentDate;
end;
DrawDialog; { Scotty ! Beam me up ! }
end;
{-----------------------------------------------------------------------------}
{------------------------------------------------ OK pressed, set resultdate -}
procedure TDateDialogForm.OKButtonClick(Sender: TObject);
begin
ResultDate:=CurrentDate;
ModalResult:=mrOK;
end;
{-----------------------------------------------------------------------------}
{-------------------------------------------- Cancel pressed, set resultdate -}
procedure TDateDialogForm.CancelButtonClick(Sender: TObject);
begin
ResultDate:=StartDate;
ModalResult:=mrCancel;
end;
{-----------------------------------------------------------------------------}
end.