home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1996 August / VPR9608A.BIN / del20try / install / data.z / CALSAMP.PAS < prev    next >
Pascal/Delphi Source File  |  1996-05-08  |  5KB  |  210 lines

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