PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 1/12
TITLE : Dynamically modifying Turbo Vision menus.
This document provides source code to an example which
dynamically modifies menus using Turbo Vision for C++.
/***********************************************************************
* *
* MMENU.CPP *
* This module contains the code to support the TMultiMenu class. *
* *
***********************************************************************/
#define Uses_TEvent
#define Uses_TMenu
#define Uses_TSubMenu
#define Uses_TMenuItem
#define Uses_TMenuBar
#include
#if !defined( __MMENU_H )
#include "mmenu.h"
#endif
/***********************************************************************
* global operator +
*
* Since the objects will always be in a linked list, and the operator+
* is processd left-to-right, we will define the function as appending
* menuItem2 to menuItem1, and then return menuItem1.
***********************************************************************/
TMenuItem& operator +( TMenuItem& menuItem1, TMenuItem& menuItem2 )
{
TMenuItem *p = &menuItem1;
while( p->next != NULL )
p = p->next;
p->next = &menuItem2;
return menuItem1;
}
/***********************************************************************
* *
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 2/12
TITLE : Dynamically modifying Turbo Vision menus.
* class TTestList *
* *
***********************************************************************
* TMultiMenu::TMultiMenu
* Constructor for a TMultiMenu object. This version takes an array
* of TMenu pointers.
***********************************************************************/
TMultiMenu::TMultiMenu( const TRect& bounds, TMenu *aMenu[],
int nMenus ) : TMenuBar( bounds, aMenu[0] ),
mList( new TMenu *[nMenus] )
{
if( nMenus == 0)
for( nMenus = 0; aMenu[nMenus] != NULL; nMenus++ )
;
numMenus = nMenus;
for( int i = 0; i < nMenus; i++ )
mList[i] = aMenu[i];
}
/***********************************************************************
* TMultiMenu::TMultiMenu
* Constructor for a TMultiMenu object. This version takes an array
* of TSubMenu objects.
***********************************************************************/
TMultiMenu::TMultiMenu( const TRect& bounds, TSubMenu aMenu[],
int nMenus ) :
TMenuBar( bounds, aMenu[0] ),
numMenus( nMenus ),
mList( new TMenu *[nMenus] )
{
mList[0] = menu; // First menu is already allocated.
for( int i = 1; i < nMenus; i++ )
mList[i] = new TMenu( aMenu[i] );
}
/***********************************************************************
* TMultiMenu::~TMultiMenu
* Destructor for a TMultiMenu object. Destroys any stored menus
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 3/12
TITLE : Dynamically modifying Turbo Vision menus.
* except for the current one (which will be destroyed by ~TMenuBar)
* and frees the space where the list was stored.
***********************************************************************/
TMultiMenu::~TMultiMenu()
{
for( int i = 0; i < numMenus; i++ )
if( mList[i] != menu ) // Delete all but current menu.
delete mList[i];
delete [] mList;
}
/***********************************************************************
* TMultiMenu::handleEvent
* Code to respond to the cmMMChangeMenu broadcast message. The
* data the arrives with this message specifies which menu to switch
* to, passed via the infoInt data member of TEvent.
***********************************************************************/
void TMultiMenu::handleEvent( TEvent& event )
{
if( event.what == evBroadcast &&
event.message.command == cmMMChangeMenu )
{
if( event.message.infoInt >= 0 &&
event.message.infoInt < numMenus )
{
if( menu != mList[ event.message.infoInt ] )
{
menu = mList[ event.message.infoInt ];
drawView();
}
}
clearEvent( event );
}
else
TMenuBar::handleEvent( event );
}
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 4/12
TITLE : Dynamically modifying Turbo Vision menus.
/***********************************************************************
* *
* TEST.CPP *
* This module contains the Turbo Vision application code to run *
* this example. It sets up the necessary menus to bring up the *
* test module represented by this demo. *
* *
* TEST MODULE for Multiple Menu Bar Demo. *
* *
***********************************************************************
* *
* This code was written by Borland Technical Support. *
* It is provided as is with no warranties expressed or implied. *
* *
***********************************************************************/
#define Uses_TRect
#define Uses_TKeys
#define Uses_TEvent
#define Uses_TDialog
#define Uses_TMenu
#define Uses_TMenuItem
#define Uses_TMenuBar
#define Uses_TDeskTop
#define Uses_TProgram
#define Uses_TApplication
#include
#pragma hdrstop
#if !defined( __CMDS_H )
#include "cmds.h"
#endif
#if !defined( __MMENU_H )
#include "mmenu.h"
#endif
/***********************************************************************
*
* Application object for demo.
*
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 5/12
TITLE : Dynamically modifying Turbo Vision menus.
***********************************************************************/
class TTestApp : public TApplication
{
public:
TTestApp();
static TMenuBar *initMenuBar( TRect r );
virtual void handleEvent( TEvent& event );
protected:
int curMenu;
};
/***********************************************************************
*
* TTestApp::TTestApp()
*
* Application object contructor.
*
***********************************************************************/
TTestApp::TTestApp() :
TApplication(),
TProgInit( initStatusLine, initMenuBar, initDeskTop ),
curMenu( 0 )
{
}
/***********************************************************************
*
* TTestApp::initMenuBar( TRect r )
*
* Build several menus and pass them in an array to the TMultiMenu
* constructor.
*
***********************************************************************/
TMenuBar *TTestApp::initMenuBar( TRect r )
{
r.b.y = r.a.y + 1;
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 6/12
TITLE : Dynamically modifying Turbo Vision menus.
TMenu *M[] =
{
/* Menu Number One */
new TMenu(
*new TMenuItem( "~N~ext menu", cmCycle, kbAltN ) +
*new TMenuItem( "~M~enu One", kbAltM, new TMenu(
*new TMenuItem( "~O~ne", cmOne, kbAltO ) +
*new TMenuItem( "~T~wo", cmTwo, kbAltT ) +
*new TMenuItem( "T~h~ree", cmThree, kbAltH )
)) +
*new TMenuItem( "~F~ile", kbAltF, new TMenu(
*new TMenuItem( "~N~ew", cmNothing, kbAltN ) +
*new TMenuItem( "~O~pen", cmNothing, kbAltO ) +
*new TMenuItem( "~S~ave", cmNothing, kbAltS ) +
*new TMenuItem( "S~a~ve all", cmNothing, kbAltA )
))
),
/* Menu Number Two */
new TMenu(
*new TMenuItem( "~N~ext menu", cmCycle, kbAltN ) +
*new TMenuItem( "~M~enu Two", kbAltM, new TMenu(
*new TMenuItem( "~O~ne", cmOne, kbAltO ) +
*new TMenuItem( "~T~wo", cmTwo, kbAltT ) +
*new TMenuItem( "T~h~ree", cmThree, kbAltH )
)) +
*new TMenuItem( "~E~dit", kbAltE, new TMenu(
*new TMenuItem( "Cu~t~", cmNothing, kbAltT ) +
*new TMenuItem( "~C~opy", cmNothing, kbAltC ) +
*new TMenuItem( "~P~aste", cmNothing, kbAltP )
))
),
/* Menu Number Three */
new TMenu(
*new TMenuItem( "~N~ext menu", cmCycle, kbAltN ) +
*new TMenuItem( "~M~enu Three", kbAltM, new TMenu(
*new TMenuItem( "~O~ne", cmOne, kbAltO ) +
*new TMenuItem( "~T~wo", cmTwo, kbAltT ) +
*new TMenuItem( "T~h~ree", cmThree, kbAltH )
)) +
*new TMenuItem( "~C~ompile", kbAltC, new TMenu(
*new TMenuItem( "~C~ompile", cmNothing, kbAltO ) +
*new TMenuItem( "~M~ake", cmNothing, kbAltT ) +
*new TMenuItem( "~L~ink", cmNothing, kbAltH ) +
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 7/12
TITLE : Dynamically modifying Turbo Vision menus.
*new TMenuItem( "~B~uild All", cmNothing, kbAltH )
))
),
/* END of Menu List Marker (NULL) */
0
};
return new TMultiMenu( r, M );
}
/***********************************************************************
*
* TTestApp::handleEvent( TEvent& event )
*
* Send appropriate messages to the new multi menu object in response
* to commands generated by the current menu. The menu bar will switch
* to a new setting automatically upon receiving the correct message.
*
***********************************************************************/
void TTestApp::handleEvent( TEvent& event )
{
if( event.what == evCommand &&
event.message.command >= cmOne &&
event.message.command <= cmThree
)
{
curMenu = (event.message.command - cmOne) % 3;
message( TProgram::menuBar, evBroadcast, cmMMChangeMenu,
(void *) curMenu
);
clearEvent( event );
}
else if( event.what == evCommand && event.message.command == cmCycle )
{
curMenu = (curMenu + 1) % 3;
message( TProgram::menuBar, evBroadcast, cmMMChangeMenu,
(void *) curMenu
);
clearEvent( event );
}
else
TApplication::handleEvent( event );
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 8/12
TITLE : Dynamically modifying Turbo Vision menus.
}
/***********************************************************************
*
* main()
*
***********************************************************************/
int main()
{
TTestApp TB;
TB.run();
return 0;
}
/***********************************************************************
* *
* CMDS.H *
* This header contains various commands used in the main message *
* system (including the menu bar, status line, and miscellaneous *
* dialog boxes.) *
* *
* HEADER FILE for Multiple Menu Bar Demo *
* *
***********************************************************************
* *
* This code was written by Borland Technical Support. *
* It is provided as is with no warranties expressed or implied. *
* *
***********************************************************************/
#ifndef _CMDS_H
#define _CMDS_H
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 9/12
TITLE : Dynamically modifying Turbo Vision menus.
const unsigned cmOne = 100;
const unsigned cmTwo = 101;
const unsigned cmThree = 102;
const unsigned cmCycle = 110;
const unsigned cmNothing = 111;
#endif
/***********************************************************************
* *
* MMENU.H *
* This module contains the class definitions for the MMENU.CPP *
* source module. *
* *
* Classes: *
* TMultiMenu New object derived from TMenuBar to support *
* dynamic changing of menus. *
* *
* TMenuItem& operator+( TMenuItem& one, TMenuItem& two ) *
* Operator that links two TMenuItems together *
* *
***********************************************************************
* *
* This code was written by Borland Technical Support. *
* It is provided as is with no warranties expressed or implied. *
* *
***********************************************************************/
/*
* class TMultiMenu - A new menubar that supports dynamic changing of menus
* via the messaging system.
*
* When the TMultiMenu object is created, an array of TMenu or TSubMenu
* objects is passed to the constructor. At runtime, any of these menus can
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 10/12
TITLE : Dynamically modifying Turbo Vision menus.
* be selected by sending a broadcast message to the menubar. The following
* parameters for the message function should be used for this object.
*
* message( TView *receiver, ushort what, ushort command, void *infoPtr )
*
* receiver = pointer to menubar object or its owner. The system menubar
* is accessible via the static variable TProgram::menubar.
*
* what = evBroadcast.
*
* command =
* cmMMChangeMenu : This command selects the menu whose number was
* passed in the infoPtr member. This number is an unsigned integer.
*
* infoPtr = Depends on command issued. See particular command for
* details
*
* Example:
*
* message( TProgram::menubar, evBroadcast, cmMMChangeMenu, (void *) 3 )
*
* This example would select menu number 3 for the system menubar. If
* there are not three menus, the message is ignored and the menu is
* unchanged.
*
* The TMultiMenu constructors are very similar to the TMenuBar constructors
* except that instead of taking a single TMenu pointer or a single TSubMenu
* reference, they take an array of either of these. (See below.) When
* using the form that takes a TMenu *[], the last member of the array
* should be a NULL when taking advantage of the default argument for the
* third parameter which represents the number of menus supported.
*
* The last component of this file is an overloaded operator that can
* link two TMenuItem objects together. This operator has been used to
* make the example code in the test module much easier to read.
*/
class TMultiMenu : public TMenuBar
{
public:
TMultiMenu( const TRect& bounds, TMenu *aMenu[], int nMenus = 0 );
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 11/12
TITLE : Dynamically modifying Turbo Vision menus.
TMultiMenu( const TRect& bounds, TSubMenu aMenu[], int nMenus );
~TMultiMenu();
virtual void handleEvent( TEvent& event );
protected:
TMenu **mList;
int numMenus;
};
const unsigned cmMMChangeMenu = 0x1600;
TMenuItem& operator +( TMenuItem& menu1, TMenuItem& menu2 );
#
# Makefile for Turbo Vision demo applications
#
# Written by Borland Tech Support, 1992.
#
.AUTODEPEND
INCDIR = c:\borlandc\include;c:\borlandc\tvision\include
LIBDIR = c:\borlandc\lib;c:\borlandc\tvision\lib
NAME = mmenu
OBJS = test.obj $(NAME).obj
CFLAGS = -c -ml -O2 -I$(INCDIR) -L$(LIBDIR)
.cpp.obj:
bcc +$(NAME).cfg {$*.cpp }
PRODUCT : Borland C++ NUMBER : 1160
VERSION : 3.1
OS : DOS
DATE : December 3, 1992 PAGE : 12/12
TITLE : Dynamically modifying Turbo Vision menus.
# MMENU.EXE
$(NAME).exe: $(NAME).cfg $(OBJS)
tlink @&&~
/c /x /L$(LIBDIR) c0l.obj + $(OBJS)
$(NAME).exe
$(NAME).map
tv.lib + cl.lib
~
# MMENU.CFG
$(NAME).cfg: makefile
copy &&~
$(CFLAGS)
~ $(NAME).cfg
DISCLAIMER: You have the right to use this technical information subject to
the terms of the No-Nonsense License Statement that you received with the
Borland product to which this information pertains.