Chapter 9 of the Turbo Pascal Reference The Turbo Vision Reference (continued) This chapter is part of the Turbo Pascal Reference electronic freeware book (C) Copyright 1992 by Ed Mitchell. This freeware book contains supplementary material to Borland Pascal Developer's Guide, published by Que Corporation, 1992. However, Que Corporation has no affiliation with nor responsibility for the content of this free book. Please see Chapter 1 of the Turbo Pascal Reference for important information about your right to distribute and use this material freely. If you find this material of use, I would appreciate your purchase of one my books, such as the Borland Pascal Developer's Guide or Secrets of the Borland C++ Masters, Sams Books, 1992. Thank you. For additional information on using Turbo Vision, including a detailed tutorial, please see Chapters 11 through 16 of the Borland Pascal Developer's Guide. TFrame object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TFrame Discussion TFrameobjects, like many of the objects in Turbo Vision, are automatically managed by Turbo Vision and you will rarely need to instantiate, let alone, directly access any of its methods. The TFrame object defines the border or "frame" that wraps around each window and is automatically created by TWindow.Init which calls TWindow.InitFrame. Fields None Methods procedure Draw; virtual; This method draws the frame, adding the owner's Title string, and the appropriate icons such as the close box, the zoom icon and the resize icon, as specified by the inherited TView.State flags. function GetPalette: PPalette; virtual; Returns a pointer to the default palette CFrame. In the unlikely event that you need to change a TFrame's color, you need to override TWindow.InitFrame to instantiate a new, TFrame-derived object with an overridden GetPalette. The overridden GetPalette then returns a pointer to the modified color palette mapping. You need to go through this indirect approach of overriding both TWindow.InitFrame and creating a new TFrame-type object because TFrame is normally used only internally to Turbo Vision. Hence, you must override the routine in TWindow that actually instantiates the TFrame. You can see an example of this type of operation in the description of TBackground. procedure HandleEvent(Event : TEvent); Calls TView.HandleEvent for general event processing, and then processes events for the TFrame icons. constructor Init(var Bounds: TRect); Creates a new TFrame object having the size and location specified by Bounds. This method is called by TWindow.InitFrame. See: TWindow.InitFrame procedure SetState(AState: Word; Enable: Boolean; virtual; TFrame.SetState passes its parameters to TView.SetState, and then checks TView.State to see if either sfActive or sfDragging are set. If these bits are set, then TFrame.SetState calls TView.DrawView. TGroup object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TGroup TWindow TDialog TDeskTop TProgram Discussion The TGroup object manages groups of objects, all of which are descended from TView. In effect, TGroup keeps track of a group of subviews, such as multiple windows on the desktop, or all of the controls within a dialog. TGroup provides the functionality to manipulate the grouped views as if they were a single view, although TGroup itself, surprisingly, is an invisible view. That's because each of the subviews contained within a group defines the group itself. For example, a TDialog contains a window, a frame, a dialog interior and a collection of controls such as input lines, checkboxes and buttons. The TDialog object is the manager of these dialog box components and is actually invisible. WhenTDialog.Draw is called to draw itself on the screen, it doesn't actually draw anything; instead, TDialog.Draw calls each of the subview's Draw methods (the window, the frame, the buttons and so on). Commonly Used Features For most applications you will use only a few of the methods provided by TGroup, including the Init constructor (via the subview's inherited Init methods), ExecView to execute a modal dialog box, Insert to add a subview to the group, and GetData and SetData to read and write the data fields of the owned views (particularly for dialogs). TGroup is an internal object used to support other Turbo Vision objects (such as TWindow or TDialog), and the remaining methods are used to implement their specific functionality. It is unlikely that you will need to instantiate a TGroup directly. Example See TApplication, TDeskTop, TDialog, TWindow Fields Buffer: PVideoBuf; { Read only } When caching of views is in effect, the contents of the group of views is stored in a temporary cache buffer to speed up screen redrawing. Buffer points to the memory buffer used for caching, or is nil if no cache buffer has been defined. See GetBufMem, TGroup.Draw, TGroup.Lock, TGroup.Unlock Current: PView; { Read only } Is a pointer to the currently selected view (the view whose Select method has been called). See: TView.Select, Chapters 16 and 18. Last: PView; { Read only } Last is a pointer to the subview that is on the bottom of the Z-ordered list of views. Each view contains a TView.Next pointer that points to the next view in the list. Phase: (phFocused, phPreProcess, phPostProcess); { Read only } Subviews can examine this field to determine at which phase in the event processing their HandleEvent method was called. See Chapter 13, "More Turbo Vision Features" in the Borland Pascal Developer's Guide for a more in depth discussion of phased event processing. Methods procedure ChangeBounds(var Bounds: TRect); virtual; Override: Never A group is resized or moved by calling ChangeBounds, which, in turn, calls TView.CalcBounds to recalculate new boundaries for its subviews, and then ChangeBounds to reposition the subviews. These calls are made for every subview in the group. function DataSize: Word; virtual; Calls each subview's DataSize method and creates a total data size value for the entire group. This function is normally used in conjunction with GetData and SetData for retrieiving specific field values. procedure Delete(P: PView); Use Delete to remove a previously inserted view from a group. For example, if you have inserted a view, like this, Insert(DirWindow); you remove the subview by calling, Delete(DirWindow); destructor Done; virtual; Call Done to dispose of the group and its contents. Done first hides the group and then calls each view's Done destructor, and finally disposes of itself. procedure Draw; virtual; If Buffer is nil, then TGroup.Draw calls each subview's Draw method. If Buffer is not nil, then Draw calls TView.WriteBuf to copy the cached view image to the screen. See: TGroup.Buffer procedure EndModal(Command: Word)(; virtual; Override: Never When the currently active dialog, for instance, that has been placed on the screen with the TGroup.ExecView method, it is the current modal view. A call to this procedure terminates the modal nature of the view and passes the Command value to ExecView, which in turn, returns Command to the caller. If a group is not currently a modal view, TGroup.EndModal calls TView.EndModal which has approximately the same result, causing ExecView to return Command to its caller. See: TView.EndModal procedure EventError(var Event: TEvent); virtual; If TGroup.Execute encounters an event that it cannot handle, it first calls TGroup.EventError, which attempts to call its owner's EventError method. You can override this function to intercept errors, if needed. function ExecView(P: PView): Word; Besides Init, Done and Insert, this is one of the most commonly used methods in a TGroup object. Call ExecView to display a modal view, such as a dialog box, on the screen. When a modal view is on the screen, all events are handled by the modal view. You can not, for instance, make menu selections or press short cut keys to activate non-dialog box functions. You must first terminate the modal dialog before resuming regular program operation. ExecView returns the command code that caused the view to complete. This might be cmOk, cmCancel or some other code that you have defined as part of the dialog definition. See: TGroup.Insert, TGroup.Delete, Chapter 12 function Execute: Word; virtual; Execute is the TGroup's main event processing loop, fetching events and then calling HandleEvent to process each event. The loop is terminated when a view calls EndModal. Execute returns the command code that caused the termination, and that is passed to ExecView for return to the caller. See: TGroup.EndModal, TGroup.HandleEvent function First: PView; Returns a pointer to the subview within the group that is currently "on top" or closest to the screen. If, for some reason, this is called when the group has no subviews, First returns nil. function FirstThat(Test: Pointer): PView; Test is a pointer to a far local function having one Pointer parameter and returning either True or False. This iterator function operates identically to the TCollection.FirstThat iterator, except that TGroup.FirstThat scans through the list of subviews within the group, in Z-order (see Chapter 13, "More Turbo Vision Features".) See: Chapter 14, "Collections", TCollection.FirstThat procedure ForEach(Action: Pointer); Action is a pointer to a far local procedure having one Pointer (or PView) parameter. ForEach scans through the subviews in Z-order, and for each subview it calls the Action procedure with a pointer to the subview. TGroup.ForEach operates similarly to TCollection.ForEach, except that you should normally call TGroup.Lock prior to calling TGroup.ForEach, and TGroup.Unlock after calling ForEach. This is particularly important when the ForEach iterator is used such that each subview is redrawn on the screen and TGroup is using a cache Buffer. Lock causes subsequent screen writes to go only to the cache Buffer, and Unlock then copies the entire Buffer to the screen. If you do not use Lock/Unlock, each of the subviews will repaint on the screen individually, causing a potentially annoying visual effect. See: Chapter 14, "Collections", TGroup.Buffer, TGroup.Lock, TGroup.Unlock procedure GetData(var Rec); virtual; Calls each subview's GetData procedure in reverse Z-order, copy each subview's data to the Rec variable. After calling each subview's GetData procedure, GetData adds the subview's DataSize value to Rec so that Rec now points past the data it just copied, making it ready to read the next subview's data. See: TView.DataSize, TGroup.SetData function GetHelpCtx: Word; virtual; Calls the currently Selected subview's GetHelpCtx to return the subview's context sensitive help index. If the subview doesn't have any context sensitive help, then GetHelpCtx returns the value of the help context for the entire TGroup. procedure GetSubViewPtr(var S: TStream; var P); This procedure is called from within TGroup.Load to read a subview pointer P from stream S. See: TGroup.Load, TGroup.PutSubViewPtr, TGroup.Store procedure HandleEvent(Event: TEvent); virtual; The TGroup.HandleEvent method passes most events onto the appropriate subview's HandleEvent method according to whether the event is a focused event, positional event or broadcast event. See Chapters 12 and 13 in the Borland Pascal Developer's Guide for a detailed description of event processing. constructor Init(var Bounds: TRect); TGroup's Init method calls TView.Init, and sets the TView.Options variable to ofSelectable and ofBuffered. The latter option enables cache buffering of the view's Draw output, if sufficient memory is available. TView's EventMask field is set to $FFFF which causes this view (or group) to respond to all classes of events. procedure Insert(P: PView); Use Insert to place a non-modal view into the group. For example, Insert is used to place windows onto the TDeskTop group object, as well as all of the individual controls within a dialog object. See: TGroup.Delete, TGroup.ExecView, TGroup.InsertBefore procedure InsertBefore(P, Target: PView); InsertBefore enables you to insert a view at any location within an existing group. The view P becomes inserted before (in Z-Order) the view specified by Target. If Target is nil, then P is inserted at the very back of the view, furthest from the screen. constructor Load(var S: TStream); Load creates a new TGroup object and reads each subview from stream S. procedure Lock; When using the cache Buffer to speed up screen output, setting Lock prevents the Buffer contents from being written to the screen. This way, multiple items or views can be written to the Buffer without causing annoying flicker, and then by calling Unlock, the entire Buffer is copied to the screen in one operation. Lock operates by incrementing a lock counter each time that it is called. Unlock decrements the counter and once the counter reaches zero, copies the Buffer to the screen. Important: Lock and Unlock must always be called in matched pairs to avoid leaving the Buffer in a locked state. If that happens, no output will be sent to the screen. See: GetBufMem, TGroup.ForEach, TGroup.Unlock procedure PutSubViewPtr(var S: TStream,; P: PView); This method is used in conjunction with the TGroup.Store method to write a subview pointer to stream S. See: TGroup.GetSubViewPtr, TGroup.Load, TGroup.Store procedure Redraw; Redraw forces an actual screen draw to occur, rather than merely copying from the cache Buffer. Otherwise, Redraw is the same as TGroup.Draw. procedure SelectNext(Forwards: Boolean); SelectNext complements the TView.Select method for making a view the focused view. If Forwards is True, then the next subview in Z-Order from the currently selected view becomes the focused view. If Forwards is False, then SelectNext moves to the previous subview. procedure SetData(var Rec); virtual; SetData is used in conjunction with GetData for accessing the data in the group. SetData calls each subview's SetData method, copying data from Rec to the subviews. procedure SetState(AState: Word; Enable: Boolean); virtual; TGroup.SetState sets or clears the bits in each subview's State field, to accomodate setting focused, active, exposed or dragging bits within State. See: TView.SetState, sfXXXX constants procedure Store(var S: TStream); Outputs all the TGroup and all of its subviews to stream S. procedure Unlock; Unlocks a previously locked cache Buffer and copies the contents of the Buffer to the screen. See: TGroup.Locked function Valid(Command: Word): Boolean; virtual; If all of the subview's Valid functions return True, then TGroup.Valid returns True, otherwise TGroup.Valid returns False. Since Valid is called when the Execute procedure is going to exit, a subview can retain control and prohbit the group from terminating by setting its Valid function to return False. See: TGroup.Execute, TView.Valid THistory object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView THistory Discussion THistory implements the history windows that display a down arrow icon on the right hand side of dialog input fields. Using THistory, a history of previously entered data is retained for future reference. Each time you enter a new value into an input field that is linked to a THistory object, the old value is stored away in a THistory list. Later, when you return to the input field, you can press down arrow or click on the down arrow icon to open a small list viewer showing your previous entries. This feature is especially useful in applications such as the Turbo Pascal IDE, where you tend to refer back to files you have opened previously. Hence, the open file dialog contains a history of the files you have recently opened. The THistory object is surprisingly easy to use considering the functions that is provides. All that needs to be done is to create the object using its Init constructor and insert it into the dialog. Data is then automatically copied from the TInputLine field to the THistory and back again, as appropriate. It is not recommended that you attempt to override any of the defined methods, except perhaps THistory.GetPalette. If you must override any of the methods, you are strongly encouraged to view the Turbo Vision source, available as a separate product from Borland. Example This short example demonstrates the use of the THistory object in a dialog, by modifying the TShell.ConfigureData procedure of TVSHELL8 (and example proggram shown in the Borland Pascal Developer's Guide), so that the EditorName field now contains a THistory list. The variable AnHistory is declared as a PHistory pointer. In the original procedure, EditorName is declared as a PView so it is recast to a PInputLine for passing to the THistory.Init constructor. To use THistory, define a Bounds rectangle for the THistory icon, typically immediately to the right of the input field, call the Init constructor, passing to it the location, a pointer to the linked input field, and a numeric value. The numeric value (from 0 to 255) uniquely defines this THistory list so that you could gain access to it from other fields. That means, more than one input field can reference the same history list by always referencing the same history list number. Alternatively, you can use different history identification numbers for each input field and have as many separate history lists as your application requires. { Editor name } Bounds.Assign (18, 2, 50, 3); EditorName := New( PInputLine, Init(Bounds, ConfigNameSize) ); Insert(EditorName); { Define the location for the THistory down arrow icon } Bounds.Assign(50, 2, 52, 3); AnHistory := New(PHistory, Init(Bounds, PInputLine(EditorName), 1 )); Insert(AnHistory); Bounds.Assign (2, 2, 15, 3); Insert( New (PLabel, Init(Bounds, '~E~ditor name:', EditorName ))); Fields HistoryId: Word; { Read only } Contains the history list number assigned as the third parameter to the Init constructor. Link: PInputLine; { Read only } Points to the input line field's TInputLine object that is associated with this history list. Methods procedure Draw; virtual; Displays the icon representing the THistory object, at the location determined by the Bounds parameter to Init. function GetPalette: PPalette; virtual; Returns a pointer to the CHistory color palette, which is intended for mapping onto the CDialog color palette. constructor Init(var Bounds: TRect; ALink: PInputLine; AHistoryId: Word);] Creates the THistory object, defining its location at Bounds, and linking to the ALink input field. AHistoryID is a number assigned by you to uniquely identify this particular history list. If you want, you can initialize other THistory objects that are linked to other input fields using the same AHistory number. When the input fields have the same AHistory number, they will all share the same history list. constructor Load(var S: TStream); Creates and reads a THistory object from stream S. procedure Store(var S: TStream); Writes this THistory object to stream S. THistoryViewer object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TListViewer THistoryViewer Discussion THistoryViewer manages the history list viewer that is displayed and owned by THistory. Normally, you will access the THistory object when you wish to use history lists in your applications, and will unlikely have any need to directly use THistoryViewer. Fields HistoryId: Word; { Read only } This contains the history identification number (see THistory) selecting which history list is to be displayed in the list box managed by THistoryViewer. Methods function GetPalette: PPalette; virtual; Returns a pointer to CHistoryViewer. function GetText (Item: Integer; MaxLen: Integer): String; virtual; GetText is the overridden TListViewer function, implemented here to return the specific history list string indexed by Item, such that the returned string is less than or equal to MaxLen in size. See TListViewer.GetText procedure HandleEvent(var Event: TEvent); virtual; HandleEvent processes mouse double clicks and the Enter key for selecting a file from the list box, and pressing the Esc key in order to cancel the list box. function HistoryWidth: Integer; Determines the longest string in the history list. constructor Init (var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar; AHistoryId: Word); Calls TListViewer.Init to create a single column listbox with the specified scroll bars, and links it to the THistory specified by AHistory. Basically, when the THistory object is made active by selecting its icon or pressing the down arrow key, THistory creates a THistoryWindow object by calling InitHistoryWindow, and the THistoryWindow object, in turn, creates this TListViewer object to display the history list and manage the selections. THistoryWindow object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TGroup TWindow THistoryWindow Discussion When the THistory history list icon is selected, the THistory object creates a TWindow object in which to insert the THistoryViewer. Therefore,the THistoryWindow is primarily useful to the implementation of THistory and is not likely to be used directly by your programs. See the THistory object for an example use of history lists. Fields Viewer: PListViewer; Contains a pointer to the THistoryViewer list box that is created by this object. Methods function GetPalette: PPalette; virtual; Returns a pointer to CHistoryWindow, which is designed to map onto a dialog palette. function GetSelection: String; virtual; Determines which list box item in the THistoryViewer has the focus, and returns that specific string. constructor Init(var Bounds: TRect; HistoryId: Word); Creates the THistoryWindow by calling TWindow.Init with appropriate parameters, and then calls InitViewer. procedure InitViewer(HistoryId: Word); virtual; This is the routine that creates the THistoryViewer list box. TInputLine object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TInputLine Discussion Use TInputLine as an edit field in dialog boxes when you need to have the user type in information such as a filename or other text. TinputLine is a powerful single line editor, providing horizontal scrolling, line editing, text selection and block deletion. If the size of the input line field is less than the maximum permitted length of the input, then TInputLine will automatically provide left and right scrolling. Commonly Used Methods and Fields When TInputLine is inserted into a dialog, you will generally use only TInputLine.Init to create the input field and will not likely have use for any of the other methods or fields. The TInputLine will become active when it receives the focus and will automatically process its input via its HandleEvent method. TInputLine processes string input however you could override several of its methods in order to process other types of data. For instance, to handle numeric input, you would create a new TInputLine-derived object and override TInputLine.Valid to check for valid numeric entries, and modify GetData to convert the entered string into a numeric representation for processing. You would also need to modify SetData, and if you intend to use the object with streams, you'd need to create new versions of Load and Store. Example This example shows instantiating a TInputLine object having a maximum input length of 40 character, and places within the rectangle defined by (3, 3, 44, 4). The TInputLine object is then inserted into the dialog group, and a TLabel is attached as a prompt. (See also TLabel). At the completion of the dialog setup, the dialog will be displayed for editing with Control := DeskTop^.ExecView( Dialog ); Be sure to look at the examples in the TVSHELL program described in Chapters 11-12 of the Borland Pascal Developer's Guide: with Dialog^ do begin ... { Add the Rename from this filename item } Bounds.Assign (3, 3, 44, 4); OldFileName := New( PInputLine, Init(Bounds, 40) ); Insert(OldFileName); Bounds.Assign (2, 2, 44, 3); Insert( New (PLabel, Init(Bounds, 'Rename this file:', OldFileName ))); ... end; { with Dialog } Fields CurPos: Integer; { Read/Write } This field is used internally to keep track of the cursor's location within the input field. Data: PString; { Read/Write } Contains the pointer to the string that is being edited by the TInputLine. FirstPos: Integer; When horizontal scrolling is being used to display portions of the line that do not fit within the specified bounds of the TInputLine, FirstPos contains the index of the first byte that appears at the left of the field. MaxLen: Integer; MaxLen contains the maximum number of characters for the line length, as specified in the TInputLine.Init method. Methods destructor Done; virtual; Disposes of the memory used by TInputLine and disposes of the object. function DataSize: Word; virtual; GetData and SetData call DataSize to determine how much space needs to be reserved for the data returned by TInputLine. Normally this is equal to MaxLen + 1, which is the maximum number of characters that can be entered, plus the length byte. See: TInputLine.GetData, TInputLine.SetData procedure Draw; virtual; Draw takes care of displaying the input line text on the screen, adding arrows when horizontal scrolling is in effect. procedure GetData(var Rec); virtual; Copies the Data^ text string to Rec. See: TInputLine.DataSize, TInputLine.SetData function GetPalette: PPalette; virtual; Returns a pointer to the CInputLine color palette. If you desire to use a different color mapping, you should derive a new object from TInputLine and override GetPalette as per the instructions in Chapter 13, "More Turbo Vision Features", of the Borland Pascal Developer's Guide. procedure HandleEvent(var Event: TEvent); virtual; When the input line is the focused event, TInputLine.HandleEvent process the mouse and editing keystroke events, including entering and selecting text, horizontal scrolling and so on. constructor Init( var Bounds: TRect; AMaxLen: Integer); Use TInputLine.Init to create a new TInputLine object located at the position specified by Bounds (which specifies the length of the visible data entry field) and AMaxLen (which specifies the maximum length that the entered string can become). Bounds should describe a one line input field; if you specify a multi-line rectangle, TInputLine will not behave correctly. constructor Load(var S: TStream); Creates and reads a TInputLine object from stream S. procedure SelectAll(Enable: Boolean); If Enable is True, SelectAll block selects the entire data input line and resets all the internal pointers (such as CurPos cursor location) to the beginning of the string. If Enable is False, all selection is turned off. In both cases, the resultant input field is displayed on the screen by calling the inherited TView.DrawView. procedure SetData(var Rec); virtual; Copies the string value in Rec to Data^ and calls SelectAll. See: TInputLine.SelectAll procedure SetState(AState: Word; Enable: Boolean); virtual; Calls TView.SetState (See TView.SetState for more information) and performs additional processing for TInputLine. procedure Store(var S: TStream); Writes the TInputLine object to stream S. TItemList type ------------------------------------------------------------ Declaration: TItemList = array[0..MaxCollectionSize-1] of Pointer; Unit: Objects Purpose: This is an internal object type used for maintaining an array of pointers in TCollection objects. TLabel object ------------------------------------------------------------ Turbo Vision Hierarchy: TObject TView TStaticText TLabel Discussion TLabel objects are similar to TStaticText in that they are typically used to display a prompt line for dialog box controls such as an input field or a group of radio buttons. TLabel objects differ from TStaticText only in that they are explicitly linked to the control such that if you click with the mouse to select the TLabel object you actually select the attached control. Using this feature, you can use keyboard Alt-letter shortcut keys to reach input fields and other controls in a dialog box. Example { Create an input line field 40 spaces wide } Bounds.Assign(3, 3, 44, 4); OldFileName := New( PInputLine, Init( Bounds, 40) ); Insert( OldFileName ); { Create a prompt label for the input field and link to the OldFileName inputline field } Bounds.Assign( 2, 2, 44, 3); Insert( New( PLabel, Init( Bounds, 'Rename this file:', OldFileName ))); Fields Link : PView { Read Only } When a TLabel object is linked to a control, such as an input line, this field contains a pointer to that control. Light: Boolean; { Read Only } Methods procedure Draw; virtual; Override: NEVER Draws the TLabel object using the color palette pointed to by GetPalette. constructor Init (var Bounds: TRect; AText; String; ALink: PView); The Init constructor creates a new TLabel object with the size and location specified in Bounds, and assigns to the label the text specified in AText. The last parameter specifies a pointer to the control that is associated with this label. function GetPalette: PPalette; virtual; Override: As needed to change colors. Returns a pointer to the CLabel color palette. To change the colors of the TLabel object, override this function to return a pointer to a different color palette. The CLabel color palette is defined to properly map onto a dialog's color palette. If, for some reason, you are creating a label to be placed on top of some other type of object, you will almost certainly need to override this function. See: Chapter 13, "More Turbo Vision Features". procedure HandleEvent( var Event: TEvent ); virtual; Override: Never HandleEvent performs the usual event processing by calling TStaticText.HandleEvent to do most of the work. However, TLabel.HandleEvent intercepts certain mouse down and keyboard shortcut keys in order to select attached controls. constructor Load( var S: TStream ); Loads a TLabel object from stream S. See: Chapter 15, "Streams" procedure Store( var S: TStream ); Stores this view on to stream S. See: Chapter 15, "Streams" TListBox object ------------------------------------------------------------ Turbo Vision Hierarchy: TObject TView TListViewer TListBox Discussion Use TListBox to implement list boxes containing collections of strings. For example, a dialog box to open a file typically contains a list of filenames and subdirectories. To use TListBox you must create and initialize a collection of PStrings containing the items to appear in the list box, and then instantiate and initialize the list box. While TListBox is intended for use with string data, you can optionally override TListBox.GetText to process non-string data. TListBox is derived from TListViewer, so all of TListViewer's methods and fields are available to TListBox objects. See: TListViewer Commonly Used Features To use the TListBox, you'll call Init to create the box, and then NewList to initialize the list that is displayed. If you wish to display items other than simple strings, you'll need to override GetText. Example TListBox is nearly identical to TListViewer except that TListBox does not support the horizontal scroll bar. Further, TListBox manages the data list internally since its designed, by default to have GetText return a string. To use TListBox, you call TListBox.Init in a manner identical to TListViewer.Init (except that there is no horizontal scroll bar). Next, you call TListBox.NewList to pass a collection of strings to the TListBox for display. Fields List: PCollection; { Read only } Holds a pointer to the collection of items to display. Typically this would be a collection of PStrings, however, if you store other object types you will also need to override GetText. See: TListBox.GetText Methods constructor Init(var Bounds: TRect; ANumCols: Word; AScrollBar: PScrollBar ); Init creates the new TListBox object using the size provided in Bounds, the number of columns specified by ANumCols, and links it to the scroll bar passed as the AScrollBar parameter, or nil if there is no scroll bar. If you do add a scroll bar, you'll need to instantiate the TScroller object prior to calling Init, and you'll need to insert both the list box and the scroller into the owner's view. After calling Init, you should call NewList to assign the data collection to this list box. There is no Done destructor for TListBox since it is inherited from TListViewer. However, you do need to dispose of the contents of List. Oneway to do that is to call NewList(nil) which then disposes of the current List and sets List to nil. See: TListBox.NewList function DataSize : Word; virtual; Override: As needed. This method is used in conjunction with the TListBox GetData and SetData methods for writing and retrieving TListBox dialog data. The default definition of DataSize returns SizeOf(Pointer) + SizeOf(Word). See: GetData, SetData, "The List Box Viewer", in Chapter 12, "Turbo Vision Dialogs and Events", in the Borland Pascal Developer's Guide. procedure GetData(var Rec); virtual; Override: As needed. GetData copies the List and Focused (from TListViewer) fields to Rec. See: DataSize, SetData, Chapter 12 function GetText(Item: Integer; MaxLen: Integer):String; virtual; GetText is called by the inherited TListViewer.Draw method to obtain the string to draw on the display. The standard implementation retrieves the Item'th entry in the List^ collection as, PString(List^.At(Item))^ Its possible to store non-string items in a TListBox type, but to do so you will need to override GetText. constructor Load( var S: TStream ); Creates and reads a TListBox object from stream S, including the data collection linked to the list box. See: Store, Chapter 16, "Collections". procedure NewList(AList: PCollection); virtual; After calling Init to create a new TListBox objecct, you need to link a data collection to the list box. You do this by passing the collection as a parameter to the NewList method, which sets List to point to the collection, and sets the list box Range to the collection's Count field and draw's the list box view by calling DrawView. If List is not nil when NewList is called, NewList disposes of the previous collection before setting List to the new collection. procedure SetData(var Rec); virtual; Copies values from Rec into the List and Focused fields and then calls NewList(List) in order to reset and display the new list. See: DataSize, GetData procedure Store(var S: TStream); Stores the contents of the list box object, including the data collection that is pointed to by List, to the stream S. See: Load, Chapter 15, "Streams". TListViewer object ------------------------------------------------------------ Turbo Vision Hierarchy: TObject TView TListViewer TListBox Discussion Use the TListViewer object type for creating various types of list box viewers. List boxes typically contain lists of information, such as filenames, through which you can scroll and select the desired item. Usingthe TListViewer object, you can create both vertical and horizontal scroll bars. Horizontal scroll bars might be used when creating a simple file viewer for viewing text wider than the list box. Commonly Used Features Call TListViewer.Init to create the list viewer. While the TListViewer manages the display of the list box it is up to you to provide the data structures that store the data shown within the box. You do this by deriving a new TListViewer object type and overriding the GetText function, which returns a string containing one line of text. GetText has two paremeters, an item index and a maximum length value. Its up to GetText to retrieve the Item'th entry in the list and format it into a string of no longer than the specified maximum length. If you insert the TListViewer into any other TGroup besides TDialog, you will almost certainly need to override GetPalette so that the color mapping works correctly. Example { Define TDirList, derived from TListViewer } PDirViewer = ^TDirList; TDirList = object( TListViewer ); function GetText( Item: Integer; MaxLen: Integer):String; virtual; function GetPalette: PPalette; virtual; procedure HandleEvent( var Event: TEvent); virtual end; ... { Instantiate a scroll bar object } ListScroller := New( PScrollerBar, Init( BarBounds )); { Instantiate a list viewer and link it to the scroll bar } ListViewer := New( PDirViewer, Init( Bounds, 1, Nil, ListScroller )); { Insert both objects into the controlling group view } Insert(ListScroller); Insert(ListViewer); Fields HScrollBar: PScrollBar; { Read only } Holds the pointer to the horizontal scroll bar object attached to this list viewer, or is nil if there is no horizontal scroll bar. VScrollBar: PScrollBar; { Read only } Holds the pointer to the vertical scroll bar object attached to this list viewer, or is nil if there is no vertical scroll bar. NumCols : Integer { Read only } This stores the number of columns specified for the list viewer and is initialized with the Init constructor. TopItem: Integer; { Read/Write } TopItem specifies the item appearing at the top of the list box viewer. TopItem varies from 0 to Range-1. Focused: Integer; { Read only } Focused specifies the item number of the focused or selected item and ranges from 0 to Range-1. Keyboard navigation keys, scroll bar movements and mouse clicks and drags all cause the focused item to be updated to point to the current location of the list box cursor. Range: Integer; { Read only } Holds the total number of items in the list. See: TListViewer.SetRange Methods constructor Init( var Bounds: TRect; ANumCols: Integer; AHScrollBar, AVScrollBar: PScrollBar ); Creates a TListViewer object with the size specified by Bounds and the number of columns specified by ANumCols. If you wish to have scroll bars, create the TScroller objects before calling Init, and then pass pointers to those scroll bars to the AHScrollBar and AVScrollBar parameters, for horizontal or vertical scroll bars, respectively, to link them to the list box. Use a value of nil if one or both scroll bars is not defined for this list box. procedure ChangeBounds( var Bounds : TRect ); virtual; Call ChangeBounds to resize the list box viewer to the size specified by the Bounds parameter. procedure Draw; virtual; Override: Never. Draws the list viewer object by calling GetText for each of the objects that could be shown on the screen. procedure FocusItem ( Item : Integer ); virtual; Override: Never. Use FocusItem to make a specific Item in the list box become the focused item. This method automatically causes the scroll bar to be adjusted accordingly. function GetPalette: PPalette; virtual; Override: As needed. Returns a pointer to the color palette for TListViewer objects. The default palette, CListViewer is intended to map directly into a CDialog palette. If you insert the TListViewer object into a view other than the TDialog, you must override the GetPalette function. See: CListViewer, CDialog, Chapter 19, More on Turbo Vision function GetText (Item : Integer; MaxLen: Integer): String; virtual; Override: Always You must implement your own GetText method to return a string representing the data that should appear in the list box at the Item'th position. Your data can be stored in whatever internal representation is appropriate for your application. This might include a collection, an array of records, a linked list, or a simple string array, as shown in this example code: { Fetch data item from internal data structure } StrBuffer := MyData[Item]; { Truncate data string if too long } if Length(StrBuffer) > MaxLen then StrBuffer[0] := Chr( MaxLen); GetText := StrBuffer; function IsSelected (Item: Integer): Boolean; virtual; Use IsSelected to check if a specific item is also the focused item. IsSelected returns True if the entry specified by Item is currently selected, False otherwise. procedure HandleEvent( var Event: TEvent ); virtual; Override: As needed. Performs event processing for the TListViewer, including mouse navigation and clicking in the list box to select an item, the use of the space bar to perform keyboard selection, and all keyboard navigation keys (up and down arrow, PgUp, PgDn, Home, End, etc). Navigation events that move through the list automatically cause the associated scroll bars to update themselves. See: See Chapter 11, "Turbo Vision Tutorial" in the Borland Pascal Developer's Guide for an example. constructor Load( var S : TStream ); Loads a TListViewer object from stream S, and also loads any associated scrollbars. procedure SelectItem( Item: Integer ); virtual; This is intended to be used and overridden by descendants, to make the Item'th entry in the list selected. This routine is essentially equivalent to TListViewer.FocusItem. procedure SetRange( ARange : Integer ); Sets the Range field to ARange or the number of items in the list and automatically adjusts the scroll bars, as needed. If the new range would put the current Focused item value out of range, then Focused is reset to zero. See: TListViewer.Range procedure SetState( AState: Word; Enable: Boolean); virtual; Basically, this calls TView.SetState to set or reset the sfOptions bits in the TView.State variable. See: sfOptions, TView.State procedure Store( var S: TStream); Stores this TListViewer object onto stream S, and stores any associated scroll bars. TMenuBar object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TMenuView TMenuBar TMenuBox Discussion The TMenuBar object manages the menu bar across the top of the application screen. Most applications merely call the TMenuBar.Init method with a series of nested NewMenu, NewSubMenu, NewLine and NewItem function calls to create an entire list of pull down menu items. It's unlikely that you will use any other TMenuBar methods. Example MenuBar := New(PMenuBar, Init(Bounds, NewMenu( NewSubMenu('~R~un', hcNoContext, NewMenu( NewItem('~R~un', '', 0, cmRunProgram, hcNoContext, NewItem('~E~dit', 'Alt-E', kbAltE, cmEdit, hcNoContext, NewItem('~V~iew', 'Alt-V', kbAltV, cmView, hcNoContext, NewItem('~U~se DOS','Alt-D', kbAltS, cmUseDOS, hcNoContext, NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext, nil)))))), ... Fields None Methods procedure Draw; virtual; Draws the menu bar on the display and highlights the selected item. procedure GetItemRect(Item: PMenuItem; var R: TRect); virtual; This internal method is used to determine if a mouse click occurred on a particular menu item. constructor Init(var Bounds: TRect; AMenu: PMenu); Creates an initializes the menu bar. See the example above, and also look at NewMenu, NewSubMenu, NewItem, and NewLine functions. TMenuBox object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TMenuView TMenuBar TMenuBox Discussion The TMenuBox object implements the menu box that drops down from the menu bar. TMenuBox displays the contents of the pulldown menu and processes the keyboard and mouse inputs to make a selection. Commonly Used Features Most applications will never reference the TMenuBox object directly. Instead, pulldown menus are created with the NewSubMenu function nested within the TMenuBar.Init constructor. However, it is possible to use the TMenuBox as a standalone pulldown menu providing a group of items from which to select. For instance, sometimes its not practical to display every option on one of the standard pulldown menus. Instead, consider adding a submenu that gets displayed only when one of the standard pulldown options is selected or perhaps as the result of a button press in a dialog box. The example code below shows how to create and execute a standalone pulldown menu, here emulating the Watches submenu from the Turbo Pascal IDE's Debug menu. Example AMenuBox is a PView-type variable. When passed to DeskTop^.ExecView(), the standalone menu is displayed at the location specified by Bounds. Oncea selection is made from the menu, Command is set to the cmXXXX constant corresponding the selected item. Begin Bounds.Assign(10,5, 40,12 ); AMenuBox := New(PMenuBox, Init( Bounds, NewMenu( NewItem('~A~dd Watch', 'Ctrl-F7', kbCtrlF7, cmAddWatch, hcNoContext, NewItem('~D~elete Watch', '', 0, cmDelWatch, hcNoContext, NewItem('~E~dit Watch...', '', 0, cmEditWatch, hcNoContext, NewItem('~R~emove all Watches', '', 0, cmRemWatch, hcNoContext, nil))))),nil)); Command := DeskTop^.ExecView(AMenuBox); End; Fields None Methods procedure Draw; virtual; Displays the menu box and contents. procedure GetItemRec(Item: PMenuItem, var R: TRect); virtual; GetItemRec is used internally determine if the particular Item was selected by a mouse click. constructor Init(var Bounds: TRect; AMenu: PMenu; AParentMenu: PMenuView ); Use Init to create a new TMenuBox object, where Bounds describes both the size and location of the menu box, and AMenu is normally constructed from a series of nest calls to NewMenu, NewItem and so on. For standard pulldown menus, AParentMenu points to the menu bar, but for standalone menu boxes, this parameter can be set to nil. TMenu type ------------------------------------------------------------ Declaration: TMenu = record Items : PMenuItem; Default : PMenuItem; end; Unit: Menus Purpose: TMenu is used for building up menu bar and pulldown menu records and is created by the NewMenu function. TMenu records are unlikely to be used except for creation and maintanance of the menu bar object. TMenuItem type ------------------------------------------------------------ Declaration: { TMENUITM.PAS } PMenuItem = ^TMenuItem; TMenuItem = record Next: PMenuItem; Name: PString; Command: Word; Disabled: Boolean; KeyCode: Word; HelpCtx: Word; case Integer of 0: (Param: PString); 1: (SubMenu: PMenu); end; Unit: Menus Purpose: TMenuItem records are created using the NewItem, NewLine and NewSubMenu functions, and are used to store a list of TMenuItem records describing each menu item on a pulldown menu. The various fields store the values passed to the NewItem or NewSubMenu functions as follows: Next points to the next item in the menu structure, or is nil if it is the last item in the menu. Name is a PString pointer to the item name, or nil in the case of a NewLine. Command contains the cmXXXX constant value used as an evCommand message to your view's HandleEvent procedure when the item is selected from the menu. Disabled is False normally, but set to True if the item has been disabled. KeyCode contains the hot key's scan code, if any, or zero if there is not hot key defined for this item. HelpCtx contains the help constant identifier for use in an on-line help system. The last variant field contains either Param, a pointer to the text displayed next to a menu item, normally the hot key prompt, such as 'Alt-A' (or nil if there is no parameter string), or SubMenu as a pointer to the submenu structure. See: Chapter 11, "Turbo Vision Tutorial", NewItem, NewLine, NewSubMenu, TMenu. TMenuStr type ------------------------------------------------------------ Declaration: TMenuStr = String[31]; Unit: Menus Purpose: TMenuStr defines the string type used for storing menu item names, and limits menu names and item names to a maximum of 31 characters in length. See: NewItem, NewSubMenu TMenuView object ------------------------------------------------------------ Turbo Vision Hierarchy TMenuView TView TMenuView TMenuBar TMenuBox Discussion TMenuView implements much of the functionality for TMenuBar and TMenuBox and is not used directly. Refer to TMenuBar and TMenuBox for examples of the menu facilities. Most of the methods shown below are used internally by the derived object types and rarely used in a typical application. Fields ParentMenu: PMenuView; { Read only } Points to the TMenuView-type object that owns this menu object. Menu: PMenu; { Read only } Points to a TMenu-type record, which in turn points to a linked list of TMenuItem records defining each of the menu items that appear on the menu. See: TMenu type, TMenuItem type Current: PMenuItem; { Read only } Keeps track of which menu item is the currently selected one. Methods function Execute: Word; virtual; Override: Never ExecView calls Execute to process the modal nature of the pulldown menu. Execute returns cmXXXX constant that was defined for the menu selection, or 0 if the Esc key was pressed and nor selection was made. function FindItem(Ch: Char); PMenuItem; FindItem scans through the menu box structure looking for a menu item that has Ch has its shortcut key, and returns a pointer to that menu item, or nil if not matches were found. procedure GetItemRect(Item: PMenuItem; var R: TRect); virtual; This internal method helps the menu code determine which menu item on which a mouse click occurred. function GetHelpCtx: Word; virtual; Returns the value of the help context constant for the current menu item. If the menu item's help context is hcNoContext, then GetHelpCtx checks the owner of the menu and return's its help context. function GetPalette: PPalette; virtual; Returns a pointer to CMenuView, the default color palette for menus. See: CMenuView procedure HandleEvent(var Event: TEvent); virtual; Override: Never. Process all events for the menu object. function HotKey(KeyCode: Word): PMenuItem; Scans through the menu structure looking for the menu item that has the hot key specified by KeyCode defined, and if found, returns a pointer to that menu item. Otherwise, if KeyCode is not found, then it returns nil. constructor Init(var Bounds: TRect); Creates a view having the indicated Bounds. TMenuView.Init should only be called by TMenuBar and TMenuBox. constructor Load(var S: TStream); Creates and loads a TMenuView object from stream S. procedure Store(var S: TStream); Writes the TMenuView object to stream S. TObject object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TCollection TStream TStringList TStrListMaker TResourceFile Discussion Nearly all objects used in Turbo Vision are defined from this root object type, and all objects written to streams must be descended from TObject. Fields None Methods destructor Done; Disposes a dynamically allocated object. procedure Free; Descendants of TObject actually call TObject.Free to dispose of the dynamically allocated object. constructor Init; TObject.Init is called from all descended object's Init constructors. Descendant's should always call their parent's Init method prior to performing their own initialization since TObject carefully zeroes all allocated fields as part of its initialization. TPalette type ------------------------------------------------------------ Declaration: TPalette = String; Unit: Views Purpose: Defines the data type used for storing color palettes. Since all color palettes are equivalent to strings, you can use, if you wish, all of the various string manipulation functions, including indexing, Copy, Delete, Insert and so on. See: Chapter 13, "More Turbo Vision Features" TParamText object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TStaticText TLabel TParamText Discussion TParamText is essentially equivalent to TStaticText, for displaying text strings in dialog boxes except that TParamText provides enhanced flexibility in the formatting of the text strings. The string parameter passed to TParamText.Init may contain embedded formatting information and is passed directly to the FormatStr procedure. See: FormatStr, TStaticText, TLabel, TDialog Commonly Used Features If you use this object type, you will probably create the object with the Init constructor and then insert it into a dialog and are unlikely to directly access the other methods. You will need to directly assign a value to the ParamList pointer as shown in the example. Example This example of TParamText shows how a variable FileName might be inserted into a TParamText derived object, AParam. Each time that the dialog is displayed, or particularly if the dialog is normally stored in a resource file, the FileName parameter can be automatically inserted into the TParamText message prompt by changing Parameters.AParamStr to a new value. var AParam : PParamText; Parameters : record AParamStr : PString; end; ... { Set up the contents of the Delete dialog } with Dialog^ do begin ... { Add the Delete Okay? } Bounds.Assign ( 8, 2, 45, 3 ); AParam := New (PParamText, Init( Bounds, 'Okay to Delete %s', 1 )); Parameters.AParamStr := NewStr(FileName); AParam^.ParamList := @Parameters; Insert( AParam ); end; { with } Control := DeskTop^.ExecView (Dialog); Fields ParamCount: Integer; Specifies the number of parameters in the ParamList^ parameter array or record. ParamList: Pointer; Points to the parameter array or parameter record that specifies the data values to be inserted into the Text string (which is inherited from TStaticText). See FormatStr for a complete description of string formatting. Methods function DataSize: Word; virtual; Used in conjunction with GetData and SetData, DataSize returns the size in bytes of the data storage used by a TParamCount object. procedure GetText(var S: String); virtual; Calls FormatStr( S, Text^, ParamList^ ) to format and merge the parameters in TParamText.ParamList^ with the TParamText.Text^ string (Text is a field inherited from TStaticText to hold the contents of this item's text) and produces the resultant output string S. See: FormatStr, TParamText.ParamList, TParamText.Text, TStaticText.Text constructor Init(var Bounds: TRect; AText: String; AParamCount: Integer); TParamText.Init calls TStaticText.Init to create the object, and then stores AParamCount into TParamText.ParamCount. AText is the text to be used for the message prompt. You must separately assign the parameter array or record to ParamList. constructor Load(var S: TStream); Creates and reads a TParamText object from stream S. procedure SetData(var Rec); virtual; Copies the number of bytes specified by DataSize into Rec. procedure Store(var S: TStream); Writes the TParamText object to stream S. TPoint object ------------------------------------------------------------ Turbo Vision Hierarchy Fields X: Integer; Y: Integer; Defines a point (X,Y) on the screen. TProgram object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TGroup TProgram TApplication Discussion TProgram contains most of the functionality present in TApplication. Usually you will derive your application directly from TApplication but it is possible to derive it from TProgram instead. All Turbo Vision programs must be derived from either TApplication (preferred) or TProgram. Commonly Used Features The following are the frequently used methods of TProgram: Init, Done, HandleEvent, Idle, InitMenuBar, InitStatusLine, OutOfMemory, Run, SetScreenMode Example See TVSHELL8 in the Borland Pascal Developer's Guide for a complete example of a finished application using the frequently used methods of TProgram (except Idle). Fields None Methods destructor Done; TProgram.Done disposes of all the application related objects, including StatusLine, MenuBar and DeskTop and essentially terminates the Turbo Vision program. procedure GetEvent(var Event: TEvent); virtual; This is the application's event processing loop. GetEvent checks for mouse and keyboard events and since TProgram owns all of the application's views, GetEvent sends the event record to the appropriate view for processing. If no events occurred, then GetEvent calls TProgram.Idle (see TProgram.Idle). function GetPalette: PPalette; virtual; Returns a pointer to the default color palette for the application. Since TProgram.GetPalette points to the application level palette, of which there are 3, CColor, CBlackWhite and CMonochrome, GetPalette checks the AppPalette variable to determine which application palette is the currently active palette. See: appPalette, apXXXX constants, CBlackWhite, CColor, CMonochrome procedure HandleEvent(var Event: TEvent); virtual; Override: Always, to implement an application's functions. Every application will override HandleEvent (but don't forget to call TProgram.HandleEvent first), to process the cmXXXX commands returned by the various menu selections and short cut keys. See: Chapter 11, "Turbo Vision Tutorial", and TVSHELL8 for examples. procedure Idle; virtual; You can have your Turbo Vision application perform background tasks during idle periods in the program's execution. To make use of idle time, override TProgram.Idle to perform your background tasks (always remember to call TProgram.Idle as the first statement within your overwritten Idle procedure). TProgram.Idle should only perform operations that can be done quickly as Idle is called from within TProgram's GetEvent loop. This means that if TProgram.Idle takes a lengthy time to complete operation, your program's execution appear to be slow down to unacceptable levels. constructor Init; Initialize's Turbo Vision support for an application, including the video screen modes, and calls InitDeskTop, InitStatusLine and InitMenuBar. You must override the last three methods to provide your application's status line and menu bar definitions. procedure InitDeskTop; virtual; Initializes an application's TDeskTop object and sets the global DeskTop pointer to point to this object. See the listing given in TBackground for an example of how this method can be overriden to create a TDeskTop object other than the default desktop. procedure InitMenuBar; virtual; You should always override InitMenuBar so that it creates a new menu bar and associated pulldown menus and setsMenuBar to point to the new menu structure. See Chapter 11. procedure InitScreen; virtual; This internal routine is called by TProgram.SetScreenMode to initialize all of the Turbo Vision screen mode dependant values: ShadowSize, AppPalette and ShowMarker. procedure InitStatusLine; virtual; You should always override InitStatusLine so that it creates a new statusline and set the global variable StatusLine to point to the new status line structure. See Chapter 11. procedure OutOfMemory; virtual; Whenever TProgram.ValidView finds that LowMemory is True, meaning that the low memory buffer area has been entered, TProgram.ValidView calls OutOfMemory. You should override this procedure to display an error or warning message to the user with information about the low memory problem. See: LowMemory, TProgram.ValidView procedure PutEvent(var Event: TEvent); virtual; PutEvent inserts Event into the pending Event queue so that the next call to GetEvent returns Event. procedure Run; virtual; Calls the inherited TGroup.Execute method, which is the main event loop of the application. procedure SetScreenMode( Mode: Word ); When you need to switch between the 3 application level color palettes, CColor, CBlackWhite or CMonochrome, or switch between 25- and 43/50-line screen modes, call TProgram.SetScreenMode, setting the Mode parameter with the values smCO80, smBW80 or smMono, OR'd, as needed, with smFont8x8. See the procedure SetVideoMode for complete details; normally you will call TProgram.SetScreenMode rather than SetVideoMode. function TProgram.ValidView(P: PView): PView; ValidView is used to determine if a newly constructed view was created appropriately. It does this by checking the LowMemory flag and if True, automatically calls TProgram.OutOfMemory. ValidView also insures that P is not nil, and if any errors are founds, ValidView returns a nil pointer. You can use ValidView to check the instantiation of new views directly as they are inserted into a group. DeskTop^.Insert(ValidView( New( PStaticText, Init( ... ) ) ) ); This results in an automatic error handling sequence, calling OutOfMemory or what not, as Insert will ignore a nil pointer and will not insert the failed view. See: TProgram.OutOfMemory, TView.Valid, TGroup.Valid, Chapter 13, "More Turbo Vision Features". TRadioButtons object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TView TCluster TRadioButtons TCheckBoxes Discussion Use TRadioButtons to implement groups of radio buttons in dialog boxes. Chapter 11 in the Borland Pascal Developer's Guide contains a tutorial on the creation and use of TRadioButtons objects. See TCheckBoxes, TDialogs Commonly Used Features Most applications will use the inherited TCluster.Init method to initialize a radio button group, and then Insert the group into the dialog. There is little need to use any of the other available methods directly. Example This example shows creating and inserting a radio button into an owner, which is normally a TDialog object, and linking it to a TLabel prompt line: Bounds.Assign(3, 2, 20, 4); VideoOptions := New (PRadioButtons, Init (Bounds, NewSItem('~2~5 lines', NewSItem('~4~3/50 lines', nil)) )); Insert(VideoOptions); Bounds.Assign( 3, 1, 20, 2); Insert( New( PLabel, Init( Bounds, 'Screen size', VideoOptions))); Fields None Methods procedure Draw; virtual; Displays each radio button, including the "( )" selection fields. function Mark(Item: Integer): Boolean; virtual; Use Mark to determine if a specific radio button, specified by Item, is currently pressed. procedure MovedTo(Item: Integer); virtual; MovedTo is identical to Press and sets the Item'th radio button to "pressed". procedure Press(Item: Integer); virtual; Makes the Item'th radio button the currently pressed radio button. procedure SetData(var Rec); virtual; Copies the Value and Sel fields from Rec, and then sets the selected item indicated by Sel to the "pressed" state. TRect object ------------------------------------------------------------ Turbo Vision Hierarchy TRect is a standalone object. Discussion TRect primarly defines two coordinates, A and B, which are the upper left and the lower right corners of a rectangle. TRect parameters are used throughout Turbo Vision to specify the screen location and size of windows, dialog boxes and entry fields. Commonly Used Features The mostly commonly used method is Assign, used to initialize the coordinate values, but several utility methods also enable quick changes in the values of the coordinate fields and making copies of the TRect object. Example var Bounds: TRect; ARectangle : TRect; ... { Initialize to the coordinates (0,0) and (80,2) } Bounds.Assign(0, 0, 80, 2); ... { Copy the contents of Bounds to ARectangle } ARectangle.Copy( Bounds ); Fields A: TPoint; A TPoint defining the upper left corner of a rectangle. B: TPoint; A TPoint defining the lower right corner of a rectangle. Methods procedure Assign( XA, YA, XB, YB: Integer); Sets A.X := XA, A.Y := YA, B.X := XB and B.Y := YB. procedure Copy(R: TRect); Sets the A and B fields to the values in R. procedure Move(ADX, ADY: Integer); Adds ADX to the X values and ADY to the Y values of A and B. Sets A.X := A.X + ADX, B.X := B.X + ADX and sets A.Y := A.Y + ADY, B.Y := B.Y + ADY. procedure Grow(ADX, ADY: Integer); Adjusts A and B as follows: A.X := A.X - ADX; B.X := B.X + ADX; A.Y := A.Y- ADY; B.Y := B.Y + ADY; procedure Intersect(R: TRect); Determines the area that this rectangle overlaps with the rectangle specified by R, and sets A and B to the intersection of the two rectangles. procedure Union(R: TRect); Creates a new rectangle that encompasses A and B and the rectangle R. function Contains(P: TPoint): Boolean; Returns True if P lies within the rectangle specified by A and B. function Equals(R: TRect): Boolean; Compares A and B to R, and returns True if they are equal, and False if they are not. function Empty: Boolean; If A and B are equal, then A and B describe a rectangle containing no spaces. Empty returns True if A = B. TResourceFile object ------------------------------------------------------------ Turbo Vision Hierarchy TObject TResourceFile Discussion TResourceFile is a special purpose random access TStream that let's you find records by a key string instead of a record number. Using TResourceFile, you can implement simple data base retrievals, as well as store Turbo Vision components. See Chapter 16, "Resources" in the Borland Pascal Developer's Guide for a complete discussion and tutorial on the use of TResourceFile objects. Commonly Used Features In addition to Init, Put, Get and Done are the most frequently used methods of the TResourceFile object. Fields Stream: PStream; Points to the stream used by this TResourceFile object. Modified: Boolean; If the file has been modified, then this flag is set to True. The TResourceFile.Flush procedure checks this flag to determine if it should update the resourc file. Methods function Count: Integer; Computes and returns the number of items or resources stored in the file. procedure Delete(Key: String); Removes the key from the index and marks the space it previously occuppied as being deleted. See TResourceFile.SwitchTo for a method to reclaim the now unused space. destructor Done; virtual; Calls TResourceFile.Flush and disposes of the index collection and resource stream file. procedure Flush; Checks the Modified flag, and if True, updates the resource stream file, and then resets Modified to False. function Get(Key: String); PObject; Uses Key as an index into the resource and returns a pointer to the object that it references, or nil if the Key is not in the file. See TResourceFile.Put constructor Init( AStream: PStream ); TResourceFile.Init is called after opening a stream. The opened stream is passed as a parameter to Init and becomes the stream that holds the resource file. See Chapter 16, "Resources". function KeyAt(I: Integer): String; Use KeyAt to scan through the entire resource file. I is an index to each resource in the file, numbered 0 to TResourceFile.Count minus 1. KeyAt returns the string corresponding to the key value at the I'th index position. procedure Put(Item: PObject; Key: String); Stores the object pointed to by Item into the resource file, using the specified Key. See TResourceFile.Get function SwitchTo(AStream: PStream; Pack: Boolean): PStream; Use SwitchTo to copy the current resource file to another stream specified by AStream. If Pack is True, SwitchTo will not copy objects marked as deleted, thereby compressing the resulting resource file. See: TResourceFile.Delete