-----------------------------------------------------------------------
TECHINFO
-----------------------------------------------------------------------
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
techinfo.zip for an easy download from the TVPlus ftp site.
-----------------------------------------------------------------------
CDROM SOURCE CODE
-----------------------------------------------------------------------
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
USA.
To subscribe to the discussion list:
Send a message to List...@vtvm1.cc.vt.edu
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
administrator.
To send a message to the discussion list:
Post your message to Tur...@vtvm1.cc.vt.edu
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 List...@vtvm1.cc.vt.edu
Leave the suject header blank if you wish
In the body of your message, put the command:
UNSUBSCRIBE TURBVIS <your name>
-----------------------------------------------------------------------
UseNet News
-----------------------------------------------------------------------
A Usenet newsgroup is a collection of the communications of various
subscribers about a predefined topic.
SELECTING NEWGROUPS
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
subjects
various topics: about all manner of things that may, or may not,
be relevant
Usenet operations: about netiquette and other hints (good for
newbies).
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
software.
comp.os.msdos.programmer.turbovision
Language
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
subject.
alt.msdos.programmer
comp.lang.c++
comp.lang.c++.moderated
comp.msdos.programmer
comp.os.msdos.programmer
comp.std.c++
Reference
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.
comp.answers
news.answers
UseNet news
Usenet and its operation
news.announce.newusers
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.
USING NEWSGROUPS
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.
How
As TV is produced in two language versions, postings to
tur...@vtvm1.cc.vt.edu or
comp.os.msdos.programmer.turbovision
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
pass.
When
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
steps:
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 ftp://ftp.borland.com;
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
available.
Where
If you still cannot solve the problem, post a question to
tur...@vtvm1.cc.vt.edu if you have access to e-mail or
comp.os.msdos.programmer.turbovision if you only have
access to UseNet News.
-----------------------------------------------------------------------
Handy ftp sites
-----------------------------------------------------------------------
GENERAL 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.
ftp://ftp.borland.com
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
series.
ftp://ftp.ee.und.ac.za
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.
ftp://ftp.pharlap.com
This site contains patches for the Pharlap DOS extender to work
with TV.
ftp://garbo.uwasa.fi
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.
ftp://oak.oakland.edu
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).
ftp://vtucs.cc.vt.edu
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
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.
SPECIALIST FTP SITES
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 <dos...@falcon.cc.ukans.edu>
ftp://ftp2.cc.ukans.edu/pub/WWW/DosLynx/ The self-extracting
archive file name is DLX0_8A.EXE; the source file name is
SCR0_8A.ZIP.
Nelson, Roger <rne...@mail.wsu.edu>
ftp://iris1.bsyse.wsu.edu 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
http://www.eecs.wsw.edu/coea The URL for WWW access to the site
referenced above.
Sierwald, Joern <sier...@tu-harburg.d400.de>
ftp://uni-stuttgart.de/pub/systems/os2/programming/support
Patches to support TV with compilers other than Borland C++.
Werthy, William (Bill) <bi...@eskimo.com>
ftp://ftp.eskimo.com This site contains NEWSWERTHY, a TV offline
reader.
TVPLUS FTP SITE
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.
ftp://ftp.zeta.org.au
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.
altf1.zip: allows user to go back one page in help window
b31tv2.zip: use TV2 with BC++ 3.1 (not protected mode)
bc31tv2.zip: use TV2 with BC++ 3.1
bc40tv.zip: use TV1.03 with BC++ 4.x
blakbl.zip: implements black text on a black background
clkclk.zip: click alternates clock between 12 and 24 h time
colord.zip: permits you to change the palette easily
colorsel.zip: selector dialog for application colours
csdude.zip: demo of TV and PXEngine, use with pmapp.zip to test
dbfram.zip: TV and PXEngine sample classes for input/output
desklogo.zip: draw a background logo on desktop
dlgdsn46.zip: dialog design tool
dpmxcp.zip: DPMI Exception Handler Library for TV 2.0
dskstr.zip: how to stream desktop objects to file
dumb.zip: class for a dumb terminal object
dyntxt.zip: dynamic version of TStaticText
ezhint.zip: demonstrates how to put hints on the status line
facetv.zip: advanced gadgets for TV; very interesting
farvt.zip: how to use far virtual tables in TV
fredtv.zip: TV library from BI (not tested)
gfx210.zip: excellent graphics library for Turbo Vision
gvision.zip: Oliver Suciu's port of TV to g++
inplis.zip: edit a TListBox item using a TInputLine
kvbugs.zip: a bug list with many fixes for TV and BC
listvi.zip: control multiple lists with a common scrollbar
makerez.zip: sample code for making resource file
mdbeep.zip: TV2, beeps on mouse click outside specified area
menunest.zip: example of cascading menu items
mibxb3.zip: message input box replacement, many features - BC3.1
mibxb4.zip: message input box replacement, many features - BC4.x
mmagic.zip: generates menus
msgcls.zip: a status box like the IDE's and a message window
msglin.zip: messages put to the status line
msgs.zip: message passing from a dialog to a window
multbo.zip: mark multiple items in a collection - toggle values
ntest.zip: for TVDT users, TMemo shoehorned into TView
option.zip: TCollection for a picklist similar to THistory
passwd.zip: password dialog and simple algorithm
phelp.zip: complete shareware replacement for TV's help system
pmapp.zip: TV1.03 and BC3.1 in protected mode - complete sources
printq.zip: background printer object
progba.zip: progress bar utility
pxlist.zip: how to implement pxeng with TListBox
radio.zip: fix memory problem for large radio button cluster
readrez.zip: sample code reading a resource file
savepal.zip: save and restore palette as resource
scrnsave.zip: demonstrates a screen saver using ISR routines
sdlg.zip: scrolling dialog box
sdlg2.zip: scrolling dialog box - revision
sg.zip: Turbo Vision Study Guide - teaches TV
spread.zip: spreadsheet like object
strmfx.zip: TObjstrm patch for the library
sysfix.zip: sysint.asm patch for the library
sysint.zip: sysint.asm patch for the library
tcombo.zip: a streamable combo box
techinfo.zip: the Borland TechInfo series on TV
testhelp.zip: demo of help system with commentary
tde.zip: class extensions from TInputLine
tdtxt1.zip: updates tde.zip
tkeys_h.zip: uses CTRL- key hotkey combinations
togmnu.zip: allows toggled items to appear in a menu
tlang.zip: how to change language at runtime dynamically
tpictu.zip: derived from TInputLine, a PDX style picture class
tprogb.zip: another progress bar utility
tpicture.zip: input line Paradox style
ttlbar.zip: adds a title bar above the menu bar
ttywin.zip: TTY style class implementation
tv_bc4.zip: how to patch TV1.03/BC4.x
tv-mc3.zip: how to use Memcheck with TV1.03
tv_may.zip: patches TV1.03 for PharLap DOS extender
tv103inf.zip: differences between TV 1.0 and TV 1.03
tv286_v6.zip: pharlap DOS extender patches for TV1.03
tv286_v7.zip: similar to above but in diff format
tv2dll.zip: patches source code to convert TV to DLL
tv2dll2.zip: further source code on converting TV to DLL
tv2dll3.zip: further comment on converting TV to DLL
+ tv2bug.zip: the latest bug release for TV2 (1995.06.07)
tv2pat.exe: more patches for TV2.0
tv2val.zip: validation classes for TV2.0
tvalid.zip: field validation object
tvalid2.zip: field validation object - later version
tvalt.zip: graphics library for Turbo Vision
tvalt2tx.zip: alternate to tvalt.zip (originally tvalt2.txt)
tvapform.txt: plain text proforma - applications catalogue entry
tvbugs.zip: the current bug list for TV 1.03 February 1994
tvcolr.zip: dynamic selection of palette
tvdbf.zip: scrollbar using long, not ushort - PXEngine demo
+ tvdpmxcp.zip: TV DPMI exception handler for BC4.x and TV2
tvdprj.zip: project file for BC4.x
tvfix.zip: older patches for TV1.03
tvg121.zip: library of graphics routines
tvhint.zip: demonstrates how to put hints on the status line
tvicon.zip: example of making windows iconic
tvmemchk.zip: memory checking utility for compiling
tvmemo.zip: memo implementation of THistory
tvoprj.zip: BC4.x project for TV1.03 overlays
tvpal.zip: palette routines for TV
tvpatch.zip: Joern Sierwald's patches
tvplus01.zip: TVPlus 1(1995)1 ie, as at January 1995
tvplus02.zip: TVPlus 1(1995)2 ie, as at Febuary 1995
tvplus03.zip: TVPlus 1(1995)3 ie, as at March 1995
tvplus04.zip: TVPlus 1(1995)4 ie, as at April 1995
tvplus05.zip: TVPlus 1(1995)5 ie, as at May 1995
tvplus06.zip: TVPlus 1(1995)6 ie, as at June 1995
tvplus07.zip: TVPlus 1(1995)7 ie, as at July 1995
tvplus08.zip: latest TVPlus for use with a browser offline
tvrw.zip: resource workshop
tvspawn.zip: spawns programmes without destroying desktop
tvtool17.zip: library of extensions and miscellaneous
tvtoys.zip: improves TV help and VGA and VESA
tvwork.zip: TVWorkshop - generates C++ source
txtxit.zip: print text to screen after exiting TV
user.zip: TListBox and PXEng example
uses.zip: all the defines for TV1.03 in one header file
ve2tv1.zip: virtual memory editor for TV1.03, BC3.1 & BC4.x
ve2tv2.zip: virtual memory editor for TV2.0
vtv.zip: demonstration menu bar generator
welstead.zip: examples of scientific data dialog box
xpwndg.zip: 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.
ON THE C++ LANGUAGE
The C++ Virtual Library
This site <http://info.desy.de/user/projects/> contains
information about C++ products, libraries, tutorials, tools and
utilities.
The Yahoo Database (C/C++ list)
This listing whose URL is <http://www.yahoo.com/Computer/Languages/>
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), <http://hpux.csc.liv.ac.uk/users/workexp/wk/>
deals with C++ and object oriented programming - and C.
The DESY user information
This page whose URL is <http://info.desy.de/general/> 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 <http://www.borland.com/>. It
covers a great deal more than just Turbo Vision material.
ON VARIOUS TOPICS
FAQs on various topics
This home page at <http://www.cis.ohio-state.edu/hypertext/faq/>
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.
Articles
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!'.
-----------------------------------------------------------------------
ARTICLES
-----------------------------------------------------------------------
Choose from this list for your selected topic:
Application and desktop
Menus and statusline*
Dialog boxes
Windows and editors
Online help*
Palettes
Streams*
Collections and resource files*
Graphics
Databases and interfacing Turbo Vision*
Overlays and memory
[* the heading requires elaboration]
----------------------------------------------------------------------
APPLICATION AND DESKTOP
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
46H;
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.
-----------------------------------------------------------------------
DIALOG BOXES
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
TDialog->redraw.
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 {
public:
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 {
public:
TNSCollCollection( ccIndex lim, ccIndex d )
: TNSCollection( lim, d ) {}
private:
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 {
public:
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() {
TDialog::shutDown();
destroy( pageList );
pageList = 0;
}
virtual void displayPage( int pageNumber ) {
if( pageNumber >= 0 &&
pageNumber < pageList->getCount() &&
pageNumber != curPage ) {
lock();
((TNSCollection*) pageList->at(curPage))->
forEach( hideView, 0 );
curPage = pageNumber;
((TNSCollection*) pageList->at(curPage))->
forEach( showView, 0 );
unlock();
}
}
static void hideView( void* v, void* ) {
((TView*)v)->hide();
}
static void showView( void* v, void* ) {
((TView*)v)->show();
}
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 );
else
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 );
else
return;
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.
-----------------------------------------------------------------------
PALETTES
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
-----------------------------------------------------------------------
WINDOWS AND EDITORS
File Editor: TV does not support files greater than 64kb. There is a
shareware TV extension - named ve2tv1.zip or ve2tv2.zip - 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,
etc.
Word wrapping editor: This is unsupported in TV. There is a TV extension
- named tvwrdwrp.zip - which provides word wrapping functionality but
requires the recompiling of the source code.
----------------------------------------------------------------------
GRAPHICS
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.
-----------------------------------------------------------------------
OVERLAYS AND MEMORY
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.
-----------------------------------------------------------------------
CODE SNIPPETS
-----------------------------------------------------------------------
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*
Palettes
Streams*
Collections and resource files
Graphics*
Databases and interfacing Turbo Vision*
Overlays and memory*
[* the heading requires elaboration]
-----------------------------------------------------------------------
APPLICATION AND DESKTOP
Spawning programmes
-----------------------------------------------------------------------
Spawning programmes
Version None specified
Author Frank Hohmann <mailto:fhoh...@rols1.oec.uni-osnabrueck.de>
Terms TApplication::suspend; TApplication::resume; overload
/*
TVSPAWN.CPP
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
e-mail: fhoh...@rols1.oec.uni-osnabrueck.de
*/
#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 {
public:
TVApp();
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 {
public:
TSpawnWindow( const TRect& r, const char *aTitle, short aNumber );
virtual void handleEvent(TEvent& event);
void spawn();
};
// ------------------- TVApp
TVApp::TVApp() :
TProgInit( &TVApp::initStatusLine,
&TVApp::initMenuBar,
&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" )+
newLine()+
*new TMenuItem( "E~x~it", cmQuit, cmQuit, hcNoContext, "Alt-X" ) );
return m;
}
void TVApp::handleEvent(TEvent& event) {
TApplication::handleEvent(event);
if( event.what == evCommand ) {
switch( event.message.command ) {
case cmNewSpawnWin:
mySpawnWindow();
break;
default:
return;
}
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);
deskTop->insert(window);
// ... 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() {
TSystemError::suspend();
TEventQueue::suspend();
}
// We must override TApplication::resume()
// since we don't want TScreen::resume() to be executed
void TVApp::resume() {
TEventQueue::resume();
TSystemError::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()
TProgram::application->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;
textattr(getColor(2));
// ... call some DOS commands (spawn() or system())
printf("Executing %s\n", DOS_CMD);
system(DOS_CMD);
system("pause");
// ... and restore our old environment
setvect(INT_NUMBER, OldInt29);
TProgram::application->resume();
// finally close our TSpawnWindow
close();
}
void TSpawnWindow::handleEvent(TEvent& event) {
if( event.what == evBroadcast && event.message.command == cmSpawn ) {
spawn();
clearEvent(event);
}
else
TWindow::handleEvent(event);
}
int main() {
TVApp tvApp;
tvApp.run();
return 0;
}
-----------------------------------------------------------------------
DIALOG BOXES
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);
break;
}
case kbEnter: {
if (valid (cmCheck)) {
selectNext (False);
}
clearEvent (event);
break;
}
case kbTab:
clearEvent (event);
break;
}
}
TDialog::handleEvent (event);
return;
}
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(......);
control->setData(buffer);
// other stuff
execView(dialog_with_TInputLine);
Here, buffer is the pointer to the text to be inserted into the
TInputLine.
-------------------------------------------------------------
Exit method (1)
Version Not specified
Author William Werth <bi...@eskimo.com>
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) {
clearEvent(ev);
ev.message.comand = cmOk;
// change event to one that will exit
searchFlag = 1;
// set a flag or somehow note cmSearch event
}
TDialog::handleEvent(ev);
}
//2) Overload the handleEvent, but as follows:
void TVDialog::handleEvent(TEvent& ev) {
if (ev.what == evCommand &&
ev.message.command == cmSearch) {
endModal(ev.message.command);
clearEvent(ev);
}
else
TDialog::handleEvent(ev);
}
-------------------------------------------------------------
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
closed.
// To trigger some action
const ushort cmTVCommand = 100;
void TVDialog::doSomething(void) {
// Insert your tasks here; messageBox() for
// demonstration only
messageBox("Doing something", mfInformation |
mfOKButton);
}
// 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)) {
doSomething();
clearEvent(event);
newEvent.what = evCommand;
newEvent.message.command = cmOK;
newEvent.message.infoPtr = NULL;
putEvent(newEvent);
return;
}
TDialog::handleEvent(event);
}
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
normally.
-------------------------------------------------------------
Password Object (1)
Version TV2
Author Pat Reilly <71333...@compuserve.com>
Terms TDialog; TInputLine
//Here is a simple password object and
//implementation -
class TPassword : public TInputLine {
public:
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 = '*';
TInputLine::draw();
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
}
-----------------------------------------------------------------------
PALETTES
Saving colours
Version Not specified
Terms TPalette; fpstream; fpstream::readBytes; fpstream::writeBytes;
opstream
// Here's how to save the colors.
void TVApp::saveColors(void) {
fpstream *f = new fpstream("ANYFILE", ios::trunc |
ios::binary);
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;
}
-----------------------------------------------------------------------
COLLECTIONS AND RESOURCE FILES
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()?
collection->insert(newStr(buf));
while (fread(&n,2,1,f)) {
sprintf(buf,"Counter %u = %u",cnt++,n);
collection->insert(newStr(buf));
}
// From array is similar
Comment: There may be difficulty reading streamable file from other
language programs.
====================== END OF TEXT PART 2 =============================
--
Rachel Polanskis gr...@zeta.org.au Robert Hazeltine
http://www.zeta.org.au/~grove/grove.html
r.pol...@nepean.uws.edu.au
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I am currently writing a newsreader for a DOS platform and would like to
know if someone knows where I could find a source for one (Pascal would be
nice). If anyone has any pointers, info, or source code please e-mail it to
me, I would very much appreciate it..
Thank you,
Roberto