Class VCrt() Foundation

Class function of the VCrt class

Description

Instances of the VCrt class provide a virtual text screen that can be used as the output device in character mode applications. It is designed for programming text mode window systems. A VCrt object is created, just like an Xbase Part, with the :new() method followed by a call to :create(), which requests resources from the operating system. Output appears on the virtual text screen after the VCrt object is defined as the output device. This is accomplished by passing the object to the SetAppWindow() function, or by its :select() method. The basic utilization of a VCrt object follows this pattern:

oVCrt := VCrt():new( 4, 4, 10, 40 ):create() 
SetAppWindow( oVCrt ) 

These two lines create a virtual text screen of 10 rows and 40 columns in size, position it at the coordinate 4, 4 on the physical screen, and define it as the output device. The most important aspect of being the output device is that the VCrt object controls keyboard, mouse and screen. All screen output is then limited to the area on the physical screen that is managed by the VCrt object. This applies to all functions performing screen output, be it QOut(), @...SAY, Browse() or MemoEdit(). When a VCrt is the output device, the origin for screen coordinates is no longer the upper left corner of the physical text screen but moved to the upper left corner of the virtual text screen. An output outside the virtual text screen is no longer possible. If a string has more characters than a VCrt object has columns, for example, the string is truncated when displayed (Function DisplOut()) or is displayed in multiple rows (Function QOut()).

A VCrt behaves just as the physical screen in text mode, except that it has its own coordinate system. All functions which retrieve information about the screen, like Row(), Col(), MaxRow() and MaxCol() for example, or those which define system settings, (SetColor() or SetCursor()), apply to the current VCrt object. When a new VCrt object is created, it uses system settings from the current one as default values and is displayed in the current window. This offers the possibility to display a VCrt object inside another one, and to program a scrollable virtual text screen that exceeds the size of the physical text screen.

Class methods
:new()
Creates an instance of the VCrt class.
Life cycle
:create()
Requests system resources for the VCrt object.
:configure()
Reconfigures the VCrt object after :create() has been executed.
:destroy()
Releases the system resources of the XbpPushButton object.
Methods
:physicalPos()
Calculates the absolute position on the screen.
:select()
Defines the VCrt object as current output device.
:setMode()
Sets or retrieves the size of a VCrt object.
:setOrigin()
Sets or retrieves the position of a VCrt object.
Examples
Displaying virtual screens in text mode

// Two VCrt objects are created in this example which are selected 
// with a left mouse click. The relative and absolute position of 
// the mouse pointer is displayed in the current output device. 
// Also, keyboard input is displayed in the current window. 

#include "Appevent.ch" 

PROCEDURE Main 
   LOCAL nEvent, mp1, oCrt, oRootCrt, oCrt1, oCrt2 
   LOCAL aPos 

   SetMouse( .T. ) 
   SetColor( "W+/BG" ) 
   CLS 
   oRootCrt := SetAppWindow() 
   ? "RootCrt" 

   oCrt1 := VCrt():new( 10,  0, 15, 40, "W+/B" ) 
   oCrt1:create():select() 
   CLS 
   ? "VCrt 1" 

   oRootCrt:select() 
   oCrt2 := VCrt():new( 10, 40, 15, 40, "W+/G" ) 
   oCrt2:create():select() 
   CLS 
   ? "VCrt 2" 

   oCrt1:select() 
   oCrt := oCrt1 

   DO WHILE nEvent <> xbeK_ESC 
      nEvent := AppEvent( @mp1 ) 

      DO CASE 
      CASE nEvent == xbeM_LbDown    // Left mouse button is pressed 
         aPos   := oCrt:physicalPos( mp1 ) 

         @ 0, 0 
         ?? "Relative Position:", Str(mp1[1],3) + ","+ Str(mp1[2],3) 
         ?  "Absolute Position:", Str(aPos[1],3)+ ","+ Str(aPos[2],3) 

         IF oCrt == oRootCrt        // Physical position 
            DO CASE                 // on screen 
            CASE mp1[1] < 10        // No VCrt is hit 
            CASE mp1[2] > 40 
               oCrt := oCrt2 
            OTHERWISE 
               oCrt := oCrt1 
            ENDCASE 
         ELSE                       // Relative position within VCrt 
            DO CASE 
            CASE mp1[1] < 0 
               oCrt := oRootCrt 
            CASE mp1[2] < 0 
               oCrt := oCrt1 
            CASE mp1[2] > MaxCol() 
               oCrt := oCrt2 
            ENDCASE 
         ENDIF 

         oCrt:select() 

      CASE nEvent > 0 .AND. nEvent < 255 
         IF nEvent == 13 
            ? "" 
         ELSE 
            ?? Chr( nEvent ) 
         ENDIF 
      ENDCASE 

   ENDDO 
RETURN 
Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.