Archive-name: C++-faq/turbovision/tvplus/part2
Posting-Frequency: monthly Last-modified: 1995/08/14 Version: 1.8 URL: http://www.zeta.org.au/~grove/tvhome.html See reader questions & answers on this topic! - Help others by sharing your knowledge ----------------------------------------------------------------------- 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 Listserv@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 Turbvis@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 Listserv@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 turbvis@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 turbvis@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 <doslynx@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 <rnelson@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 <sierwald@tu-harburg.d400.de> ftp://uni-stuttgart.de/pub/systems/os2/programming/ Patches to support TV with compilers other than Borland C++. Werthy, William (Bill) <billw@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:fhohmann@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: fhohmann@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 <billw@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.2764@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 grove@zeta.org.au Robert Hazeltine http://www.zeta.org.au/~grove/grove.html r.polanskis@nepean.uws.edu.au ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ User Contributions: |
Comment about this article, ask questions, or add new information about this topic: