home *** CD-ROM | disk | FTP | other *** search
- unit TurbCalc;
-
- interface
-
- uses Dos,
- TPCrt,
- TPDate,
- TPMouse,
- TPString,
- TPWindow;
-
- procedure Calendar(X,Y,
- Current_Attr,
- Select_Attr,
- Other_Attr,
- CalFrame_Attr,
- CalHeader_Attr,
- HelpFrame_Attr,
- HelpHeader_Attr,
- HelpText_Attr,
- HelpChars_Attr : byte;
- Flag : boolean;
- var Year,Month,Day : word);
-
- implementation
- {$V-}
-
- const
-
- IntenseAttr : byte = $0F; {default attribute for days of current month}
- ReverseAttr : byte = $70; {default attribute for selected day}
- NormalAttr : byte = $07; {default attribute for days of non-current months}
- BlinkAttr : byte = $80; {blink attribute, ORed with other attribute to
- cause blinking of current system date}
-
-
- NULL = #0; {defines for ScanKey Function from MISCTOOL unit}
- BELL = #7; {MISCTOOL is a unit supplied in the Turbo Pascal}
- BS = #8; {Database Toolbox for TP4. That software is NOT}
- LF = #10; {required for operation of this unit, the necessary}
- CR = #13; {code is included here}
- ESC = #27;
- Space = #32;
- Tab = #9;
-
- {
- The following constants are based on the scheme used by the scan key
- function to convert a two key scan code sequence into one character
- by adding 128 to the ordinal value of the second character.
- }
-
- F1 = #187;
- F2 = #188;
- F3 = #189;
- F4 = #190;
- F5 = #191;
- F6 = #192;
- F7 = #193;
- F8 = #194;
- F9 = #195;
- F10 = #196;
- UpKey = #200;
- DownKey = #208;
- LeftKey = #203;
- RightKey = #205;
- PgUpKey = #201;
- PgDnKey = #209;
- HomeKey = #199;
- EndKey = #207;
- InsKey = #210;
- DelKey = #211;
- CopyRightKey = #255;
-
- Dpm : array[0..11] of integer = (31,28,31,30,31,30,31,31,30,31,30,31);
- Names : array[0..11] of string[9] = ('January','February','March','April',
- 'May','June','July','August','September',
- 'October','November','December');
-
- type
-
- BoxType = array[1..242] of byte; { this is an array type used to store
- information about the month which is
- being displayed
- }
-
- DateType = record { type used internally, corresponds with }
- Year, { the values returned by the GetDate }
- Month, { procedure in TP4 }
- Day,
- DayofWeek : word;
- end;
-
-
- var
-
- HelpWindow : WindowPtr; {window types from TPWindow}
- CalendarWindow : WindowPtr;
- KeyCode : word;
- Ch3 : char absolute KeyCode;
- Tday,C,Extra,
- Mo,TYear : integer;
- DayStr : string[4];
- Ch : char;
- Color : byte;
- YrStr : string[4];
- TodaysDate : Datetype; {internal storage of current system date}
- Date : Datetype; {internal useage of date passed in var parameters}
- Buffer : pointer; {needed for use by savewindow and restorewindow}
- CalBox : BoxType; {
- actual array variable used to store calendar. This
- array contains one byte for the character of the
- display and one byte for its attribute
- }
-
- CalPtr : pointer; {pointer to location of calbox}
- Chr1, Chr2 : char;
- TempDate : DateType;
- N : integer;
- OldXY,
- ScanLines : word;
-
- {.$DEFINE USEMOUSE} { Remove the period to enable mouse support }
- {$IFDEF USEMOUSE}
-
- {$F+}
- procedure MouseCalendarHandler;
-
- begin
- case MouseStatus of
- BothButtons : StuffKey($3B00); { simulate F1 key }
- LeftButton : case MouseLastY of
- 3 : if (MouseLastX = 11)
- then StuffKey($4B00) { Decrement date }
- else
- if (MouseLastX = 18)
- then StuffKey($4D00); { Increment date }
- 4 : if (MouseLastX = 11)
- then StuffKey($4800) { Decrement month }
- else
- if (MouseLastX = 18)
- then StuffKey($5000); { Increment month }
- 5 : if (MouseLastX in [10..13])
- then StuffKey($4900) { Increment year }
- else
- if (MouseLastX in [16..19])
- then StuffKey($5100); { Decrement year }
- 6 : if (MouseLastX in [7..9])
- then StuffKey($1C0D); { Return with date }
- end; { of case }
- RightButton : case MouseLastY of
- 7 : if (MouseLastX in [7..9]) then StuffKey($011B);
- end; { of case }
- end; { of case }
- end;
- {$F-}
-
- {$ENDIF}
-
- function ScanKey : char;
-
- {
- Reads a key from the keyboard and converts 2 scan code escape
- sequences into 1 character.
- }
-
- begin
- KeyCode := ReadKeyWord;
- if lo(KeyCode) = 0 then begin
- KeyCode := swap(KeyCode);
- if ord(Ch3) < 128 then
- Ch3 := Chr(Ord(Ch3) + 128);
- ScanKey := Ch3;
- end
- else ScanKey := Ch3;
- end; { ScanKey }
-
- {*********************************************************}
- {* The following two functions: leap_year and *}
- {* day_of_week are from the file EXDATE.PAS which is *}
- {* available in Data Library 2 of the Borland Turbo *}
- {* Pascal SIG on Compuserve. These functions were *}
- {* authored by Ted Lassagne. *}
- {*********************************************************}
-
-
- function Leap_Year(Year : integer) : boolean;
-
- { Returns true for a leap year and false for others }
-
- begin
- if Year and 3 <> 0 then Leap_Year := false
- else
- if year mod 100 <> 0 then Leap_Year := true
- else
- if year mod 400 <> 0 then Leap_Year := false
- else leap_year := true;
- end;
-
- function Day_Of_Week(Day, Month, Year : integer) : integer;
-
- {
- Returns integer day of week for date. 0 = Sunday, 6 = Saturday
- Uses Zeller's congruence.
- }
-
- var Century, Yr, Dw : integer;
-
- begin
- if Month < 3 then begin
- Month := Month + 10;
- Year := Year -1
- end
- else
- Month := Month - 2;
- Century := Year div 100;
- Yr := Year mod 100;
- Dw := (((26*Month - 2) div 10)+Day+Yr+(Yr div 4)+
- (Century div 4) - (2*Century)) mod 7;
- if Dw < 0 then Day_Of_Week := Dw + 7
- else Day_Of_Week := Dw;
- end;
-
- procedure Calendar;
-
- procedure StuffCal;
- {
- Tthis is the procedure which actually places the calendar on the screen. The
- calendar is constructed in memory in its entirety and then placed on to the
- screen with the restorewindow procedure. This is actually a trick since the
- calbox window was never saved.
- }
-
- var
- Count,S : integer;
- Limit :integer;
-
- begin
- Str(Date.Year,YrStr); {make year string for display}
-
- { write name of month on top line of calendar window }
- FastWrite(Center(Names[Date.Month-1]+' '+YrStr,20),Y+1,X+1,CalHeader_Attr);
- { clear array each time }
- for count:=1 to 242 do
- if odd(Count) then
- CalBox[count] := 32 {set character to 'space'}
- else
- CalBox[count] := NormalAttr; {set attribute for character}
- Count := 1;
-
- { get day of week for the month in question }
- TDay := Day_Of_Week(1,integer(Date.Month),integer(Date.Year));
- TYear := Date.Year;
- Mo := Date.Month-1; {constant dpm and names arrays are zero based}
- Color := NormalAttr; {set attribute to low intensity for days of month
- which precede month to be displayed}
- S := 0;
- C := 0;
-
- { set up calendar for last days of previous month }
- if (TDay > 0) then
- for S := 0 to TDay - 1 do begin
- if ((Mo - 1 = 1) and (Leap_Year(Date.Year))) then
- { if the last month was }
- Extra := 2 { February, check for }
- else { leap year }
- Extra :=1;
- if (Mo = 0) then
- DayStr := Long2Str((Dpm[Mo+1]+S-TDay+Extra)) { make 2 character string }
- else { for number value of day }
- DayStr := Long2Str((Dpm[Mo-1]+S-TDay+Extra));{ pad left with blank for }
- DayStr := LeftPad(DayStr,2); { single digit days }
-
- CalBox[Count] := ord(DayStr[1]); { for each day, place ord }
- CalBox[Count+1] := Color; { value of string char in }
- CalBox[Count+2] := ord(DayStr[2]); { array, followed by attr }
- CalBox[Count+3] := Color; { for that value. Each }
- CalBox[Count+4] := 32; { day needs to be followed}
- CalBox[Count+5] := Color; { by a space character for}
- C := C + 1; { separation from the next}
- Count := Count + 6; { day }
- end;
-
- TDay := 1;
- Color := IntenseAttr; { change color to that for days of month to be
- displayed }
-
- while (TDay <= Dpm[Mo]) do begin
- DayStr := Long2Str(TDay);
- DayStr := LeftPad(DayStr,2);
- if (TDay = Date.Day) then begin
- CalBox[Count] := ord(DayStr[1]); { as above stuff array with values }
- CalBox[Count+1] := ReverseAttr; { and attributes. This section }
- CalBox[Count+2] := ord(DayStr[2]); { tests to see if day being }
- CalBox[Count+3] := ReverseAttr; { stuffed is the current selection }
- CalBox[Count+4] := 32; { day and if so, sets attribute to }
- CalBox[Count+5] := Color; { the attribute for selected day }
- end
- else begin
- CalBox[count] := ord(DayStr[1]); { if day being stuffed was NOT the }
- CalBox[count+1] := Color; { selected day, then attribute is }
- CalBox[count+2] := ord(DayStr[2]); { the attribute for days of current }
- CalBox[count+3] := Color; { month }
- CalBox[count+4] := 32;
- CalBox[count+5] := Color;
- end;
- if ((TDay = TodaysDate.Day) and (Mo = TodaysDate.Month-1) and
- (TYear = TodaysDate.Year) and (Flag)) then begin
- CalBox[Count+1] := (CalBox[Count+1] or Blink);
- { if the day being stuffed }
- CalBox[Count+3] := (CalBox[Count+3] or Blink);
- { is the current day as in }
- end; { system date cause to }
- { blink }
-
- TDay := TDay + 1;
- C := C + 1;
- Count := Count + 6;
- if (C > 6) then begin
- C := 0;
- Count := Count - 2;
- end;
- end;
-
- { the following sections makes adjustments to February for leap year }
-
- if ((Mo = 1) and (Leap_Year(Date.Year))) then begin
- DayStr := Long2Str(TDay);
- DayStr := LeftPad(DayStr,2);
- C := C + 1;
- CalBox[Count] := ord(DayStr[1]);
- if (Date.Day <> 29) then
- CalBox[Count+1] := Color
- else
- CalBox[Count+1] := ReverseAttr;
- CalBox[Count+2] := ord(DayStr[2]);
- if (Date.Day <> 29) then
- CalBox[Count+3] := Color
- else
- CalBox[Count+3] := ReverseAttr;
- CalBox[Count+4] :=32;
- CalBox[count+5] :=color;
- Count := Count + 6;
- end;
-
- Color := NormalAttr; { set attribute back in order to display days of }
- if (C > 0) then { month which follow the displayed month }
- for S := 1 to 7-C do begin
- DayStr := Long2Str(S);
- DayStr := LeftPad(DayStr,2); { stuff days as before }
- CalBox[Count] := ord(DayStr[1]);
- CalBox[Count+1] := Color;
- CalBox[Count+2] := Ord(DayStr[2]);
- CalBox[Count+3] := Color;
- CalBox[count+4] := 32;
- CalBox[Count+5] :=color;
- Count := Count + 6;
- end;
-
- CalPtr := @CalBox; { set pointer to point to calendar array, this is the
- trick which allows restorewindow to restore a window
- which has never been saved
- }
-
- RestoreWindow(X+1,Y+2,X+20,Y+7,False,CalPtr);
- end;
-
-
- {
- This procedure is used to adjust the displayed month based upon the key
- pressed while in the selection mode
- }
-
- procedure GetCalKey(var Date : DateType);
-
- begin
- GetCursorState(OldXY,ScanLines); { hide the cursor }
- HiddenCursor;
- TempDate := Date;
- repeat
- Date := TempDate;
- StuffCal; { draw calendar }
- Chr1 := ScanKey; { get keypress }
- {$IFDEF USEMOUSE}
- SetMouseEventHandler(AllMouseEvents,nil); { disable mouse handler }
- {$ENDIF}
- case Chr1 of
- NULL : ;
- CR : begin { this accepts the date displayed }
- end;
- ESC : begin { exit set date values to 0 }
- TempDate.Year := 0;
- TempDate.Month := 0;
- TempDate.Day := 0;
- end;
- F1 : ;
- {
- The mouse handler simulates this function key if both
- mouse buttons are pressed (LEFT and RIGHT)
- }
- LeftKey : if TempDate.Day > 1 then { decrement day value }
- TempDate.Day := TempDate.Day - 1
- else
- if TempDate.Month > 1 then begin
- TempDate.Month := TempDate.Month - 1;
- TempDate.Day := Dpm[TempDate.Month - 1];
- if ((TempDate.Month = 2) and (Leap_Year(TempDate.Year))) then
- TempDate.Day := 29;
- end
- else begin
- if (TempDate.Year > 1) then
- TempDate.Year := TempDate.Year - 1;
- TempDate.Month := 12;
- TempDate.Day := 31;
- end;
- RightKey: if TempDate.Day < Dpm[TempDate.Month-1] then
- { increment day value }
- TempDate.Day := TempDate.Day + 1
- else
- if ((TempDate.Month = 2) and (Leap_Year(TempDate.Year))) then
- if (TempDate.Day <> 29) then
- TempDate.Day := 29
- else begin
- TempDate.Day := 1;
- TempDate.Month := TempDate.Month + 1;
- end
- else
- if TempDate.Month < 12 then begin
- TempDate.Month := TempDate.Month + 1;
- TempDate.Day := 1;
- end
- else begin
- if (TempDate.Year < 65535) then
- TempDate.Year := TempDate.Year + 1;
- TempDate.Month := 1;
- TempDate.Day :=1;
- end;
- UpKey : if TempDate.Month > 1 then begin { decrement month value }
- TempDate.Month := TempDate.Month - 1;
- if TempDate.Day > Dpm[TempDate.Month - 1] then
- TempDate.Day := Dpm[TempDate.Month - 1];
- end
- else begin
- TempDate.Month := 12;
- if (TempDate.Year > 1) then
- TempDate.Year := TempDate.Year - 1;
- end;
- DownKey : if TempDate.Month < 12 then begin { increment month value }
- TempDate.Month := TempDate.Month + 1;
- if TempDate.Day > Dpm[TempDate.Month - 1] then
- TempDate.Day := Dpm[TempDate.Month - 1];
- end
- else begin
- if (TempDate.Year < 65535) then
- TempDate.Year := TempDate.Year + 1;
- TempDate.Month := 1;
- end;
- PgUpKey : begin { increment year value }
- if (TempDate.Year > 1) then begin
- TempDate.Year := TempDate.Year - 1;
- if ((TempDate.Month = 2) and (TempDate.Day = 29)) then
- TempDate.Day:=28;
- end;
- end;
- PgDnKey : begin { decrement year value }
- if (TempDate.Year < 65535) then begin
- TempDate.Year := TempDate.Year + 1;
- if ((TempDate.Month = 2) and (TempDate.Day = 29)) then
- TempDate.Day:=28;
- end;
- end;
- else write(BELL)
- end;{case}
- {$IFDEF USEMOUSE}
- SetMouseEventHandler(AllMouseEvents,@MouseCalendarHandler);
- {$ENDIF}
- until Chr1 in [CR,ESC]; { can only exit with these two key values }
- Date := TempDate;
- RestoreCursorState(OldXY,ScanLines); { restore cursor }
- end;
-
- begin { calendar }
- { set up mouse handler }
- {$IFDEF USEMOUSE}
- SetMouseEventHandler(AllMouseEvents,@MouseCalendarHandler);
- {$ENDIF}
- if (CalFrame_Attr = 0) then { check attribute values }
- CalFrame_Attr := NormalAttr;
- if (CalHeader_Attr = 0) then
- CalHeader_Attr := ReverseAttr;
- if (HelpFrame_Attr = 0) then
- HelpFrame_Attr := NormalAttr;
- if (HelpHeader_Attr = 0) then
- HelpHeader_Attr := NormalAttr;
- if (Helptext_Attr = 0) then
- HelpText_Attr := NormalAttr;
- if (HelpChars_Attr=0) then
- HelpChars_Attr :=IntenseAttr;
- if (Other_Attr<>0) then
- NormalAttr := Other_Attr;
- if (Current_Attr<>0) then
- IntenseAttr := Current_Attr;
- if (Select_Attr<>0) then
- ReverseAttr := Select_Attr;
-
- if (X < 1) then { check display coordinates }
- X := 1;
- if (Y < 1) then
- Y := 1;
- if (X > 58) then
- x := 58;
- if (Flag) then begin
- if (Y > 8) then
- Y := 8;
- end
- else
- if (Y > 16) then
- Y := 16;
-
- with TodaysDate do
- getdate(Year,Month,Day,DayofWeek); { get current system date }
- if (not(Month in [1..12])) then { check VAR parameter values }
- Month := 1;
- if (Month = 2) then begin
- if (Leap_Year(Year)) then begin
- if (Day > 29) then Day:=29;
- end
- else
- if (Day > 28) then Day:=28;
- end
- else
- case month of
- 1,3,5,7,8,10,12 : if (Day > 31) then Day := 31;
- 2,4,6,8,11 : if (Day > 30) then Day := 30;
- end;
- if (Year < 1) then Year := 1;
- if (Day < 1) then Day:=1;
- Date.Year := Year;
- Date.Month := Month;
- Date.Day := Day;
-
- {
- Make the calendar window, however nothing is done if this fails. This is
- because likelyhood of failure is remote due to small size of window
- }
-
- if not MakeWindow(CalendarWindow,X,Y,X+21,Y+8,True,False,False,
- NormalAttr,CalFrame_Attr,7,'') then;
- if not DisplayWindow(CalendarWindow) then;
- if Flag then begin
- if not MakeWindow(HelpWindow,X,Y+11,X+21,Y+18,True,True,False,
- NormalAttr,HelpFrame_Attr,HelpHeader_Attr,
- 'Calendar Keys') then;
- if not DisplayWindow(HelpWindow) then;
-
- { Set up mouse window and adjust for frame around window }
- {$IFDEF USEMOUSE}
- MouseWindow(X,Y+11,X+21,Y+18); ShowMouse;
- {$ENDIF}
- FastWrite('Prev Next',Y+12,X+9,HelpText_Attr); { draw instruction screen }
- FastWrite('Day '+chr(27)+' '+chr(26),Y+13,X+3,HelpText_Attr);
- FastWrite('Month '+chr(24)+' '+chr(25),Y+14,X+3,HelpText_Attr);
- FastWrite('Year PgUp PgDn',Y+15,X+3,HelpText_Attr);
- FastWrite(chr(17)+chr(196)+chr(217)+' Accept',Y+16,X+6,HelpText_Attr);
- FastWrite('Esc Cancel',Y+17,X+6,HelpText_Attr);
- ChangeAttribute(8,Y+13,X+10,HelpChars_Attr);
- ChangeAttribute(8,Y+14,X+10,HelpChars_Attr);
- ChangeAttribute(10,y+15,X+9,HelpChars_Attr);
- ChangeAttribute(3,Y+16,X+6,HelpChars_Attr);
- ChangeAttribute(3,Y+17,X+6,HelpChars_Attr);
- GetCalKey(Date); HideMouse;
- repeat { reclaim heap and erase windows }
- HelpWindow := EraseTopWindow;
- until HelpWindow = nil;
- end
- else begin { if not using selection mode, then just draw }
- StuffCal; { calendar }
- {$IFDEF USEMOUSE}
- HideMouse;
- {$ENDIF}
- if SaveWindow(X,Y,X+21,Y+18,True,Buffer) then;
- DisposeWindow(EraseTopWindow); { restore heap and erase window }
- RestoreWindow(X,Y,X+21,Y+18,True,Buffer); { restore window }
- end;
- Year := Date.Year; { return selected date in VAR parameters }
- Month := Date.Month;
- Day := Date.Day;
- {$IFDEF USEMOUSE}
- SetMouseEventHandler(AllMouseEvents,nil); { disable mouse handler }
- MouseWindow(1,2,ScreenWidth,ScreenHeight-1);
- {$ENDIF}
- end;
-
- begin
- end.