234 lines
6.0 KiB
Plaintext
234 lines
6.0 KiB
Plaintext
|
|
|||
|
{ Copyright (c) 1989 by Borland International, Inc. }
|
|||
|
|
|||
|
unit TCMenu;
|
|||
|
{ Turbo Pascal 5.5 object-oriented example command line menu system.
|
|||
|
This unit is used by TCALC.PAS.
|
|||
|
See TCALC.DOC for an more information about this example.
|
|||
|
}
|
|||
|
|
|||
|
{$S-}
|
|||
|
|
|||
|
interface
|
|||
|
|
|||
|
uses Crt, TCUtil, TCScreen;
|
|||
|
|
|||
|
{ The menus in this unit are very simple. Each menu points to a parent (so
|
|||
|
that ESC will take you back to the previous menu) and a list of items.
|
|||
|
Each item is either a pointer to a procedure that will be executed when
|
|||
|
you choose the item, or is a pointer to a new menu.
|
|||
|
}
|
|||
|
|
|||
|
type
|
|||
|
MenuItemPtr = ^MenuItem;
|
|||
|
MenuPtr = ^Menu;
|
|||
|
Menu = object
|
|||
|
MenuString, CommandString : StringPtr;
|
|||
|
MenuItems, LastItem : MenuItemPtr;
|
|||
|
Parent : MenuPtr;
|
|||
|
constructor Init(InitMenuString : String; InitParent : MenuPtr);
|
|||
|
procedure AddItem(NewItem : MenuItemPtr);
|
|||
|
function AddItemProc(NewProc : ProcPtr) : Boolean;
|
|||
|
function AddItemMenu(NewMenu : MenuPtr) : Boolean;
|
|||
|
procedure RunMenu;
|
|||
|
destructor Done;
|
|||
|
end;
|
|||
|
MenuItem = object
|
|||
|
Next : MenuItemPtr;
|
|||
|
constructor Init;
|
|||
|
procedure RunItem(var CurrMenu : MenuPtr); virtual;
|
|||
|
end;
|
|||
|
MenuItemProcPtr = ^MenuItemProc;
|
|||
|
MenuItemProc = object(MenuItem)
|
|||
|
Proc : ProcPtr;
|
|||
|
constructor Init(InitProc : ProcPtr);
|
|||
|
procedure RunItem(var CurrMenu : MenuPtr); virtual;
|
|||
|
end;
|
|||
|
MenuItemMenuPtr = ^MenuItemMenu;
|
|||
|
MenuItemMenu = object(MenuItem)
|
|||
|
NewMenu : MenuPtr;
|
|||
|
constructor Init(InitMenu : MenuPtr);
|
|||
|
procedure RunItem(var CurrMenu : MenuPtr); virtual;
|
|||
|
end;
|
|||
|
|
|||
|
implementation
|
|||
|
|
|||
|
constructor Menu.Init(InitMenuString : String; InitParent : MenuPtr);
|
|||
|
{ Initializes a new menu }
|
|||
|
var
|
|||
|
S : String;
|
|||
|
Counter : Word;
|
|||
|
begin
|
|||
|
MenuItems := nil;
|
|||
|
LastItem := nil;
|
|||
|
GetMem(MenuString, Succ(Length(InitMenuString)));
|
|||
|
if MenuString = nil then
|
|||
|
Fail;
|
|||
|
MenuString^ := InitMenuString;
|
|||
|
S := '';
|
|||
|
for Counter := 1 to Length(InitMenuString) do
|
|||
|
begin
|
|||
|
if (InitMenuString[Counter] in ['A'..'Z']) then
|
|||
|
{ Build command string based on upper case letters in mwenu string }
|
|||
|
S := S + InitMenuString[Counter];
|
|||
|
end;
|
|||
|
GetMem(CommandString, Succ(Length(S)));
|
|||
|
if CommandString = nil then
|
|||
|
begin
|
|||
|
Done;
|
|||
|
Fail;
|
|||
|
end;
|
|||
|
CommandString^ := S;
|
|||
|
Parent := InitParent;
|
|||
|
end; { Menu.Init }
|
|||
|
|
|||
|
destructor Menu.Done;
|
|||
|
{ Removes a menu from memory }
|
|||
|
begin
|
|||
|
if MenuString <> nil then
|
|||
|
FreeMem(MenuString, Succ(Length(MenuString^)));
|
|||
|
if CommandString <> nil then
|
|||
|
FreeMem(CommandString, Succ(Length(CommandString^)));
|
|||
|
LastItem := MenuItems;
|
|||
|
while LastItem <> nil do
|
|||
|
begin
|
|||
|
MenuItems := LastItem;
|
|||
|
LastItem := LastItem^.Next;
|
|||
|
Dispose(MenuItems);
|
|||
|
end;
|
|||
|
end; { Menu.Done }
|
|||
|
|
|||
|
procedure Menu.AddItem(NewItem : MenuItemPtr);
|
|||
|
{ Adds a new item to a menu }
|
|||
|
begin
|
|||
|
if MenuItems = nil then
|
|||
|
begin
|
|||
|
MenuItems := NewItem;
|
|||
|
LastItem := MenuItems;
|
|||
|
end
|
|||
|
else begin
|
|||
|
LastItem^.Next := NewItem;
|
|||
|
LastItem := LastItem^.Next;
|
|||
|
end;
|
|||
|
end; { Menu.AddItem }
|
|||
|
|
|||
|
function Menu.AddItemProc(NewProc : ProcPtr) : Boolean;
|
|||
|
{ Adds a procedure item to a menu }
|
|||
|
var
|
|||
|
NewItem : MenuItemProcPtr;
|
|||
|
begin
|
|||
|
NewItem := New(MenuItemProcPtr, Init(NewProc));
|
|||
|
if NewItem <> nil then
|
|||
|
begin
|
|||
|
AddItem(NewItem);
|
|||
|
AddItemProc := True;
|
|||
|
end
|
|||
|
else
|
|||
|
AddItemProc := False;
|
|||
|
end; { Menu.AddItemProc }
|
|||
|
|
|||
|
function Menu.AddItemMenu(NewMenu : MenuPtr) : Boolean;
|
|||
|
{ Adds a new menu item to a menu }
|
|||
|
var
|
|||
|
NewItem : MenuItemMenuPtr;
|
|||
|
begin
|
|||
|
NewItem := New(MenuItemMenuPtr, Init(NewMenu));
|
|||
|
if NewItem <> nil then
|
|||
|
begin
|
|||
|
AddItem(NewItem);
|
|||
|
AddItemMenu := True;
|
|||
|
end
|
|||
|
else
|
|||
|
AddItemMenu := False;
|
|||
|
end; { Menu.AddItemMenu }
|
|||
|
|
|||
|
procedure Menu.RunMenu;
|
|||
|
{ Run a menu system }
|
|||
|
var
|
|||
|
Ch, Counter, P : Word;
|
|||
|
CurrMenu : MenuPtr;
|
|||
|
I : MenuItemPtr;
|
|||
|
begin
|
|||
|
CurrMenu := @Self;
|
|||
|
repeat
|
|||
|
with CurrMenu^ do
|
|||
|
begin
|
|||
|
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.MenuLoColor); { Print the menu }
|
|||
|
for Counter := 1 to Length(MenuString^) do
|
|||
|
begin
|
|||
|
if MenuString^[Counter] in ['A'..'Z'] then
|
|||
|
WriteColor(MenuString^[Counter], Colors.MenuHiColor)
|
|||
|
else
|
|||
|
WriteColor(MenuString^[Counter], Colors.MenuLoColor);
|
|||
|
end;
|
|||
|
repeat
|
|||
|
Ch := GetKeyUpCase;
|
|||
|
case Ch of
|
|||
|
ESC : CurrMenu := Parent;
|
|||
|
Ord(' ')..Ord('~') : begin
|
|||
|
P := Pos(Chr(Lo(Ch)), CommandString^);
|
|||
|
if P <> 0 then { A menu item has been chosen }
|
|||
|
begin
|
|||
|
I := MenuItems;
|
|||
|
for Counter := 2 to P do
|
|||
|
begin
|
|||
|
if I <> nil then
|
|||
|
I := I^.Next;
|
|||
|
end;
|
|||
|
if I <> nil then
|
|||
|
begin
|
|||
|
I^.RunItem(CurrMenu); { Run the procedure or switch menus }
|
|||
|
Ch := ESC;
|
|||
|
end;
|
|||
|
end;
|
|||
|
end;
|
|||
|
end; { case }
|
|||
|
until Ch = ESC;
|
|||
|
end; { with }
|
|||
|
until CurrMenu = nil;
|
|||
|
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.MenuLoColor);
|
|||
|
end; { Menu.RunMenu }
|
|||
|
|
|||
|
constructor MenuItem.Init;
|
|||
|
{ Initializes a menu item }
|
|||
|
begin
|
|||
|
Next := nil;
|
|||
|
end; { MenuItem.Init }
|
|||
|
|
|||
|
procedure MenuItem.RunItem(var CurrMenu : MenuPtr);
|
|||
|
begin
|
|||
|
Abstract('MenuItem.RunItem');
|
|||
|
end; { MenuItem.RunItem }
|
|||
|
|
|||
|
constructor MenuItemProc.Init(InitProc : ProcPtr);
|
|||
|
{ Initializes a procedure menu item }
|
|||
|
begin
|
|||
|
MenuItem.Init;
|
|||
|
Proc := InitProc;
|
|||
|
end; { MenuItemProc.Init }
|
|||
|
|
|||
|
procedure MenuItemProc.RunItem(var CurrMenu : MenuPtr);
|
|||
|
{ Runs the procedure that a procedure menu item points to }
|
|||
|
begin
|
|||
|
ClrEOLXY(1, Pred(Scr.CurrRows), Colors.MenuLoColor);
|
|||
|
if @Proc <> nil then
|
|||
|
Proc;
|
|||
|
CurrMenu := nil;
|
|||
|
end; { MenuItemProc.RunItem }
|
|||
|
|
|||
|
constructor MenuItemMenu.Init(InitMenu : MenuPtr);
|
|||
|
{ Initializes a new menu menu item }
|
|||
|
begin
|
|||
|
MenuItem.Init;
|
|||
|
NewMenu := InitMenu;
|
|||
|
end; { MenuItemMenu.Init }
|
|||
|
|
|||
|
procedure MenuItemMenu.RunItem(var CurrMenu : MenuPtr);
|
|||
|
{ Changes CurrMenu so that the menu that the item points to becomes the new
|
|||
|
current menu }
|
|||
|
begin
|
|||
|
CurrMenu := NewMenu;
|
|||
|
end; { MenuItemMenu.RunItem }
|
|||
|
|
|||
|
end.
|
|||
|
|