Search the FAQ Archives

3 - A - B - C - D - E - F - G - H - I - J - K - L - M
N - O - P - Q - R - S - T - U - V - W - X - Y - Z - Internet FAQ Archives

C++ Turbo Vision FAQ, part2/3

( Part1 - Part2 - Part3 )
[ Usenet FAQs | Web FAQs | Documents | RFC Index | Business Photos and Profiles ]
Archive-name: C++-faq/turbovision/tvplus/part2
Posting-Frequency: monthly
Last-modified: 1995/08/14
Version: 1.8

See reader questions & answers on this topic! - Help others by sharing your knowledge

   Borland International makes technical advice available through a series
   known as TechInfo, abbreviated as TInnnn. The series is not limited to
   TV and covers other topics relevant to Borland products. Each issue
   covers a specific topic.

   All issues in this series mentioning Turbo Vision are listed here.

   TI1006 Overlaying Turbo Vision 1992.08.12
   TI1011 Modal and Modeless Dialog Boxes using Turbo Vision 1992.08.12
   TI1013 Making string lists using Turbo Vision 1992.08.12
   TI1020 Understanding & Using Turbo Vision's Palette 1992.08.21
   TI1021 How to extract text from a TEditor Buffer 1992.10.23
   TI1022 Initialization Order of Objects & Turbo Vision 1992.12.03
   TI1023 Persistent Objects using Turbo Vision 1992.12.23
   TI1025 Optimizing Screen Updates with Turbo Vision v3.1 1992.12.23
   TI1033 Example of derived TListViewer for Turbo Vision 1992.12.23
   TI1158 A modal dialog from a modal dialog with Turbo Vision1992.11.11
   TI1159 Graying Buttons with Turbo Vision 1992.11.11
   TI1160 Dynamically modifying Turbo Vision menus1992.12.03
   TI1296 Using Turbo Vision resource files 1993.10.25
   TI1297 Example of password entry using a TInputLine 1993.10.25
   TI1369 Changing the color of shadows in Turbo Vision 1993.10.25
   TI1395 How to use HeapView in a Turbo Vision program 1993.10.25
   TI1398 tools.h++ from Rogue Wave conflicts with Turbo Vision 1993.10.25
   TI1532 Continuously updated message box in Turbo Vision1992.12.03
   TI1541 Using cmReleasedFocus message to update a dialog box 1993.10.25
   TI1549 Switching between text video modes in Turbo Vision 1993.10.25
   TI1552 Turbo Vision example of determining cursor position 1993.10.25
   TI1553 How to override freeItem for Collections 1993.10.25
   TI1554 Context sensitive help example (Turbo Vision) 1993.08.30
   TI1555 Example of a restricted InputLine (Turbo Vision) 1993.10.25
   TI1557 Creating red error dialog boxes in Turbo Vision 1993.10.25
   TI1558 Saving/Restoring the mouse state in Turbo Vision 1993.09.01
   TI1701 Turbo Vision: Streaming a user defined dialog 1993.10.07
   TI1707 Broadcast to close a Turbo Vision Modeless Dialog 1993.10.12
   TI1708 Using setData to initialize dialog box contents 1993.10.25
   TI1712 Turbo Vision Dialog Box (Modal/Modeless) Examples 1993.10.25
   TI1720 How to disable a button in Turbo Vision 1993.10.25
   TI1730 Inserting text into a Turbo Vision window 1993.10.21
   TI1752 Rebuilding Turbo Vision 1.0x with Borland C++ 4.0 1994.01.13
   TI1753 Using Turbo Vision 1.0x with Borland C++ 4.0 1994.01.13
   TI1773 How to build DOS applications in Borland C++ 4.0 1994.01.25
   TI1778 Common questions and answers about Borland C++ 4.0 1994.02.17

   These text files have been bundled together under the name for an easy download from the TVPlus ftp site.


   There are commercial compilations of source code and code snippets
   written in various programming languages. The compiler (of the human
   variety) will obtain material from various locations and sites for
   distribution as CDROM collections.

   There are CDROM collections that include TV code. Such compilations can
   greatly facilitate programming by providing consolidations of sources,
   snippets, hints and tools. Much of the material is shareware; some of it
   in the public domain.

   These compilations are a useful service provided that they do not breach
   copyright. However, there are numerous CDROM services which are
   advertised in computer magazines and which you can easily select without
   recommendations from here.

			 The discussion list

   The Turbo Vision discussion list is run as an unmoderated site from
   Virginia Polytechnic Institute ('Virginia Tech'), Blacksburg, Virginia

   To subscribe to the discussion list:

	   Send a message to
	   Leave the subject header blank if you wish
	   In the body of your message, type the command:
	   SUBSCRIBE TURBVIS <your name>

   Expect confirmation of your subscription and a list of additional
   Listserv commands which you should keep handy.

   Any question about Listserv should be addressed to your system

   To send a message to the discussion list:

	   Post your message to
	   Do not use this address to subscribe or unsubscribe
	   to the discussion list because, if you do, everyone
	   will get the commands intended only for Listserv.

   Note the distinction between Listserv and Turbvis - commands are sent to
   Listserv; messages, to Turbvis.

   Check on posting to the discussion list before doing so.

   To unsubscribe to the Turbo Vision discussion list:

	   Send a message to
	   Leave the suject header blank if you wish
	   In the body of your message, put the command:

			   UseNet News

   A Usenet newsgroup is a collection of the communications of various
   subscribers about a predefined topic.


   We have divided the newsgroups into four sections, moving from the most
   to the least relevant:

	  special interest: about Turbo Vision itself
	  programming: about your language of choice and other programming
	  various topics: about all manner of things that may, or may not,
		  be relevant
	  Usenet operations: about netiquette and other hints (good for

   After selecting a newsgroup in which you are interested, you will be
   presented a list of topics currently under discussion within that group.
   Go for it.

   Application framework

   Just after the discussion group on TV went on line towards the end of
   1992, this news group was established with a link to the discussion
   list. It covers both the C++ and Pascal language version of the



   It goes without saying that using the TV library will not make you self
   sufficient in techniques or programming tools. These groups present an
   opportunity to look further afield into the C++ language as a related



   The following sites are somewhat chaotic, catch all sites and are
   included on the basis that they specialise in FAQs on diverse topics.
   They may be a bit like a junk shop but you are more than likely to find
   a treasure or two - they are quite useful as a starting point in your
   research on all kinds of interests.

		   UseNet news

   Usenet and its operation


   The purpose of this newsgroup is to discuss Usenet and the way it
   operates.  Questions about netiquette, the Usenet FAQ, posting rules
   and similar matters can be put to this group.


   Each newsgroup has its own area of expertise and going outside this area
   could bring down the wrath of the regulars. They like to keep the topic
   tight and you should check to see if the subject you want to discuss is
   pertinent to the particular group.

   In any event, it is to your own advantage to ensure you have the right
   group for your posting as you will get a better answer from those
   experienced in the subject than from someone who is merely acquainted
   with the topic.

   Do not post test articles to an active newsgroup. Find a test group such
   as alt.test designated for this purpose.

   Also see about posting to the Turbo Vision discussion list.


   As TV is produced in two language versions, postings to or

   should bear a subject header that readily identifes the language version
   if applicable to the topic under discussion. It make life a little
   easier - it helps communication and gets the information sought in one


   Before you resort to the net for a solution to your code problem, make
   sure you have done your homework and have been through the following

	  read the manual (it may happen to be lucid on your
	  particular problem);

      check ..\turbovision\demos and ..\turbovision\docdemos of TV;

      browse through the examples from;

	  read the source code if you have it;

      refer to the relevant FAQ which is, in this case, TVPlus; and

	  try to resolve the difficulty using whatever resources you have


   If you still cannot solve the problem, post a question to if you have access to e-mail or

	   comp.os.msdos.programmer.turbovision if you only have
	   access to UseNet News.

			   Handy ftp sites


   These archives contain collections of files that may be of
   interest and that may have duplicate material from other sites;
   but there are some unique items at each site as well.
	   This site was dis-organised early in 1995.  There are Turbo Vision
	   files to be found at /pub/techinfo/techdoc/language/c++/bcpp - if
	   you can detect which one are TV.  The LARN like maze to
	   /pub/techinfo/techdoc/language/c++/bcpp/ti contains the TI
	   Of special interest here are a graphical version of TV and
	   patches for porting TV to other compilers. This site is very slow
	   if you are accustomed to US ftp speeds.
	   This site contains patches for the Pharlap DOS extender to work
	   with TV.
	   This is the Garbo Archives sited in sunny Finland. There are
	   libraries for database applications and C++ sources which are
	   suitable for use with TV.
	   This is a popular site for all kinds of code. The turbovis
	   directory contains code listings for C++ TV1.03 and TV2.0 (and
	   Pascal Turbo Vision).
	   This site, amongst other things, archives the Turbo Vision
	   discussion list and comp.os.msdos.programmer.turbovision for both
	   the C++ and Pascal versions of TV.
	   CompuServe is one of many commercial alternatives to the Internet
	   which contains a Turbo Vision forum. For the information of CIS
	   customers, the TV files are located at BCPPDOS Library 11.


   This group of archives is devoted to a rather narrow purpose in
   that they usually contain files that have originated from one
   author or relate to one application.

   DosLynx Project: Kansas University <>   The self-extracting
	   archive file name is DLX0_8A.EXE; the source file name is
   Nelson, Roger <>   There are five directories which may
	   be of interest to TV programmers: ../pub/rvision (Pascal and C++
	   library), ../pub/rlib ../pub/language ../pub/latex2hyp
	   (LaTeX2hyp) and ../pub/ucscu
   Nelson, Roger   The URL for WWW access to the site
	   referenced above.
   Sierwald, Joern <>
	   Patches to support TV with compilers other than Borland C++.
   Werthy, William (Bill) <>   This site contains NEWSWERTHY, a TV offline


   TV files mentioned in TVPlus, and a few others besides, are
   available from this site. The original file collection resulted
   from the research of Rachel Polanskis and is presented with our
   compliments; others have added to it.
	   At present, limited access.  TVPlus is archived here;  there
	   is a selection of TV C++ files, some related C++ files and other
	   programming tools available from this site.

   File list

   The + indicates a new addition since the last change. allows user to go back one page in help window use TV2 with BC++ 3.1 (not protected mode) use TV2 with BC++ 3.1 use TV1.03 with BC++ 4.x implements black text on a black background click alternates clock between 12 and 24 h time permits you to change the palette easily selector dialog for application colours demo of TV and PXEngine, use with to test TV and PXEngine sample classes for input/output draw a background logo on desktop dialog design tool DPMI Exception Handler Library for TV 2.0 how to stream desktop objects to file class for a dumb terminal object dynamic version of TStaticText demonstrates how to put hints on the status line advanced gadgets for TV; very interesting how to use far virtual tables in TV TV library from BI (not tested) excellent graphics library for Turbo Vision Oliver Suciu's port of TV to g++ edit a TListBox item using a TInputLine a bug list with many fixes for TV and BC control multiple lists with a common scrollbar sample code for making resource file TV2, beeps on mouse click outside specified area example of cascading menu items message input box replacement, many features - BC3.1 message input box replacement, many features - BC4.x generates menus a status box like the IDE's and a message window messages put to the status line message passing from a dialog to a window mark multiple items in a collection - toggle values for TVDT users, TMemo shoehorned into TView TCollection for a picklist similar to THistory password dialog and simple algorithm complete shareware replacement for TV's help system TV1.03 and BC3.1 in protected mode - complete sources background printer object progress bar utility how to implement pxeng with TListBox fix memory problem for large radio button cluster sample code reading a resource file save and restore palette as resource demonstrates a screen saver using ISR routines scrolling dialog box scrolling dialog box - revision Turbo Vision Study Guide - teaches TV spreadsheet like object TObjstrm patch for the library sysint.asm patch for the library sysint.asm patch for the library a streamable combo box the Borland TechInfo series on TV demo of help system with commentary class extensions from TInputLine updates uses CTRL- key hotkey combinations allows toggled items to appear in a menu how to change language at runtime dynamically derived from TInputLine, a PDX style picture class another progress bar utility input line Paradox style adds a title bar above the menu bar TTY style class implementation how to patch TV1.03/BC4.x how to use Memcheck with TV1.03 patches TV1.03 for PharLap DOS extender differences between TV 1.0 and TV 1.03 pharlap DOS extender patches for TV1.03 similar to above but in diff format patches source code to convert TV to DLL further source code on converting TV to DLL further comment on converting TV to DLL
   + the latest bug release for TV2 (1995.06.07)
   tv2pat.exe: more patches for TV2.0 validation classes for TV2.0 field validation object field validation object - later version graphics library for Turbo Vision alternate to (originally tvalt2.txt)
   tvapform.txt: plain text proforma - applications catalogue entry the current bug list for TV 1.03 February 1994 dynamic selection of palette scrollbar using long, not ushort - PXEngine demo
   + TV DPMI exception handler for BC4.x and TV2 project file for BC4.x older patches for TV1.03 library of graphics routines demonstrates how to put hints on the status line example of making windows iconic memory checking utility for compiling memo implementation of THistory BC4.x project for TV1.03 overlays palette routines for TV Joern Sierwald's patches TVPlus 1(1995)1 ie, as at January 1995 TVPlus 1(1995)2 ie, as at Febuary 1995 TVPlus 1(1995)3 ie, as at March 1995 TVPlus 1(1995)4 ie, as at April 1995 TVPlus 1(1995)5 ie, as at May 1995 TVPlus 1(1995)6 ie, as at June 1995 TVPlus 1(1995)7 ie, as at July 1995 latest TVPlus for use with a browser offline resource workshop spawns programmes without destroying desktop library of extensions and miscellaneous improves TV help and VGA and VESA TVWorkshop - generates C++ source print text to screen after exiting TV TListBox and PXEng example all the defines for TV1.03 in one header file virtual memory editor for TV1.03, BC3.1 & BC4.x virtual memory editor for TV2.0 demonstration menu bar generator examples of scientific data dialog box exploding windows and dialog boxes

				 The World Wide Web

   We trust that these links to other World Wide Web pages contribute to
   the usefulness of TVPlus.


   The C++ Virtual Library
	  This site <> contains
	  information about C++ products, libraries, tutorials, tools and
   The Yahoo Database (C/C++ list)
	  This listing whose URL is <>
	  is from the well known Web database, Yahoo
   The Captain's Log (C/C++ FAQ)
	  The URL for this home page, which is found at the University of
	  Liverpool (UK), <>
	  deals with C++ and object oriented programming - and C.
   The DESY user information
	  This page whose URL is <> is devoted
	  to object oriented programming and presented by Deutsches
	  Electronen-Synchrotron in Hamburg, Germany.
   The Borland WebPage
	  Borland's effort on the WWW is at <>. It
	  covers a great deal more than just Turbo Vision material.


   FAQs on various topics
	  This home page at <>
	  for Ohio State (US) presents FAQs in hypertext format.

			Selected answers on programming

   Although the division of the subject matter into the two headings listed
   here is somewhat artificial (because written explanations are often
   accompanied by code examples), we are adopting such a division to cater
   for both methods, only one of which may be used to illustrate the point
   in question.

		 Code snippets

   At this stage, it is proposed that material in these two headings be
   divided into twelve sections but this depends very much on the material
   that comes to hand. Select here if you want to get an overview.

   PLEASE NOTE: There are very few articles in this section of TVPlus at
   present. It is our aim, with your help, to provide a reasonably
   comprehensive collection of the FAQs.

   If you have a contribution to or comments on this chapter, please see
   the section, 'Wanted!'.


   Choose from this list for your selected topic:

   Application and desktop
   Menus and statusline*
   Dialog boxes
   Windows and editors
   Online help*
   Collections and resource files*
   Databases and interfacing Turbo Vision*
   Overlays and memory

   [* the heading requires elaboration]



   Child programme re-direction


   Child Programme Standard-Device Redirection

   Version  None specified
   Terms    None used

   This article outlines one approach to simultating a DOS box under
   MS-Windows so that, when the utility runs, its stdout is redirect to a
   window in the TV application.

   First write a character device driver that places standard output on the
   screen where you want it.

   Then from within your programme

       duplicate the standard-device handle with Interrupt 21H function 45h;
       save the duplicate handle;
       open the new device;
       with the new device handle retreived in step 3, modify the standard -
       device handle by using Force Duplicate Handle, Interupt 21H function
       run the child process;
       restore the standard-device handle saved in step 2 with Force 
	  Duplicate Handle, Interupt 21H function 46H; and
       close new device.

   You will need to refer to your Borland C++ Manual and a MS-DOS
   Programmer's reference for the details.



   Arranging input layout
   Chaining dialog boxes
   Scrolling dialog boxes
   Paging dialog boxes
   Progress Bar


   Arranging input layout
   Version  None specified
   Terms    TDialog

   There have been a number of alternative methods proposed to put data
   entry fields to a dialog box that does not easily accommodate them:
     scrolling dialog box

       see article on scrolling dialog box
	   see code SDLG2.ZIP in TVPlus file collection

     chaining dialog boxes

       see article on chaining dialog boxes
       see code in TI1158 in Borland TI series

     paging dialog boxes

       see article on paging dialog boxes


   Chaining dialog boxes

   Version  None specified
   Terms    None specified

   This article suggests a way to chain dialog boxes where information from
   the user is too much for one screen alone.

   Create global instance variables of the dialog boxes in your main
   program. Then attach commands to the appropriate buttons in the dialog
   boxes, and make sure they are all different.

   Create an event handler for each box, so that when it sees the button
   command, it issues a broadcast message to the desktop using that event
   as part of the broadcast.

   Create an event handler for the desktop which can respond to the
   broadcast messages, and depending on the particular message, the desktop
   will create the appropriate dialog box.


   Scrolling dialog box

   Version  None specified
   Terms    TDialog; TView::origin; TView::size; TGroup::redraw;

   One way to manage more input fields than would normally fit into one
   dialog box is to make the dialog scroll. This can be done because a
   subview of a view can have "bounds" that place all or part of it outside
   the bounds of the owner - the portion outside of the owner simply does
   not get drawn.

   Thus you can rig it so that the dialog responds to a "down arrow" press
   by decreasing origin.y for all of the subviews by 1, the "page down" key
   decreases origin.y for all of the subviews by the TDialog->size.y - 2
   (the minus 2 because of the line at the top and bottom used by the
   frame), and so on. After changing each TViews->origin.y, call
   You can also place restrictions on how far up/down the scrolling is
   allowed to go. For example, to stop scrolling downwards when the
   "bottom" view is entirely visible, test for TVPBottomView->origin.y +
   TVPBottomView->size.y = TDialog->size.y.

   Do not blindly scroll every subview - some things, such as the frame,
   should stay where they are - i.e., set the GrowMode flag for every view
   appropriately and test it before adjusting its origin/size fields.

   The contributor had not used a scroll bar for this, but claimed it works
   very well with the arrow keys and the page up/down keys.


   Paging dialog box

   Version  None specified
   Terms    TDialog; TView::hide; TNSCollection

   You can have a "paged" dialog by inserting all of the controls into the
   dialog in pages. At any one time, only one page's controls would be
   visible; you hide() the others.

   This probably sounds complex, but its actually pretty simple. Create a
   collection that stores TView pointers - the only real added
   functionality is NOT to destroy the views:

   class TNSViewCollection : public TNSCollection {
	  TNSViewCollection( ccIndex lim, ccIndex d )
	  : TNSCollection( lim, d ) {
	  shouldDelete = False; }

   Now consider if you have a "collection-of-collections". Here, the major
   reason for subclassing is that freeItem() correctly destroys the
   contained collections:

   class TNSCollCollection : public TNSCollection {
	  TNSCollCollection( ccIndex  lim, ccIndex d )
	  : TNSCollection( lim, d ) {}
	  virtual void freeItem( void* item ) {
	      destroy( (TNSCollection*) item );

    Now you can subclass a dialog which has a collection-of- collections
    with each item representing a page in the dialog. Each contained
    collection holds pointers to all the TViews that make up that page. An
    example base class might look like:

    class TPagedDialog : public TDialog {
	  TPagedDialog( const TRect& r, const char* s,
	    int nrPages ) :
	    TWindowInit( TPagedDialog::initFrame ),
	    TDialog( r, s ),
	    pageList( new TNSCollCollection(nrPages,0) ),
	    curPage(0) {
	    for( int i = 0; i < nrPages; i++ )
	      pageList->insert( new TNSViewCollection(0,5) );
	    virtual void shutDown() {
	      destroy( pageList );
		  pageList = 0;
	    virtual void displayPage( int pageNumber ) {
	      if( pageNumber >= 0 &&
	      pageNumber < pageList->getCount() &&
	      pageNumber != curPage ) {
		((TNSCollection*) pageList->at(curPage))->
		  forEach( hideView, 0 );
		curPage = pageNumber;
		((TNSCollection*) pageList->at(curPage))->
		  forEach( showView, 0 );
	    static void hideView( void* v, void* ) {
		static void showView( void* v, void* ) {
	    void pageInsert( TView* view ) {
	      insert( view );
	      ((TNSCollection*) pageList->at(curPage))->
	      insert( view );
	   TNSCollection* pageList;
	// The author has written all these members as inline.
	// In use, you would put them in a source file.

    For this base class, you start with page[0] as the active page stored in
    curPage. When you want to hide this page and display a different one,
    you call TPagedDialog::displayPage(pg) with the new page number.

    The author also put in TPagedDialog::pageInsert() so that it is easy to
    build the dialog. You start by pageInserting all the controls for page
    [0]. When you are done, you set page[1] as active by calling
	displayPage(1) and pageInsert the views for page[1]; etc.

	The member function TPagedDialog::displayPage() goes through the list of
    the views that are currently visible and hides them, and then goes
    through the list of views for the new page and shows them. This may not
    leave the focus where you want it when a new page is displayed - so you
    need to add code to do that.

    If you want a view to permanently be in the dialog, i.e. visible in all
    the pages, insert() it directly and do not use TPagedDialog::
    pageInsert(). Note, however, that it may end up being a bit goofy as far
    as the tabbing order goes. If it is the first view inserted (counting
    the ones in the pages), then it is OK - it will always be the first tab
    view. If it is at the end of the first page, the view is equivalent to
    being first in all the subsequent pages (which, tab- wise, is also OK).

    So, for example, you could subclass from TPagedDialog and have two
    "permanent" buttons (views) - a Prev button, and a Next button. You
    would start out with the Prev button disabled, and Next enabled. You
    would then override TPagedDialog::displayPage() so that it updates the
	buttons. For example:

	virtual void displayPage( int pageNr ) {
	TPagedDialog::displayPage( pageNr );
	  if( pageNr == 0 ) {
	      disableCommand( cmPrevBtn );
	      enableCommand( cmNextBtn );
	  else {
	      enableCommand( cmPrevBtn );
	      if( pageNr != pageList->getCount()-1 )
		  enableCommand( cmNextBtn );
		  disableCommand( cmNextBtn );

    This assumes that cmNextBtn and cmPrevBtn are disable-able commands (in
    the range of 100-255) and are assigned to these buttons.

	Finally, override handleEvent() to handle page switching:

	void handleEvent( TEvent& event ) {
	  TPagedDialog::handleEvent( event );
	  if( event.what == evCommand )
	    if( event.message.command == cmPrevBtn )
	      displayPage( curPage-1 );
	    else if( event.message.command == cmNextBtn )
	      displayPage( curPage+1 );
	    clearEvent( event );


    Progress Bar

    Version  None specified
    Terms    TStaticText; TView::setData

    To create a progress bar, you can derive a class from TStaticText which
	will allow setting of colour and re-displaying the string (via a
    setData() member function). This can be used to display a bar and then
    periodically update it.


    Palette with LCD displays


    Palette with LCD displays

    Version  None specified
    Terms    TPalette

    TV has three predefined palettes as the manual describes (1992, pp
	119-126, 384-386 and 455). Normally, the appropriate palette is selected
    when you start the application, but with LCD displays it does not always
	do that. You can obtain an example of how to set the palette from the
    command line or a menu option by downloading TVCOLR.ZIP from the TVPlus
    file collection



   File Editor: TV does not support files greater than 64kb. There is a
   shareware TV extension - named or - which does so;
   designed by Eric Woodruff, it allows some professional file editing
   features that can make TV a useful editing platform; and the source code
   is required as some specific objects are renamed. You could also
   recompile the TV source using one of the TV ports to djgpp, gcc/emx,

   Word wrapping editor: This is unsupported in TV. There is a TV extension
   - named - which provides word wrapping functionality but
   requires the recompiling of the source code.


   Turbo Vision can be made to run in graphics mode. However, the point to 
   bear in mind is that, as TV is designed from the ground up as a text
   mode application, the performance of the screen redraws can suffer.
   There are two options: if graphics has only a secondary role in your
   program, try switching screen modes and doing your graphics processing
   there; if you need a complete graphics system, use one of the TV
   libraries available.



   TV is large. It can add 200 to 300 kb onto your application. Bear this
   in mind when you are writing a program using it. It is generally well
   behaved provided that you have made the appropriate patches to your
   compiler and you have used the destroy() operator as suggested.

   If you need more memory, the use of overlays can be be added. This
   involves the recompiling of the source code, to allow for the division
   of files into separate libraries. If you do not have the sources, there
   is not much you can do... Overlaying your application will present other
   factors that you will have to deal with. They can slow down execution,
   the tracking down of bugs is more difficult and you cannot compress an
   overlayed program.

   You can use a DOS extender. This is available in BC4.x but is not
   supported in BC31. You can try a third party DOS extender such as
   Pharlap's, but there is a fee for executables distributed with it. There
   are patches that can be used with the TV source to allow Pharlap's
   extender to be used with TV.


   The basis of selecting code for inclusion within this heading is its
   useful in demonstrating TV coding techniques. This is the practical
   aspect of the questions covered in the section, Articles.

   Choose from this list to view code snippets on your selected topic

   Application and desktop
   Menus and statusline*
   Dialog boxes
   Windows and editors*
   Online help*
   Collections and resource files
   Databases and interfacing Turbo Vision*
   Overlays and memory*

   [*  the heading requires elaboration]



   Spawning programmes


   Spawning programmes

   Version  None specified
   Author   Frank Hohmann <>
   Terms    TApplication::suspend; TApplication::resume; overload

   This is a demo for calling programs from within the TV environment
   without destroying the desktop.
   The approach is as follows:
   - overload TApplication::suspend() and TApplication::resume().
	 We must do this to avoid TScreen::suspend() and TScreen::resume()
     to be executed.
   - display a non-movable, non-resizable TWindow on the screen
     (see class TSwanWindow)
   - define a window() (see conio.h) that covers the client
     area of our TSpawnWindow and set "directvideo=1"
   - redirect INT 29h "fast console output" to an own interrupt
     routine (INT 29h is called everytime a character is written to
     stdout). This routine calls cprintf() to display the character
   - proceed with spawning a child process as described in
     Borland examples
   - restore INT 29h to the original
   I tested the above on different standard text modes and encountered
   no problems. Nevertheless this example comes without any warranty.

   Please report any experiences/errors/enhancements to
     Frank Hohmann
	 University of Osnabrueck, Germany

   #include <stdlib.h>        // for system()
   #include <dos.h>           // for setvect(), getvect()
   #include <conio.h>         // cprintf(), window()
   #include <stdio.h>

   #define Uses_TEvent
   #define Uses_TProgram
   #define Uses_TApplication
   #define Uses_TKeys
   #define Uses_TRect
   #define Uses_TMenuBar
   #define Uses_TSubMenu
   #define Uses_TMenuItem
   #define Uses_TStatusLine
   #define Uses_TStatusItem
   #define Uses_TStatusDef
   #define Uses_TDeskTop
   #define Uses_TWindow
   #define Uses_TSystemError
   #define Uses_TEventQueue
   #include <tv.h>

   #define INT_NUMBER 0x29        // interrupt for "fast console output"
   #define DOS_CMD    "MEM /C"    // command to spawn for test purpose
   const int cmNewSpawnWin   = 100;
   const int cmSpawn      = 1000;

   class TVApp : public TApplication {
       static TStatusLine *initStatusLine( TRect r );
       static TMenuBar *initMenuBar( TRect r );
       virtual void handleEvent( TEvent& event);
	   void mySpawnWindow();
       virtual void suspend();
	   virtual void resume();

   class TSpawnWindow : public TWindow {
       TSpawnWindow( const TRect& r, const char *aTitle, short aNumber );
       virtual void handleEvent(TEvent& event);
       void spawn();

   // ------------------- TVApp
   TVApp::TVApp() : 
     TProgInit( &TVApp::initStatusLine,
		&TVApp::initDeskTop) {

      TStatusLine *TVApp::initStatusLine(TRect r) {
	  r.a.y = r.b.y - 1;     // move top to 1 line above bottom
      return new TStatusLine( r,
	  *new TStatusDef( 0, 0xFFFF ) +
      *new TStatusItem( 0, kbF10, cmMenu ) +
      *new TStatusItem( 0, kbAltF3, cmClose ) +
      *new TStatusItem( "~Alt-X~ Exit", kbAltX, cmQuit ) );

   TMenuBar *TVApp::initMenuBar( TRect r ) {
     r.b.y = r.a.y + 1;    // set bottom line 1 line below top line
     TMenuBar *m =
     new TMenuBar( r,
     *new TSubMenu( "~S~pawn", kbAltF )+
      *new TMenuItem( "~T~est",  cmNewSpawnWin,   kbF4, hcNoContext, "F4" )+
      *new TMenuItem( "E~x~it", cmQuit, cmQuit, hcNoContext, "Alt-X" )       );
       return m;

    void TVApp::handleEvent(TEvent& event) {
      if( event.what == evCommand ) {
	  switch( event.message.command ) {
	      case cmNewSpawnWin:
	  clearEvent( event );       // clear event after handling

    void TVApp::mySpawnWindow() {
      TRect r( 2, 2, 78, 21 );

      // insert a new TSpawnWindow
      TSpawnWindow *window = new TSpawnWindow ( r, "Output", wnNoNumber);
      // ... and let it do its job
	  message(window, evBroadcast, cmSpawn, NULL);

    // We must override TApplication::suspend()
    // since we don't want TScreen::suspend() to be executed
    void TVApp::suspend() {

    // We must override TApplication::resume()
    // since we don't want TScreen::resume() to be executed
    void TVApp::resume() {

    // ------------------- TSpawnWindow
    TSpawnWindow::TSpawnWindow( const TRect& r, const char *aTitle,
      short aNumber) : TWindow( r, aTitle, aNumber),
	  TWindowInit( &TSpawnWindow::initFrame) {
	  flags = 0; // no Zoom/close/move style bits

    #pragma argsused
    void interrupt NewInt29( unsigned bp, unsigned di, unsigned si,
      unsigned ds, unsigned es, unsigned dx, unsigned cx,
      unsigned bx, unsigned ax, unsigned ip, unsigned cs,
      unsigned flags ) {
      // the character to be outputted must be taken from AL
	 cprintf("%c", (ax &~ 0xFF00));
      // signal end of interrupt (EOI)
	 outportb(0x20, 0x20);

    void TSpawnWindow::spawn() {
      // first call our new suspend()

	  // ... then save old INT 29h vector and replace it with our own
      void interrupt (*OldInt29)(...) = getvect(INT_NUMBER);
	  setvect(INT_NUMBER, (void interrupt (*)(...))NewInt29);

      // ... define a conio window that matches our TSpawnWindow's client area,
      // activate direct video and set the appropiate color
      window(origin.x+3, origin.y+3, origin.x + size.x -2, origin.y + size.y);
      directvideo = 1;

      // ... call some DOS commands (spawn() or system())
      printf("Executing %s\n", DOS_CMD);
      // ... and restore our old environment
      setvect(INT_NUMBER, OldInt29);

      // finally close our TSpawnWindow

    void TSpawnWindow::handleEvent(TEvent& event) {
      if( event.what == evBroadcast && event.message.command == cmSpawn ) {

    int main() {
      TVApp tvApp;;
      return 0;



   Cursor control
   Default value
   Exit method (1)
   Exit method (2)
   Password (1)
   Password (2)


   Cursor movement

   Version  Not specified
   Terms    TDialog; TInputLine

   The standard behaviour in Turbo Vision for moving from one field to
   another within a dialog box is to use the TAB. The following code
   snippet shows how to modify this behaviour so that you can instead use
   ENTER or arrow keys to move to another field.

   // Override handleEvent for your dialog class with
   // the following:

   void TVDialog::handleEvent (TEvent &event) {
   if (event.what == evKeyDown) {
      switch (ctrlToArrow (event.keyDown.keyCode)) {
	case kbUp: {
	    if (valid (cmCheck)) {
	       selectNext (True);
	    clearEvent (event);
	 case kbEnter: {
	    if (valid (cmCheck)) {
	       selectNext (False);
	    clearEvent (event);
	 case kbTab:
		clearEvent (event);
   TDialog::handleEvent (event);

   NB.  There are a number of class extensions available
   which provide code along such lines.


   Default values

   Version  None specified
   Terms    TDialog; TInputLine

   This code example shows how to display a default value in a dialog box.

   TInputLine *control = new TInputLine(......);
	// other stuff

   Here, buffer is the pointer to the text to be inserted into the


   Exit method (1)

   Version  Not specified
   Author   William Werth <>
   Terms    TDialog; TButton

   //To exit a modal TDialog by pressing a
	//TButton hat does not send cmExit, cmQuit
   //or equivalent but sends cmSearch instead, and
   //to call another TDialog.
   TVDialog::TVDialog ()
     : TDialog (...), TWindowInit (...) {
     // other stuff
     insert (new TButton 
	 (TRect(40,20,50,22), "~S~earch", cmSearch,
	 bfDefault) );
     selectNext (False);
   //There are two ways to do this
   //1) Overload the handleEvent function in TVDialog
   void TVDialog::handleEvent(TEvent& ev) {
      if (ev.what == evCommand &&
	 ev.message.command == cmSearch) {
	 ev.message.comand = cmOk;
	 // change event to one that will exit
	 searchFlag = 1;
	 // set a flag or somehow note cmSearch event 
   //2) Overload the handleEvent, but as follows:
   void TVDialog::handleEvent(TEvent& ev) {
      if (ev.what == evCommand &&
      ev.message.command == cmSearch) {


   Exit method (2)

   Version  Not specified
   Terms    TDialog

   This procedure does not use an OK or Cancel button to close the dialog
   because the specified action is accomplished before the dialog is

   //  To trigger some action
   const ushort cmTVCommand = 100;

   void TVDialog::doSomething(void) {
   // Insert your tasks here;  messageBox() for
   // demonstration only
      messageBox("Doing something", mfInformation |

   // Virtual function:  if the event type is a command
   // which is yours and the dialog is valid
   void TVDialog::handleEvent(TEvent& event) {
		TEvent newEvent;

	  if (event.what == evCommand &&
	 event.message.command = cmTVCommand &&
	 valid(cmOK)) {
	 newEvent.what = evCommand;
	 newEvent.message.command = cmOK;
	 newEvent.message.infoPtr = NULL;


   Whether or not to put the newEvent event into the event queue
   could depend on the result from doSomething().

   Either way, the next time around you will have performed your
   tasks (which, by the way, cannot include posting another event
   -- only one can be posted at a time without processing the
   other) and handleEvent will get the cmOK command, and treat it


   Password Object (1)

   Version  TV2
   Author   Pat Reilly <>
   Terms    TDialog; TInputLine

   //Here is a simple password object and
	//implementation -
   class TPassword : public TInputLine {
      TPassword( const TRect& r, int aMaxLen,
      TValidator* aValid = 0 ) :
		TInputLine ( r, aMaxLen, aValid ) {}
      virtual void draw();
   void TPassword::draw() {
	  char* oldData = newStr(data);
      for ( char* p = data; *p != EOS; p++ )
	 *p = '*';
      strcpy( data, oldData );
      delete [] oldData;
  strcpy( data, oldData );
  delete [] oldData;
  // ...


   Password (2)

   Version  Not specified
   Terms    TDialog; TInputLine; TPasswordInput; TPasswordInput:: draw()

   To enter a password in a dialog box and to avoid having that password
   displayed can be achieved with the following code

   #define chrPassword '*'

   TPasswordInput::TPasswordInput( const TRect& bounds, int maxLen ) :
   TInputLine( bounds, maxLen), starData( new char[ maxLen] ) {
      memset( starData, chrPassword, maxLen);     // fill with stars
      *(starData+maxLen-1) = EOS;                 // end of line

   TPasswordInput::~TPasswordInput() {
      delete [] starData; 

   void TPasswordInput::draw( void) {
      char *origData;
      char *curEnd = starData + strlen( data);   // length of string

      *curEnd  = EOS;            // make '*'-string correct length
	  origData = data;           // remember pointer;
      data     = starData;       // point to new data (all stars)

      TInputLine::draw();        // draw myself

      data     = origData;       // restore pointer
      *curEnd  = chrPassword;    // restore original '*'-string



   Saving colours

   Version  Not specified
   Terms    TPalette; fpstream; fpstream::readBytes; fpstream::writeBytes;

   // Here's how to save the colors.
   void TVApp::saveColors(void) {
      fpstream *f = new fpstream("ANYFILE", ios::trunc |

      opstream &strm = *f;

      // Store the palettes
      short curr_palette = appPalette;
      for(short i = 0; i < 3; i++) {
	 appPalette = i;
	 TPalette *palette = &getPalette();
	 strm.writeBytes(palette->data, palette->data[0] + 1);
	 appPalette = curr_palette;

   // Here's how to load the colors.
   void TVApp::loadColors(void) {
	 fpstream *f = new fpstream("ANYFILE", ios::in |
     ios::nocreate | ios::binary);
	 ipstream &strm = *f;

     // Read palettes from the configuration file.
     short curr_palette = appPalette;
     for(short i = 0; i < apTotalPalettes; i++) {
	appPalette = i;
	TPalette *palette = &getPalettes();
	strm.readBytes(palette->data, palette->data[0] + 1);
   appPalette = curr_palette;



   TListBox and arrays

   Version  None specified
   Terms    TListBox; TNSCollection::insert; ::newStr; arrays

   // From file:
   FILE *f;
   char buf[80];
   int n, cnt=0;
   while (fgets(buf,80,f))
   // could use strdup()?

   while (fread(&n,2,1,f)) {
     sprintf(buf,"Counter %u = %u",cnt++,n);
   // From array is similar

   Comment: There may be difficulty reading streamable file from other
   language programs.

   ====================== END OF TEXT PART 2 =============================
Rachel Polanskis               Robert Hazeltine  

User Contributions:

Comment about this article, ask questions, or add new information about this topic:


Part1 - Part2 - Part3

[ Usenet FAQs | Web FAQs | Documents | RFC Index ]

Send corrections/additions to the FAQ Maintainer: (Rachel Polanskis)

Last Update March 27 2014 @ 02:11 PM