home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-02-10 | 57.4 KB | 1,430 lines |
- Menus
- Menus
- Menus
-
-
-
- "Ninety-eight percent of the adults in this country are decent, hard-
- working Americans. It's the other lousy two percent that get all the
- publicity. But then we elected them."
-
- Lily Tomlin
-
-
-
-
-
- Introduction
- You want menus, we got menus!
-
- The Toolkit includes three main menu types: pop-up menus, Lotus-style
- menu bars and pull-down menus. All the menus can be nested many levels
- deep, i.e. when the user selects an item from a menu, another menu can
- be automatically displayed. You may optionally specify a description
- for any menu item, and when the user highlights the item, the descrip-
- tive text is automatically displayed. All the menus provide full mouse
- support, and if the mouse cursor drifts across a specific item, it is
- automatically highlighted. Menu items can also be selected with the
- cursor keys or by pressing a menu item hotkey.
- The object hierarchy includes a number of abstract objects, as illus-
- trated in figure 12.1. You should never declare an instance of type
- BaseMenuOBJ, WinMenuOBJ, BarMenuOBJ or KwikPullOBJ, as these are
- abstract. Use one of the following objects to display a menu:
-
- MenuOBJ This object displays a simple menu in a window. This
- object is commonly used for a program's main menu
- which is displayed when the program starts.
- MoveMenuOBJ This object is similar to MenuOBJ, except that the
- user can drag the menu around the screen to view the
- contents of the screen below.
-
- LotusMenuOBJ The LotusMenuOBJ provides a 1-2-3 (or Paradox!)
- style menu bar. The user scrolls left and right
- along the menu bar.
- PullMenuOBJ This is an "IDE-like" pull-down menu which supports
- multiple levels of sub-menus.
-
- EZPullArrayOBJ This objects provides a quick and easy way of
- creating a sophisticated pull-down menu. All you
- have to do is update a string array with the
- individual item details, and instruct the Toolkit to
- display the menu.
-
- 12-2 User's Guide
- --------------------------------------------------------------------------------
-
- EZPullLinkOBJ This object is similar to the EZPullArrayOBJ, except
- that the menu item details are added to a linked
- list (of type DLLOBJ or descendant).
-
-
- Figure 12.1 [PICTURE]
- Menu
- Object Hierarchy
-
-
-
- Common Methods
- All menus contain items, hotkeys, descriptions, and the like. The Tool-
- kit's varied menu objects share a variety of common methods which are
- used to construct the menu details and characteristics.
-
-
- Adding Menu Item Details
-
- The following methods are used to set the individual menu details:
-
- Init;
-
- The Init method is passed no parameters, and should be called before
- any other menu method.
-
- AddItem(Txt:StrVisible);
-
- This method is used to add an item to the menu. The method is passed
- one parameter identifying the menu text to be displayed. The item
- string may include embedded highlight characters to indicate that a
- specific character is designated as a hot key -- refer to the WriteHi
- method on page 5-3 for further information. Special strings can be
- passed to force blanks or lines in the menu item list - see the note at
- the end of this section.
-
- The following methods may be called to further define the settings for
- each item. Note, however, that the item must have been added with AddI-
- tem (or AddFullItem) before these additional settings can be specified.
-
-
- SetHK(Item:byte; HK:word);
- Any item can be assigned a hotkey, which provides a way for the user to
- select the item without scrolling to the item. All the user does is
- press the hotkey. The de facto standard is to use normal alphabet char-
- acters as the hotkeys. (Lotus and pull-down menus support additional
- hotkeys which can be pressed even when the appropriate menu is not on
- display -- this subject is discussed in detail later).
-
-
- Menus Menus Menus 12-3
- --------------------------------------------------------------------------------
-
- SetMessage(Item:byte; Msg:StrVisible);
-
- The SetMessage method is used to define a message for an item. When the
- item is highlighted, the message will be automatically displayed, and
- when the user moves to a different item, the message is removed. The
- Toolkit does not save the contents of the screen where the message is
- displayed.
-
- SetID(Item:byte; ID:word);
-
- In a menu system, which includes sub-menus, this method can be used to
- assign each topic in the menu a unique ID. The method is passed two
- parameters; the item number and the item ID. This ID is of type word,
- and will be returned by the menu method Activate if the item is
- selected by the user. Note that you should not use IDs greater than
- 65000, because some of these IDs are used internally by the Toolkit.
-
- SetStatus(Item:byte, On:boolean);
-
- Sometimes, certain menu items will not be selectable. For example, a
- File Save option may not be operative until a file has been loaded or
- created. The SetStatus method is used to control whether an option is
- selectable. The method is passed two parameters; the item number and a
- boolean parameter. Set the boolean to TRUE to enable the item and FALSE
- to disable it.
-
- SetSubMenu(Item:byte; SubMenu:BaseMenuPtr);
-
- This method is used to indicate that another menu should be displayed,
- if the item is selected by the user. The Toolkit will automatically
- display the new menu below and to the right of the active menu. The
- method is passed two parameters; the item number and the address of the
- sub-menu object. Normally, you will call another menu instance of the
- same type as the parent, e.g. if the parent menu is of type MenuOBJ,
- then the sub-menu is usually of type MenuOBJ. This, however, is not
- mandatory, and any menu item can display a sub-menu of any type in the
- menu object hierarchy. Note that the second parameter is the address of
- the sub-menu, and is normally specified by preceding the menu object
- with the Turbo Pascal "@" address symbol. For example:
-
- SetSubMenu(5,@FileMenu);
-
- When you want to specify all the menu item details, e.g. message, HK,
- sub-menu, etc., you can use the following all-in-one method:
-
-
- AddFullItem(Txt:StrVisible;ID,Hk:word; Msg:StrVisible; SubM:Baseme-
- nuPtr);
-
-
-
- 12-4 User's Guide
- --------------------------------------------------------------------------------
-
- As you may have guessed, this method is used to add a new item and
- specify its settings in one heavy statement! This method is a single
- replacement for five of the previous six methods. The only method that
- is not accommodated by AddFullItem is SetStatus, and the Status is set
- to true by default. Use one of the following values to suppress the
- setting of one or more of the item elements:
-
- No ID 0
- No hotkey 0
- No message ''
- No sub-menu nil
-
- Listed below are two code fragments, both of which define the same
- three-item menu. The first code block uses the individual methods, and
- the second block takes advantage of AddFullItem. It doesn't matter
- which technique you use, so use the one which seems easiest to you.
- with MainMenu do
- begin
- Init;
- AddItem(' ~L~oad file ')
- SetID(1,1);
- SetHK(1,76);
- SetMessage(1,'Load a database file from disk');
- AddItem(' ~S~ave file ');
- SetID(2,2);
- SetHK(83);
- SetMessage(2,'Save the current database to disk');
- AddItem(' ~Q~uit ');
- SetID(3,99);
- SetHK(3,81);
- Setmessage(3,'Let''s party!');
- ...
- end;
-
-
- with MainMenu do
- begin
- Init;
- AddFullItem(' ~L~oad file ',1,76,'Load a database file from disk',-
- nil);
- AddFullItem(' ~S~ave file ',2,83,'Save the current database to
- disk',nil);
- AddFullItem(' ~Q~uit ',99,81,'Let''s party!',nil);
- ...
- end;
-
- Having created a menu, the following methods can be used to display,
- start, remove and dispose of the menu.
-
-
-
- Menus Menus Menus 12-5
- --------------------------------------------------------------------------------
-
- Draw;
-
- This method instructs the object to draw itself. As soon as the menu is
- drawn, the method returns control back to your program, i.e. the object
- does not process any user input.
-
- Activate: word;
-
- This is the main "DO-IT!" method. If the menu is not already visible,
- the menu is drawn, and then the Toolkit processes user input until the
- user selects a menu item or ESCapes (if ESC is enabled). The function
- method returns the ID of the selected item. If the ID was never speci-
- fied, i.e. it is set to zero, the Toolkit will return the actual item
- number. Note, however, that this number is the item number in the
- currently displayed menu. In a system with sub-menus you will not know
- which sub-menu was on display. In a system with sub-menus, you should
- therefore always assign a unique ID to each selectable item. A zero is
- returned if the user escaped.
-
- Remove;
-
- This methods removes the menu. If the menu is of type MenuOBJ or Move-
- MenuOBJ, the underlying screen contents are restored. All other menu
- objects do not restore any underlying screen contents -- they simply
- erase the menu text.
-
- Done;
-
- When the menu is no longer required, call this method to dispose of the
- memory used internally by the menu.
-
-
-
- Changing Menu Characteristics
-
- The following methods are used to control the general display charac-
- teristics of the menu:
-
- SetGap(G:byte);
-
- This method is used to create a space (or gap) to the left and right of
- each menu item. In a pop-up menu, this can be used to create a space
- between the menu border and the menu text. With Lotus and pull-down
- menus, this method creates a space between each item along the top menu
- bar. The method is passed one parameter; a byte representing the number
- of characters space to allow on either side of each menu item.
-
- SetMenuXY(X,Y: byte);
-
-
-
- 12-6 User's Guide
- --------------------------------------------------------------------------------
-
- This method is used to set the specific location of the menu on the
- screen. The method is passed two byte parameters representing the (X,Y)
- coordinate of the top left corner of the menu. With pop-up menus, the
- menu will be centered laterally and vertically if the X or Y parameter
- is set to zero.
-
-
- SetMesssageXY(X,Y:byte);
- This method is used to specify the location of the optional message
- which is displayed when a topic is highlighted. The method is passed
- two parameters representing the (X,Y) coordinate of the first character
- in the message.
-
-
- SetAllowEsc(On:boolean);
- This method is used to control whether the user may escape from the
- menu. It is passed a single boolean parameter, which should be set to
- TRUE to enable escape (the default), or FALSE to disable it.
-
-
- SetActiveItem(Item:byte);
- Normally, the first item in a menu is highlighted when the menu is
- first displayed. If this item is non-selectable, or if you want to
- highlight a different item, use the method SetActiveItem. The method is
- passed one byte parameter identifying the topic number of the item to
- be highlighted.
-
-
- The display colors are controlled by the menu item colors, and (in the
- case of pop-up and pull-down menus) the window display colors. All the
- colors default to values established by LookTOT. To change the look and
- feel of your menus, you should assign new default values to LookTOT.
- Refer to page 3-12 for a description of how to control the LookTOT
- defaults. The following two methods can be used to control the display
- colors of any individual menu:
-
- SetColors(HiHot,HoNorm,LoHot,LoNorm,Off:byte);
-
- This method changes the display colors of the individual menu items.
- The procedure is passed five byte parameters: the first two parameters
- control the display color of the menu highlight bar -- the first param-
- eter is the attribute of any highlighted text, e.g. the 'Q' in
- '~Q~uit', and the second parameter is the standard display color, e.g.
- the 'uit' part. The third and fourth parameters are the display attrib-
- utes for the un-selected (or normal) menu items, and the fifth parame-
- ter is the display attribute of inactive items. Note that this method
- automatically sets the window body display color to the parameter
- LoNorm.
-
-
-
- Menus Menus Menus 12-7
- --------------------------------------------------------------------------------
-
- Win^.SetColors(Border,Body,Title,Icons: byte);
-
- In the case of pop-up and pull-down menus, this method sets the colors
- of the underlying window. Refer to page 7-6 for a general description
- of this window method.
-
-
- Adding Lines and Gaps
- Sometimes, you may want to display a menu with some items separated
- from others. By specifying special item text, you instruct the Toolkit
- to draw special lines, or leave a gap. The following item text should
- be used:
-
- '' A null string creates a gap in the menu.
- '-' A string comprising entirely of the minus sign will result in a
- single horizontal line being drawn from the left to the right of
- the menu.
-
- '=' A string comprising entirely of the equals sign will result in a
- double horizontal line being drawn from the left to the right of
- the menu.
- For example, the following code fragment will force a blank line
- between the third and fourth selectable items, and draws a single line
- between the last two picks:
-
- AddItem('Whips');
- AddItem('Chains');
- Additem('Rubber');
- AddItem('');
- AddItem('Hard Disks');
- AddItem('Floppies');
- AddItem('-');
- AddItem('Quit');
-
-
-
- Note: even non-selectable menu items are recognized as items in
- the menu list. When you use one of the Set methods (described
- earlier), be sure to include the non-selectable items in the list.
- For example, in the above code fragment, the "Quit" item is item
- number 8 (not 6), and its hotkey could be set to "Q" with the
- following method call:
-
- SetHK(8,ord('Q'));
-
-
-
- 12-8 User's Guide
- --------------------------------------------------------------------------------
-
- Examples
-
- Listed below is the demo file DEMMN1.PAS, which illustrates how to
- create a simple menu using some of the methods already described. Fig-
- ure 12.2 illustrates the resultant display.
- program DemoMenuOne;
- {DEMMN1 - a basic menu}
-
- USES DOS, CRT,
- totMENU, totFAST;
- var
- Main: MenuOBJ;
- Choice: byte;
- begin
- Screen.Clear(white,'░'); {paint the screen}
- with Main do
- begin
- Init;
- AddItem('');
- AddItem(' Load a file ');
- AddItem(' Edit Date ');
- AddItem(' Save the file ');
- AddItem(' Change configuration ');
- AddItem('-');
- AddItem(' Quit ');
- SetStyleTitle(1,' Main Menu ');
- SetActiveItem(2);
- Choice := Activate;
- Done;
- end;
- if Choice = 0 then
- Writeln('You escaped')
- else
- Writeln('You selected menu item ',Choice);
- end.
-
-
- Figure 12.2 [SCREEN]
- A Simple Menu
-
-
- Creating Pop-Up Menus
-
- totMENU provides two objects for creating pop-up menus: MenuOBJ and
- MoveMenuOBJ. Both these objects create menus which are displayed in a
- window, the only difference being that MoveMenuOBJ creates moveable
- menus, i.e. menus that the user can drag around the screen.
-
-
-
- Menus Menus Menus 12-9
- --------------------------------------------------------------------------------
-
- Both objects are descendant from BaseMenuOBJ and inherit the following,
- previously described, methods:
-
- Init;
- AddItem(Txt:StrVisible);
- SetHK(Item:byte; HK:word);
- SetMessage(Item:byte; Msg:StrVisible);
- SetID(Item:byte; ID:word);
- SetStatus(Item:byte, On:boolean);
- SetSubMenu(Item:byte; SubMenu:BaseMenuPtr);
- AddFullItem(Txt:StrVisible;ID,Hk:word; Msg:StrVisible; SubM:Baseme-
- nuPtr);
- Draw;
- Activate: word;
- Remove;
- SetGap(G:byte);
- SetMenuXY(X,Y: byte);
- SetMessageXY(X,Y:byte);
- SetAllowEsc(On:boolean);
- SetActiveItem(Item:byte);
- SetColors(HiHot,HoNorm,LoHot,LoNorm,Off:byte);
- Done;
-
- The menu is drawn on a window, and the following function methods can
- be used to called any of the window methods:
-
-
- Win: WinPtr;
- Win: MoveWinPtr;
- This function returns a pointer to the menu on which the menu is drawn.
- For MenuOBJ instances the method returns a pointer to WinOBJ, and for
- MoveWinOBJ it returns a pointer to MoveWinOBJ. Using the syntax
- Win^.method you may call any of the window methods.
-
-
- The menu window dimensions are automatically calculated from the width
- and number of menu items. You should therefore avoid calling the window
- method SetSize. As a convenience, the following method provides an easy
- way to change the menu style and title.
-
- SetStyleTitle(Style:byte; Tit:StrVisible);
-
- This method sets the style and title of the menu window. The style
- parameter is the same as the box style parameter discussed on page 5-7,
- and the title supports the special title characters discussed on page
- 5-8.
-
-
-
- 12-10 User's Guide
- --------------------------------------------------------------------------------
-
- The first example shown at the end of the previous section illustrated
- how to create a MenuOBJ menu. The on-disk demo file DEMMN2.PAS shows
- how to create a moveable menu and control the display colors. Listed
- below is the demo file DEMMN3.PAS, which illustrates how to create a
- nested menu system. Figure 12.3 shows the generated menu.
-
- program DemoMenuThree;
- {DEMMN3 - nested pop-up menus}
- USES DOS, CRT,
- totMENU, totFAST, totLOOK, totSYS;
-
- var
- Main,
- Load: MenuOBJ;
- Choice: byte;
- begin
- Screen.PartClear(1,1,80,24,white,'░'); {paint the screen}
- Screen.PartClear(1,24,80,25,30,' ');
- with Load do
- begin
- Init;
- AddItem('');
- AddFullItem(' ~1~ Accounts Payable ',11,49,
- 'Load database ACTP1',nil);
- AddFullItem(' ~2~ Accounts Receivable ',12,50,
- 'Load database ACTR7',nil);
- AddFullItem(' ~3~ Net Assets Employed ',13,51,
- 'Load the ledger file',nil);
- AddFullItem(' ~4~ Net Cash Flow ',14,52,
- 'Load the cash file',nil);
- SetStyleTitle(6,'Load Menu');
- SetActiveItem(2);
- SetMessageXY(25,25);
- SetGap(1);
- Win^.SetClose(False);
- end;
- with Main do
- begin
- Init;
- AddItem('');
- AddFullItem(' ~1~ Load a file ',1,49,
- 'Loads a new database file',@Load);
- AddFullItem(' ~2~ Edit Date ',2,50,
- 'Full screen editing of data base entries',nil);
- AddFullItem(' ~3~ Save the file ',3,51,
- 'Save database file to disk',nil);
- AddFullItem(' ~4~ Change configuration ',4,52,
- 'Modify colors and defaults',nil);
-
-
-
- Menus Menus Menus 12-11
- --------------------------------------------------------------------------------
-
- AddItem('');
- AddFullItem(' ~Q~ Quit ',99,81,
- 'Exit system and return to DOS',nil);
- SetStyleTitle(6,'Main Menu');
- SetActiveItem(2);
- SetMenuXY(0,4);
- SetMessageXY(25,25);
- SetGap(1);
- Win^.SetClose(False);
- Choice := Activate;
- Done;
- Load.Done;
- end;
- if Choice = 0 then
- Writeln('You escaped')
- else
- Writeln('You selected menu item ',Choice);
- end.
-
-
- Figure 12.3 [SCREEN]
- Nested Pop-Up
- Menus
-
-
- Creating Lotus-style Menus
-
- Lotus-style menus are menu bars which occupy a single line, and the
- user scrolls left and right through the items. An optional description
- of the highlighted item is usually displayed on the line immediately
- below the menu bar.
- The LotusMenuOBJ object makes building Lotus-style menus easy. LotusMe-
- nuOBJ is descendant from BaseMenuOBJ, and inherits the following, pre-
- viously described, methods:
-
- Init;
- AddItem(Txt:StrVisible);
- SetHK(Item:byte; HK:word);
- SetMessage(Item:byte; Msg:StrVisible);
- SetID(Item:byte; ID:word);
- SetStatus(Item:byte, On:boolean);
- SetSubMenu(Item:byte; SubMenu:BaseMenuPtr);
- AddFullItem(Txt:StrVisible;ID,Hk:word; Msg:StrVisible; SubM:Baseme-
- nuPtr);
- Draw;
- Activate: word;
- Remove;
- SetGap(G:byte);
- SetMenuXY(X,Y: byte);
-
-
- 12-12 User's Guide
- --------------------------------------------------------------------------------
-
- SetMessageXY(X,Y:byte);
- SetAllowEsc(On:boolean);
- SetActiveItem(Item:byte);
- SetColors(HiHot,HoNorm,LoHot,LoNorm,Off:byte);
- Done;
-
-
- Listed below are the contents of the file DEMMN4.PAS, which uses these
- basic methods to build a simple single-level Lotus menu. Figure 12.4
- shows the resultant menu display.
- program DemoMenuFour;
- {DEMMN1 - a simple lotus menu}
-
- USES DOS, CRT,
- totMENU, totFAST;
- var
- P: LotusMenuOBJ;
- Choice: byte;
- begin
- Screen.Clear(white,'░'); {paint the screen}
- with P do
- begin
- Init;
- AddItem('Worksheet');
- AddItem('Range');
- AddItem('Copy');
- AddItem('Move');
- AddItem('File');
- AddItem('Print');
- AddItem('Graph');
- AddItem('Data');
- AddItem('System');
- AddItem('Quit');
- SetActiveItem(1);
- SetGap(1);
- Choice := Activate;
- Done;
- end;
- GotoXY(1,5);
- if Choice = 0 then
- Writeln('You escaped')
- else
- Writeln('You selected menu item ',Choice);
- end.
-
-
- Figure 12.4 [SCREEN]
- A Simple Lotus
- Menu
-
-
- Menus Menus Menus 12-13
- --------------------------------------------------------------------------------
-
- If the user is using a mouse to select an item, the item is selected
- when the user lets go of the mouse button. If the user holds down the
- mouse button, and drifts away from the menu surface, none of the items
- will be highlighted. If the user then releases the mouse button (while
- the mouse cursor is not over the menu surface), a special ID DriftID is
- returned by Activate. DriftID is declared as a constant in the totMENU
- unit. To recap, if the ID 0 is returned, the user escaped, and if
- DriftID is returned, the user drifted off the menu and selected no
- item. All other values indicate that the user chose a specific item
- from the menu.
-
- In addition to the inherited methods, LotusMenuOBJ objects support the
- following methods:
-
- SetSpecialKey(HK:word; ID:word);
-
- The hotkeys which are defined for each menu item allow the user to
- select the item by pressing the appropriate hotkey. However, only the
- hotkeys for the currently displayed menu are recognized. In a nested
- menu system, the SetSpecialKey method can be used to define hotkeys
- which will be recognized regardless of which menu level is being dis-
- played. The method is passed two parameters; the keycode of the hotkey
- and the ID which will be returned when the user presses this special
- key. Special hotkeys can be added in any order, and they do not have to
- correspond to any of the actual menu items. For example, you could add
- an [KEYCAP] key to return the value of 1000 with the following state-
- ment:
-
- SetSpecialKey(301,1000);
-
- If the menu is active, and the user presses [KEYCAP], the menu will
- immediately end and return a value of 1000.
-
- Menukey(K:word; X,Y: byte): boolean;
-
- This method is passed three parameters defining the details of a key-
- press, i.e. the keycode, and the (X,Y) coordinate of the mouse when the
- key was pressed. The function method returns TRUE if the key's details
- are recognized by the menu, i.e. if the details represent a menu
- hotkey, or a mouse click on the menu surface.
-
- Push(K:word; X,Y: byte);
-
- The Activate method is used to start the menu and wait for user input.
- The Push method is similar to activate, except that the procedure is
- passed the key details for the first input to be processed. This method
- can be used in conjunction with MenuKey to test for a menu key and then
-
-
-
- 12-14 User's Guide
- --------------------------------------------------------------------------------
-
- process it. For example, the following code fragment prompts the user
- for input. If it is related to the menu, the menu is invoked, otherwise
- SomeOtherTask is called:
-
- var
- Lmenu: LotusMenuOBJ;
- K: word;
- X,Y: byte;
- Choice: word;
- procedure SetUpLMenu;
- {}
- begin
- with Lmenu do
- begin
- Init;
- {...}
- end;
- end;
-
- procedure SomeOtherTask(K:word;X,Y:byte);
- {}
- begin
- {...}
- end; {SomeOtherTask)}
- begin
- Screen.Clear(white,'░'); {paint the screen}
- SetUpLmenu;
- Choice := 0;
- Lmenu.Draw;
- Mouse.Show;
- Repeat
- K := Key.Getkey;
- X := Key.LastX;
- Y := Key.LastY;
- if Lmenu.Menukey(K,X,Y) then
- Choice := Lmenu.Push(K,X,Y)
- else
- SomeOtherTask(K,X,Y);
- Until (Choice <> 0) and (Choice <> DriftID);
- Mouse.Hide;
- writeln(Choice);
- end.
-
-
- Lotus menus can be nested many levels deep. Listed below is the demo
- file DEMMN5.PAS, which shows how to create nested menus. Figure 12.5
- shows the resultant display.
-
-
-
- Menus Menus Menus 12-15
- --------------------------------------------------------------------------------
-
- program DemoMenuFive;
- {DEMMN5 - a nested Lotus menu}
-
- USES DOS, CRT,
- totMENU, totFAST;
- var
- Main,
- Worksheet,
- Range: LotusMenuOBJ;
- Choice: word;
-
- procedure Pretend;
- begin
- Screen.Clear(31,' '); {paint the screen}
- Screen.WriteAt(1,4,48,replicate(80,' '));
- Screen.WriteCenter(4,48,'Not 1-2-3!');
- Screen.PartClear(1,5,4,25,48,' ');
- end; {Pretend}
- begin
- Pretend;
- with Worksheet do
- begin
- Init;
- AddFullItem('~G~lobal',100,71,'Global stuff',nil);
- AddFullItem('~I~nsert',101,73,'Insert stuff',nil);
- AddFullItem('~D~elete',102,68,'Delete stuff',nil);
- AddFullItem('~C~olumn',103,67,'Column stuff',nil);
- AddFullItem('~E~rase',104,69,'Erase stuff',nil);
- AddFullItem('~T~itles',105,84,'Titles stuff',nil);
- AddFullItem('~W~indow',106,87,'Window stuff',nil);
- AddFullItem('~S~tatus',107,83,'Status stuff',nil);
- AddFullItem('~P~age',108,80,'Page stuff',nil);
- AddFullItem('~H~ide',109,72,'Hide things',nil);
- SetActiveItem(1);
- SetGap(1);
- end;
- with Range do
- begin
- Init;
- AddFullItem('~F~ormat',200,70,'Format stuff',nil);
- AddFullItem('~L~abel',201,76,'Label stuff',nil);
- AddFullItem('~E~rase',202,69,'Erase stuff',nil);
- AddFullItem('~N~ame',203,78,'Name stuff',nil);
- AddFullItem('~J~ustify',204,74,'Justify stuff',nil);
- AddFullItem('~P~rot',205,80,'Protect stuff',nil);
- AddFullItem('~U~nprot',206,85,'Unprotect stuff',nil);
- AddFullItem('~I~nput',207,73,'Input stuff',nil);
- AddFullItem('~V~alue',208,86,'Value stuff',nil);
-
-
-
- 12-16 User's Guide
- --------------------------------------------------------------------------------
-
- AddFullItem('~T~rans',209,84,'Transpose stuff',nil);
- AddFullItem('~S~earch',209,83,'Search for things',nil);
- SetActiveItem(1);
- SetGap(1);
- end;
- with Main do
- begin
- Init;
- AddFullItem('~W~orksheet',1,87,
- 'Worksheet and global operations',@Worksheet);
- AddFullItem('~R~ange',2,82,
- 'Commands for manipulating data ranges',@Range);
- AddFullItem('~C~opy',3,67,
- 'Cell and range copying commands',nil);
- AddFullItem('~M~ove',4,77,'Cell and range moving commands',nil);
- AddFullItem('~F~ile',5,70,'File loading and saving operation-
- s',nil);
- AddFullItem('~P~rint',6,80,'Graph and spreadsheet printing',nil);
- AddFullItem('~G~raph',7,71,'Spreadsheet charting',nil);
- AddFullItem('~D~ata',8,68,'Database operations',nil);
- AddFullItem('~S~ystem',9,83,'Drop to the Operating System',nil);
- AddFullItem('~Q~uit',99,81,'Miller Time!',nil);
- SetActiveItem(1);
- SetGap(1);
- Choice := Activate;
- Done;
- Worksheet.Done;
- Range.Done;
- end;
- gotoxy(1,5);
- if Choice = 0 then
- Writeln('You escaped')
- else
- Writeln('You selected menu item ',Choice);
- end.
-
-
-
- Figure 12.5 [SCREEN]
- Nested Lotus
- Menus
-
-
-
- Pull Down Menus
- The totMENU unit provides a number of objects to help you create pull-
- down menus like the one used in the Turbo Pascal integrated environ-
- ment. The main pull-down menu object is PullMenuOBJ, and it is a
-
-
-
- Menus Menus Menus 12-17
- --------------------------------------------------------------------------------
-
- descendant of LotusMenuOBJ -- a pull-down menu is really a Lotus menu
- which calls pop-up menus when an item is selected from the main menu
- bar. The other pull-down menus are EZPullArrayOBJ and EZPullLinkOBJ,
- which allow you to quickly create a pull-down menu based on the con-
- tents of a string array or linked list, respectively. Hence the prefix,
- EZ!
-
-
- PullMenuOBJ
-
- 99% of Toolkit users will use the EZ objects, but before moving on to
- explain such shortcuts, the PullMenuOBJ object needs to be described in
- detail.
- PullMenuOBJ supports the following, previously described, methods:
-
- Init;
- AddItem(Txt:StrVisible);
- SetHK(Item:byte; HK:word);
- SetMessage(Item:byte; Msg:StrVisible);
- SetID(Item:byte; ID:word);
- SetStatus(Item:byte, On:boolean);
- SetSubMenu(Item:byte; SubMenu:BaseMenuPtr);
- AddFullItem(Txt:StrVisible;ID,Hk:word; Msg:StrVisible; SubM:Baseme-
- nuPtr);
- Draw;
- Activate: word;
- Remove;
- SetGap(G:byte);
- SetMenuXY(X,Y: byte);
- SetMessageXY(X,Y:byte);
- SetAllowEsc(On:boolean);
- SetActiveItem(Item:byte);
- SetColors(HiHot,HoNorm,LoHot,LoNorm,Off:byte);
- SetSpecialKey(HK:word; ID:word);
- Menukey(K:word; X,Y: byte): boolean;
- Push(K:word; X,Y: byte);
- Done;
-
- To build a pull-down menu using PullMenuOBJ, you create an object of
- type PullMenuOBJ, and one MenuOBJ object for each pull-down menu panel.
- When you add the items to PullMenuOBJ, the sub-menu parameter should be
- a pointer to the appropriate MenuOBJ instance. Listed below is the demo
- program DEMMN6.PAS, followed by figure 12.6 showing the display.
-
- program DemoMenuSix;
- {DEMMN6 - a simple pullmenu}
- USES DOS, CRT,
- totMENU, totFAST;
-
-
-
- 12-18 User's Guide
- --------------------------------------------------------------------------------
-
- var
- Fmenu,
- Emenu: MenuOBJ;
- Pmenu: PullMenuOBJ;
- Choice: word;
-
- procedure InitSubmenus;
- {}
- begin
- with Fmenu do
- begin
- Init;
- AddFullItem(' ~O~pen... ',101,79,'',nil);
- AddFullItem(' ~N~ew ',102,78,'',nil);
- AddFullItem(' ~S~ave... ',103,83,'',nil);
- AddFullItem(' S~a~ve as ',104,65,'',nil);
- AddFullItem(' Save a~l~l ',105,79,'',nil);
- AddItem('-');
- AddFullItem(' ~C~hange dir ...',106,67,'',nil);
- AddFullItem(' ~P~rint ',107,80,'',nil);
- AddFullItem(' ~G~et info... ',108,71,'',nil);
- AddFullItem(' ~D~OS shell ',109,68,'',nil);
- AddFullItem(' E~x~it ',110,88,'',nil);
- SetForPull;
- end;
- with Emenu do
- begin
- Init;
- AddFullItem(' ~R~estore line ',201,82,'',nil);
- AddItem('-');
- AddFullItem(' Cu~t~ ',202,84,'',nil);
- AddFullItem(' ~C~opy ',203,67,'',nil);
- AddFullItem(' ~P~aste ',204,80,'',nil);
- AddFullItem(' Copy ~E~xample ',205,69,'',nil);
- SetStatus(6,false);
- AddFullItem(' ~S~how clipboard ',206,83,'',nil);
- AddItem('-');
- AddFullItem(' C~l~ear ',207,76,'',nil);
- SetForPull;
- end;
- end; {InitSubMenus}
- begin
- Screen.Clear(white,'░'); {paint the screen}
- Screen.PartClear(1,1,80,1,31,' ');
- InitSubMenus;
- with Pmenu do
- begin
- Init;
-
-
-
- Menus Menus Menus 12-19
- --------------------------------------------------------------------------------
-
- AddFullItem(' ~F~ile ',1,70,'',@Fmenu);
- AddFullItem(' ~E~dit ',2,69,'',@Emenu);
- AddFullItem(' ~R~un ',3,82,'',nil);
- SetID(3,3);
- Choice := Activate;
- Done;
- end;
- GotoXY(25,15);
- if Choice = 0 then
- Writeln('You escaped')
- else
- Writeln('You selected menu item ',Choice);
- end.
-
-
-
- Figure 12.6 [SCREEN]
- A Simple Pull-down
- Menu
-
-
- The demo program creates a pull-down menu with three elements on the
- menu bar: File, Edit and Run. A sub-menu is displayed when either of
- the first two items is selected. The program therefore requires three
- menu objects: a PullMenuOBJ to define the main menu bar, and two
- MenuOBJ objects to define the pull-down elements. Notice the method
- call SetForPull in both the MenuOBJ set-up routines. This method sets
- the characteristics of the MenuOBJ objects to fit in a pull-down menu
- environment, e.g. the border is set to 1, any titles are removed, etc.
-
- Also, notice that each selectable item is assigned a unique ID. When
- the user chooses an Item (which doesn't call a sub-menu), the item ID
- is returned by the method Activate or Push.
- If you want to add more sub-sub-menus, simply create additional MenuOBJ
- objects, and set a menu item to point to the sub-menu instance. For
- example, the following code fragment will result in a sub-menu being
- displayed when the Print option is selected from the file menu (it is
- assumed that PrintMenu is an instance of MenuOBJ):
-
- AddFullItem(' ~P~rint ',106,80,'',@PrintMenu);
- As demonstrated by the third item "Run", items on the main menu bar do
- not have to call sub-menus. If the user selects Run from the main menu,
- an ID of three is returned.
-
-
-
- 12-20 User's Guide
- --------------------------------------------------------------------------------
-
- EZ Pull-Down Menus
-
- The objects EZPullArrayOBJ and EZPullLinkOBJ provide a quick and easy
- way of building powerful pull-down menus. The basic principle of the EZ
- objects is that you define all the components of each menu item in a
- string, and then instruct the Toolkit to build a pull-down menu from
- the strings. The strings can either be stored in an array or in a
- linked list.
- Each string can have between one and four elements, with each element
- being separated by a double-quote ("). The first element is the menu
- item text, the second element is the message or menu description, the
- third element is the item ID, and the fourth element is an optional
- special hotkey which can be pressed anywhere in the menu hierarchy to
- select the item. The syntax of the string is as follows:
-
- 'menu text"description"ID"SpecialHK'
- For example, the following string declares the menu item "Open..." :
-
- ' ~O~pen... "Locate and open a file in an edit window"201"316'
- You do not need to specify all four elements. For example, if the item
- does not have a special hotkey, omit the fourth part. If the item text
- includes a highlighted character, e.g. ~O~, the Toolkit will automati-
- cally assign that letter as the standard item hotkey.
-
- The strings in the array or list must be specified in the order that
- the picks will appear in the menu, and strings representing a main menu
- item must begin with the backslash character. If you want a topic to be
- non-selectable, start the string with an underscore, '_'. For example,
- the following strings could be used to create a menu similar to the
- DEMMN6.PAS program described earlier:
- '\ ~F~ile ';
- ' ~O~pen... "101'
- ' ~N~ew "102'
- ' ~S~ave... "103'
- ' S~a~ve as "104'
- ' Save a~l~l "105'
- '-'
- ' ~C~hange dir ..."106'
- ' ~P~rint "107'
- ' ~G~et info... "108'
- ' ~D~OS shell "109'
- ' E~x~it "110'
- '\ ~E~dit '
- ' ~R~estore line "201'
- '-'
- ' Cu~t~ "202'
- ' ~C~opy "203'
- ' ~P~aste "204'
-
-
-
- Menus Menus Menus 12-21
- --------------------------------------------------------------------------------
-
- '_Copy ~E~xample "205'
- ' ~S~how clipboard "206'
- '-'
- ' C~l~ear "207'
- '\ ~R~un "3'
-
-
-
- Note: the EZ objects can only be used to create a single-level
- pull-down menu. Refer to the section Adding Sub-Menus to see how
- to customize an EZ pull-down menu with sub-menus.
-
- The EZ pull object dynamically creates an instance of PullMenuOBJ, and
- as many MenuOBJ instances as needed to create the menu. The EZ pull
- objects include the following two function methods which allow you to
- directly access the internal PullMenuOBJ and MenuOBJ instances:
-
-
- MainMenu: PullMenuPtr;
- This function returns a pointer to the PullMenuOBJ instance used by the
- EZ object. You may change the characteristics settings of the instance
- by using the syntax Mainmenu^.method. For example, the following method
- will draw the main menu bar: Mainmenu^.Draw.
-
-
- SubMenu(MenuNumber: byte): SubMenuPtr;
- This function returns a pointer to one of the MenuOBJ instances, i.e.
- one of the first-level menu panels. You may change the characteristics
- of the instance by using the syntax Submenu(num)^.method.
-
-
- EZPullArrayOBJ
-
- The EZPullArrayOBJ builds and displays a pull-down menu based on the
- contents of a string array. After calling Init, the following method
- should be called to pass the menu details to the object:
-
- AssignList(var StrArray; Total:longint; StrLength:byte);
-
- AssignList identifies the string array which contains the menu struc-
- ture. The method is passed three parameters; the string array, the
- total number of elements in the array, and the defined string length of
- each array element.
-
- Unlike other Toolkit objects such as List and Browse, the EZPullArray-
- OBJ copies the data from the string array. This means that, after
- assignment, you can dispose of the string array. The partial listing of
-
-
-
-
- 12-22 User's Guide
- --------------------------------------------------------------------------------
-
- the demo file DEMMN7.PAS (listed below), illustrates this technique.
- The string array is created locally in the procedure CreateMenu, and is
- automatically disposed of when the CreateMenu procedure finishes.
-
- The demo program is a mock-up of Turbo Pascal's own IDE menu (see
- Figure 12.7)
- program DemoMenuSeven;
- {DEMMN7 - using EZPull objects}
- USES DOS, CRT,
- totMENU, totFAST;
-
- var
- Menu: EZPullArrayOBJ;
- Choice: word;
- procedure CreateMenu;
- {}
- var
- Mtxt: Array[1..84] of string[90];
- begin
- MTxt[1] := '\ p "System Commands';
- MTxt[2] := ' ~A~bout... "Show version and copyright information-
- "100';
- MTxt[3] := ' ~R~efresh display "Redraw the screen"101';
- MTxt[4] := ' ~C~lear desktop "Close all windows on the desktop,
- clear history lists"102';
- MTxt[5] := '\ ~F~ile "File management commands (Open, New, Save,
- etc.)';
- MTxt[6] := ' ~O~pen... "Locate and open a file in an edit
- window"201';
- {...}
- MTxt[84] := ' ~H~elp on Help "How to use online Help"1005';
- with Menu do
- begin
- Init;
- AssignList(MTxt,84,90);
- end;
- end; {CreateMenu}
-
- begin
- Screen.PartClear(1,2,80,24,white,'░'); {paint the screen}
- Screen.PartClear(1,1,80,1,31,' ');
- Screen.PartClear(1,25,80,25,31,' ');
- Screen.WritePlain(9,25,'│');
- CreateMenu;
- with Menu do
- begin
- Choice := Push(13,0,0); {Pass Enter to make menu pull down}
- Done;
- end;
-
-
- Menus Menus Menus 12-23
- --------------------------------------------------------------------------------
-
- GotoXY(25,15);
- if Choice = 0 then
- Writeln('You escaped')
- else
- Writeln('You selected menu item ',Choice);
- end.
-
-
- Figure 12.7 [SCREEN]
- An EZ Pull-down
- Menu
-
-
-
- EZPullLinkOBJ
- The EZPullLinkOBJ reads the menu definition from a linked list, i.e.
- from an instance of DLLOBJ or one of its descendants. After calling
- Init, the following method should be called to pass the menu details to
- the object:
-
-
- AssignList(var LinkList DLLOBJ);
- AssignList identifies the linked list which contains the menu defini-
- tion. The method is passed one parameter; an instance of DLLOBJ or a
- descendant, e.g. StrDLLOBJ.
-
-
- As with EZPullArrayOBJ, the data is copied from the linked list to the
- internal menu objects. Listed below is the demo program DEMMN8.PAS,
- which shows how EZPullLinkOBJ can be used to read a menu from disk.
- program DemoMenuEight;
- {DEMMN8 - reading a menu from disk}
- USES DOS, CRT,
- totMENU, totFAST, totLINK;
-
- var
- Menu: EZPullLinkOBJ;
- Choice: word;
- procedure CreateMenu;
- {}
- var
- FileList: StrDLLOBJ;
- Retcode: integer;
- F: text;
- Line:string;
- begin
- assign(F,'DEMMN8.TXT');
- {$I-}
-
-
-
-
- 12-24 User's Guide
- --------------------------------------------------------------------------------
-
- reset(F);
- {$I+}
- if ioresult <> 0 then
- begin
- Writeln('Error: the file DEMMN8.TXT must be in the default
- directory!');
- halt(1);
- end;
- with FileList do
- begin
- Init;
- Retcode := 0;
- ReadLn(F,Line);
- while not eof(F) and (Retcode = 0) do
- begin
- Readln(F,Line);
- Retcode := Add(Line);
- end;
- close(F);
- end;
- with Menu do
- begin
- Init;
- AssignList(FileList);
- FileList.Done;
- end;
- end; {CreateMenu}
-
- begin
- Screen.PartClear(1,2,80,24,white,'░'); {paint the screen}
- Screen.PartClear(1,1,80,1,31,' ');
- Screen.PartClear(1,25,80,25,31,' ');
- Screen.WritePlain(9,25,'│');
- CreateMenu;
- with Menu do
- begin
- Choice := Push(13,0,0); {Pass Enter to make menu pull down}
- Done;
- end;
- GotoXY(25,15);
- if Choice = 0 then
- Writeln('You escaped')
- else
- Writeln('You selected menu item ',Choice);
- end.
-
-
-
- Menus Menus Menus 12-25
- --------------------------------------------------------------------------------
-
- Adding Sub-Menus
-
- The EZ objects provide a quick way of building a single level pull-down
- menu. If you want to have some sub-menus, you can still use the EZ
- objects. First call the AssignList method to create the main pull-down
- menu objects, and then create as many MenuOBJ instances as needed.
- Finally, use the SubMenu function method to access individual menu ele-
- ments and assign your own MenuOBJ instances to the appropriate menu
- item.
- Listed below is an extract of the demo file DEMMN9.PAS, which illus-
- trates this technique:
-
- program DemoMenuNine;
- {DEMMN9 - using a EZPull object with sub menus and hotkeys}
- USES DOS, CRT,
- totMENU, totFAST;
- var
- Env,Watch: MenuOBJ;
- Menu: EZPullArrayOBJ;
- Choice: word;
-
- procedure CreateSubMenus;
- {}
- begin
- with Env do
- begin
- Init;
- SetForPull;
- AddFullItem(' ~P~references... ',8061,80,
- 'Specify desktop settings',nil);
- AddFullItem(' ~E~ditor... ',8062,69,
- 'Specify editor settings',nil);
- AddFullItem(' ~M~ouse... ',8063,77,
- 'Specify mouse settings',nil);
- AddFullItem(' ~S~tartup... ',8064,83,
- 'Permanently change default startup options',nil);
- AddFullItem(' ~C~olors... ',8065,67,
- 'Customize IDE colors for windows, menus, etc.',nil);
- end;
- with Watch do
- begin
- Init;
- SetForPull;
- AddFullItem(' ~A~dd watch... ',7021,65,
- 'Insert a watch expression into the Watch window',nil);
- AddFullItem(' ~D~elete watch ',7022,68,
- 'Remove the current watch expression from the Watch window',-
- nil);
- AddFullItem(' ~E~dit watch... ',7023,69,
-
-
- 12-26 User's Guide
- --------------------------------------------------------------------------------
-
- 'Edit the current watch expression in the Watch window',nil);
- AddFullItem(' ~R~emove all watches ',7024,82,
- 'Delete all watch expressions from the Watch window',nil);
- end;
- end; {CreateSubMenus}
-
- procedure CreateMenu;
- {}
- var
- Mtxt: Array[1..84] of string[100];
- begin
- MTxt[1] := '\ p "System Commands';
- {...}
- MTxt[84] := ' ~H~elp on Help "How to use online Help"1005';
- with Menu do
- begin
- Init;
- AssignList(MTxt,84,100);
- end;
- end; {CreateMenu}
- begin
- Screen.PartClear(1,2,80,24,white,'░'); {paint the screen}
- Screen.PartClear(1,1,80,1,31,' ');
- Screen.PartClear(1,25,80,25,31,' ');
- Screen.WritePlain(9,25,'│');
- CreateMenu;
- CreateSubMenus;
- with Menu do
- begin
- SubMenu(7)^.SetSubMenu(2,@Watch);
- SubMenu(8)^.SetSubMenu(7,@Env);
- Choice := Activate
- Done;
- Env.Done;
- Watch.Done;
- end;
- GotoXY(25,15);
- if Choice = 0 then
- Writeln('You escaped')
- else
- Writeln('You selected menu item ',Choice);
- end.
-
-
- Figure 12.8 [SCREEN]
- Nested Pull-down
- Menus
-
-
-
- Menus Menus Menus 12-27
- --------------------------------------------------------------------------------
-
- Adding Help
-
- Adding help to menu objects is very similar to the ways described for
- other objects like DirWinOBJ. To add a help facility to any menu
- object, all you have to do is create a procedure following some spe-
- cific rules, and then call the menu method SetHelpHook to instruct the
- Toolkit to use your procedure.
- For a procedure to be eligible as a help hook, it must adhere to the
- following rules:
-
- Rule 1 The procedure must be declared as a FAR procedure. This can
- be achieved by preceding the procedure with a {$F+} compiler
- directive, and following the procedure with a {$F-} direc-
- tive. Alternatively, Turbo 6 users can use the new keyword
- FAR following the procedure statement.
- Rule 2 The procedure must be declared with one passed parameter of
- type word. This parameter indicates the ID of the high-
- lighted item at the time the user requested help.
-
- Rule 3 The procedure must be at the root level, i.e. the procedure
- cannot be nested within another procedure.
- The following procedure declaration follows these rules:
-
- {$F+}
- procedure MyHelpHook(ID:word);
- .....{procedure statements}
- end;
- {$F-}
-
- The following method SetHelpHook is then called to instruct the Toolkit
- to call your procedure when the user asks for help:
-
-
- SetHelpHook(PassedProc:HelpProc);
- This method is passed the procedure name of a procedure declared using
- the rules outlined above.
-
-
- Remember that if you are using an EZ object, you must access the Pull-
- MenuOBJ using the following statement:
- Mainmenu^.SetHelpHook(YourProc);
-