The SElib ObjectThe methods in this object extend the functionality of Javascript. Like the Clib object, the SElib object is a collection of convenient functions that let you work with files and how they are stored on your system, memory, script execution, etc.The SElib object also contains operating system specific functions. For example, it contains functions that let you create windows and process window messages which may only be used on systems running Windows. Functions that are only valid in certian operating systems will have the pertinent system indicated to the right of the function name. In addition to the miscellaneous functions rsprintf() and getArraySpan(), the SElib object contains functions that deal with the following:
.rsprintf(formatString...) printf("%s has seen %s %d times.\n", name, movie, timesSeen);and you wanted to pass the resulting string as a parameter to a function, you could do it like this: func(rsprintf("%s has seen %s %d times.\n", name, movie, timesSeen));The following two lines of code achieve the same result, i.e. create a string named word that contains the string "Who is #1?": word = rsprintf("Who is #%d?", 3-2); sprintf(word, "Who is #%d?", 3-2); .getArrayLength(array, minIndex) EXAMPLE: This script demonstrates getArrayLength: string = "I do not like green eggs and ham." gas = getArrayLength(string); printf("string = %s\ngetArrayLength(string) = %d\n string[getArrayLength(string)] = %d\n string[getArrayLength(string)-1] = %c\n strlen(string) = %d\n", string, gas, string[gas], string[gas-1], strlen(string));and has the following output: string = I do not like green eggs and ham. getArrayLength(string) = 33 string[getArrayLength(string)] = 0 string[getArrayLength(string)-1] = . strlen(string) = 33getArrayLength() returns the same value as strlen() does because of the NULL byte that terminates the string. The NULL byte is at string[33]; so getArrayLength() returns 33, the highest index in the array. Since the string contains 33 elements (at indexes 0-32) strlen also returns 33. EXAMPLE: This function clips off any array value below zero (negative indices) and returns the number of elements in the new array: // clip off negative indexes in array, and return // the number of elements in the truncated array AbsElementCount(array) { SetArraySpan(array,0,getArrayLength(array)); return (1 + getArrayLength(array)); }The following properties deal with memory:
._BigEndianMode .BLObGet(BLObVar, offset, DataFormat) UWORD8, SWORD8, UWORD16, SWORD16, UWORD24, SWORD24, UWORD32, SWORD32, FLOAT32, FLOAT64, FLOAT80 See fread() in the Clib object for more information on these DataType values. .blobSize(blobVar[, setSize]) The first syntax gets the size of the variable blobVar. If setSize is supplied then the size of blobVar will be set to setSize, even creating blobVar if it does not exist or is not already a BLOb. It returns the number of bytes in blobVar; if setSize is supplied, it will return setSize. The second syntax, in which an Object description is passed as the only parameter, returns the number of bytes the Object requires if it is to be inserted or extracted from a blob. .address(segment, offset) DOS, 16-bit Windows .interrupt(Interrupt, RegIn [, RegOut]) DOS, 16-bit Windows Since many interrupts set the carry flag for error, this function will return False if the carry flag is set, else returns True. .segment(buffer) DOS, 16-bit Windows If the address versions are used, then address is assumed to be a far pointer to data, and segment will be the high word while address will be the low word. See address() for converting segment and offset into a single address. Return segment or offset of buffer such that 8086 would recognize the address segment::buffer as pointing to the first byte of buf. .offset DOS, 16-bit Windows
.directory([, fileSpec[, subdirs [, IncAttr[, reqAttrib]]]] ) By default, this returns the names of subdirectories and filenames of normal files (files with no attributes set), readonly, and files with the archive bit set. The IncludeAttrib parameter may be modified to change this. fileSpec is any valid file specification (including wildcards and drives and/or paths) that matches the parameters of the operating system. If this parameter is not supplied then it defaults to the current directory. subdirs is TRUE to search recursively through subdirectories, and FALSE to only search the directory specified in fileSpec. If this parameter is not supplied then its default is FALSE. IncludeAttrib is an OR of flags specifying which files to match based on file flags; files that have attribute flags set must have the corresponding flag set in order to match fileSpec. Flags that do not apply to the operating system are ignored. If 0 is suppied here the function only returns the names of files that have no attributes set. If this parameter is not specified then it defaults to: (FATTR_RDONLY | FATTR_SUBDIR | FATTR_ARCHIVE). The defined flags for Attrib are:
The file object returned has the following properties:
ListDirectory(FileSpec) // list all files except // directory entries { FileList = Directory(FileSpec,False,~FATTR_SUBDIR) if (NULL == FileList) printf("No files found for search spec \"%s\".\n", FileSpec); else { FileCount = 1 + GetArrayLength(FileList); for (i = 0; i < FileCount; i++) printf("%s\tsize = %d\tCreate date/time = %s\n", FileList[i].name, FileList[i].size, ctime(FileList[i].Create) ) } } .fullpath(pathSpec) CurDir() { return FullPath(".") }This routine works in DOS and OS/2 to test whether a drive letter is valid: ValidDrive(DriveLetter) { sprintf(CurdirSpec,"%c:.",DriveLetter) return (NULL != FullPath(CurdirSpec) ) }The following functions deal with script execution: .interpret(Code[, InterpretFlags[, ErrorString]) Note that INTERP_FILE and INTERP_TEXT are mutually exclusive. If neither is supplied intepret() examines Code and decides whether it looks like a file or like pure code. If there is an error handling the Interpret() function, the variable ErrorString will be set to a string describing the error (otherwise it will be NULL). You cannot use the Interpret function on ScriptEase scripts that have been turned into executable with the /BIND option. EXAMPLE: The following example code: Interpret(`puts("Hello world!")`, INTERP_TEXT);produces this output: Hello world!Similarly, the following code: Interpret("CmmEdit C:\autoexec.bat", INTERP_FILE);will open the script CmmEdit with the file autoexec.bat loaded. .spawn(mode, ExecutableSpec [, arg1[, arg2[,...]]]) mode may be one of the following values:
ExecutableSpec is automatically passed as argument 0. ScriptEase will implicitly convert the arguments into strings before passing them on to the child process. Searches for ExecutableSpec in the current directory, then in the directories of the PATH environment variable. If there is no extension on ExecutableSpec it will search first for .COM, then .EXE files, then .BAT and .CMD files. If a batch file is being spawned in 16-bit DOS and the environment variable COMSPEC_ENV_SIZE exists, the command processor will be provided the amount of memory as indicated by COMSPEC_ENV_SIZE. If COMSPEC_ENV_SIZE does not exist then the command processor receives only enough memory for existing environment variables. RETURN: Returns -1 for error and sets errno to identify the error. For success returns the exit code of the child process for P_WAIT, does not return for P_OVERLAY, else returns the an identifier of the child process. EXAMPLES: This example calls a mortgage program MORTGAGE.EXE which takes three parameters, initial debt, rate, and monthly payment, and returns number of months needed to pay the debt in its exit code: months = spawn(P_WAIT, "MORTGAGE.EXE 300000 10.5 1000"); if (months < 0) printf( "Error spawning MORTGAGE\n"); else printf("%d months to pay off the mortgage\n", months);The parameters could also be passed to MORTGAGE.EXE as separate variables: months = spawn(P_WAIT,"MORTGAGE.EXE", 300000,10.5,1000);The same arguments could be passed to MORTGAGE.EXE in a variable array, provided that they are all he same data type (in this case strings): MortgageData[0] = "300000"; MortgageData[1] = "10.5"; MortgageData[2] = "1000"; ths = spawn(P_WAIT,"MORTGAGE.EXE",MortageData);See also the example for SElib.suspend(). .splitFileName(fileSpec)
EXAMPLE: The following script shows results from sample inputs to .splitFileName() (the second example applies to the file structure for DOS and OS/2): // sets parts.dir= "", // parts.name="foo", // parts.ext="", // parts = SplitFileName("foo") // parts.dir="..\\", // parts.name="*", // parts.ext=".doc" parts = SplitFileName("..\\*.doc") .suspend(milliSecondDelay) EXAMPLE: This example spawns a copy of the Windows application Notepad, puts the date and time into the document (by simulating the selection of "Time/Date" from the Edit menu), and then prints the line "You asked for the time?". The suspend function gives the processor time to finish completing the menu command before entering the text; if the Keystroke() command came immediately after the call to MenuCommand(), the text would be output while the menu item was still being selected, and would become garbled. wHnd = spawn(P_NOWAIT, "notepad"); MenuCommand(wHnd, "Edit##Time"); suspend(300) Keystroke("\nYou asked for the time?");In this example, execution is suspended for a little less than a third of a second. The delay will not be noticeable to a human, but it gives the computer enough time to finish what it is doing. (The function MenuCommand is in the .hmm library menuctrl.hmm). .Eset(fileSpec) Win32, OS/2 .instance() 32-bit Windows .interpretInNewThread(filename, textToInterpret) It is up to the script writer to ensure any synchronization between threads; ScriptEase data and globals will be per-thread only. If filename is not NULL then it is the name of a file to interpret and textToInterpret will be parsed as if they are command-line parameters to the main() function. If filename is NULL then textToInterpret will be treated as Javascript code and interpreted directly. This function is not supported on operating systems that do not support multithreading, such as DOS and 16-bit Windows. .multiTask(bool) 16-bit Windows EXAMPLE: The following section of code empties the clipboard. Multitasking is turned off during this brief interval to ensure that no other program tries to open the clipboard while this program is accessing it. MultiTask(FALSE); DynamicLink("USER","OPENCLIPBOARD",SWORD16, PASCAL,ScreenHandle()); DynamicLink("USER","EMPTYCLIPBOARD",SWORD16,PASCAL); DynamicLink("USER","CLOSECLIPBOARD",SWORD16,PASCAL); MultiTask(TRUE);The following functions are only applicable in DOS and Windows 3.x systems; the allow you to read and write data to hardware ports: .inport(portID) DOS, 16-bit Windows, OS/2 .inportw(portID) DOS, 16-bit Windows, OS/2 .outport(int portid, byte value) DOS, 16-bit Windows, OS/2 .outportw(int portid, int value) DOS, 16-bit Windows, OS/2 .BreakWindow([WindowHandle]) 16 and 32-bit Windows .doWindows([boolean]) 16 and 32-bit Windows #include "message.hmm" #include "window.hmm" main() { hwnd = MakeWindow(NULL,NULL,"WindowFunction", "Display Windows' messages", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 500, 350, NULL,0 ) MessageFilter(hwnd, WM_LBUTTONDOWN); while(DoWindows()); } WindowFunction(hwnd,msg,parm1,parm2,counter) { if (msg == WM_LBUTTONDOWN) { msgHwnd = MakeWindow(hwnd, "static", NULL, "You clicked me!", WS_CHILD | WS_VISIBLE, 200, 150, 100, 50, NULL, 0); suspend(1000); BreakWindow(msgHwnd); } } .messageFilter(WinHandle [, Message1 [, Message2 [,...]]]]) .subclassWindow(WindowHandle, WindowFunction [, UtilVar]) .PMDynamicLink() OS/2 .PMInfo() OS/2 .PMPeek() OS/2 .PMPoke OS/2 .processList([boolean IncludeThreadInfo]) OS/2 If there is an error getting ThreadInfo, this will return NULL; otherwise it returns an array of objects containing the following properties: .id ProcessID for this process .parent ProcessID for the parent of this process .name ProcessID for the parent of this process .name String containing the full name of this process .threads Array of structures describing each thread of this process; this structure element will not be returned unless IncludeThreadInfo is set to equal TRUE, in which case .threads is an array of structures for each thread in the process, where the thread structure contains these structure elements: .ProcID ID of this thread within the process .SysID ID of this thread within the system .Priority Running priority of this thread .Status Current running state of this thread .DynamicLink( LibraryName, Procedure, Convention,...) OS/2 There are three versions of DynamicLink(): one for OS/2, one for Windows 3.x, and one for Windows `95 or NT. These three versions differ slightly in the way they are called, so if you wish to use the function in a script that will be run on different platforms you must create an operating system filter with the preprocessor directives #if, #ifdef, #elif, #else, and #endif. Since the three versions are different in the way that they call DynamicLink, they will be treated separately. Of the three, 32-bit Windows has the simplest syntax:
DynamicLink(Library, Procedure, Convention,...)
Procedure is the name or ordinal number of the procedure in the ModuleName dynamic link library, if this procedure can be referenced by name. Calling Convention may be any of the following:
16-bit WindowsThe syntax for 16-bit Windows (3.x, i.e.) requires the addition of a RetType parameter: DynamicLink(Library, Procedure, RetType, Convention,...) RetType tells ScriptEase what type of value the procedure returns, so that it can be properly converted into an int. The Return Types (such as SWORD16, UWORD32, etc...) are described in the fread() function of the Clib object.OS/2The syntax for OS/2 requires the addition of a bitSize parameter (instead of RetType). DynamicLink(Library, Ordinal, BitSize, Convention,...) BitSize defines whether this is a 16-bit or a 32-bit call. It may be either one of the pre-defined values: BIT16 or BIT32. The OS/2 processor also allows you to call a function via a call gate with this syntax:DynamicLink(CallGate, BitSize, Convention,...) where CallGate is the gate selector for a routine referenced through a call gate. Any parameters required by the dynamically linked function should be passed at the end of the parameters listed above. These variables will be interpreted as follows (depending on the operating system used): 32-bit WindowsAll values will be passed as 32-bit values. If a parameter is undefined when DynamicLink() is called, then it is assumed that that parameter will be a 32-bit value that will be filled in (i.e., the address of a 32-bit data element is passed to the function, and that function will set the value). If any parameter is a structure then it must be a structure that defines the binary data types in memory to represent the following variable. Before calling the DLL function, the structure will be copied to a binary buffer as described in BLObPut() and fwrite(). After calling the DLL function the binary data will be converted back into the data structure according to the rules defined in BLObGet() and fread(). Data conversion will be performed according to the current BigEndianMode setting (see fread()). 16-bit WindowsIf the parameter is a blob or a byte-array or an undefined value, it will be passed as a far pointer. All other numeric values will be passed as 16-bit values. If 32-bits are needed the parameter will have to be passed in parts, with the low word first and the high word second for CDECL calls, and the high word first and low word second for PASCAL calls.If a parameter is undefined when DynamicLink() is called, then it is assumed that the parameter is a far pointer that will be filled in (i.e., the far address of a data element is passed to the function, and that function will set the value). If any parameter is a structure, then it must be a structure that defines the binary data types in memory to represent the following variable. Before calling the DLL function, the structure will be copied to a binary buffer as described in BLObPut() and fwrite(). After calling the DLL function, the binary data will be converted back into the data structure according to the rules defined in BLObGet() and fread(). Data conversion will be performed according to the current _BigEndianMode setting (see fread()). OS/2For 32-bit functions, all values will be passed as 32-bit values. For 16-bit functions, if the parameter is a blob or a byte-array or an undefined value, then it will be passed as a 16:16 segment:offset pointer, otherwise all numeric values will be passed as 16-bit values, so if 32-bits is needed it will have to be passed in parts, with the low word first and the high word second.If a parameter is undefined when DynamicLink() is called, then it is assumed that parameter will be a 32-bit value that will be filled in (i.e., the address of a 32-bit data element is passed to the function, and that function will set the value). If any parameter is a structure then it must be a structure that defines the binary data types in memory to represent the following variable. Before calling the DLL function, the structure will be copied to a binary buffer as described in BLObPut() and fwrite(). After calling the DLL function the binary data will be converted back into the data structure according to the rules defined in BLObGet() and fread(). Data conversion will be performed according to the current _BigEndianMode setting (see fread()). Any of these calls return the value returned by the dynamically-linked function as interpreted according to ReturnType. This example function would call the Windows MessageBeep() function: #define MESSAGE_BEEP_ORDINAL 104 DynamicLink("USER.EXE",MESSAGE_BEEP_ORDINAL, SWORD16,PASCAL,0); This example displays a simple message box, and waits for user to press Enter: #define MESSAGE_BOX_ORDINAL 1 #define MB_OK 0x0000 // Message box contains one push button: OK. #define MB_TASKMODAL 0x2000 // Must respond to this message DynamicLink("USER.EXE",MESSAGE_BOX_ORDINAL,SWORD16, PASCAL, NULL, "This is a simple message box", "Title of box", MB_OK | MB_TASKMODAL);This accomplishes the same thing: #define MB_OK 0x0000 // Message box contains one push button: OK. #define MB_TASKMODAL 0x2000 // Must respond to message DynamicLink("USER","MESSAGEBOX",SWORD16,PASCAL, NULL,"This is a simple message box", "Title of box", MB_OK | MB_TASKMODAL); |