Writing to the Screen "Some of the newer computer-related equipment is of considerable help... Among the most useful tools is the cathode-ray-tube console, a computer-connected instrument resembling a television set, which can display on its screen textual information from the computer's memory in easily readable form." The American Heritage Dictionary, 1981 Most programs need to write output to the display, and usually this needs to be done very quickly! The totFAST unit includes a variety of objects for writing to the screen. The main object ScreenOBJ is capable of writing to the physical screen as well as virtual screens. A virtual screen is a screen that is not visible but provides all the facilities of the physical screen. A vir- tual screen can be used to keep a snapshot copy of the physical screen so that it may be restored at some later date. Virtual screens can also be used to prepare full screen displays "off line", which, when required, can be pushed onto the visible screen using a variety of effects. The ScreenOBJ object provides methods for writing to the screen using varied justification, as well as methods to draw lines and boxes, read information from the screen, move blocks of text around the screen, and control cursor location and appearance. The totFAST unit also includes objects for controlling the appearance of scroll bars and window shadows. Note: remember that the display colors are always specified as the composite foreground and background attribute (refer to page 3.11 for more information). The Writing Engine Before plunging into the totFAST unit, you ought to be aware of an important Toolkit feature. At the heart of the ScreenOBJ object is another object called WriteOBJ (yes, an object within an object). This object is the screen writing engine, and performs all of the primary screen manipulation tasks. There are methods for writing text, controlling the cursor, and for making direct video memory moves. You should never need to access the WriteOBJ methods; when you make calls to the ScreenOBJ methods, the Toolkit makes calls to the WriteOBJ engine. Ordinarily, therefore, you don't even need to be aware that WriteOBJ exists. However, if you want to use some different routines for accessing the display (e.g. you want to run programs on non- 5-2 User's Guide -------------------------------------------------------------------------------- standard hardware, or you want to run in graphics mode), then all you have to do is create your own WriteOBJ-type object, and instruct the Toolkit to use it. This "back door" gives you complete control of the Toolkit's engine. This feature allows you to modify the Toolkit display engine without making a single change to the Toolkit source code. This whole subject is discussed in detail in Part 2: Extending the Toolkit. Managing the Visible Screen One of the few parts of the Toolkit written in Assembler is the screen writing code. The reason? Speed. The totFAST unit provides very high performance screen writing, especially in CGA systems, which are noto- rious for "snow" and slow speeds. The Toolkit can write to all PC monitor types ranging from monochrome to VGA. For performance reasons, totFAST bypasses DOS screen writing services (BIOS) and writes directly to the video area of memory. The Toolkit automatically switches off the mouse cursor during screen writes. Using SCREEN totFAST includes a global object SCREEN of type ScreenOBJ. SCREEN is automatically initialized when you use the totFAST unit. All direct screen writing should be performed using the SCREEN instance. For exam- ple, to write "Hello World" at the current cursor position, you would call the method Write as follows: Screen.Write("Hello World"); Most of the other screen writing methods must be passed the X and Y coordinates where the string is to be written. Like Turbo Pascal, the Toolkit uses a one-based system where the top left of the screen is at coordinates (1,1) and the bottom right of the screen is normally (80,25). Some routines, like the box drawing methods, need to be passed a pair of coordinates. Pass the upper-left and lower-right coordinates, respectively. Basic Screen Writing This section explains how to use the methods for writing strings using varied justification methods, how to clear all or part of the screen, how to change the display attributes and how to draw lines and boxes. Writing to the Screen 5-3 -------------------------------------------------------------------------------- Note: unfortunately, Turbo Pascal provides no facility for writing procedures or functions which can be passed different parameter types or varying numbers of parameters. For this reason, the Tool- kit is incapable of providing the ultra-flexible facilities similar to Turbo Pascal's own Write and WriteLn procedures. The Toolkit therefore expects a single string to be passed to its main screen writing methods. If you need to write a non-string item, you can use one of the string conversion functions in the totSTR unit. For example, to display the value of a real variable REALVAL, use the following statement: SCREEN.Write(RealToStr(REALVAL)); For plain screen writing, feel free to use Turbo Pascal's proce- dures Write and WriteLn, e.g. Write(REALVAL);, but remember to hide the mouse first. Writing Strings The following eleven methods simplify the tasks of writing strings to the screen: Write(Str:string); Writes a string at the current cursor position using the default dis- play attributes. The display attributes are set with Turbo Pascal's CRT procedures TextColor and TextBackground. The cursor is automatically moved to the position following the last character of the string. WriteLn(Str:string); This method is the same as Write, except that the cursor is moved to the beginning of the next line. If the string is written to the last line of the display (or the last line of a window - discussed later), the display scrolls up one line. WriteAT(X,Y,Attr:byte; Str:string); Writes a string at the specified X and Y coordinates using the display attribute Attr. The cursor is not moved. WriteHi(X,Y,AttrHi,Attr:byte; Str:string); 5-4 User's Guide -------------------------------------------------------------------------------- This method is used to write a string with a combination of color attributes. Some parts of the string may be written in attribute AttrHi, and other parts in Attr. A special character must be embedded into the string to indicate when to change attributes. By default, this character is '~'. Any text written up to the first occurrence of '~' is written using Attr, the next set of text is written in AttrHi. If another '~' is encountered, the attribute is switched back to Attr, and so on. For example, the following statement would write the string 'F1 Help' so that the 'F1' is highlighted: Screen.WriteHi(1,1,yellow,white,'~F1~ Help'); Similarly, the following statement would write the text so that the letter H is highlighted: Screen.WriteHi(1,1,yellow,white,'F1 ~H~elp'); The method SetHiMarker can be used to instruct the Toolkit to recognize a different special character. For example, the following statement would change the special character to an asterisk: Screen.SetHiMarker('*'); Screen.WriteHi(1,1,yellow,white,'F1 *H*elp'); WriteCap(X,Y,AttrCap,Attr:byte; Str:string); WriteCap is similar to WriteHi. The only difference is that there are no embedded markers in the string; WriteCap automatically highlights the first capital letter. WriteClick(X,Y,Attr:byte; Str:string); This method is the functional equivalent of WriteAT. WriteClick, how- ever, causes the PC speaker to emit a "click" after each character is written, and the text expands onto the screen from left to right. WriteCenter(Y,Attr:byte; Str:string); WriteCenter is ideal for titles and headings. The string is automati- cally displayed at the center of the specified line. There is no need to compute the X coordinate based on the length of the string, as this is all done automatically. WriteBetween(X1,X2,Y1,Attr:byte; Str:string); This method writes the string centered between two X coordinates. If the text is too long to fit between the coordinates, the full string is written starting at X1. Writing to the Screen 5-5 -------------------------------------------------------------------------------- WriteRight(X,Y,Attr:byte; Str:string); WriteAT writes the text left-justified at the X coordinate. This method, WriteRight, writes the text right-justified at the X coordi- nate. The last character of the string will be positioned at (X,Y). WriteVert(X,Y,Attr:byte; Str:string); This method writes the string in a vertical column starting at (X,Y), i.e. the second character will be drawn at coordinates (X,Y+1), and so on. WritePlain(X,Y:byte; Str:string); Whereas Write and Writeln use the default attributes, and all the other methods are passed the display attribute(s), WritePlain uses the exis- ting color attributes at the location where the string is written. Because the display attributes are not modified, this is the fastest screen writing routine in the Toolkit. Listed below is the demo program DEMWR1.PAS and a screen shot of the resultant output. Figure 5.1 [SCREEN] The Screen Writing Methods Program DemoWriteOne; {DEMWR1} USES DOS,CRT, totFAST; begin ClrScr; with Screen do begin WriteCenter(1,attr(white,red),'TechnoJock''s Object Toolkit'); WriteCenter(2,79,'Write Demo One'); WriteAT(5,5,lightgreen,'Written using WriteAT'); WriteHi(5,7,white,cyan,'Written with the Write~Hi~ method'); WriteRight(80,9,yellow,'Written with WriteRight'); WriteCap(5,11,white,cyan,'Written with WriteCap'); WriteCap(5,13,white,cyan,'also written with WriteCap'); WriteVert(40,5,12,'Writevert'); WriteBetween(1,40,15,lightgreen,'Left Half'); WriteBetween(41,80,15,lightgreen,'Right Half'); WritePlain(5,17,'This is written with WritePlain'); GotoXY(5,19); 5-6 User's Guide -------------------------------------------------------------------------------- Write('Good Old Write! '); Writeln('And ...'); Writeln('Good old Writeln'); Writeln(''); System.Writeln('This ','is',' Turbo''s Writeln'); WriteClick(33,24,white,'That''s all Folks!'); GotoXY(1,25); end; end. Clearing the Screen In addition to Turbo's ClrScr function, the Toolkit provides the fol- lowing screen clearing methods in ScreenOBJ: Clear(Attr:byte; Ch:char); This method erases the entire screen and fills the screen with the character Ch, using the specified attribute. PartClear(X1,Y1,X2,Y2,Attr:byte; Ch:char); This method is similar to Clear, except that only the rectangular area between (X1,Y1) and (X2,Y2) is cleared. ClearText(X1,Y1,X2,Y2:byte); The method ClearText erases all the characters in the specified region, but does not change the display attribute. Changing Display Attributes The ScreenOBJ object includes the following method, Attrib, for chang- ing the display attribute of a rectangular area of the screen: Attrib(X1,Y1,X2,Y2,Attr:byte); Changes the display in the region between coordinates (X1,Y1) to (X2,Y2) to the specified attribute. The displayed characters in this region are unscathed except for their color being changed. Writing to the Screen 5-7 -------------------------------------------------------------------------------- Drawing Lines and Boxes ScreenOBJ includes a host of methods for drawing lines and boxes. The boxes may optionally have left, center or right justified title posi- tion at the top, bottom, or in a drop box. Using the standard (upper ASCII) characters, lines may be drawn using either a single or double line. Each line drawing method requires a style parameter, of type byte. A style of 1 indicates a single line, and 2 a double line. When drawing boxes, the following styles should be used: 0 no box border 1 single line box 2 double line box 3 double sides, single top and bottom 4 single sides, double top and bottom 5 single left and upper, double lower and right 6 menu box style If a style value of 7 or greater is specified, the lines are drawn using the ASCII character represented by the style value. Figure 5.2 graphically illustrates the impact of the style parameter, and was generated from the file DEMBX1.PAS. Drawing Boxes The following three methods are included in the ScreenOBJ: Box(X1,Y1,X2,Y2,attr,style:byte); This method draws a rectangular box from (X1,Y1) to (X2,Y2) in the specified attribute and style. Only the box border is drawn -- the area within the box perimeter is not affected. Figure 5.2 [SCREEN] Line Drawing Styles FillBox(X1,Y1,X2,Y2,attr,style:byte); This method is the same as Box, except that the interior of the box is erased (or filled). ShadFillBox(X1,Y1,X2,Y2,attr,style:byte); This method is the same as FillBox, except that a shadow is also drawn. The shadow characteristics are defined with the global instance Shadow- TOT^ (see page 3-12). 5-8 User's Guide -------------------------------------------------------------------------------- Boxes with Titles Often times, you will want to add a title to the box. The method Title- Box will draw a filled box with a title. The syntax of the method is as follows: TitledBox(X1,Y1,X2,Y2,Battr,Tattr,Mattr,style: byte; Title:string); This method will draw a box from (X1,Y1) to (X2,Y2) using the style specified. The box border will be drawn with attribute Battr, the inte- rior of the box will be filled using the attribute Mattr, and the title string will be drawn in the attribute Tattr. By default, the title will be displayed in the center of the top box border. However, by embedding some special characters at the beginning of the string, you can control precisely where the title is positioned. The title can be prefixed with two special character codes to control the justification and position of the title. The justification special characters are as follows: '<' Left Justify '>' Right Justify '+' Center (default) The position special characters are as follows: '^' Top of box '|' In a drop box '_' Bottom of box These special characters should be inserted at the beginning of the title string. It does not matter in which order the justification and position characters are specified. For example, either '<_Hello' or '_Right'); TitledBox(21,12,39,22,27,31,30,1,'_|Drop Right'); TitledBox(61,12,80,22,27,31,30,1,'< Spaced Left '); WriteCenter(24,white,'You get the idea!'); GotoXY(1,25); end; end. Figure 5.3 [SCREEN] Box Title Positions Drawing Lines ScreenOBJ includes the two following methods for drawing simple straight lines: HorizLine(X1,X2,Y,Attr,Style:byte); This procedure draws a horizontal straight line from (X1,Y) to (X2,Y) in the specified attribute. If a style of 1 or 3 is used, a single line is drawn. Styles 2 and 4 result in a double line. Any other style results in a line being drawn using the ASCII character represented by the style number. VertLine(X,Y1,Y2,Attr,Style:byte); This method is similar to HorizLine, except that the line is drawn vertically from (X,Y1) to (X,Y2). Intelligent Lines! There are two line drawing methods designed to help you draw irregular shapes from individual lines. The methods SmartHorizLine and SmartVert- Line are similar to HorizLine and VertLine, but smarter! These smart methods automatically add joints and corners if the line crosses or butts up against another line. The syntax of the smart line drawing methods is as follows: SmartHorizLine(X1,X2,Y,Attr,Style:byte); Draws a horizontal line between (X1,Y) and (X2,Y), using line joining characters as necessary. 5-10 User's Guide -------------------------------------------------------------------------------- SmartVertLine(X,Y1,Y2,Attr,Style:byte); Draws a vertical line between (X,Y1) and (X,Y2), using line joining characters as necessary. Listed below is the demo program DEMBX3, followed by figure 5.4 illus- trating the output. Program DemoBoxThree; {DEMBX3} USES DOS,CRT, totFAST; begin with Screen do begin TitledBox(1,1,80,25,27,31,30,1,' Smart Line Drawing '); FillBox(30,7,50,18,27,2); SmartVertLine(10,1,25,27,2); SmartVertLine(70,1,25,27,1); SmartVertLine(40,7,18,27,2); SmartHorizLine(1,80,10,27,1); SmartHorizLine(1,80,20,27,2); SmartHorizLine(30,50,13,27,1); GotoXY(1,25); end; end. Figure 5.4 [SCREEN] Smart Line Drawing Reading the Screen ScreenOBJ includes the following methods to help you read characters and attributes directly from the screen: ReadChar(X,Y:byte):char; This function method returns the character read from the screen at location (X,Y). ReadAttr(X,Y:byte):byte; This function method returns the display attribute at the screen loca- tion (X,Y). Writing to the Screen 5-11 -------------------------------------------------------------------------------- ReadWord(X,Y:byte; var Attr:byte; var Ch:char); This method is a combination of the ReadChar and ReadAttr functions. It updates the passed parameters Attr and Ch with the attribute and char- acter found at location (X,Y). ReadStr(X1,X2,Y:byte):string; The ReadStr method function reads the characters from (X1,Y) to (X2,Y) and returns the characters concatenated as a string. Drawing Scroll Bars The totFAST unit includes a global instance pointer ScrollTOT^, which defines the cosmetic appearance of all scroll bars used by the Toolkit. Refer to page 3-14 for further information on how to change the Scroll- TOT^ settings. The totWIN unit includes window objects which draw horizontal and ver- tical scroll bars. However, the following two ScreenOBJ methods are available if you need to draw independent scroll bars. In both methods, two values must be passed which control the position of the elevator on the slide bar. WriteHScrollBar(X1,X2,Y,Attr:byte; Current,Max:longint); This method draws a horizontal scroll bar from (X1,Y) to (X2,Y) in the specified attribute. The location of the elevator is controlled by the percentage Current is of Max. WriteVScrollBar(X,Y1,Y2,Attr:byte; Current,Max:longint); This method draws a vertical scroll bar from (X,Y1) to (X,Y2) in the specified attribute. The location of the elevator is controlled by the percentage Current is of Max. Listed below is the demo program DEMSC1.PAS which generates the output shown in figure 5.5. Program DemoScrollOne; {DEMSC1} USES DOS,CRT, totFAST; begin Clrscr; with Screen do begin WriteHScrollBar(1,80,1,31,1,1000); 5-12 User's Guide -------------------------------------------------------------------------------- WriteHScrollBar(1,80,3,31,950,1000); WriteHScrollBar(1,39,5,31,500,1000); WriteHScrollBar(41,80,5,31,25,100); WriteVScrollBar(1,7,23,31,1,50); WriteVScrollBar(3,7,23,31,50,50); WriteVScrollBar(5,7,23,31,2,4); ScrollTOT^.SetScrollChars(chr(30),chr(31),chr(17), chr(16),chr(4),chr(219)); WriteHScrollBar(10,70,11,27,5,10); WriteVScrollBar(50,13,23,27,8,10); GotoXY(1,24); end; end. Figure 5.5 [SCREEN] Scroll Bars Moving Screen Blocks ScreenOBJ includes the following three methods to help you manage rect- angular areas of the screen: Scroll(Way:tDirection; X1,Y1,X2,Y2:byte); The totFAST unit includes the declaration of an enumerated type tDirec- tion, which has the members Up, Down, Left, Right, Vert, Horiz. The Scroll method can be used to scroll a rectangular portion of the screen in any of the first four directions, e.g. Up, Down, Left, or Right. The area between the coordinates (X1,Y1) and (X2,Y2) is scrolled in the direction specified. One line or column of the display area is removed and the opposite line or column is replaced with blanks. For example, if the text is scrolled Up, all the text is moved up one line; the first line of the area is replaced by the second, and the gap vacated by the last line is left blank. CopyScreenBlock(X1,Y1,X2,Y2,X,Y:byte); This method takes a rectangular portion of the screen bounded by the coordinates (X1,Y1) to (X2,Y2) and copies both the characters and the attributes to another location on the screen. The top left coordinates of the newly copied block are located at coordinates (X,Y). MoveScreenBlock(X1,Y1,X2,Y2,X,Y:byte); Writing to the Screen 5-13 -------------------------------------------------------------------------------- This method is similar to CopyScreenBlock, except that the text is moved, i.e. it is removed from the original location and repositioned so the new top left coordinate is (X,Y). Controlling the Cursor The ScreenOBJ object includes a variety of methods for determining the cursor location and style, as well as routines to re-position and re- size it. Listed below are the public methods related to cursor control. GotoXY(X,Y:byte); This method relocates the cursor to the position (X,Y). WhereX:byte; This function method returns the X coordinate of the current cursor location. WhereY: byte; This function method returns the Y coordinate of the current cursor location. CursOff; This method makes the cursor invisible. CursOn; This method makes the cursor visible and sets it to the DOS default shape, i.e. a blinking line at the bottom of the character. CursHalf; This method makes the cursor a block filling the lower half of the character field. CursFull; This method makes the cursor a full block filling the entire character field. CursReset; CursReset moves the cursor to the top left of the display and sets it to the DOS default shape. 5-14 User's Guide -------------------------------------------------------------------------------- CharHeight:integer; In text mode, an individual character is comprised of a number of scan lines. Usually, the cursor is located on one or two scan lines near the bottom of the character. Different display systems use varying numbers of scan lines. For example, a monochrome display usually has fourteen scan lines, as does an EGA system, but a CGA has only eight. This method, CharHeight, is a function which returns the actual number of scan lines per character. You will need to use this function if you want to manually set the cursor shape using CursSize (discussed next). CursSize(T,B:byte); This method sets the cursor to the specified top and bottom scan lines. The top scan line (e.g. the top bar of the letter "T") is scan line zero. As an example, to set the cursor on an EGA system to a half block filling the upper half of the character, call CursSize(0,7). CursTop:byte; This function method returns the scan line of the uppermost part of the cursor. CursBot: byte; This function returns the scan line of the lowermost part of the cur- sor. The following program, DEMCU1.PAS, illustrates the main cursor control- ling methods. Execute the program to see how the cursor shape changes. program DemoCursorOne; uses DOS,CRT, totSYS, totFAST; var Ch : char; Temp: byte; procedure Msg; {} begin writeln('Character height: ',Screen.CharHeight); writeln('Press N-on O-off F-full H-half C-condensed S-25 lines Esc- quit'); end; {Msg} Writing to the Screen 5-15 -------------------------------------------------------------------------------- begin Msg; repeat Ch := ReadKey; case upcase(Ch) of 'N': Screen.CursOn; 'O': Screen.CursOff; 'F': Screen.CursFull; 'H': Screen.CursHalf; 'C': begin Temp := Monitor^.SetCondensed; Msg; end; 'S': begin Monitor^.Set25; Clrscr; Msg; end; end; {case} until Ch = #027; Screen.CursOn; Monitor^.Set25; end. The Impact of Windows You may be familiar with the Turbo Pascal CRT Window command which confines writing to a specific area of the screen. The Toolkit also supports this basic windowing feature. Use the method SetWindow to confine screen writing to one area of the screen. The method ResetWindow can be used to "remove" the window set- tings, i.e. set the window back to the entire display. The method Win- dowOFF can be used to temporarily disable the window confinement. WindowON is used to reactivate the window settings. Alternatively, the method SetWinIgnore will instruct all screen writing operations to ignore the current window settings. The full syntax of the window related methods are as follows: SetWindow(X1,Y1,X2,Y2: byte); Restricts all screen writing to the area within the region (X1,Y1) and (X2,Y2). The top left corner of the window area is set to coordinates (1,1). Any attempt to write data outside of the window area is ignored, and strings which are too long to fit are truncated, i.e. only the element of the string which will fit within the window is written. 5-16 User's Guide -------------------------------------------------------------------------------- ResetWindow; Removes the window setting. WindowActive: boolean; Returns true if the screen writing is currently restricted within a window. WindowOff: boolean; Temporarily disables the window settings, and returns true if a window was active. This is useful if you want most of the screen writes to be confined within a window, but you also want to briefly write some text outside the window boundary. For example, the following code fragment could be used to write the time at the lower right of the screen: var WinWasActive: boolean; .... WinWasActive := WindowOff; WriteRight(1,25,white,CurrentTime); if WinWasActive then WindowOn; ... WindowOn; Reactivates the window settings. This method should only be used after a call to WindowOff. WindowCoords(var Coords: tByteCoords); The totFAST unit includes a type, tByteCoords, which is declared as follows: tByteCoords = record X1,Y1,X2,Y2: byte; end; This method will update the passed parameter Coords with the current window settings. SetWinIgnore(On:boolean); When passed a True parameter, this method instructs the Toolkit screen writing methods to ignore the current window settings, and assume that the coordinates (1,1) refer to the top left of the display. Passing a False parameter instructs the Toolkit to adjust all screen writes rela- Writing to the Screen 5-17 -------------------------------------------------------------------------------- tive to the current method. This method is designed for use in hooked procedures when the procedure wants to ignore any window settings which may have been effective when it was invoked. Listed below is the demo program DEMFS1.PAS, which illustrates the impact of the window commands on screen writing. Figure 5.6 shows the screen display generated by the program. Program DemoFastOne; {DEMFS1} USES DOS,CRT, totFAST; var WasOn: boolean; begin Clrscr; with Screen do begin WriteAt(1,1,white,'* 1,1 (original)'); WriteAt(5,5,white,'* 5,5 (original)'); SetWindow(20,8,60,15); Clear(31,' '); WriteAt(1,1,lightcyan,'* 1,1 (in window)'); WriteAt(5,5,lightcyan,'* 5,5 (in window)'); WriteAt(20,7,Lightcyan,'This text is too long to fit!'); GotoXY(1,2); TextColor(Lightcyan); System.Writeln('Written with Turbo''s Writeln'); WasOn := WindowOff; {disable the window} WriteRight(80,23,white,'Written with WindowOff'); WindowOn; WriteAt(1,8,lightcyan,'Window enabled again'); ResetWindow; GotoXY(1,24); end; end. Figure 5.6 [SCREEN] ScreenOBJ Window Commands Please note that the totWIN unit (discussed in chapter 7) provides formatted window support. The window features described in this section 5-18 User's Guide -------------------------------------------------------------------------------- simply influence the coordinates of where text is written. The rich windows implemented in totWIN save the underlying screen and restore the original contents when the window is removed. Using Virtual Screens So far in this chapter, only the physical or visible screen has been discussed. Here we see that the totFAST unit also supports virtual screens. A virtual screen can be considered as an invisible screen - you may write to the virtual screen, but the changes are not visible on the display. A virtual screen can be copied (i.e. displayed) to the visible screen at any time. Virtual screens allow a programmer to build a number of "out of sight" screens which can be popped into view at a moment's notice. A good application is the preparation of help screens. After a virtual screen instance has been initialized with INIT, it must be created. A virtual screen can be created by one of two methods. A copy can be taken of the physical screen using the method SAVE, or a new blank screen can be created with the method CREATE. Once you have created a virtual screen, you can write to it using the ScreenOBJ methods as described previously in this chapter. You can also set the screen windows and change the cursor location and shape. In fact, you can use all the ScreenOBJ methods described in the previous section - instead of affecting the visible screen, the virtual screen is updated. For example, the following code fragment creates a virtual screen, MyScreen, and writes to it: with MyScreen do begin Init; Create(80,25,' '); WritePlain(1,1,'This is written to the virtual'); WritePlain(1,2,'screen, not the visible screen.'); GotoXY(20,20); .... end; Saving the Visible Screen To create a screen which is a copy of the physical screen, initialize the instance and then call the Save method. For example: Writing to the Screen 5-19 -------------------------------------------------------------------------------- var Screen1: ScreenOBJ begin Screen1.Init; Screen1.Save; .... end. All the text being displayed on the screen, together with the display attributes, is copied to the virtual screen. The virtual screen cursor is initially positioned in the same location as the real cursor. Creating New Virtual Screens The Create method is used to create a new virtual screen without copy- ing the physical screen. The syntax of the Create method is as follows: Create(Width,Depth,Attr:byte); This method creates a virtual screen. The screen will be created Width characters wide and Depth lines deep. Any values in the range 1 to 255 are acceptable. The screen is cleared or blanked, and the display attribute is set to Attr. The following code fragment shows how to create a virtual screen: var Screen1: ScreenOBJ begin Screen1.Init; Screen1.Create(100,150,white); .... end. Although normally you wouldn't need to call them, there are four func- tion methods which return information about the virtual screen. The syntax of these methods is as follows: ScreenPtr:pointer; Returns a pointer to the heap location of the virtual screen. Width:byte; Returns the width of the virtual screen in characters. Depth:byte; Returns how many lines deep the virtual screen is. 5-20 User's Guide -------------------------------------------------------------------------------- Exists: boolean; Only returns true when the virtual screen has been created. Displaying a Virtual Screen The ScreenOBJ provides a number of methods for displaying all or part of a virtual screen, i.e. transferring the information from the virtual screen to the physical screen. A virtual screen can be instantly dis- played, or slid onto the display with interesting visual effects. Note that the coordinates specified in these methods are global coordinates, i.e. the methods ignore the current window settings. The syntax of the screen displaying methods is as follows: Display; This method instantly transfers the image stored on the virtual screen to the physical screen. If the virtual screen is smaller than the phys- ical screen, the virtual screen will be drawn at the top left of the display. If the virtual screen is larger than the physical screen, the upper-left portion of the virtual screen will be displayed. SlideDisplay(Way:tDirection); This method operates the same as Display, except the virtual screen sl i d e s ... onto the screen -- just for the fun of it! The method is passed a single enumerated type parameter which may have one of the following values: Up slides up onto the screen from the bottom Down slides down onto the screen from the top Left slides left onto the screen from the right Right slides right onto the screen from the left Vert slides inwards from the left and the right simultaneously (like some drapes closing) Horiz slides inwards from the top and the bottom simultaneously (like teeth closing) PartDisplay(X1,Y1,X2,Y2,X,Y:byte); This method restores a rectangular portion of the virtual screen from virtual coordinates (X1,Y1) to (X2,Y2) and positions this information with the upper-left corner of the image position at physical coordi- nates (X,Y). Writing to the Screen 5-21 -------------------------------------------------------------------------------- PartSlideDisplay(X1,Y1,X2,Y2:byte; Way:tDirection); This method is similar to PartDisplay, except that the image slides onto the display, and the image cannot be relocated, i.e. the image will be placed at coordinates (X1,Y1) on the physical screen. Disposing of a Virtual Screen As with all Toolkit objects, the DONE method must be called when the virtual screen instance is no longer required. When Done is called, the memory reserved for the virtual screen is automatically released. Always call Done! A Virtual Screen Example Listed below is an abbreviation of the demo program DEMVI1.PAS, which illustrates how to manage virtual screens and create interesting visual effects. We can't show the effects in a manual, so just run the pro- gram! Program DemoVirtualOne; Uses CRT, totFast; Var Screen1, Screen2, Screen3 : ScreenObj; {screen objects} HeadCol, MsgCol, NormCol : byte; procedure Pause; {} var Ch : char; begin Ch := ReadKey; end; {of proc pause} procedure Initialize; {} begin Screen1.Init; Screen2.Init; Screen3.Init; HeadCol := Attr(yellow,blue); MsgCol := Attr(yellow,red); NormCol := Attr(white,blue); end; {proc Initialize} 5-22 User's Guide -------------------------------------------------------------------------------- procedure IntroScreen; {} const Tab = 8; begin HeadCol := Attr(yellow,blue); MsgCol := Attr(yellow,red); NormCol := Attr(white,blue); with Screen do {manipulate the visible screen} begin Clear(NormCol,' '); WriteCenter(1,HeadCol,'TechnoJock''s Object Toolkit'); WritePlain(Tab,18,'the display.'); WriteRight(80,25,MsgCol,'Press any key to continue ....'); end; end; {of proc IntroScreen} procedure BuildScreen2; {} const Tab = 8; Tab1 = 10; begin HeadCol := Attr(yellow,red); MsgCol := Attr(yellow,red); NormCol := Attr(white,red); with Screen2 do begin Create(80,25,NormCol); WriteCenter(1,HeadCol,'Screen Writing'); WritePlain(Tab,6,'methods, including the following:'); GotoXY(57,23); end; end; {of proc BuildScreen2} procedure BuildScreen3; {} const Tab = 8; begin HeadCol := Attr(yellow,blue); MsgCol := Attr(yellow,red); NormCol := Attr(white,blue); with Screen3 do begin Create(80,25,NormCol); TitledBox(1,1,80,25,NormCol,HeadCol,NormCol,4,'|Box drawing'); CursOff; end; end; {of proc BuildScreen3} Writing to the Screen 5-23 -------------------------------------------------------------------------------- begin Initialize; IntroScreen; BuildScreen2; BuildScreen3; Pause; Screen1.Save; Screen2.SlideDisplay(horiz); Pause; Screen3.SlideDisplay(vert); Pause; with Screen do begin SmartHorizLine(1,80,14,white,1); SmartVertLine(35,8,19,white,2); SmartVertLine(64,10,19,white,2); WriteCenter(25,attr(black,white),'That''s all Folks!'); end; Pause; Screen1.Done; Screen2.Done; Screen3.Done; ClrScr; Screen.CursOn; end.