home *** CD-ROM | disk | FTP | other *** search
- {$R-,S-,I+,D+,T+,F-,V-,B-,N-,L+ }
- Unit Windows;
-
- Interface
-
- Uses Crt;
-
- Type
- BorderType = (None,Single,Double,DoubleTop,DoubleSide,Solid);
-
- Var
- VideoMode : Byte Absolute $0000:$0449; { current video mode }
-
- Procedure DrawBox(X1,Y1,X2,Y2,Forground,Background : Word;
- Border : BorderType);
-
- Procedure MakeWindow(X1,Y1,X2,Y2,Forground,BackGround : Word;
- Border : BorderType);
-
- Procedure RemoveWindow;
-
- Procedure SetCursor(Cursor : Word);
-
- InLine($59/ { pop cx }
- $B4/$01/ { mov ah,1 }
- $CD/$10); { int 10h }
-
- Implementation
-
- Type
- ScreenType = Array[1..2000] of Word;
- ScreenPtr = ^ScreenRecord;
- ScreenRecord = Record
- Screen : ScreenType; { holds the screen memory }
- UpperCors : Word; { holds window coordinates }
- LowerCors : Word; { holds window coordinates }
- OldAttr : Word; { holds character attribute }
- XY : Word; { holds the cursor position }
- Cursor : Word; { holds the cursor shape }
- Previous : ScreenPtr; { pointer to underlying window }
- End;
-
- Var
- MonoScreen : ScreenType Absolute $B000:0000; { monochome screen }
- ColorScreen : ScreenType Absolute $B800:0000; { CGA screen }
- CurrentScreen : ScreenPtr; { place to save screen info }
- ScreenSaved : Boolean; { Are any windows on the heap? }
-
- Procedure GotoXYAbs(XY : Word);
-
- InLine($5A/ { pop dx }
- $B4/$02/ { mov ah,2 }
- $30/$FF/ { xor bh,bh }
- $CD/$10); { int 10h }
-
- Function WhereXYAbs : Word;
-
- InLine($B4/$03/ { mov ah,3 }
- $30/$FF/ { xor bh,bh }
- $CD/$10/ { int 10h }
- $89/$D0); { mov ax,dx }
-
- Function CursorShape : Word;
-
- InLine($B4/$03/ { mov ah,3 }
- $30/$FF/ { xor bh,bh }
- $89/$C8); { mov ax,cx }
-
- Procedure SaveScreen;
-
- { saves the screen memory, window coordinates, }
- { cursor position, and character attribute. }
-
- Var
- NewScreen : ScreenPtr;
-
- Begin
- New(NewScreen);
- With NewScreen^ Do
- Begin
- If ScreenSaved
- Then Previous := CurrentScreen
- Else Previous := Nil;
- ScreenSaved := True;
- If VideoMode = 7 { save the screen memory }
- Then Screen := MonoScreen
- Else Screen := ColorScreen;
- UpperCors := WindMin; { save the window coordinates }
- LowerCors := WindMax;
- OldAttr := TextAttr; { save the character attribute }
- XY := WhereXYAbs; { save the cursor position }
- Cursor := CursorShape;
- End;
- CurrentScreen := NewScreen;
- End;
-
- Procedure DropWindow;
-
- Var
- OldScreen : ScreenPtr;
-
- Begin
- With CurrentScreen^ Do
- Begin
- If Previous = Nil Then ScreenSaved := False;
- OldScreen := CurrentScreen; { release heap memory }
- CurrentScreen := Previous;
- Dispose(OldScreen);
- End;
- End;
-
- Procedure RemoveWindow;
-
- { Restores screen memory, window coordinates, }
- { cursor position, and character attribute. }
-
- Begin
- If Not ScreenSaved Then Exit;
- With CurrentScreen^ Do
- Begin
- If VideoMode = 7 { restore screen memory }
- Then MonoScreen := Screen
- Else ColorScreen := Screen;
- WindMin := UpperCors; { restore the window coordinates }
- WindMax := LowerCors;
- TextAttr := OldAttr; { restore the character attribute }
- GotoXYAbs(XY); { restore the cursor position }
- SetCursor(Cursor);
- DropWindow;
- End;
- End;
-
- Procedure DuplicateChar(Character : Char;Count : Integer);
-
- { Uses the BIOS to write multiple copies of a character to the screen }
-
- Begin
- InLine($8A/$46/$06 { mov al,byte ptr char[bp] }
- /$8B/$4E/$04 { mov cx,count[bp] }
- /$B4/$09 { mov ah,09h }
- /$8A/$1E/>TextAttr { mov bl,[TextAttr] }
- /$32/$FF { xor bh,bh }
- /$CD/$10 { int 10h }
- );
- End;
-
- Procedure DrawBox(X1,Y1,X2,Y2,Forground,Background : Word;Border : BorderType);
-
- { Draws a double box around the window and reduces the window size. }
- { Inputs are the same as for MakeWindow. }
-
- Type
- BorderPart = (Top,Side,UpperLeft,UpperRight,LowerLeft,LowerRight);
-
- Var
- Loop : Integer;
-
- Const
- Borders : Array[Single..Solid,Top..LowerRight] of Char =
- (('─','│','┌','┐','└','┘'), {single}
- ('═','║','╔','╗','╚','╝'), {double}
- ('═','│','╒','╕','╘','╛'), {combo }
- ('─','║','╓','╖','╙','╜'), {combo }
- (' ',' ',' ',' ',' ',' '));{solid }
-
- { window type 0 has no border, type 5 uses the space character }
-
- Begin
- If VideoMode = 7 Then { Make sure the attributes can be }
- Begin { seen on a monochrome screen. }
- Forground := 7;
- Background := 0;
- End;
- Window(X1,Y1,X2,Y2);
- TextColor(Forground);
- TextBackground(Background);
- GotoXY(1,1);
- If Border > None Then
- Begin
- Write(Borders[Border,UpperLeft]); { upper left }
- DuplicateChar(Borders[Border,Top],Pred(X2-X1)); { top }
- GotoXY(Succ(X2-X1),1);
- Write(Borders[Border,UpperRight]); { upper right }
- For Loop := 2 To Y2-Y1 Do
- Begin
- GotoXY(1,Loop);
- Write(Borders[Border,Side]); { left side }
- GotoXY(Succ(X2-X1),Loop);
- Write(Borders[Border,Side]); { right side }
- End;
- Write(Borders[Border,LowerLeft]); { lower left }
- DuplicateChar(Borders[Border,Top],Pred(X2-X1)); { bottom }
- GotoXY(Succ(X2-X1),Succ(Y2-Y1));
- DuplicateChar(Borders[Border,LowerRight],1); { lower right }
- Window(Succ(X1),Succ(Y1),Pred(X2),Pred(Y2)); { reduce the window size }
- End;
- ClrScr;
- End;
-
- Procedure MakeWindow(X1,Y1,X2,Y2,Forground,BackGround : Word;
- Border : BorderType);
-
- { Saves the screen and draws a box. }
-
- { Inputs are: The four window coordinates, }
- { the forground color, }
- { the background color, }
- { and the border type (see DrawBox) }
-
- Begin
- SaveScreen;
- DrawBox(X1,Y1,X2,Y2,Forground,Background,Border);
- End;
-
- Begin
- ScreenSaved := False;
- End.