home *** CD-ROM | disk | FTP | other *** search
- { MSMENU.PAS
- MS 4.0
- Copyright (c) 1985, 87 by Borland International, Inc. }
-
- {$I msdirect.inc}
-
- unit MsMenu;
- {-Pulldown and custom menu systems}
-
- interface
-
- uses
- Crt, {Basic video operations - standard unit}
- Dos, {DOS interface - standard unit}
- Errors, {Runtime error handler}
- MsVars, {Global types and declarations}
- MsScrn1, {Fast screen writing routines}
- MsString, {String primitives}
- MsPtrOp, {Pointer primitives}
- EscSeq, {Returns text string for extended scan codes}
- MsCmds, {Maps keystrokes to commands}
- Int24, {DOS critical error handler}
- Message, {Message system}
- MsUser, {User keyboard input, line edit, error report, help}
- MsBack, {Background processes}
- MsScrn2; {Editor screen updating}
-
- procedure EdGetCustomMenuChoice(var Menu : CustomMenuRec; var Choice : Integer);
- {-Display a custom menu, get selection, dispose of menu, and return choice}
-
- procedure EdGetMenuChoice(var Cmd : CommandType; var ExitMenu : Boolean);
- {-Display the menu system, and get a selection}
-
- {==========================================================================}
-
- implementation
-
- procedure EdGetCustomMenuChoice(var Menu : CustomMenuRec;
- var Choice : Integer);
- {-Display a custom menu, get selection, dispose of menu, and return choice}
- var
- Quitting, UseWindow : Boolean;
- Ch : Char;
- CheckChoice : Integer;
- Wmenu : WindowRec;
- LetterSet : Charset;
-
- procedure EdSetMaxCoords(var Menu : CustomMenuRec);
- {-Compute the max x and y coordinates of the window}
- var
- MsgLen, PromptLen, Wid : Integer;
-
- function EdGetMaxStrLen(var Messages : MenuArrayPtr; MinChoice, MaxChoice : Integer) : Integer;
- {-Return the longest string length in the menu}
- var
- Item : Integer;
- Maxlen, Len : Integer;
-
- begin {EdGetMaxStrLen}
- Maxlen := 0;
- for Item := MinChoice to MaxChoice do begin
- Len := Length(Messages^[Item]^);
- if Len > Maxlen then
- Maxlen := Len;
- end;
- EdGetMaxStrLen := Maxlen;
- end; {EdGetMaxStrLen}
-
- begin {EdSetMaxCoords}
- with Menu do begin
- MsgLen := EdGetMaxStrLen(Messages, MinChoice, MaxChoice);
- PromptLen := Length(EdGetMessage(PromptNum));
- if MsgLen > PromptLen then
- Wid := MsgLen
- else
- Wid := PromptLen;
- Xmax := Xmin+Wid+3;
- Ymax := Ymin+(MaxChoice-MinChoice)+2;
- end;
- end; {EdSetMaxCoords}
-
- procedure EdBuildLetterSet(var Menu : CustomMenuRec; var LetterSet : Charset);
- {-Build a set of characters comprising the first letter of each menu selection}
- var
- Item : Integer;
-
- begin {EdBuildLetterSet}
- LetterSet := [];
- with Menu do
- for Item := MinChoice to MaxChoice do
- LetterSet := LetterSet+[Upcase(EdFirstLetter(Messages^[Item]^))];
- end; {EdBuildLetterSet}
-
- procedure EdWriteEntry(var Menu : CustomMenuRec; var W : WindowRec; Item : Integer; Selected : Boolean);
- {-Write one menu entry}
- var
- X, Y, Posn : Integer;
- S : VarString;
-
- begin {EdWriteEntry}
- if UseWindow then
- with W, Menu do begin
- S := EdPadEntry(Messages^[Item]^, XSize-2);
- X := Succ(XPosn);
- Y := YPosn+Succ(Item-MinChoice);
- if Selected then
- EdFastWrite(S, Y, X, ScreenAttr[MsColor])
- else if UseLetters then begin
- {Highlight the first non-blank character}
- Posn := 1;
- while S[Posn] = Blank do
- Inc(Posn);
- if Posn > 1 then
- EdFastWrite(Copy(S, 1, Pred(Posn)), Y, X, ScreenAttr[MnColor]);
- EdFastWrite(S[Posn], Y, X+Pred(Posn), ScreenAttr[MhColor]);
- EdFastWrite(Copy(S, Succ(Posn), PhyScrCols), Y, X+Posn, ScreenAttr[MnColor]);
- end else
- EdFastWrite(S, Y, X, ScreenAttr[MnColor]);
- end;
- end; {EdWriteEntry}
-
- procedure EdDrawAllChoices(var Menu : CustomMenuRec; var W : WindowRec; MinChoice, MaxChoice, SelectNum : Integer);
- {-Draw all of the filename choices}
- var
- Item : Integer;
-
- begin {EdDrawAllChoices}
- for Item := MinChoice to MaxChoice do
- EdWriteEntry(Menu, W, Item, (Item = SelectNum));
- end; {EdDrawAllChoices}
-
- function EdLetterPos(var Menu : CustomMenuRec; Ch : Char) : Integer;
- {-Return the choice number corresponding to ch}
- var
- Item : Integer;
-
- begin {EdLetterPos}
- with Menu do
- for Item := MinChoice to MaxChoice do
- if Ch = Upcase(EdFirstLetter(Messages^[Item]^)) then begin
- EdLetterPos := Item;
- Exit;
- end;
- end; {EdLetterPos}
-
- procedure EdDisposeCustomMenu(var Menu : CustomMenuRec);
- {-Release the heap space used by the menu}
- var
- Item : Integer;
-
- begin {EdDisposeCustomMenu}
- with Menu do begin
- {Release the strings}
- for Item := MinChoice to MaxChoice do
- FreeMem(Messages^[Item], Succ(Length(Messages^[Item]^)));
- {Release the pointers to strings}
- FreeMem(Messages, Succ(MaxChoice) shl 2);
- end;
- end; {EdDisposeCustomMenu}
-
- begin {EdGetCustomMenuChoice}
-
- AbortEnable := True;
-
- {Draw on screen only if not within a macro}
- UseWindow := (EditUsercommandInput = 0);
-
- {Compute maximum window coordinates}
- EdSetMaxCoords(Menu);
-
- with Menu do begin
-
- if UseLetters then
- {Build a character set from the first letters of the menu strings}
- EdBuildLetterSet(Menu, LetterSet)
- else
- LetterSet := [];
-
- {Put up a menu of selections}
- if UseWindow then begin
- EdSaveTextWindow(Border, EdGetMessage(PromptNum), Xmin, Ymin, Xmax, Ymax, Wmenu);
- EdEraseMenuHelp;
- EdWritePromptLine(EdGetMessage(MessageNum));
- EdSetCursor(CursorOff);
- end;
- Choice := InitChoice;
- EdDrawAllChoices(Menu, Wmenu, MinChoice, MaxChoice, Choice);
-
- {Select until done}
- Quitting := False;
- repeat
-
- EdWriteEntry(Menu, Wmenu, Choice, True);
-
- Ch := EdGetCursorCommand(CmdSet+LetterSet);
-
- if (Ch in LetterSet) then begin
-
- {Selection matches first letter of command}
- Choice := EdLetterPos(Menu, Ch);
- Quitting := True;
-
- end else
- case Ch of
-
- '0'..'9' : {Select by number}
- begin
- CheckChoice := (Ord(Ch)-48);
- if (CheckChoice >= MinChoice) and (CheckChoice <= MaxChoice) then begin
- Quitting := True;
- Choice := CheckChoice;
- end;
- end;
-
- ^J : {Help on current topic}
- begin
- EdHelpWindow(GlobalCmd);
- if UseWindow then begin
- {Assure hardware cursor is off again}
- EdSetCursor(CursorOff);
- {Assure prompt message is redisplayed}
- EdWritePromptLine(EdGetMessage(MessageNum));
- end;
- end;
-
- ^M : {Select current}
- Quitting := True;
-
- ^[ : {Escape}
- Abortcmd := True;
-
- ^E : {Scroll up}
- begin
- EdWriteEntry(Menu, Wmenu, Choice, False);
- if Choice > MinChoice then
- Dec(Choice)
- else
- Choice := MaxChoice;
- end;
-
- ^X : {Scroll down}
- begin
- EdWriteEntry(Menu, Wmenu, Choice, False);
- if Choice < MaxChoice then
- Inc(Choice)
- else
- Choice := MinChoice;
- end;
-
- end;
- until Abortcmd or Quitting;
-
- if not(Abortcmd) then
- {Save the choice as an initial one for next time}
- InitChoice := Choice;
-
- if UseWindow then
- {Restore the screen}
- EdRestoreTextWindow(Wmenu);
-
- {Dispose of the custom menu heap space}
- EdDisposeCustomMenu(Menu);
-
- end;
- end; {EdGetCustomMenuChoice}
-
- procedure EdGetMenuChoice(var Cmd : CommandType; var ExitMenu : Boolean);
- {-Display the menu system, and get a selection}
- type
- {Available commands when menu selection is being made}
- MenuCommandType = (Mup, Mdown, Mright, Mleft, Mesc, Msel, Mhelp, Mnul);
- var
- Ch : Char;
- Mcmd : MenuCommandType;
- Done : Boolean;
- Sub : Byte;
-
- function EdMenuCommand(CurrMenu : Menuptr;
- var Ch : Char;
- var Mcmd : MenuCommandType) : Boolean;
- {-Return a menucommand or a character}
- const
- WScommands : string[6] = ^@^D^E^S^X^J;
- EXcommands : string[5] = 'MHKP;';
- var
- Orient : MenuOrientation;
- Lev : Integer;
-
- begin {EdMenuCommand}
- EdMenuCommand := True;
- {Get the orientation of the current menu}
- Lev := CurrMenu^.MenuLev;
- Orient := MenuDesc[Lev].Orientation;
- Mcmd := Mnul;
-
- Ch := EdGetAnyChar;
- if Ch = Null then
- {Extended character, get other half and convert to WS format}
- Ch := WScommands[Succ(Pos(EdGetAnyChar, EXcommands))];
-
- case Ch of
- ^J : {F1}
- Mcmd := Mhelp;
- ^E : {Up arrow}
- if Orient = Vertical then
- Mcmd := Mup;
- ^X : {Down arrow}
- if Lev = 1 then
- Mcmd := Msel
- else if Orient = Vertical then
- Mcmd := Mdown;
- ^S : {Left arrow}
- if Lev <= 2 then
- Mcmd := Mleft;
- ^D : {Right arrow}
- if Lev <= 2 then
- Mcmd := Mright;
- ^M : {Enter}
- Mcmd := Msel;
- ^[ : {Esc}
- Mcmd := Mesc;
- else
- {Can't be a menu command}
- EdMenuCommand := False;
- end;
- end; {EdMenuCommand}
-
- function EdMenuSelection(CurrMenu : Menuptr; Ch : Char; var Sub : Byte) : Boolean;
- {-Return true and a submenu number if ch matches a select character}
- var
- Found : Boolean;
-
- begin {EdMenuSelection}
- with CurrMenu^ do begin
- Ch := Upcase(Ch);
- Sub := 1;
- Found := False;
- while not(Found) and (Sub <= SubMax) do begin
- with SubMenus^[Sub] do
- Found := EdCmdAccessible(CurrMenu, Sub) and
- (Upcase(Prompt^[Soffset]) = Ch);
- if not(Found) then
- Inc(Sub);
- end;
- end;
- EdMenuSelection := Found;
- end; {EdMenuSelection}
-
- procedure EdUpdateItem(Menu : Menuptr; SubLast, SubCur : Byte);
- {-Highlight the current menu item}
-
- begin {EdUpdateItem}
- EdDrawItem(Menu, SubLast);
- EdDrawItem(Menu, SubCur);
- end; {EdUpdateItem}
-
- procedure EdDecCurSubmenu(Menu : Menuptr);
- {-Move to the previous selection, and wrap}
- var
- SubLast : Byte;
-
- begin {EdDecCurSubmenu}
- with Menu^ do begin
- SubLast := SubCur;
- repeat
- if SubCur > 1 then
- Dec(SubCur)
- else
- SubCur := SubMax;
- until EdCmdAccessible(Menu, SubCur);
- EdUpdateItem(Menu, SubLast, SubCur);
- end;
- end; {EdDecCurSubmenu}
-
- procedure EdIncCurSubmenu(Menu : Menuptr);
- {-Move to the next selection, and wrap}
- var
- SubLast : Byte;
-
- begin {EdIncCurSubmenu}
- with Menu^ do begin
- SubLast := SubCur;
- repeat
- if SubCur < SubMax then
- Inc(SubCur)
- else
- SubCur := 1;
- until EdCmdAccessible(Menu, SubCur);
- EdUpdateItem(Menu, SubLast, SubCur);
- end;
- end; {EdIncCurSubmenu}
-
- procedure EdSetInitSelection(CurrMenu : Menuptr);
- {-Assure initial menu selection is accessible}
-
- begin {EdSetInitSelection}
- with CurrMenu^ do begin
- if SubCur < 1 then
- SubCur := 1;
- while not(EdCmdAccessible(CurrMenu, SubCur)) do
- if SubCur < SubMax then
- Inc(SubCur)
- else
- SubCur := 1;
- end;
- end; {EdSetInitSelection}
-
- procedure EdDisplayKeys(Cmd : CommandType);
- {-Write a text representation of command keystrokes to status line}
- var
- Kptr : Integer;
- Special : Boolean;
- Dis, Keys : VarString;
-
- begin {EdDisplayKeys}
- if EdKeyInterrupt then
- Exit;
- Keys := EdCommandKeys(Cmd, Primary);
- EdClearString(Dis);
- Kptr := 1;
- while Kptr <= Length(Keys) do
- Dis := Dis+EdTextRepresentation(Keys, Kptr, Special);
- EdWritePromptLine(Dis);
- end; {EdDisplayKeys}
-
- function EdEvaluateMenuCommand(var CurrMenu : Menuptr;
- Mcmd : MenuCommandType;
- var Cmd : CommandType) : Boolean;
- {-Change current selection and current menu as indicated}
- var
- Done : Boolean;
- Ch : Char;
-
- begin
- Done := False;
-
- case Mcmd of
-
- Mleft :
- begin
- {Move the root menu selection left}
- EdDecCurSubmenu(RootMenu);
- if CurrMenu <> RootMenu then begin
- EdUndrawMenu(CurrMenu);
- with RootMenu^ do
- CurrMenu := SubMenus^[SubCur].SubMenu;
- EdSetInitSelection(CurrMenu);
- EdDrawMenu(CurrMenu);
- end;
- end;
-
- Mright :
- begin
- {Move the root menu selection right}
- EdIncCurSubmenu(RootMenu);
- if CurrMenu <> RootMenu then begin
- EdUndrawMenu(CurrMenu);
- with RootMenu^ do
- CurrMenu := SubMenus^[SubCur].SubMenu;
- EdSetInitSelection(CurrMenu);
- EdDrawMenu(CurrMenu);
- end;
- end;
-
- Mup :
- {Move the current menu selection up}
- EdDecCurSubmenu(CurrMenu);
-
- Mdown :
- {Move the current menu selection down}
- EdIncCurSubmenu(CurrMenu);
-
- Mesc :
- if CurrMenu = RootMenu then begin
- {Leave the menu system}
- Done := True;
- if WindowCount > 0 then
- EdEraseMenus;
- Cmd := CmdNull;
- end else begin
- EdUndrawMenu(CurrMenu);
- if CurrMenu^.MenuLev = 2 then
- {Move back to the root menu}
- CurrMenu := RootMenu
- else
- with RootMenu^ do
- {Move back to level 2}
- CurrMenu := SubMenus^[SubCur].SubMenu;
- CurrMenu^.SubOn := False;
- end;
-
- Msel :
- with CurrMenu^ do
- if EdPtrNotNil(SubMenus^[SubCur].SubMenu) then begin
- {Another menu below, display it and move to it}
- SubOn := True;
- CurrMenu := SubMenus^[SubCur].SubMenu;
- EdSetInitSelection(CurrMenu);
- EdDrawMenu(CurrMenu);
- end else begin
- {Bottom level menu, return a command}
- Done := True;
- Cmd := SubMenus^[SubCur].Command;
- end;
-
- Mhelp :
- with CurrMenu^ do begin
- Cmd := SubMenus^[SubCur].Command;
- if (Cmd <> CmdNull) and (Cmd <> CmdNullMain) then begin
- EdHelpWindow(Cmd);
- if SaveKeyHelpMode then
- {Redisplay the keystrokes as a helpful prompt}
- EdDisplayKeys(Cmd);
- end else
- EdDisplayPromptWindow(
- EdGetMessage(55)+'-'+EdGetMessage(305), 13, [#27], Ch, NormalBox);
- EdSetCursor(CursorOff);
- end;
-
- end;
- EdEvaluateMenuCommand := Done;
- end; {EdEvaluateMenuCommand}
-
- function EdEvaluateSelectionCommand(var CurrMenu : Menuptr;
- Sub : Byte;
- var Cmd : CommandType) : Boolean;
- {-Select from the menu based on a prompt character}
- var
- Done : Boolean;
- SubLast : Byte;
-
- begin {EdEvaluateSelectionCommand}
- Done := False;
- with CurrMenu^ do begin
- SubLast := SubCur;
- if EdPtrNotNil(SubMenus^[Sub].SubMenu) then begin
- {Open up the selected submenu}
- SubCur := Sub;
- SubOn := True;
- {Update the screen}
- EdUpdateItem(CurrMenu, SubLast, SubCur);
- CurrMenu := SubMenus^[SubCur].SubMenu;
- EdSetInitSelection(CurrMenu);
- EdDrawMenu(CurrMenu);
- end else begin
- {Accept the command}
- Done := True;
- SubCur := Sub;
- {Update the screen}
- EdUpdateItem(CurrMenu, SubLast, SubCur);
- Cmd := SubMenus^[SubCur].Command;
- end;
- end;
- EdEvaluateSelectionCommand := Done;
- end; {EdEvaluateSelectionCommand}
-
- begin {EdGetMenuChoice}
-
- EdSetCursor(CursorOff);
- EdEraseMenuHelp;
-
- if EdPtrIsNil(CurrMenu) then
- CurrMenu := RootMenu;
-
- {Set the initial menu selection to an acceptable one}
- EdSetInitSelection(CurrMenu);
-
- if CurrMenu = RootMenu then
- EdDrawMenu(CurrMenu)
- else
- {Menu already on screen, just update the items}
- for Sub := 1 to CurrMenu^.SubMax do
- EdDrawItem(CurrMenu, Sub);
-
- Done := False;
-
- repeat
-
- if SaveKeyHelpMode then
- {Display the keystrokes as a helpful prompt}
- with CurrMenu^ do
- EdDisplayKeys(SubMenus^[SubCur].Command);
-
- if EdMenuCommand(CurrMenu, Ch, Mcmd) then
- {Move the cursor, escape, or select the current submenu}
- Done := EdEvaluateMenuCommand(CurrMenu, Mcmd, Cmd)
-
- else if EdMenuSelection(CurrMenu, Ch, Sub) then
- {Select an entry by letter}
- Done := EdEvaluateSelectionCommand(CurrMenu, Sub, Cmd);
-
- until Done;
-
- {Should the menus stay on-screen?}
- if (Cmd = CmdNull) and (WindowCount = 0) then
- ExitMenu := False
- else
- ExitMenu := not(Cmd in StayCommands);
-
- if ExitMenu and not(SolidCursor) then
- EdUpdateCursor;
-
- end; {EdGetMenuChoice}
-
- type
- InitArray = array[1..MaxInt] of Byte;
- InitArrayPtr = ^InitArray;
-
- {$L MSMENU}
-
- function EdGetMenuInitPtr : InitArrayPtr; external;
- {-Return a pointer to the menu initialization data}
-
- procedure EdInitMenus;
- {-Set up the dynamic data structure of the menus}
- var
- P : InitArrayPtr;
- InitPos, Smax, I : Integer;
- Tmenu : Menuptr;
-
- procedure EdInitMenuDesc(var MenuDesc : Menulevels);
- {-Initialize general descriptions of each level of menu}
- const
- RootBorder : BorderChars = '┌┐└┘─│├┤';
- SubBorder : BorderChars = '┬┬└┘─│├┤';
-
- begin {Edinitmenudesc}
- with MenuDesc[1] do begin
- Border := RootBorder;
- Orientation := Horizontal;
- EdSetPtrNil(Overlap);
- end;
- with MenuDesc[2] do begin
- Border := SubBorder;
- Orientation := Vertical;
- EdSetPtrNil(Overlap);
- end;
- with MenuDesc[3] do begin
- Border := RootBorder;
- Orientation := Vertical;
- EdSetPtrNil(Overlap);
- end;
- end; {EdInitMenuDesc}
-
- function EdGetInitByte(P : InitArrayPtr; var InitPos : Integer) : Byte;
- {-Return the next byte from the menu initialization data}
-
- begin {EdGetInitByte}
- EdGetInitByte := P^[InitPos];
- Inc(InitPos);
- end; {EdGetInitByte}
-
- procedure EdInitMenu(P : InitArrayPtr; var InitPos, Smax : Integer; var Tmenu : Menuptr);
- {-Initialize the parameters of one menu level}
- var
- Lev, Xp, Yp, Xs, Ys : Byte;
- Smenu : Menuptr;
-
- procedure EdError(msg : VarString);
- {-Halt in case of error during initialization}
- begin {EdError}
- Write(^M^J, msg);
- Halt(1);
- end; {EdError}
-
- begin {EdInitMenu}
-
- {Get the next six bytes from the initialization data}
- Lev := EdGetInitByte(P, InitPos);
- Xp := EdGetInitByte(P, InitPos);
- Yp := EdGetInitByte(P, InitPos);
- Xs := EdGetInitByte(P, InitPos);
- Ys := EdGetInitByte(P, InitPos);
- Smax := EdGetInitByte(P, InitPos);
-
- if Smax = 0 then
- {No items in this menu}
- EdSetPtrNil(Tmenu)
- else begin
- {Get the menu record and initialize it}
- if EdMemAvail(SizeOf(Menuptr), FreeListPerm) then
- New(Tmenu)
- else
- EdError(EdGetMessage(35));
- with Tmenu^ do begin
- XPosn := Xp;
- YPosn := Yp;
- XSize := Xs;
- YSize := Ys;
- MenuLev := Lev;
- SubMax := Smax;
- SubCur := 0;
- SubOn := False;
- if EdMemAvail(SubMax*SizeOf(SubMenuRecord), FreeListPerm) then
- GetMem(SubMenus, SubMax*SizeOf(SubMenuRecord))
- else
- EdError(EdGetMessage(35));
- end;
- end;
-
- case Lev of
- 1 : RootMenu := Tmenu;
-
- 2 : if EdPtrIsNil(RootMenu) then
- EdError(EdGetMessage(106))
- else
- with RootMenu^ do begin
- Inc(SubCur);
- if SubCur > SubMax then
- EdError(EdGetMessage(107));
- SubMenus^[SubCur].SubMenu := Tmenu;
- end;
-
- 3 : if EdPtrIsNil(RootMenu) then
- EdError(EdGetMessage(106))
- else
- with RootMenu^ do begin
- Smenu := RootMenu^.SubMenus^[RootMenu^.SubCur].SubMenu;
- if EdPtrIsNil(Smenu) then
- EdError(EdGetMessage(106))
- else
- with Smenu^ do begin
- Inc(SubCur);
- if SubCur > SubMax then
- EdError(EdGetMessage(107));
- SubMenus^[SubCur].SubMenu := Tmenu;
- end;
- end;
-
- else
- EdError(EdGetMessage(108));
- end;
-
- end; {EdInitMenu}
-
- procedure EdInitItem(P : InitArrayPtr; var InitPos : Integer;
- var Sub : SubMenuRecord);
- {-Initialize the parameters of one menu entry}
- var
- Cord, Dofs, Spec, Sofs : Byte;
-
- begin {Edinititem}
-
- {Get the next four bytes from the initialization data}
- Cord := EdGetInitByte(P, InitPos);
- Dofs := EdGetInitByte(P, InitPos);
- Spec := EdGetInitByte(P, InitPos);
- Sofs := EdGetInitByte(P, InitPos);
-
- {Store the record}
- with Sub do begin
- Soffset := Succ(Sofs); {String index where selection char is}
- Doffset := Dofs;
- StatVal := Spec;
- Command := CommandType(Cord);
- {Assume no deeper submenus}
- EdSetPtrNil(SubMenu);
- {Store pointer to string}
- Prompt := Ptr(Seg(P^), Ofs(P^)+Pred(InitPos));
- {Skip over string}
- InitPos := InitPos+Succ(P^[InitPos]);
- end;
-
- end; {Edinititem}
-
- procedure EdTraverseMenus(Menu : Menuptr);
- {-Traverse the entire menu system, setting the current submenu to 1}
- var
- Sub : Byte;
- S : Menuptr;
-
- begin {EdTraverseMenu}
- with Menu^ do begin
- SubCur := 1;
- for Sub := 1 to SubMax do begin
- S := SubMenus^[Sub].SubMenu;
- if EdPtrNotNil(S) then
- {Recursive call to traverse the next level}
- EdTraverseMenus(S);
- end;
- end;
- end; {EdTraverseMenu}
-
- begin {EdInitMenus}
-
- {No root menu exists initially}
- EdSetPtrNil(RootMenu);
-
- {Initialize the menu descriptors for each menu level}
- EdInitMenuDesc(MenuDesc);
-
- {Get a pointer to the embedded menu initialization data}
- P := EdGetMenuInitPtr;
- InitPos := 1;
-
- repeat
- {Initialize a menu group}
- EdInitMenu(P, InitPos, Smax, Tmenu);
- if EdPtrNotNil(Tmenu) then
- {Initialize the entries for the menu group}
- for I := 1 to Smax do
- EdInitItem(P, InitPos, Tmenu^.SubMenus^[I]);
- until P^[InitPos] = $FF;
-
- {Set initial selections}
- EdTraverseMenus(RootMenu);
-
- {No menu is currently displayed}
- EdSetPtrNil(CurrMenu);
- ExitMenu := True;
-
- end; {EdInitMenus}
-
- begin
- {Initialize menu system}
- EdInitMenus;
- end.