Version 2.43

04-15-93

Bumped up the version number because it's been a while since I last
changed it.

Starting with this version MarxMenu stores it's serial number
information in the Bindery as well as the MARXMENU.EXE file. Thus when
you get a new version of MarxMenu it will serialize itself the first
time you run it. This makes updates easier.


04-16-93

BiosDate : String
Returns the date of the rom Bios.


04-18-93
MarxMenu is now more Windows aware. When running MarxMenu under Windows
the TaskNumber variable reads the Virtual Machine ID. Thus MarxMenu no
longer requires that you set a TASK= environment variable under windows.


DriveType (Drive) : String
DriveType returns the type of drive of a given drive letter. This is
like DiskType with the exception of how it deals with floppy drives.
DiskType actually tries to read the floppy so if you put a 720k disk in
a 1.4 meg drive then DiskType will return 720. DriveType returns the
type of drive the CMOS is configured for.


PcType : String
PcType returns the type of computer you are running as a string. Types
include: PC, XT, AT, PS2.


CpuName : String
Returns the name of the CPU. CPU names include:

  8088, 8086, V20 ,V30, 80188, 80186, 80286,
  80386, 80386SX, 80486, 80486SX


McpClass : Number
Returns the math coprocessor class.

 0 = None
 1 = 8078
 2 = 80287
 3 = 80387
 4 = 80487 (486 CPU)


McpName : String
Returns the name of the marh coprocessor. If there is no math
coprocessor then an empty string is returned. Names include:

  8087, 80287, 80387, 80487


EmsInstalled : Boolean
Returns True if EMS memory manager is installed.


EmsVersion : String
EmsVersion returns the version of the EMS driver you are using. If EMS
isn't present it returns an empty string.


XmsInstalled : Boolean
Returns True if XMS memory manager is installed.


XmsVersion : String
XmsVersion returns the version of the XMS driver you are using. If XMS
isn't present it returns an empty string.


VCPIInstalled : Boolean
Returns True if VCPI services are installed.


VCPIVersion : String
VCPIVersion returns the version of the VCPI driver you are using. If
VCPI isn't present it returns an empty string.


DPMIInstalled : Boolean
Returns True if DPMI services are installed.


DPMIVersion : String
DPMIVersion returns the version of the DPMI driver you are using. If
DPMI isn't present it returns an empty string.


MouseVersion : String
MouseVersion returns the version of the mouse driver you are using. If a
mouse driver isn't present it returns an empty string.


MouseIRQ : Number
Returns the interrupt number that the mouse driver is using.


MouseType : String
Reurns the type of mouse being used. If a mouse driver isn't present it
returns an empty string.

 Mouse Types: BUS, SERIAL, HP, INPORT, PS2, UNKNOWN


04-21-93

ComNewLineProgram : Procedure
ComNewLineProgram is a procedure variable that if set to point to a
procedure is executed every time a new line is received at the modem.

 Example:
   ComNewLineProgram = Loc ExamineLastLine

   Procedure ExamineLastLine
   var St P
      P = pos('Time Sync:',ComLastLine)
      if P = 0 then Return
      St = mid(ComLastLine,P + 11,17)    ;read Date and Time
      NovServerTime = TimeOf(St)
   EndProc

In this example, ExamineLastLine is executed once each new line and is
scaned for the word "Time Sync:". If the word is found it sets the
server time to the value following that word.


04-23-93

NovChangeObjPassword (Obj, Type, OldPassword, NewPassword)
NovChangeObjPassword is like NovChangePassword except it allows you to
change the password on other objects than yourself. Type refers to the
object type. Users are type 1.

 Example:
    NovChangeObjPassword('DAN',1,'POTATOE','POTATO')


05-06-93

ClearKbdBuffer
ClearKbdBuffer clears the characters out of the keyboard buffer.


05-18-93

Overlayed : Boolean
Overalyed returns true if menu is loaded as an overlay.


05-25-93

I've expanded the use of the word Trim. Besides trimming the blanks from
the ends of strings it will also trim blank lines from the ends of
arrays.


05-28-93

Local : Array
Parameters passed to procedures and local variables in a procedure are
elements of an array of local variables. By using the word Local you can
address passed parameters and local variables as if they were elements
of an array.

 Example:
   Procedure Test (A,B)
   var C,D
      Writeln A B C D
   EndProc

In the above example the variable A is the same as Local[1], B is
Local[2], C is Local[3], and D is Local[4]. The Local command can be
used to pass a varying number of parameters to a procedure as follows:

 Example:
   Procedure Test
      Loop Local
         Writeln Local[LoopIndex]
      endloop
   EndProc

   Test (1,2,3,4)

This allows the procedure Test to accept and process any number of
parameters you wish to pass to it.

===============================================================

Version 2.44

06-21-93

I've changed the semaphores to work with TSRs in upper memory. You no
longer need a TSR in low memory for semaphores to live. This improves
software metering.


TSRs (Array)
TSRs returns a list of all TSRs in memory as well as the names of
pending batch files.

 Example:
   var TsrList
   TSRs(TsrList)
   Loop TsrList
      Writeln TsrList[LoopIndex]
   EndLoop


InMem (TsrName) : Boolean
Inmem returns true if the TSR you are looking for is loaded. This allow
you to do conditionals based on the presence or absence of a TSR. It
will also check for the names of pending batch files.

 Example:
   if not InMem('BTRIEVE')
      Bat 'BTRIEVE.EXE'
   endif


MemoryLoc (TsrName) : Number
MemoryLoc returns the memory segment address of the TSR name you
specify. If the TSR isn't in memory it returns a 0.

 Example:
   Writeln 'Btrieve is at $' HexString(MemoryLoc('BTRIEVE'),4)


07-16-93

Well, I'm now jumping into the VLM stuff and making MarxMenu Netware 4
smart. Here's what I have so far. I still don't consider netware 4 to be
done yet, but it's getting at least close enough to start developing
for. Since this involves a lot of changes it's likely that I might have
broken a command or two. If you find something that doesn't work, let me
know about it.


VlmLoaded : Boolean
Returns true if the VLM shell is loaded.


NovConTableSize : Number
NovConTableSize returns the maximum number of servers the shell can
connect to. In the past using the NETX shells this has been 8. But the
new shells can be set to different values.


07-20-93

NovFirstNetworkDrive : String
NovFirstNetworkDrive returns the drive letter of the first network drive
on a Novell network.


07-27-93

The NovFullName command is now writeable.
  Example:
  NovFullName ('RNOORDA') = 'Ray Noorda'


NovManager (UserName) : Boolean
Returns True if the user has workgroup manager priveledges. If UserName
isn't specified then the current user is assumed.

 Example:
   if NovManager ('FRED') then Writeln 'Fred is a Manager'
   if NovManager then Writeln 'I am a Manager'


NovMaxUserConnections (UserName) : Number
Returns the maximum number of connections that a user is limited to. A
zero means unlimited connections. If UserName isn't specified then the
current user is assumed. You can also use this command to set the limit.

 Example:
   Writeln NovMaxConnection ('FRED')    ; Fred's Limit
   Writeln NovMaxConnection             ; My Limit
   NovMaxConnections ('BARNEY') = 5     ; Set Barney's limit to 5


NovSpaceUsed (UserName,Volume) : Number
NovSpaceUsed returns the total disk space in use by the user on the
specified volume.

 Example:
   Writeln NovSpaceUsed ('BILL','F:')   ; Bill's disk space on F:

NovSpaceLimit (UserName, Volume) : Number
NovSpaceLimit returns the disk space limit for the user on the specified
volume. You can also use this command to set the limit.

 Example:
   Writeln NovSpaceLimit ('BILL','F:')     ; Bill's space limit on F:
   NovSpaceLimit ('BILL','SYS:') = 2000000 ; Limits Bill's space


NovSerialNumber : String
NovSerialNumber returns the current server serial number as a string.

 Example:
   Writeln NovSerialNumber


NovUserFiles (UserName,Volume) : Number
NovUserFiles returns the number of files on the volume that are owned by
the user. This commamd takes a while to run. Expect delays from a few
seconds to several minutes.

 Example:
   Writeln NovUserFiles ('PETE','SYS:')


NovUserDirectories (UserName,Volume) : Number
NovUserDirectories returns the number of directories on the volume that
are owned by the user. This commamd takes a while to run. Expect delays
from a few seconds to several minutes.

 Example:
   Writeln NovUserDirectories ('PETE','F:')

===============================================================

Version 2.45

08-09-93

I bumped up the version number so that this can be the first official
VLM shell version.

I've enhanced the compilers ability to deal with conditionals. You can
now use the following syntax:

 if <condition> then <statement> else <statement>

This will work if the statements a single statements. Also:

 Repeat <Statement>
 Until <Condition>

or

 Repeat <Statement> Until <Condition>

have been added. Before you had to put Repeat on a line by itself.


The command ExitMenu can now take a command line which tells MarxMenu to
run this one line and then don't come back to the menu.

Example:
  ExitMenu 'DIR /W'


I made a change in the MXSTOP.BAT file. MarxMenu no longer deletes the
temporary batch file itself when exiting the menu. MarxMenu sets an
environment variable DELBAT to the name of the temporary batch file. The
MXSTOP.BAT file actually deletes it. You will want to run MARXMENU INST
to create a new MXSTOP.BAT file.


I added logic into MarxMenu to automatically process environment
variable referrences within filenames. Thus:

 F:\HOME\%USERNAME%\WINDOWS becomes F:\HOME\MARC\WINDOWS

This logic works with all commands that use file names.


New Commands:

LoopVal
LoopVal returns the current variable in a Loop EndLoop when the loop is
started using an array.

 Example:
   var X
   ReadDirectory X
   Loop X
      LoopVal = CleanFileName LoopVal
      Writeln LoopVal
   EndLoop

LoopVal can be read or written to. It can be indexed or used with
qualifiers. Any function that can be used with variables can be used
with LoopVal. With nested loops, LoopVal always references the innermost
loop.


EnvExpandString (String) : String
EnvExpandString will take a string that has environment variable
referrences in it and substitute the environment variable for that part
of the string.

 Example:
   Writeln EnvExpandString 'F:\HOME\%USERNAME%\WINDOWS'
   ; returns F:\HOME\MARC\WINDOWS


08-13-93

NovSemaphoreInfo (2DArray,Commection)
NovSemaphoreInfo reads the semaphore information of a connection number.
It returns a two dimensional array of the semaphore names, open count,
value, and task number.

 Example:
   Var Sem
   Qualifier Name, OpenCount, Val, Task
   NovConSemaphoreInfo(Sem,9)
   Loop Sem
      Write   LoopVal.Name ' ' LoopVal.OpenCount ' '
      Writeln LoopVal.Val ' ' LoopVal.Task
   EndLoop


NovLoginTime (Connection)
Returns the login time of a specific connection. If the connection
number isn't specified then the current connection is assumed.

 Example:
   var X
   X = NovLoginTime
   Writeln DateString(X) ' ' TimeString(X)


NovServDescription (Array)
NovServDescription returns an array of strings that contain the novell
file server description,

 Example:
   var Des
   NovServDescription(Des)
   Loop Des
      Writeln LoopVal
   EndLoop


NovConUsingAFile (Array,FileName)
NovConUsingAFile creates an array with a list of connection numbers that
have a file open.

 Example:
   ;WhoHas program in MarxMenu
   var ConnectionList
   NovConUsingAFile(ConnectionList,ParamStr(2))
   Loop ConnectionList
      Writeln NovLoginName(LoopVal) ' [' LoopVal ']'
   EndLoop


NovDiskSpaceFromDel (Path) : Number
NovDiskSpaceFromDel returns the amount of disk space that is used by
deleted files and is available for reuse.

 Example:
    Writeln NovDiskSpaceFromDel 'F:'


NovDiskSpaceFromDelNA (Path) : Number
NovDiskSpaceFromDelNA returns the amount of disk space that is used by
deleted files and is not yet available for reuse.

 Example:
    Writeln NovDiskSpaceFromDelNA 'F:'


CommaString (String) : String
CommaString takes a string that represents a number and adds commas
every three characters. If you pass it a number it will convert it to a
string and then add the commas.

 Example:
    Writeln CommaString ('12345')     ; returns 12,345
    Writeln CommaString (45 * 75)     ; returns 3,375


LongestString (Array) : Number
LongestString returns the length of the longest string in an array of
strings.

 Example:
   var X
   ReadTextFile('MARX.BAT',X)
   Writeln LongestString (X)


AmPm : Boolean
When AmPm is set true the TimeString function returns AmPm time format.

 Example:
    AmPm On
    Writeln TimeString(Now)  ; returns 10:13:34 am


08-18-93

NovConLoggedIn (Array)
NovConLoggedIn returns an array of connection numbers that have someone
logged in.

 Example:
   var Connections
   NovConLoggedIn(Connections)
   Loop Connection
      Writeln LoopVal
   EndLoop


NovMaxConnectionsUsed : Number
Returns the maximum number of connection used on the server. If you're
hunting through connection numbers you can use this value as a maximum
instead of NovMaxConnections to reduce the number of connections you
have to deal with.


NovShowNotLoggedIn : Boolean
NovShowNotLoggedIn is used with NovUsersLoggedIn and NovConLoggedIn.
Normally users who are connected but not logged in are filtered out buy
MarxMenu. But if you set NovShowNotLoggedIn to True, then NOT-LOGGED-IN
will be included in the list.


09-08-93

Forever
Forever is part of a loop Repeat -- Forever. Forever is an unconditional
jump to Repeat.

 Example:
   Repeat
      [statement]
      [statement]
   Forever


ComWriteRecChar (On/Off)
If ComWriteRecChar is set to On then any characters comming in the
serial port will be written to the screen. In a terminal program you
would typically turn ComWriteRecChar and ComSendKbdChar both on.


ComSendKbdChar (On/Off)
If ComSendKbdChar is set to On then any characters typed at the keyboard
will be sent out the serial port. In a terminal program you would
typically turn ComWriteRecChar and ComSendKbdChar both on.


ComLocalInput (On/Off)
If ComLocalInput is set to On then keys typed at the keyboard will be
treated as if they came in over the serial port. This allows a host
program like a BBS to be run from the local console as if the user were
typing in characters.


ComCheckActivity
ComCheckActivity will check the serial ports and keyboard and route
characters if anything needs to be routed. It is typically used in the
main process loop of communication programs to make it run fast.


ComZRecover (On/Off)
If ComZRecover is set to On then if you retry an aborted ZModem download
it will resume at the point where it was aborted.


ComFullFileName : String
Returns the full file name of the file that is currently being
transmitted.


09-20-93

UpperCaseCompare (On/Off)
When UpperCaseCompare is set to On, all string commands that compare
strings are case insensitive.

 Example:
   UpperCaseCompare On
   Writeln 'ABC' = 'abc'   ; returns true

The commands this affects include all comparison operators, Pos,
PosInList, and PosInSortedList.


PosInListPartial (String,Array) : Number
PosInListPartial is similar to the PosInList command. It searches a
string array for a matching string and returns the line number of the
first match. Unlike PosInList which compares the whole string,
PosInListPartial will find the first string that contains the search
string.

 Example:
   var List
   List[1] = 'Date=09-20-93'
   List[2] = 'Time=10:18'
   List[3] = 'Name=Marc'
   Writeln PosInListPartial('Name=',List)  ; returns 3


09-22-93

ComAcceptFileProgram
ComAcceptFileProgram is a variable that contains a procedure that you
use when receiving a file to determine if the file name being sent is
acceptable. You procedure needs to return a True to accept the name or a
False to reject the name.

 Example:
   ComAcceptFileProgram = Loc MyAcceptName

   ;- Always overwrite file

   Procedure MyAcceptName
      if ExistFile ComFullFileName
         DelFile ComFullFileName
      endif
      Return True
   EndProc

   ;----- Ask to overwrite existing file

   Procedure MyAcceptName
   var Ch
      if ExistFile ComFullFileName
         DoubleLineBox
         BoxBorderColor LCyan Mag
         BoxInsideColor Yellow Mag
         InverseColor Yellow Red
         DrawBox 31 7 47 3
         UseArrows Off
         Write ' File ' ComFileName ' exists. Replace it? (Y/n) '
         Ch = UpperCase(ReadKey)
         EraseTopWindow
         if Ch = 'N'
            Return False
         else
            DelFile ComFullFileName
            Return True
         endif
      endif
      Return True
   EndProc


10-12-93

NovDirectoryRights (Dir) : Number
NovDirectoryRights return your effective rights in the directory Dir.

 Example:
   Writeln NovDirectoryRights 'F:\PUBLIC'


NovAddTrustee (Dir,Rights,Object,Type)
NovAddTrustee adds a directory and access rights to a user or group. To
add rights to a user the Type is 1. For a group the Type is 2.

 Example:
   NovAddTrustee ('F:\PUBLIC',$FF,'EVERYONE',2)


NovDeleteTrustee (Dir,Object,Type)
NovDeleteTrustee removes a directory access rights from a user or group.
To delete rights from a user the Type is 1. For a group the Type is 2.

 Example:
   NovDeleteTrustee ('F:\PUBLIC','EVERYONE',2)


NovCreateUser (Name)
Creates a user in the bindery along with all the minimum default
properties.

 Example:
   NovCreateUser 'MARC'


NovCreateGroup (Name)
Creates a group in the bindery along with all the minimum default
properties.

 Example:
   NovCreateGroup 'ACCOUNTING'


NovCreatePrintQueue (Name)
Creates a print queue in the bindery along with all the minimum default
properties.

 Example:
   NovCreatePrintQueue 'ACCOUNTING'


10-18-93

I've fixed the Volume command so that a disk with no volume name works
correctly. I also made the Volume command setable so that you can set
the Volume as well as read it.

I also made the FileAttr command setable so that you can set file
attributes as well as read them.

I did some serious reworking of PickOne and PickMany so that they are
smarter than they were. Both are fully reenterant now so if you are in a
PickMany and you use a KeyEvent to call up another PickMany it still
works.

New Commands:

PickManyFlags : Array
PickManyFlags is an array that PickMany creates in real time indicating
which items are picked. The array is an array of boolean values
(True/False) that has the same number of elements as the array you are
picking from. Every element that is picked is set to true in the same
position in the PickManyFlags array.

Since updating is done in real time a KeyEvent or background task can
monitor this array and read which elements of the array are being
selected. You could pop up another window that listed those elements
already selected.


PickRedisplay
PickRedisplay sets a flag for PickOne or PickMany to redisplay the
choices in the array. If a KeyEvent were to alter the contents of an
array that is currently being picked, this commant would force a
redisplay the that the user sees the changes.

PickOne and PickMany automatically detect and redisply the array if the
number of elements of the array changes.

===============================================================

Version 2.46

10-25-93

Working on breaking the 64k barrier for MRX files. MRX code is still
limited to 64k but I've moved the space used by strings out of the code.
This allows for 64k of code and 64k of string space. Most MRX files are
about one third strings so this will allow MRX files to be significantly
bigger than they were.


10-29-93

EatKbdChar (On/Off)
EatKbdChar controls the behavior of WaitOrKbdReady. If it is On
(default) and a key is pressed the character will be absorbed from the
keyboard buffer. If it is off the character is left in the buffer.


FormatNum (Real,Format) : String
Form converts a real number to a string in a specific format which is
controlled by a format string. The characters of the string control the
decimal places, size of the string, and money signs.

 #  A digit position, blank if not available.
 *  A digit position, fill with asterisk if not available.
 @  A digit position, fill with zero if not available.
 $  A digit position, activating a floating dollar sign.
 -  A sign position, needed if * or @ digits used exclusively.
 +  A sign position, shows '+' for positive numbers as well.
 ,  A decimal comma or a separator comma.
 .  A decimal period or a separator period.

 Example:
   Writeln FormatNum(Pi,'#.#####')  ;returns 3.14159


Beginning to add the ability to access dBase files.

DbOpen (FileName) : Handle
DbOpen opens a dBase file and returns a file handle. The file handle is
used to access the data file with all other dBase commands. If you don't
specify a file extension the extension '.DBF' is assumed.

 Example:
   Handle = DbOpen 'MAILLIST.DBF'


DbFields (Handle,Fields)
DbFields reads the list of dBase fields into a 2 dimensional array. The
fields are as follows:

 1 - Name
 2 - Type
 3 - Length
 4 - Decimal Position

 Example:
   var Handle Fields
   Handle = DbOpen 'MAILLIST.DBF'
   DbFields(Handle,Fields)

   loop Fields
      loop LoopVal
         Write LoopVal ' '
      endloop
      Writeln
   endloop

 Field Types:
   C - Character
   D - Date
   N - Number
   L - Logical (True/False)

DbCreateFile (Name,Fields)
DbCreateFile creates an empty dBase file. The Fields parameter is a 2
dimensional array that specifies the field structure. The field
structure of the array is as follows:

 1 - Name
 2 - Type
 3 - Length
 4 - Decimal Position

 Example:
   var Fields
   Fields[1] = Set['Name','C',35,0]
   Fields[2] = Set['Age','N',3,0]
   DbCreateFile('AGE.DBF',Fields)


DbRecords (Handle) : Number
DbRecords return the number of records in a dBase file.


DbRecLen (Handle) : Number
DbRecLen return the record size in a dBase file.


DbGetRecord (Handle,Record,Data)
DbGetRecord reads a specific physical record from a dBase file into
array Data. It sets a variable DbDeleted to true if the record is
deleted. Error status information is returned in the variable
FileResult. If FileResult returns 5, the record is locked.

 Example:
   Handle = DbOpen 'MAILLIST.DBF'
   DbGetRecord(Handle,1,Data)
   loop Data
      Write LoopVal ' '        ;writes the first record
   endloop
   Writeln
   DbClose(Handle)


DbClose (Handle)
DbClose closes a dBase file.


DbDeleted : Boolean
After a DbGetRecord, DbDeleted returns True if the record was deleted.

 Example:
   Handle = DbOpen 'MAILLIST.DBF'
   DbGetRecord(Handle,33,Data)
   if DbDeleted then Writeln 'Record 1 is Deleted'


11-01-93

DbWriteRecord (Handle,Record,Data) DbWriteRecord writes a physical
record into a dBase file from Data at location Record. Error status
information is returned in the variable FileResult. If FileResult
returns 5, the record is locked.

MarxMenu automatically sets file locks while writing to a record so that
it prevents multiple writes to the same record when used on a network.

If you write a record that is one record past the end of the file, the
record will be appended. If you write beyond the end of the file,
MarxMenu will fill in the gap with empty deleted records.

 Example:
   Handle = DbOpen 'MAILLIST.DBF'
   DbWriteRecord(Handle,45,Data)
   DbClose(Handle)


DbDeleteRecord (Handle,Record)
DbDeleteRecord sets a specified record as deleted. The data in the
record remains and can be set undeleted.

 Example:
   Handle = DbOpen 'MAILLIST.DBF'
   DbDeleteRecord(Handle,20)
   DbClose(Handle)


DbUnDeleteRecord (Handle,Record)
DbUnDeleteRecord sets a specified record as not deleted.

 Example:
   Handle = DbOpen 'MAILLIST.DBF'
   DbUnDeleteRecord(Handle,55)
   DbClose(Handle)


DbLockRecord (Handle,Record)
Sets a file lock on a specified record. If you are accessing multiple
records or multiple files that all have to be updated at once, you might
want to lock them all first before doing the update,


DbUnLockRecord (Handle,Record)
Removes a file lock on a specified record. If you are accessing multiple
records or multiple files that all have to be updated at once, you might
want to lock them all first before doing the update,


DbLockFile (Handle)
DbLockFile puts a file lock on the entire dBase file.


DbUnLockFile (Handle)
DbUnLockFile removes a file lock from the entire dBase file.


DBaseMode (On/Off)
When MarxMenu reads a dBase record it converts numbers into real
numbers, boolean fields into boolean variables, and truncates spaces
from string variables. DBase programmers, however, like to have all
fields returned as strings with all the spaces included. If DBaseMode is
set to On, MarxMenu returns data as dBase programmers expect.


PadLeftChar (String,Char,Length) : String
PadLeftChar returns a string that is padded on the left side with the
character Char to a length of Length.

 Example:
   St = 'MARC'
   Writeln PadLeftChar(St,'*',8)   ;returns '****MARC'


PadRightChar (String,Char,Length) : String
PadRightChar returns a string that is padded on the right side with the
character Char to a length of Length.

 Example:
   St = 'MARC'
   Writeln PadRightChar(St,'*',8)   ;returns 'MARC****'


TrimLead (St)
TrimLead trims the leading spaces off of the left side of a string.

 Example:
   St = ' MARC '
   TrimLead(St)
   Writeln St      ;returns 'MARC '


TrimTrail (St)
TrimTrail trims the trailing spaces off of the right side of a string.

 Example:
   St = ' MARC '
   TrimTrail(St)
   Writeln St      ;returns ' MARC'


CharString (Char,Length)
CharString returns a string Length long made of of Char.

 Example:
   Writeln CharString ('*',4)  ;returns '****'


11-15-93

After getting complaints that MARXCOMP is using too much memory, I've
reworked the memory management so that it uses a lot less.


11-20-93

ComIRQ (ComPort) : Number
ComIRQ returns the interrupt number for the specified com port. It can
also me used to set the interrupt number to a non-standard interrupt.
The interrupt must be set before using ComInitPort.

 Example:
   Writeln ComIRQ (Com3)      ; displays the interrupt
   ComIRQ (Com3) = 5          ; set Com3 to use interrupt 5
   ComInitPort(38400,8,'N',1) ; Initialize the port


ComBasePort (ComPort) : Number
ComBasePort returns the base port address for the specified com port. It
can also me used to set the base port address to a non-standard base
port. The base port address must be set before using ComInitPort.

 Example:
   Writeln ComBasePort (Com3)      ; displays the base port
   ComBasePort (Com3) = $4F8       ; set Com3 base port
   ComInitPort(38400,8,'N',1)      ; Initialize the port


11-26-93

CopyFile (Source,Dest)
CopyFile copies a file from source to destination. If the destination
file already exists it will be deleted, even if it is a read-only file.
On novell networks it takes advantage of the server copy function to
increase speed. Results are returned in the FileResult variable.

 Example:
   CopyFile('MARXMENU.EXE','A:')


CurrentDrive : String
Returns the letter of the current drive.

 Example:
   Writeln CurrentDrive  ; returns C


12-07-93

ShareInstalled : Boolean
ShareInstalled returns True if the dos program SHARE is installed.


AssignInstalled : Boolean
AssignInstalled returns True if the dos program ASSIGN is installed.


AppendInstalled : Boolean
AppendInstalled returns True if the dos program APPEND is installed.


AnsiInstalled : Boolean
AnsiInstalled returns True if the ANSI device driver is installed.


PrintInstalled : Boolean
PrintInstalled returns True if the dos program PRINT is installed.


DosKeyInstalled : Boolean
DosKeyInstalled returns True if the dos program DOSKEY is installed.


12-10-93

Changed NovScanTrusteePath to return the trustees on all volumes of the
current server. If you had to use a lot of strange tricks to read all
volumes in the past you can now remove those tricks.


12-15-93

NovLoginType (Connection) : Num
NovLoginType returns the object type at a specific connection number.

 Example:
   Writeln NovLoginType(1)    ;returns the object type on connection 1


NovConnectionInfo (2D Array)
NovConnectionInfo reads all the connections and gathers a variety of
information about each connection into a two dimensional array. This
fields of this array include:

 1 - Connection Number
 2 - Connection Name
 3 - Connection Station Address
 4 - Connection Object Type
 5 - Connection Login Time
 6 - Connection Object Number

 Example:
   Var ConInfo
   NovConnectionInfo ConInfo
   Loop ConInfo
      Loop LoopVal
         Write LoopVal ' '
      EndLoop
      Writeln
   EndLoop


Unique (Array)
Unique removes duplicates from a sorted array.

 Example:
    Var A
    A = Set['A','B','B','C']
    Unique(A)                 ;removes the duplicate 'B'


12-17-93

EchoChar (On/Off)
When used with Readln, EchoChar controls whether or not characters typed
in will echo to the screen. Turning EchoChar Off is handy when entering
a password.

 Example:
   var PassW
   EchoChar Off
   Write ' Password: '
   PassW = Readln


NovNumberOfPrinters
When using the VLM shells you can specify up to 9 printers. This command
returns the number of printers your shell will support. With NETX it
returns 3 printers.

 Example:
   if NovNumberOfPrinters = 9
      NovCaptureQueue(9) = 'DOT'
   endif


NovGetRootLevel (Drive) : Number
NovGetRootLevel returns the number of directories below the fake root
that the current directory is. Drives with no fake root return 255.

 Example:
   The current directory is H:\LETTERS, but H: is mapped to the
   directory: TYME/SYS:HOME\MARC.

   Writeln NovGetRootLevel('H')  ;returns 1

===============================================================

Version 2.47

01-10-94

Linked in a new updated communications library, APRO 2.0. Besides
working better, I can now do more things with it. One new advance is
that MarxMenu now supports Compuserve B+ uploads and downloads.
Compuserve B+ is fully automatic and requires no aditional commands to
make it work. You just log onto Compuserve with it and start a file
transfer and the MarxMenu end just handles it.


02-01-94
Made the string to date conversion smarter. Now you can pass a string
'020194' and get 02-01-94.


02-02-94

PosInListLeft (String,Array) : Number
PosInListLeft is similar to the PosInList command. It searches a string
array for a matching string and returns the line number of the first
match. Unlike PosInList which compares the whole string, PosInListLeft
will find the first string that starts with the search string.

The difference between PosInListPartial and PosInListLeft is that
PosInListPartial will match anywhere in the string, and PosInListLeft
will match only if the string start with the search string.

 Example:
   var List
   List[1] = 'Date=09-20-93'
   List[2] = 'Time=10:18'
   List[3] = 'Name=Marc'
   Writeln PosInListPartial('Name=',List)  ; returns 3

===============================================================

Version 2.48

02-06-94

I'm working on better ways to deal with memory when using MarxMenu to
log into the network. One of the things I want to accomplish is for
MarxMenu to be able to execute LOGIN.EXE. This is very nasty and I think
I have it. But, I bumped the version number up because of these changes.
If you have problems with NovLogin, let me know. If you use MarxMenu to
log in to Netware, keep a copy of an earlier version handy in case this
doesn't work.


02-21-93

The dispose command will now take multiple parameters on the same line.

 Example
   Dispose X Y Z

The UpperCase command will now take arrays as parameters. All strings in
the array will become uppercase. Will work with multidimensional arrays.
Elements that aren't strings are left alone.


DisposeAll
DisposeAll does a dispose on all global variables. This can be used to
reset everything to nothing. Local variables are not affected. So, if
you want to save something you can copy it to a local variable and copy
is back when you're done.


02-28-94

I made some improvements in parameter passing to procedures.

You can pass many parameters and have them concatinated into a single
string as the real parameter, much the way the parameters of the Writeln
command work. Numbers passed are converted to strings.

When you define your procedure, if you have a single parameter whose
name begins with a "$", MarxMenu will process all parameters passed as a
single string.

 Example:

   Procedure WriteALine ($Line)
      FileWriteln(OutputFile,Line)
   EndProc

   WriteALine DateString ' ' TimeString ' ' Temperature

In the above example, because WriteALine had the parameter $Line, it
tells MarxMenu to concatinate all parameters passed to it into a single
string and put it into the variable Line.


03-03-94

ReadlnTimeout (Seconds)
ReadlnTimeout is set to control the number of seconds a Readln or
Readkey will wait for input before timing out.

If a timeout occurs, LastKey will be set to char(255).

 Example:
    ReadlnTimeout = 5
    Line = Readln


03-04-94

I've added swaping ability to the Execute command. When Swapping is set
to On, MarxMenu will swap itself out to EMS, XMS or disk reducing it's
memory footprint to about 5k of ram. If MarxMenu uses a disk file, the
file name is the same as the temporary batch file name with the
extension SWP.


Swapping (On/Off)
If Swapping is set to On, the Execute command will cause MarxMenu to
swap itself out of memory allowing more ram for the application being
run.


03-07-94

I've added some new features to the Loop - EndLoop logic.

You can specify a start and end of the loop:

 Example:
   Loop 5 10
      Writeln LoopIndex
   EndLoop

This will loop starting at 5 and ending at 10. If you also specify and
array variable, you can loop through a section of the array.

 Example:
   Loop 3 9 MyArray
      Writeln LoopVal
   EndLoop

In the above example, MarxMenu will write out the loop values for
elements 3 thru 9 of MyArray.


StartsWith (String) : Boolean
StartsWith compares two strings and tests to see if one string starts
with another string.

 Example:
    if IniString StartsWith 'DEVICE='
       Writeln IniString
    endif


ParamsToArray
The ParamsToArray command allows you to pass any number of parameters to
a procedure and receive those parameters into a single array.

 Example:
   Procedure WriteList (LinesToWrite)
      ParamsToArray
      Loop LinesToWrite
         Writeln LoopVal
      EndLoop
   EndProc

   WriteList ('Line1','Line2','Line3')


03-16-94
ComHangupOnExit
If ComHangupOnExit is set to On, MarxMenu will hang up the modem
connection when exiting. If set to Off, MarxMenu will leave the modem
online when exiting. The default is On.


04-07-94

Added a feature to load the MarxMenu overlays into XMS or EMS memory
when used to log into a novell network. This helps avoid losing access
to the MARXMENU.OVR file.


XmsOverlays
Loads the MARXMENU.OVR file into XMS memory.


EmsOverlays
Loads the MARXMENU.OVR file into EMS memory.


04-14-94

Changed the XMS overlay logic. MarxMenu no longer automatically loads
overlays into XMS memory in the login directory. You have to add the
command XMSOverlays or EMSOverlays to make this happen.

Example:
   XMSOverlays
   if not RamOverlay then EmsOverlays


RamOverlays : Boolean
Returns true if overlays are loaded into ram by either EMSOverlays or
XMSOverlays.


EndsWith (String) : Boolean
EndsWith compares two strings and tests to see if one string ends with
another string.

 Example:
    if IniString EndsWith 'NO'
       Writeln IniString
    endif


05-01-94

ResultsInK (On/Off)
Normally the value returned by TotalDiskSpace and other similar disk
functions are returned in bytes. When ResultsInK is set to true the
values return are in K (1024 bytes). This allows you to show the total
disk space on drives larger than 2 gigabytes.

 Example:
   ResultsInK
   Writeln FreeDiskSpace('.') / 977 ' Mb' ;1,000,000 / 1024 = 997

InitialCursorPos (Byte)
When inputting a string using Readln, MarxMenu positions the cursor at
the beginning of the string if the InputString variavle is set. You can
override this by setting InitialCursorPos to a value other than 1.
InitialCursorPos can be set to a value beyond the end of the string.
After input, InitialCursorPos is set back to 1.

 Example:
    InputString = '1234'
    InitialCursorPos = 3                       ;starts at 3rd character
    InitialCursorPos = Length(InputString) + 1 ;starts at end of string
    St = Readln


ClearIfNewInput (On/Off)
If ClearIfNewInput is set to True, then the string set by InputString
will only be the start of the new input if the first character typed is
an arrow key. Otherwise the InputString is cleared to blank.

 Example:
    InputString = '1234'
    ClearIfNewInput On
    St = Readln


WindowsLoaded : Boolean
Returns True if MarxMenu is being run under Microsoft Windows. The
virtual machine number can be read in the TaskNumber variable.


CarouselLoadedLoaded : Boolean
Returns True if the task swapper, Software Carousel is loaded. The
Carousel task number can be read in the TaskNumber variable.


05-11-94

NovLongMachineName : String
NovLongMachineName returns the long machine name from the shell.


NovShortMachineName : String
NovShortMachineName returns the short machine name from the shell.


NovCaptureBanner (String)
NovCaptureBanner sets the banner name to be printed with print jobs. You
can't specify a different user name for each LPT device. If the banner
is set to an empty string then the users login name is used for the
banner.

 Example:
    NovCaptureBanner = 'Beavis'

===============================================================

Version 2.49

06-24-94

LeftOfEqual (String) : String
LeftOfEqual returns that part of the string that is left of the equal
character (includes the equal character itself) and with the leading
spaces trimmed off.

 Example:
   Writeln LeftOfEqual('Device=VIPX.386')  ;returns 'Device='


RightOfEqual (String) : String
RightOfEqual return that part of the string that is right of the equal
character (not including the equal character itself) and with trailing
spaces trimmed off.

 Example:
   Writeln RightOfEqual('Device=VIPX.386')  ;returns 'VIPX.386'


EraseWinAfterOvr (On/Off)
After an overlay executes, MarxMenu by default erases all the windows
the overlay created. If you don't want MarxMenu to erase these windows,
set EraseWinAfterOvr to Off.


06-30-94

NovPasswordInterval (User) : Num
NovPasswordInterval returns the number of days between forced
password changes. if the user name is left off, the current user is
assumed. This command can also be used to set this value.

 Example:
   NovPasswordInterval('MARC') = 50       ;sets to 50
   Writeln NovPasswordInterval('MARC')    ;writes 50


07-27-94
DosBusy (Num)
Increments (or decrements) the Dos Busy flag by the number passed. This
can be used to prevent TSRs from taking action by signaling that Dos is
busy.

 Example:
    DosBusy(1)
    ;-Critical Section
    DosBusy(-1)


08-11-94
SemAttachTo (String)
Novell Semahpores work by finding a TSR in memory and attaching the
semaphore to it. Normally it attaches to the first TSR, but if
SemAttachTo is set it will attach to a specific TSR. If SemAttachTo is
empty it will be set to the name of the TSR that MarxMenu uses to attach
the Semaphore. That way you can read it's value.

 Example:
   SemAttachTo = 'LSL'


08-19-94

NovMapRoot now works on local drives as well as network drives. It works
like the dos SUBST command.


08-26-94
Well, I'm finally documenting the Hash functions I added about 2 months
ago and been using in INITYME.

Hash (String)
Hashing strings is a very fast way to find a string in a list of
strings. It is much faster than a binary search. In MarxMenu, I've
implemented hashing in a way that is very innovative. What I do is to
associate a hashed string with a MarxMenu variable that is dynamically
allocated. The string becomes the key to access the variable for either
reading or writing.

 Example:
   Hash('AGE') = 21
   Hash('HAIR') = 'Brown'
   Writeln Hash('AGE')       ;returns 21
   Writeln Hash('HAIR')      ;returns 'Brown'

In the above example, a variable accessed by Hash('AGE') is created and
set to the value 21. Like any other variable it can be read or
overwritten with a new value. What is happening here is that we are
giving MarxMenu variables a name, which is a string they can be accessed
by for either read or write. This allow you to build applications that
data and procedures can be accessed through their own vocabulary that
you create.


HashLevel : Number
HashLevel is a number that allows you to segment strings into separate
categories for the purpose of later disposing of a group of strings by
level number. HashLevel defaults to 1. All hashed variable names are
tagged with the current value of HashLevel.

 Example:
   HashLevel = 2


HashDispose (String)
HashDispose allows you to remove a name from the hash dictionary and
dispose of the value associated with that name.

 Example:
   HashDispose('AGE')


HashDisposeLevel (Number)
HashDisposeLevel is used to dispose of all hash variable names created
with a specific hash level. This allows you to create classes of named
variables and get rid of a specific class in one step.

 Example:
   HashDispose(5)   ;disposes all names created with HashLevel 5


HashDisposeAll
HashDisposeAll removes all names from the hash dictionary and disposes
all associated variables.


HashLib (Array,Level)
HashLib returns the list of all know hash names in the hash dictionary
associated with a specific hash level. If level 0 is passed, all names
are returned.

 Example:
   Var Lib
   HashLib(Lib,0)
   Loop Lib
      Writeln LoopVal
   EndLoop


08-30-94

OldKbdBuffer : String
When MarxMenu loads it clears the keyboard buffer of any characters left
from the previous application. However, there are some applications that
chain from one part to another by stuffing the keyboard buffer and
exiting to dos. These applications are difficult to run from menu
systems.

So, when MarxMenu clears the buffer, it stores the buffer and it can be
read by OldKbdBuffer. This allows you to execute other programs based on
what was left in the buffer.

 Example:
   if OldKbdBuffer > ''
      Bat OldKbdBuffer
      ExitMenu
   endif


09-01-94

Substitute (String,Old,New)
Substitute wiil scan a string to see if it contains the substring Old
and replace it with New. If UpperCaseCompare is set to True then case is
ignored in the comparison.

 Example:
   Var St
   St = 'ABCDEFABC'
   Substitute(St,'ABC','XX')
   Writeln St                   ;returns XXDEFXX


09-07-94

InterpretCounter : Number
InterpretCounter is a number that is incremented by 1 every time you
execute NextWord. This allows you to tell which word in a string that
you are on.

 Example:
   if InterpretCounter = 1
      ...
   else
      ...
   endif


NilProgram

Normally, if you use the Run command on a Nil value, it does nothing.
However, if you set NilProgram to the Loc of a procedure then it will
run that procedure instead. This is used if you are writing an
interpreter in MarxMenu and you want to deal with a "command not found"
type error.

 Example:
   NilProgram = Loc BadCommandError


09-15-94

Contains
Returns True if the first string contains the second string.

 Example:
   if 'ABCD' contains 'BC'


10-12-94

NewOverlayName (FileName)
NewOverlayName closes the overlay file and reopens a new overlay file.
This is used if you are in the Novell LOGIN directory and yo want to
change servers and drive mappings and attach to the MARXMENU.OVR file on
a different server.

This command does nothing if EmsOverlays or XmsOverlays are used.

 Example:
   NewOverlayName('Z:\LOGIN\MARXMENU.OVR')


10-14-94
DefaultExtension (FileName,Extension) : FileName
DefaultExtension returns the filename with the Extension appended to it
if the FileName doesn't already have an extension.

 Example:
   St = 'WIN'
   Writeln DefaultExtension(St,'INI')   ;returns WIN.INI


10-19-94

Under Netware, the FixPath command will now set the Novell search drive
table.


11-03-94

All Novell bindery commands now support passing SERVER/OBJECT for the
object name.
