home *** CD-ROM | disk | FTP | other *** search
- { Window Procedures Version 2.0, Copyright (c) 1987, SofTouch.
-
- Here are some easy-to-use procedures for creating pop-up windows:
-
- Make_Window : creates a pop-up window (saves what is "underneath" it).
- : args: Left : byte : [2..78] : left edge of the window
- Top : byte : [2..23] : top edge of the window
- Right : byte : [3..79] : right edge of the window
- Bottom : byte : [3..24] : bottom edge of the window
- (the 4 preceding are the coordinates of the WINDOW;
- it's frame lies outside the specified area.)
- Title : string : [0..78] : title of the window
- Title_Posn : (Left, Center, Right) : where to put the
- title (if there is a title) -- on the left
- edge, centered, or against the right edge
- BrdrText : byte : color of frame text
- BrdrBack : byte : color of frame background
- WndwText : byte : text color in the window
- WndwBack : byte : text background color in the window
- Initialize_Windows : sets up variables required for the window system. This
- procedure MUST be run before any calls to any of the window procedures can
- be made. It is a good idea to run this procedure at the beginning of your
- program to insure against accidental calls to the window procedures.
- Calling the procedures before initializing the window system can cause a
- program to bomb. Also, call INITIALIZE_WINDOWS only ONCE. Calling it
- more than once can trash the window system and can eat memory. Note that
- SAME_COLOR can be passed in for the colors if you don't want to change
- them or their values are unavailable (SAME_COLOR can only be used if
- COLOR has already been called). Finally, INITIALIZE_WINDOWS assumes the
- active window is the default (1,1,80,25). If this is not the case,
- either alter the values in the procedure or do a WINDOW(1,1,80,25) before
- calling INITIALIZE_WINDOWS.
- : args: F : byte : [0..15] : starting foreground color
- B : byte : [0..15] : starting background color
- (if >7, characters blink)
- Color : changes the current text foreground and background colors. In order
- for the window system to recognize color changes, use this procedure
- whenever you want to change the color. If you want, passing SAME_COLOR in
- for either argument will leave that attribute alone. Example: if current
- color is F := 14, B := 4 and the call Color(15, Same_Color) is made, the
- new values are F := 15, B := 4. Color(Same_Color, Same_Color) does
- nothing.
- : args: F : byte : [0..15] : new foreground color
- B : byte : [0..15] : new background color (if >7, characters
- blink)
- Normal_Window : creates a window (identical to Turbo's WINDOW procedure) but
- updates variables for the window system. Does NOT frame the window, clear
- it, or anything else. All it does is create the window, like WINDOW does.
- : args: Left : byte : [1..79] : left edge of the window
- Top : byte : [1..24] : top edge of the window
- Right : byte : [2..80] : right edge of the window
- Bottom : byte : [2..25] : bottom egde of the window
- Remove_Window : removes a pop-up window (created with Make_Window) from the
- screen and restores what was beneath it when it was created (or moved).
- Does nothing if no windows have been created.
- : args: none
- Move_Window : moves the current window to a new location on the screen
- : args: New_Left : byte : [2..78] : new left edge of window
- New_Top : byte : [2..23] : new top line of window
- (the 2 preceding are the coordinates of the WINDOW;
- it's frame lies outside the specified area.)
- Remove_All_Windows : removes all windows that have been created by
- MAKE_WINDOW. Does nothing if no windows have been created.
- : args: none
- Swap_Windows : swaps the active window with the window beneath it. Does
- nothing if less than two windows are active.
- : args : none
-
- These routines are valid ONLY in 80 column mode. 40 Column will be UGLY and
- might not work!
-
- You DO have to initialize the window system before using the procedures.
- Otherwise the program will randomly bomb whenever the last window is
- removed! PLEASE run procedure INITIALIZE_WINDOWS before you do anything!
-
- You can't remove more windows than you create.
-
- You can move the windows around with great ease.
-
- The only limit to the number of windows you can open is how much RAM
- your computer has (each window takes up minimal heap space).
-
- This code is UGLY!! It was designed for pure speed. This destroys elegant
- programs. I used arithmetic shifts instead of multiplies and divides. I
- index off of pointer variables (Buff^[1]...). This sort of stuff isn't
- pretty. I recommend not fiddlin' with these procedures yourself unless you
- are a Turbo Pascal expert.
-
- SofTouch takes no responsibility, either incidental or consequential, for
- any damage that may result from the use or misuse of these routines.
-
- Versions are available from the below address that use different
- framing techniques (like a single bar instead of a double bar), no
- frame at all, support the MDA, etc. If we don't have it written we'll
- write it for you. This offer is only valid if you are a registered
- user (See below for info about registering).
-
- We worked a lot of hours developing these routines. We even took the time
- to document (wow!) what the procedures do so that it would be easier to
- figure out how to use them. We're distributing these procedures because
- We've found ourselves disappointed with the other window management
- procedures (even Borland's) available as shareware and we think others, like
- you, might be disappointed, too. Anyway, onto the shareware part:
-
- Feel free to use these routines in any program you write. I won't try
- to charge royalties. But, if you like them and use them, please send
- $15 to:
-
- Windows - Pascal
- SofTouch
- P.O. Box 2184
- Indianapolis, IN 46206
-
- This will make you a registered user and will get you on our mailing list.
-
- If you have any questions, comments, criticisms, etc. about these
- procedures, write to the above address. Please include an SASE if you
- expect a response.
-
- LOOK FOR: Menus.Inc - 1-2-3 type horizontal menus and vertical menus.
- (requires MakeWind.Inc)
- DateTime.Inc - Functions to get & set the machine's date & time
-
- COMING SOON: Similar routines in Turbo C and Turbo BASIC
-
- **************************************************************************** }
-
- Const Same_Color : Byte = 255;
-
- Type Win_Title_Str = String[78];
- Win_Title_Posn_Type = (Left, Center, Right);
- Win_Buff_Ptr = ^Win_Buff;
- Win_Buff = Array[0..3999] Of Byte;
- Win_Rec_Ptr = ^Win_Rec;
- Win_Rec = Record
- Buff : Win_Buff_Ptr;
- Colour, WherX, WherY,
- Start_Row, Start_Col,
- End_Row, Col_Len,
- Old_Left, Old_Right,
- Old_Top, Old_Bottom : Byte;
- Next : Win_Rec_Ptr;
- End; { Win_Rec Record }
-
- Var Win_First : Win_Rec_Ptr;
- Win_Word_Array : Array[1..25,1.. 80] Of Integer Absolute $B800:0;
- Win_Byte_Array : Array[1..25,1..160] Of Byte Absolute $B800:0;
- Win_Left, Win_Right, Win_Top, Win_Bottom, Win_Color : Byte;
- Win_Count : Integer;
-
- { ************************************************************************** }
-
- Procedure Color(Fore, Back : Byte);
- Begin
- If (Back <> Same_Color) And (Fore <> Same_Color) Then Begin
- Win_Color := Fore + Back shl 4;
- TextColor(Fore);
- TextBackground(Back);
- End Else
- If Fore <> Same_Color Then Begin
- Win_Color := Win_Color and 240 + Fore;
- TextColor(Fore);
- End Else
- If Back <> Same_Color Then Begin
- Win_Color := Win_Color and 15 + Back shl 4;
- TextBackground(Back);
- End; { If Back <> Same_Color }
- End; { Procedure Color }
-
- { ************************************************************************** }
-
- Procedure Initialize_Windows(Fore, Back : Byte);
- Begin
- Win_Left := 1;
- Win_Top := 1;
- Win_Right := 80;
- Win_Bottom := 25;
- Win_Count := 0;
- Color(Fore, Back);
- End; { Procedure Initialize_Windows }
-
- { ************************************************************************** }
-
- Procedure Normal_Window(Left, Top, Right, Bottom : Byte);
- Begin
- Win_Left := Left;
- Win_Top := Top;
- Win_Right := Right;
- Win_Bottom := Bottom;
- Window(Left, Top, Right, Bottom);
- End; { Procedure Normal_Window }
-
- { ************************************************************************** }
-
- Procedure Make_Window(Lft, Top, Rite, Bottom : Byte; Title : Win_Title_Str;
- Title_Posn : Win_Title_Posn_Type;
- Frame_Fore, Frame_Back, Win_Fore, Win_Back : Byte);
- Var Cur_Win : Win_Rec_Ptr;
- Index, Size,
- Char_n_Color,
- Pred_Top,
- Succ_Bottom,
- BrdrClr, I : Integer;
- Begin
- New(Cur_Win);
- Pred_Top := Pred(Top);
- Succ_Bottom := Succ(Bottom);
- With Cur_Win^ Do Begin
- Next := Win_First;
- Colour := Win_Color;
- Start_Row := Pred_Top;
- Start_Col := Pred(Lft);
- End_Row := Succ_Bottom;
- Col_Len := (Rite - Lft + 3) shl 1;
- WherX := WhereX;
- WherY := WhereY;
- Old_Left := Win_Left;
- Old_Right := Win_Right;
- Old_Top := Win_Top;
- Old_Bottom:= Win_Bottom;
- Size := Col_Len * (Bottom - Top + 3);
- GetMem(Buff, Size);
- Index := 0;
- BrdrClr := (Frame_Back shl 4 + Frame_Fore) shl 8;
- Char_n_Color := BrdrClr + 186;
- For I := Pred_Top To Succ_Bottom Do Begin
- Move(Win_Word_Array[I, Pred(Lft)], Buff^[Index], Col_Len);
- Index := Index + Col_Len;
- Win_Word_Array[I, Pred(Lft)] := Char_n_Color;
- Win_Word_Array[I, Succ(Rite)] := Char_n_Color;
- End; { For I }
- Char_n_Color := BrdrClr + 205;
- For I := Lft To Rite Do Begin
- Win_Word_Array[Pred_Top, I] := Char_n_Color;
- Win_Word_Array[Succ_Bottom, I] := Char_n_Color;
- End; { For I }
- Win_Word_Array[Pred_Top, Succ(Rite)] := BrdrClr + 187;
- Win_Word_Array[Succ_Bottom, Succ(Rite)] := BrdrClr + 188;
- Win_Word_Array[Succ_Bottom, Pred(Lft)] := BrdrClr + 200;
- Win_Word_Array[Pred_Top, Pred(Lft)] := BrdrClr + 201;
- If Length(Title) > Col_Len shr 1 - 4 Then
- Size := Col_Len shr 1 - 4
- Else
- Size := Length(Title);
- If Size > 0 Then Begin
- Case Title_Posn Of
- Left : Index := Pred(Lft shl 1);
- Center : Index := (Lft + Col_Len shr 2 - Size shr 1) shl 1 - 5;
- Right : Index := Succ((Rite - Size - 2) shl 1);
- End; { Case Title_Posn }
- Win_Byte_Array[Pred_Top, Index] := 181;
- For I := 1 To Size Do
- Move(Title[I], Win_Byte_Array[Pred_Top, Index + (I shl 1)], 1);
- Win_Byte_Array[Pred_Top, Index + Succ(I) shl 1] := 198;
- End; { If Size > 0 }
- End; { With Cur_Win^ }
- Win_First := Cur_Win;
- Win_Count := Succ(Win_Count);
- Normal_Window(Lft, Top, Rite, Bottom);
- Color(Win_Fore, Win_Back);
- ClrScr;
- End; { Procedure Make_Window }
-
- { ************************************************************************** }
-
- Procedure Remove_Window;
- Var Cur_Win : Win_Rec_Ptr;
- Index, I : Integer;
- Begin
- If Win_Count > 0 Then Begin
- Win_Count := Pred(Win_Count);
- Cur_Win := Win_First;
- Win_First := Win_First^.Next;
- With Cur_Win^ Do Begin
- Index := 0;
- For I := Start_Row To End_Row Do Begin
- Move(Buff^[Index], Win_Word_Array[I, Start_Col], Col_Len);
- Index := Index + Col_Len;
- End; { For I }
- Normal_Window(Old_Left, Old_Top, Old_Right, Old_Bottom);
- Color(Colour and 15, (Colour shr 4) and 15);
- GoToXY(WherX, WherY);
- FreeMem(Buff, Col_Len * Succ(End_Row - Start_Row));
- End; { With Cur_Win^ }
- Dispose(Cur_Win);
- End; { If Win_Count > 0 }
- End; { Procedure Remove_Window }
-
- { ************************************************************************** }
-
- Procedure Remove_All_Windows;
- Begin
- While Win_Count > 0 Do Remove_Window;
- End; { Procedure Remove_All_Windows }
-
- { ************************************************************************** }
-
- Procedure Move_Window(Left, Top : Byte);
- Var Tmp_Buff : Win_Buff_Ptr;
- Index, I,
- X, Y, Size : Integer;
- Begin
- If Win_Count > 0 Then
- With Win_First^ Do Begin
- Size := Col_Len * Succ(End_Row - Start_Row);
- GetMem(Tmp_Buff, Size);
- Index := 0;
- For I := Start_Row To End_Row Do Begin
- Move(Win_Word_Array[I, Start_Col], Tmp_Buff^[Index], Col_Len);
- Move(Buff^[Index], Win_Word_Array[I, Start_Col], Col_Len);
- Index := Index + Col_Len;
- End; { For I }
- Index := 0;
- For I := Top To Top + End_Row - Start_Row Do Begin
- Move(Win_Word_Array[I, Left], Buff^[Index], Col_Len);
- Move(Tmp_Buff^[Index], Win_Word_Array[I, Left], Col_Len);
- Index := Index + Col_Len;
- End; { For I }
- X := WhereX;
- Y := WhereY;
- Normal_Window(Succ(Left), Succ(Top), Left + Col_Len shr 1 - 2,
- Top + Pred(End_Row) - Start_Row);
- GoToXY(X, Y);
- End_Row := Succ(Win_Bottom);
- Start_Row := Top;
- Start_Col := Left;
- FreeMem(Tmp_Buff, Size);
- End; { With Win_First^ }
- End; { Procedure Move_Window }
-
- { ************************************************************************** }
-
- Procedure Swap_Windows;
- Var Buff_1, Buff_2 : Win_Rec;
- Index, I, Size_1, Size_2 : Integer;
- Begin
- If Win_Count > 1 Then Begin
- With Buff_1 Do Begin
- Colour := Win_Color;
- WherX := WhereX;
- WherY := WhereY;
- Size_1 := SizeOf(Win_First^.Buff^);
- GetMem(Buff, Size_1);
- Index := 0;
- Start_Col := Win_First^.Start_Col;
- Start_Row := Win_First^.Start_Row;
- End_Row := Win_First^.End_Row;
- Col_Len := Win_First^.Col_Len;
- For I := Start_Row To End_Row Do Begin
- Move(Win_Word_Array[I, Start_Col], Buff^[Index], Col_Len);
- Index := Index + Col_Len;
- End; { For }
- End; { With }
- Remove_Window;
- With Buff_2 Do Begin
- Colour := Win_Color;
- WherX := WhereX;
- WherY := WhereY;
- Size_2 := SizeOf(Win_First^.Buff^);
- GetMem(Buff, Size_2);
- Index := 0;
- Start_Col := Win_First^.Start_Col;
- Start_Row := Win_First^.Start_Row;
- End_Row := Win_First^.End_Row;
- Col_Len := Win_First^.Col_Len;
- For I := Start_Row To End_Row Do Begin
- Move(Win_Word_Array[I, Start_Col], Buff^[Index], Col_Len);
- Index := Index + Col_Len;
- End; { For }
- End; { With }
- Remove_Window;
- With Buff_1 Do Begin
- Make_Window(Succ(Start_Col), Succ(Start_Row),
- Start_Col+(Col_Len shr 1)-2,Pred(End_Row),'',Left,Buff^[1] and 15,
- (Buff^[1] shr 4) and 15,Colour and 15,(Colour shr 4) and 15);
- Index := 0;
- For I := Start_Row To End_Row Do Begin
- Move(Buff^[Index], Win_Word_Array[I, Start_Col], Col_Len);
- Index := Index + Col_Len;
- End; { For }
- GoToXY(WherX, WherY);
- FreeMem(Buff, Size_1);
- End; { With }
- With Buff_2 Do Begin
- Make_Window(Succ(Start_Col), Succ(Start_Row),
- Start_Col+(Col_Len shr 1)-2,Pred(End_Row),'',Left,Buff^[1] and 15,
- (Buff^[1] shr 4) and 15,Colour and 15,(Colour shr 4) and 15);
- Index := 0;
- For I := Start_Row To End_Row Do Begin
- Move(Buff^[Index], Win_Word_Array[I, Start_Col], Col_Len);
- Index := Index + Col_Len;
- End; { For }
- GoToXY(WherX, WherY);
- FreeMem(Buff, Size_2);
- End; { With }
- End; { If }
- End; { Procedure Swap_Windows }
-
- { ************************************************************************** }
- { To run the test program, delete the line below this one }
- (*
- { To disable the test program, add a line above this one that contains a "("
- immediately followed by a "*" }
- Procedure Press_A_Key;
- Var Ch : Char;
- Begin
- WriteLn('Press a key..');
- Read(Kbd,Ch);
- End; { Procedure Press_A_Key }
- Var I, X, Y : Integer;
- C : Char;
- Begin { test program for MakeWind.Inc }
- Initialize_Windows(9,0);
- WriteLn('I''ll run a little demo. First, I''ll create a bunch of windows.');
- Press_A_Key;
- For I := 1 To 255 Do Begin
- X := Random(40) + 2;
- Y := Random(12) + 2;
- Make_Window(X,Y,X + Random(35) + 2, Y + Random(10) + 2, 'Window: '+Chr(I),
- Left, Succ(Random(15)), Succ(Random(7)), Succ(Random(15)),
- Succ(Random(7)));
- End; { For }
- Write('Press a key to remove the windows...');
- Read(Kbd, C);
- Remove_All_Windows;
- Make_Window(2,2,20,6,'Window 1',Center,14,4,15,0);
- WriteLn('Create a window.');
- Press_A_Key;
- WriteLn('Slide it around.');
- For I := 2 To 40 Do Move_Window(I,2);
- For I := 2 To 12 Do Move_Window(40,I);
- Press_A_Key;
- WriteLn('Or just move it.');
- Move_Window(2,2);
- Press_A_Key;
- Make_Window(4,4,39,8,'Window 2',Right,9,0,14,1);
- WriteLn('Create a second window, overlapping the first.');
- Press_A_Key;
- Swap_Windows;
- WriteLn('And pull the first one on top of it.');
- Press_A_Key;
- Remove_Window;
- WriteLn('Kill window 1');
- Press_A_Key;
- Remove_Window;
- WriteLn('And then remove window 2.');
- End. { test program for MakeWind.Inc } (**)
- { End of Included File MakeWind.Inc **************************************** }