home *** CD-ROM | disk | FTP | other *** search
/ PC Format Collection 48 / SENT14D.ISO / tech / delphi / disk11 / calendar.pak / CALSAMP.PAS
Encoding:
Pascal/Delphi Source File  |  1995-08-24  |  5.9 KB  |  245 lines

  1. unit CalSamp;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  7.   Forms, Dialogs, Grids, StdCtrls;
  8.  
  9. type
  10.   TSampleCalendar = class(TCustomGrid)
  11.   private
  12.     { Private declarations }
  13.     FDate: TDateTime;
  14.     FMonthOffset: Integer;
  15.     FOnChange: TNotifyEvent;
  16.     procedure SetCalendarDate(Value: TDateTime);
  17.     function GetDateElement(Index: Integer): Integer;
  18.     procedure SetDateElement(Index: Integer; Value: Integer);
  19.   protected
  20.     { Protected declarations }
  21.     procedure Change; dynamic;
  22.     procedure Click; override;
  23.     function DayNum(ACol, ARow: Integer): Integer;
  24.     procedure DrawCell(ACol, ARow: Longint; ARect: TRect;
  25.       AState: TGridDrawState); override;
  26.     function SelectCell(ACol, ARow: Longint): Boolean; override;
  27.     procedure UpdateCalendar; virtual;
  28.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  29.   public
  30.     { Public declarations }
  31.     constructor Create(AOwner: TComponent); override;
  32.     function DaysThisMonth: Integer;
  33.     function IsLeapYear: Boolean;
  34.     procedure NextMonth;
  35.     procedure NextYear;
  36.     procedure PrevMonth;
  37.     procedure PrevYear;
  38.     property CalendarDate: TDateTime  read FDate write SetCalendarDate;
  39.     property Day: Integer  index 3 read GetDateElement write SetDateElement;
  40.     property Month: Integer  index 2 read GetDateElement write SetDateElement;
  41.     property Year: Integer  index 1 read GetDateElement write SetDateElement;
  42.   published
  43.     { Published declarations }
  44.     property Align;
  45.     property BorderStyle;
  46.     property Color;
  47.     property Ctl3D;
  48.     property Font;
  49.     property GridLineWidth;
  50.     property ParentColor;
  51.     property ParentFont;
  52.     property OnChange: TNotifyEvent  read FOnChange write FOnChange;
  53.     property OnClick;
  54.     property OnDblClick;
  55.     property OnDragDrop;
  56.     property OnDragOver;
  57.     property OnEndDrag;
  58.     property OnKeyDown;
  59.     property OnKeyPress;
  60.     property OnKeyUp;
  61.   end;
  62.  
  63. procedure Register;
  64.  
  65. implementation
  66.  
  67. procedure Register;
  68. begin
  69.   RegisterComponents('Samples', [TSampleCalendar]);
  70. end;
  71.  
  72. constructor TSampleCalendar.Create(AOwner: TComponent);
  73. begin
  74.   inherited Create(AOwner);
  75.   ColCount := 7;
  76.   RowCount := 7;
  77.   FixedCols := 0;
  78.   FixedRows := 1;
  79.   ScrollBars := ssNone;
  80.   Options := Options - [goRangeSelect] + [goDrawFocusSelected];
  81.   FDate := Date;
  82.   UpdateCalendar;
  83. end;
  84.  
  85. procedure TSampleCalendar.Change;
  86. begin
  87.   if Assigned(FOnChange) then FOnChange(Self);
  88. end;
  89.  
  90. procedure TSampleCalendar.Click;
  91. var
  92.   TempDay: Integer;
  93. begin
  94.   inherited Click;
  95.   TempDay := DayNum(Col, Row);
  96.   if TempDay <> -1 then Day := TempDay;
  97. end;
  98.  
  99. function TSampleCalendar.DayNum(ACol, ARow: Integer): Integer;
  100. begin
  101.   Result := FMonthOffset + ACol + (ARow - 1) * 7;
  102.   if (Result < 1) or (Result > DaysThisMonth) then Result := -1;
  103. end;
  104.  
  105. function TSampleCalendar.DaysThisMonth: Integer;
  106. const
  107.   DaysPerMonth: array[1..12] of Integer =
  108.     (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  109. begin
  110.   if FDate = 0 then Result := 0
  111.   else
  112.   begin
  113.     Result := DaysPerMonth[Month];
  114.     if (Month = 2) and IsLeapYear then Inc(Result);
  115.   end;
  116. end;
  117.  
  118. procedure TSampleCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
  119. var
  120.   TheText: string;
  121.   TempDay: Integer;
  122. begin
  123.   if ARow = 0 then
  124.     TheText := ShortDayNames[ACol + 1]
  125.   else
  126.   begin
  127.     TheText := '';
  128.     TempDay := DayNum(ACol, ARow);
  129.     if TempDay <> -1 then TheText := IntToStr(TempDay);
  130.   end;
  131.   with ARect, Canvas do
  132.     TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2,
  133.       Top + (Bottom - Top - TextHeight(TheText)) div 2, TheText);
  134. end;
  135.  
  136. function TSampleCalendar.GetDateElement(Index: Integer): Integer;
  137. var
  138.   AYear, AMonth, ADay: Word;
  139. begin
  140.   DecodeDate(FDate, AYear, AMonth, ADay);
  141.   case Index of
  142.     1: Result := AYear;
  143.     2: Result := AMonth;
  144.     3: Result := ADay;
  145.     else Result := -1;
  146.   end;
  147. end;
  148.  
  149. function TSampleCalendar.IsLeapYear: Boolean;
  150. begin
  151.   Result := (Year mod 4 = 0)
  152.     and ((Year mod 100 <> 0) or (Year mod 400 = 0));
  153. end;
  154.  
  155. procedure TSampleCalendar.NextMonth;
  156. begin
  157.   if Month < 12 then
  158.     Month := succ(Month)
  159.   else
  160.   begin
  161.     Year := Year + 1;
  162.     Month := 1;
  163.   end;
  164. end;
  165.  
  166. procedure TSampleCalendar.NextYear;
  167. begin
  168.   Year := Year + 1;
  169. end;
  170.  
  171. procedure TSampleCalendar.PrevMonth;
  172. begin
  173.   if Month > 1 then
  174.     Month := pred(Month)
  175.   else
  176.   begin
  177.     Year := Year - 1;
  178.     Month := 12;
  179.   end;
  180. end;
  181.  
  182. procedure TSampleCalendar.PrevYear;
  183. begin
  184.   Year := Year - 1;
  185. end;
  186.  
  187. function TSampleCalendar.SelectCell(ACol, ARow: Longint): Boolean;
  188. begin
  189.   if DayNum(ACol, ARow) = -1 then Result := False
  190.   else Result := inherited SelectCell(ACol, ARow);
  191. end;
  192.  
  193. procedure TSampleCalendar.SetCalendarDate(Value: TDateTime);
  194. begin
  195.   FDate := Value;
  196.   UpdateCalendar;
  197.   Change;
  198. end;
  199.  
  200. procedure TSampleCalendar.SetDateElement(Index: Integer; Value: Integer);
  201. var
  202.   AYear, AMonth, ADay: Word;
  203. begin
  204.   if Value > 0 then
  205.   begin
  206.     DecodeDate(FDate, AYear, AMonth, ADay);
  207.     case Index of
  208.       1: AYear := Value;
  209.       2: AMonth := Value;
  210.       3: ADay := Value;
  211.       else Exit;
  212.     end;
  213.     FDate := EncodeDate(AYear, AMonth, ADay);
  214.     UpdateCalendar;
  215.     Change;
  216.   end;
  217. end;
  218.  
  219. procedure TSampleCalendar.UpdateCalendar;
  220. var
  221.   AYear, AMonth, ADay: Word;
  222.   FirstDate: TDateTime;
  223. begin
  224.   if FDate <> 0 then
  225.   begin
  226.     DecodeDate(FDate, AYear, AMonth, ADay);
  227.     FirstDate := EncodeDate(AYear, AMonth, 1);
  228.     FMonthOffset := 2 - DayOfWeek(FirstDate);
  229.     Row := (ADay - FMonthOffset) div 7 + 1;
  230.     Col := (ADay - FMonthOffset) mod 7;
  231.   end;
  232.   Refresh;
  233. end;
  234.  
  235. procedure TSampleCalendar.WMSize(var Message: TWMSize);
  236. var
  237.   GridLines: Integer;
  238. begin
  239.   GridLines := 6 * GridLineWidth;
  240.   DefaultColWidth := (Message.Width - GridLines) div 7;
  241.   DefaultRowHeight := (Message.Height - GridLines) div 7;
  242. end;
  243.  
  244. end.
  245.