| 1 | Unit Calendar; | 
|---|
| 2 |  | 
|---|
| 3 | Interface | 
|---|
| 4 |  | 
|---|
| 5 | Uses | 
|---|
| 6 | SysUtils, Classes, Forms, Grids; | 
|---|
| 7 |  | 
|---|
| 8 | {Declare new class} | 
|---|
| 9 | Type | 
|---|
| 10 | TCalendar=Class(TGrid) | 
|---|
| 11 | Private | 
|---|
| 12 | FDate: TDateTime; | 
|---|
| 13 | FMonthOffset: Integer; | 
|---|
| 14 | FOnChange:TNotifyEvent; | 
|---|
| 15 | Private | 
|---|
| 16 | Function DayNum(Col,Row:LongInt):LongInt; | 
|---|
| 17 | Function DaysThisMonth:LongInt; | 
|---|
| 18 | Function GetYear:LongInt; | 
|---|
| 19 | Function GetMonth:LongInt; | 
|---|
| 20 | Function GetDay:LongInt; | 
|---|
| 21 | Procedure SetYear(NewValue:LongInt); | 
|---|
| 22 | Procedure SetMonth(NewValue:LongInt); | 
|---|
| 23 | Procedure SetDay(NewValue:LongInt); | 
|---|
| 24 | Function IsLeapYear:Boolean; | 
|---|
| 25 | Procedure UpdateCalendar; | 
|---|
| 26 | Procedure SetCalendarDate(NewValue:TDateTime); | 
|---|
| 27 | Protected | 
|---|
| 28 | Procedure SetupComponent; Override; | 
|---|
| 29 | Procedure Resize; Override; | 
|---|
| 30 | Procedure DrawCell(Col,Row:LONGINT;rec:TRect;AState:TGridDrawState); Override; | 
|---|
| 31 | Procedure Change;Virtual; | 
|---|
| 32 | Public | 
|---|
| 33 | Destructor Destroy; Override; | 
|---|
| 34 | Procedure NextYear; | 
|---|
| 35 | Procedure PrevYear; | 
|---|
| 36 | Procedure NextMonth; | 
|---|
| 37 | Procedure PrevMonth; | 
|---|
| 38 | Public | 
|---|
| 39 | Property Year:LongInt read GetYear write SetYear; | 
|---|
| 40 | Property Month:LongInt read GetMonth write SetMonth; | 
|---|
| 41 | Property Day:LongInt read GetDay write SetDay; | 
|---|
| 42 | Property CalendarDate:TDateTime read FDate write SetCalendarDate; | 
|---|
| 43 | Published | 
|---|
| 44 | Property OnChange:TNotifyEvent  read FOnChange write FOnChange; | 
|---|
| 45 | Property Align; | 
|---|
| 46 | Property Bottom; | 
|---|
| 47 | Property DragCursor; | 
|---|
| 48 | Property DragMode; | 
|---|
| 49 | Property Enabled; | 
|---|
| 50 | Property Font; | 
|---|
| 51 | Property Height; | 
|---|
| 52 | Property Left; | 
|---|
| 53 | Property ParentFont; | 
|---|
| 54 | Property ParentShowHint; | 
|---|
| 55 | Property PopupMenu; | 
|---|
| 56 | Property ShowHint; | 
|---|
| 57 | Property TabOrder; | 
|---|
| 58 | Property Visible; | 
|---|
| 59 | Property Width; | 
|---|
| 60 | Property ZOrder; | 
|---|
| 61 |  | 
|---|
| 62 | Property OnCanDrag; | 
|---|
| 63 | Property OnCommand; | 
|---|
| 64 | Property OnDblClick; | 
|---|
| 65 | Property OnDragDrop; | 
|---|
| 66 | Property OnDragOver; | 
|---|
| 67 | Property OnEndDrag; | 
|---|
| 68 | Property OnEnter; | 
|---|
| 69 | Property OnExit; | 
|---|
| 70 | Property OnFontChange; | 
|---|
| 71 | End; | 
|---|
| 72 |  | 
|---|
| 73 | Implementation | 
|---|
| 74 |  | 
|---|
| 75 | Procedure TCalendar.Change; | 
|---|
| 76 | Begin | 
|---|
| 77 | IF FOnChange<>Nil Then FOnChange(Self); | 
|---|
| 78 | End; | 
|---|
| 79 |  | 
|---|
| 80 | Procedure TCalendar.SetCalendarDate(NewValue: TDateTime); | 
|---|
| 81 | Begin | 
|---|
| 82 | FDate := NewValue; | 
|---|
| 83 | UpdateCalendar; | 
|---|
| 84 | Change; | 
|---|
| 85 | End; | 
|---|
| 86 |  | 
|---|
| 87 | Function TCalendar.GetYear:LongInt; | 
|---|
| 88 | Var AYear,AMonth,ADay:Word; | 
|---|
| 89 | Begin | 
|---|
| 90 | DecodeDate(FDate, AYear, AMonth, ADay); | 
|---|
| 91 | Result := AYear; | 
|---|
| 92 | End; | 
|---|
| 93 |  | 
|---|
| 94 | Function TCalendar.GetMonth:LongInt; | 
|---|
| 95 | Var AYear,AMonth,ADay:Word; | 
|---|
| 96 | Begin | 
|---|
| 97 | DecodeDate(FDate, AYear, AMonth, ADay); | 
|---|
| 98 | Result := AMonth; | 
|---|
| 99 | End; | 
|---|
| 100 |  | 
|---|
| 101 | Function TCalendar.GetDay:LongInt; | 
|---|
| 102 | Var AYear,AMonth,ADay:Word; | 
|---|
| 103 | Begin | 
|---|
| 104 | DecodeDate(FDate, AYear, AMonth, ADay); | 
|---|
| 105 | Result := ADay; | 
|---|
| 106 | End; | 
|---|
| 107 |  | 
|---|
| 108 | Procedure TCalendar.SetYear(NewValue:LongInt); | 
|---|
| 109 | Var AYear,AMonth,ADay:Word; | 
|---|
| 110 | Begin | 
|---|
| 111 | If NewValue<0 Then exit; | 
|---|
| 112 | DecodeDate(FDate, AYear, AMonth, ADay); | 
|---|
| 113 | AYear:=NewValue; | 
|---|
| 114 | FDate := EncodeDate(AYear, AMonth, ADay); | 
|---|
| 115 | UpdateCalendar; | 
|---|
| 116 | Change; | 
|---|
| 117 | End; | 
|---|
| 118 |  | 
|---|
| 119 | Procedure TCalendar.SetMonth(NewValue:LongInt); | 
|---|
| 120 | Var AYear,AMonth,ADay:Word; | 
|---|
| 121 | Begin | 
|---|
| 122 | If NewValue<0 Then exit; | 
|---|
| 123 | DecodeDate(FDate, AYear, AMonth, ADay); | 
|---|
| 124 | AMonth:=NewValue; | 
|---|
| 125 | FDate := EncodeDate(AYear, AMonth, ADay); | 
|---|
| 126 | UpdateCalendar; | 
|---|
| 127 | Change; | 
|---|
| 128 | End; | 
|---|
| 129 |  | 
|---|
| 130 | Procedure TCalendar.SetDay(NewValue:LongInt); | 
|---|
| 131 | Var AYear,AMonth,ADay:Word; | 
|---|
| 132 | Begin | 
|---|
| 133 | If NewValue<0 Then exit; | 
|---|
| 134 | DecodeDate(FDate, AYear, AMonth, ADay); | 
|---|
| 135 | ADay:=NewValue; | 
|---|
| 136 | FDate := EncodeDate(AYear, AMonth, ADay); | 
|---|
| 137 | UpdateCalendar; | 
|---|
| 138 | Change; | 
|---|
| 139 | End; | 
|---|
| 140 |  | 
|---|
| 141 | Procedure TCalendar.UpdateCalendar; | 
|---|
| 142 | Var AYear, AMonth, ADay: Word; | 
|---|
| 143 | ADate:TDateTime; | 
|---|
| 144 | Begin | 
|---|
| 145 | If FDate <> 0 Then | 
|---|
| 146 | Begin | 
|---|
| 147 | DecodeDate(FDate,AYear,AMonth,ADay); | 
|---|
| 148 | ADate:=EncodeDate(AYear,AMonth,1); | 
|---|
| 149 | FMonthOffset:=2-DayOfWeek(ADate); | 
|---|
| 150 | Row:=(ADay-FMonthOffset) Div 7+1; | 
|---|
| 151 | Col:=(ADay-FMonthOffset) Mod 7; | 
|---|
| 152 | End; | 
|---|
| 153 | Refresh; | 
|---|
| 154 | End; | 
|---|
| 155 |  | 
|---|
| 156 | Procedure TCalendar.SetupComponent; | 
|---|
| 157 | Begin | 
|---|
| 158 | Inherited SetupComponent; | 
|---|
| 159 | Name:='Calendar'; | 
|---|
| 160 | ColCount:=7; | 
|---|
| 161 | RowCount:=7; | 
|---|
| 162 | FixedCols:=0; | 
|---|
| 163 | FixedRows:=1; | 
|---|
| 164 | FDate:=Date; | 
|---|
| 165 | Options:=Options-[goMouseSelect]+[goAlwaysShowSelection]; | 
|---|
| 166 | UpdateCalendar; | 
|---|
| 167 | End; | 
|---|
| 168 |  | 
|---|
| 169 | Destructor TCalendar.Destroy; | 
|---|
| 170 | Begin | 
|---|
| 171 | Inherited Destroy; | 
|---|
| 172 | End; | 
|---|
| 173 |  | 
|---|
| 174 | Procedure TCalendar.Resize; | 
|---|
| 175 | Begin | 
|---|
| 176 | Inherited Resize; | 
|---|
| 177 | DefaultColWidth:=Width DIV 7; | 
|---|
| 178 | DefaultRowHeight:=Height DIV 7; | 
|---|
| 179 | End; | 
|---|
| 180 |  | 
|---|
| 181 | Function TCalendar.DayNum(Col,Row:LongInt):LongInt; | 
|---|
| 182 | Begin | 
|---|
| 183 | Result:=FMonthOffset+Col+(Row-1)*7; | 
|---|
| 184 | If (Result<1)Or(Result>DaysThisMonth) Then Result :=-1; | 
|---|
| 185 | End; | 
|---|
| 186 |  | 
|---|
| 187 | Function TCalendar.DaysThisMonth:LongInt; | 
|---|
| 188 | Const | 
|---|
| 189 | DaysPerMonth:Array[1..12] Of Integer = | 
|---|
| 190 | (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); | 
|---|
| 191 | Begin | 
|---|
| 192 | If FDate = 0 Then Result:=0 | 
|---|
| 193 | Else | 
|---|
| 194 | Begin | 
|---|
| 195 | Result := DaysPerMonth[Month]; | 
|---|
| 196 | If ((Month=2)And(IsLeapYear)) Then inc(Result); | 
|---|
| 197 | End; | 
|---|
| 198 | End; | 
|---|
| 199 |  | 
|---|
| 200 | Function TCalendar.IsLeapYear:Boolean; | 
|---|
| 201 | Begin | 
|---|
| 202 | Result:=(Year mod 4=0)And((Year mod 100<>0)Or(Year mod 400=0)); | 
|---|
| 203 | End; | 
|---|
| 204 |  | 
|---|
| 205 | Procedure TCalendar.DrawCell(Col,Row:LONGINT;rec:TRect;AState:TGridDrawState); | 
|---|
| 206 | Var OldClip,Exclude:TRect; | 
|---|
| 207 | X,Y,CX,CY:LongInt; | 
|---|
| 208 | Cap:String; | 
|---|
| 209 | Day:LongInt; | 
|---|
| 210 | Back,Fore:TColor; | 
|---|
| 211 | Begin | 
|---|
| 212 | SetupCellColors(Col,Row,AState,Back,Fore); | 
|---|
| 213 | Canvas.Brush.Color:=Back; | 
|---|
| 214 | Canvas.Pen.Color:=Fore; | 
|---|
| 215 |  | 
|---|
| 216 | If Row=0 Then Cap:=ShortDayNames[Col+1] //Fixed | 
|---|
| 217 | Else | 
|---|
| 218 | Begin | 
|---|
| 219 | Day:=DayNum(Col,Row); | 
|---|
| 220 | If Day>=0 Then Cap:=tostr(Day) | 
|---|
| 221 | Else Cap:=''; | 
|---|
| 222 | End; | 
|---|
| 223 |  | 
|---|
| 224 | X:=rec.Left+2; | 
|---|
| 225 | Y:=rec.Top-2-Canvas.Font.Height; | 
|---|
| 226 | Canvas.GetTextExtent(Cap,CX,CY); | 
|---|
| 227 | Canvas.TextOut(X,Y,Cap); | 
|---|
| 228 |  | 
|---|
| 229 | OldClip:=Canvas.ClipRect; | 
|---|
| 230 | Exclude.Left:=X; | 
|---|
| 231 | Exclude.Right:=X+CX-1; | 
|---|
| 232 | Exclude.Bottom:=Y; | 
|---|
| 233 | Exclude.Top:=Y+CY-1; | 
|---|
| 234 | Canvas.ClipRect:=rec; | 
|---|
| 235 | Canvas.ExcludeClipRect(Exclude); | 
|---|
| 236 | Inherited DrawCell(Col,Row,rec,AState); | 
|---|
| 237 | Canvas.ClipRect:=OldClip; | 
|---|
| 238 | End; | 
|---|
| 239 |  | 
|---|
| 240 | Procedure TCalendar.NextYear; | 
|---|
| 241 | Begin | 
|---|
| 242 | Year:=Year+1; | 
|---|
| 243 | End; | 
|---|
| 244 |  | 
|---|
| 245 | Procedure TCalendar.PrevYear; | 
|---|
| 246 | Begin | 
|---|
| 247 | Year:=Year-1; | 
|---|
| 248 | End; | 
|---|
| 249 |  | 
|---|
| 250 | Procedure TCalendar.NextMonth; | 
|---|
| 251 | Begin | 
|---|
| 252 | If Month=12 Then | 
|---|
| 253 | Begin | 
|---|
| 254 | Month:=1; | 
|---|
| 255 | NextYear; | 
|---|
| 256 | End | 
|---|
| 257 | Else Month:=Month+1; | 
|---|
| 258 | End; | 
|---|
| 259 |  | 
|---|
| 260 | Procedure TCalendar.PrevMonth; | 
|---|
| 261 | Begin | 
|---|
| 262 | If Month=1 Then | 
|---|
| 263 | Begin | 
|---|
| 264 | Month:=12; | 
|---|
| 265 | PrevYear; | 
|---|
| 266 | End | 
|---|
| 267 | Else Month:=Month-1; | 
|---|
| 268 | End; | 
|---|
| 269 |  | 
|---|
| 270 | Initialization | 
|---|
| 271 | {Register classes} | 
|---|
| 272 | RegisterClasses([TCalendar]); | 
|---|
| 273 | End. | 
|---|
| 274 |  | 
|---|