Nombas Logo

  • Return to main SE:WSE page
  • Introduction
  • Installation instructions for ScriptEase:WebServer Edition
  • A description of the Javascript language
  • A tutorial for some ScriptEase:Webserver Edition demos
  • A description of the Clib object
  • A description of the SElib object
  • The SElib Object

    The 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:

    MemoryOperating system and directories
    Script ExecutionHardware Ports
    OS/2Windows

    .rsprintf(formatString...)
    This function returns a formatted string. It is exactly like printf(), except that the string is returned instead of printed. For example, if in a script you had a line:

         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)
    This returns one more than the highest index of the array. If the first element of the array begins with 0 (as is most common), this function will return the length of the array. If MinIndex is passed in then it will be set to the minimum index, which will be zero or less.

    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) = 33
    
    getArrayLength() 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
    blobSize()
    blobGet()
    blobPut()
    address() (DOS, 16-bit Windows)
    interrupt() (DOS, 16-bit Windows)
    segment() (DOS, 16-bit Windows)
    offset() (DOS, 16-bit Windows)

    ._BigEndianMode
    This property specifies whether data read or written by the Clib functions fread() and fwrite() or the SElib functions BLObGet(), BLObPut(), peek(), poke(), PMpeek(), PMpoke(), or DynamicLink() are stored in memory in a Big-Endian or Little-Endian format. This defaults to BIG_ENDIAN.

    .BLObGet(BLObVar, offset, DataFormat)
    The companion function to BLObPut(), BLObGet() retrieves data from a specified location from a BLOb and returns it in a variable of the type specified by DataFormat. DataFormat must be either a buffer, an object definition, or one of the following:

    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])
    .blobSize(DefinitionStructure) This method gets or sets the size of a blob, or determines the size of an object. The object size is required for calls to .blobGet() and .blobPut().

    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
    Address() converts the segment and offset into a single segment:offset address. It returns a segment:offset address suitable for use in calls such as peek() and poke().

    .interrupt(Interrupt, RegIn [, RegOut]) DOS, 16-bit Windows
    Set registers, call 8086 interrupt function, and get the return values of the registers. RegIn and RegOut are objects containing properties corresponding to the registers on an 8086. On input, the properties that are defined will be set, and those that are not defined will be set to zero, with the exception of the segment registers (ES & DS) which retain their current values if not explicitly specified. The possible defined input values are AX, AH, AL, BX, BH, BL, CX, CH, CL, DX, DH, DL, BP, SI, DI, DS, ES. All Fields of the Output reg structure are the same, with the addition of the FLAGS member, and all are set before returning. If RegOut is not supplied, then the return registers and FLAGS register will be set for RegIn on return from the interrupt call.

    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
    This function (and its companion function offset()) return the segment and offset of the data at index 0 of buffer, which must be a byte array. The buffer must be already big enough for whatever purpose it is used, and no changes must be made to the size of the buffer after these values are determined because changing the size of the buffer might change its absolute address.

    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
    This function, along with its companion function segment(), breaks a buffer or far pointer into its segment and offset components.

    The following fuctions deal with your operating system, its directories and subdirectories, and the way that scripts are executed:

    directory()
    fullpath()
    interpret()
    spawn()
    splitFileName()
    suspend()
    Eset() (32-bit Windows and OS/2)
    instance() (32-bit Windows)
    interpretInNewThread (32-bit Windows and OS/2)
    multitask() (16-bit Windows)

    .directory([, fileSpec[, subdirs [, IncAttr[, reqAttrib]]]] )
    This function returns an object whose properties are strings containing the names of files that match the path specification supplied by fileSpec. If no files match fileSpec, the function returns NULL

    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:
    FATTR_RDONLYRead-only file
    FATTR_HIDDENHidden file
    FATTR_SYSTEMSystem file
    FATTR_SUBDIRDirectory
    FATTR_ARCHIVEArchive file
    RequiredAttrib is an OR of the same flags as defined under IncludeAttrib. In this case, all files will be excluded from the search that do not have all of the RequiredAttrib flags set. If no flags are supplied it defaults to 0.

    The file object returned has the following properties:
    .nameFull file name, including the SearchSpec path.
    .attribOR of file flags, as defined above in IncludeAttrib
    .sizeSize of file, in bytes
    .accessDate and time of last file access
    .writeDate and time of last write to file
    .createDate and time of file creation
    EXAMPLE: This routine would list all files in the current directory, except for subdirectory entries:

    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)
    This function converts pathSpec, which should be a valid file-system path specification, into an absolute path name. Absolute path will correspond to the operating system's conventions. A string containing the full path specification is returned. If PathSpec is not valid, NULL is returned. EXAMPLE:The following example returns the full specification of the current directory:

    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])
    This function interprets a string as if it were Javascript code. It is more flexible than the Javascript eval function in that it interpret a file as well as a string, and it gives you more control about how the code inherits variables from the script that calls it. By default, all variables in the script will be inherited as global variables. If successful, interpret returns whatever the code it is interpreting returns; if it fails, -1 will be returned. Code is a string containing Javascript code to be interpreted, or the path and filename of a file to interpret as Javascript followed by any parameters it takes; the function will return whatever value this code returns (or -1 if there is an error). InterpretFlags must be 0 (zero) or a bitwise or of the following choices: INTERP_FILE: Code must be name of ScriptEase source file, followed by any arguments INTERP_TEXT: Code is ScriptEase source code; no arguments INTERP_LOAD: Load code into same function and variable space as the code that is calling Interpret(). All functions, and variables will be supplied to the code being called, which can modify and use them. If the code being called has similarly named functions or variables as the calling code, the functions in the called code will replace those in the calling code. INTERP_NOINHERIT_LOCAL: Local variables will not be inherited by the interpreted code. INTERP_NOINHERIT_GLOBAL: Global variables will not be inherited as global variables in the interpreted code. The flags indicate to the computer how to interpret the Code parameter. If they are not supplied, then the computer will parse the string and try to figure out the most appropriate way to interpret it.

    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[,...]]])
    This function launches another application. Mode determines the behavior of the script after the spawn call, while ExecuteableSpec is the name of the process you are spawning. Any arguments to the spawned process follow.

    mode may be one of the following values:
    P_WAIT (All)Wait for the child program to complete before continuing.
    P_NOWAIT (OS/2 and Windows)The script continues to run while the child program runs. In windows, a successful call with mode P_NOWAIT will return the window handle of the spawned process.
    P_SWAP (DOS only)Like P_WAIT, but swap out ScriptEase to create more room for child process. P_SWAP will free up as much memory as possible by swapping ScriptEase to EMS/XMS/INT15 memory or to disk (in TMP directory, else TEMP, else current directory) before executing the child process (thanks to Ralf Brown for his excellent spawn library).
    P_OVERLAY (16-bit DOS only) The script exits and child program is executed in its place.
    ExecuteableSpec may be the path and filename of an executeable or the name of a ScriptEase script. If it is a script, it will run from the same instance of ScriptEase as the script that called it (i.e., it won't launch a new instance of the interpreter but will run from the open one). You cannot spawn a script that has been bound with the ScriptEase /BIND function.

    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)
    Splits the fileSpec into its various components conform to the conventions of the operating system and returns an object with the following properties:
    .dirthe directory name, including leading and drive separator characters
    .nameroot name of the file
    .extextension name of the file, including preceding dot (.)
    All properties are guaranteed to be non-NULL, and fileSpec can be reconstructed with this source statement: FileSpec = strcat(strcat(dir,name),ext)

    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)
    This function suspends program operation for the amount of time specified by milliSecondDelay. Total millisecond accuracy is not guaranteed, but is only approximated according to the accuracy provided by the underlying operating system. This allows the computer to devote more time to other processes. It can also be used to give the processor time to complete tasks before calling the next line.

    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
    This function writes new environment variable settings to a file, returning TRUE if it was successful and FALSE if it was unable to write the settings to the file. FileSpec is the name of the file to (create and) write to. When a call is made to putenv(), as at least as many statements of the form "SET VAR=Value" as necessary will be written to the file so that ScriptEase always has an updated version of the variables. Note that this operation is unnecessary if the SE_ESET environment variable is set. In this case, the call ESet(%SE_ESET%) is automatically generated as the last statement before a smooth exit of ScriptEase.

    .instance() 32-bit Windows
    This function returns the instance of this ScriptEase session.

    .interpretInNewThread(filename, textToInterpret)
    32-bit Windows, OS/2
    This function creates a new thread within the current ScriptEase process and interprets a script within that new thread. The new script runs independently of the currently executing thread. This differs from interpret() in that the calling thread will not wait for the interpretation to finish, and it differs from spawn() in that the new thread will run in the same memory and process space as the currently running thread. It returns the ID number of the thread containing the new instance of ScriptEase. If there is an error, 0 or -1 will be returned, depending on the operating system.

    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
    Normally, multitasking is enabled. You should only turn multitasking off for very brief, critical sections of code. No messages are received by this program or any other program while multitasking is off. MultiTask() is additive, meaning that if you call MultiTask(FALSE) twice, then you must call MultiTask(TRUE) twice before multitasking is resumed.

    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
    This function reads a byte from the hardware port indicated by portID.

    .inportw(portID) DOS, 16-bit Windows, OS/2
    Read a word (16 bit) from the hardware port indicated by portid. The value read is unsigned (not negative).

    .outport(int portid, byte value) DOS, 16-bit Windows, OS/2
    Write a byte value to the hardware port indicated by portid.

    .outportw(int portid, int value) DOS, 16-bit Windows, OS/2
    Write a word (16-bit) value to the hardware port indicated by portid. The following functions are valid for Windows (3.x, 95 or NT) systems only. They allow you to create windows and control what they do.

    .BreakWindow([WindowHandle]) 16 and 32-bit Windows
    Destroy a window created with MakeWindow(), or controlled by SubClassWindow(). WindowHandle is a handle of a window created with a previous call to MakeWindow(). It is not an error for WindowHandle to be no longer valid. If WindowHandle is a window created with MakeWindow(), then this destroys the window, calling all appropriate Windows' internal DestroyWindow() functions. Child windows are always removed before the parent. Any child windows of WindowHandle (created by earlier calls to MakeWindow() with WindowHandle as the parent) will be automatically destroyed with BreakWindow() before WindowHandle is destroyed. If WindowHandle is a window controlled by SubclassWindow() then this will remove the WindowFunction from the message function loop. If WindowHandle is not supplied, then all windows created with MakeWindow() will be removed. This function returns True if the window was destroyed or un-subclassed, else False. If WindowHandle is not specified then returns True if all windows created with MakeWindow() were destroyed, otherwise it returns False. If WindowHandle is specified and WindowHandle window does not exist this returns True.

    .doWindows([boolean]) 16 and 32-bit Windows
    The DoWindows() function starts up the ScriptEase Window Manager to activate whatever windows have been created or subclassed with MakeWindow or SubclassWindow. All such windows are registered with the Window manager. The Window Manager controls the window messages sent to the windows in its registry and routes them to their respective window functions. There should not be more than one copy of the Window Manager running at a time. In the common situation where you have a succession of windows, you only need to call DoWindows() once. All windows created or subclassed after the DoWindows() call will automatically be registered with the Window Manager. The flags that define window messages are kept in the library file message.hmm. If the optional boolean variable passed to this function is TRUE (default is FALSE) it returns immediately, regardless of whether there were messages for this application or not. Otherwise this function yields control to other applications until a message has been processed (subject to filtering by MessageFilter()) for this application or for any window SubClassed by this application. Returns TRUE if any of the windows created with MakeWindow() or subclassed with SubClassWindow() are still open (i.e., have not received WM_NCDESTROY); returns FALSE if there are no valid windows registered with the Window Manager The following sample script will display a standard Windows window. If you click anywhere in the window, the string "You clicked me!" is printed briefly in the middle of the window. When the window is closed the script will terminate.

    #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 [,...]]]])
    16 and 32-bit Windows This function restricts the messages handled by ScriptEase for a window created with MakeWindow() or subclassed with SubclassWindow(). When Windows sends lots of messages, but you're only interested in handling a few of them within ScriptEase code, you can increase performance by specifying only those messages you want to handle in MessageFilter(). Any messages that have not been specified to MessageFilter() will not be handle by your WindowFunction and might not cause DoWindows() to return immediately (if Peek==False). Initially, there are no message filters so all messages are processed by ScriptEase. To remove all message filters, so that all messages are passed through to the ScriptEase handler, use the third form of MessageFilter(). WinHandle is handle for a windows created with MakeWindow() or subclassed with SubclassWindow(). MessageID1, MessageID2,... are messages to be added to those being filtered. Returns an array of messages being filtered prior to taking this call. Returns NULL if no messages are in the filter (i.e., all messages are passed through to ScriptEase functions) or if WinHandle is not a handle from a MakeWindow() or SubclassWindow() window.

    .subclassWindow(WindowHandle, WindowFunction [, UtilVar])
    16 and 32-bit Windows This function will hook the specified WindowFunction() into the message loop for this window such that your function is called before the window's default or previously-defined function. WindowHandle is the window handle of an already existing window to subclass. WindowFunction is the same as in the MakeWindow() function. See MakeWindow(). Note that, as in the MakeWindow()function, if this function returns a value, then the default or subclassed function is not called. If this function returns no value then call is passed on to the previous function. This function may be used to subclass any Window that is not already being managed by a WindowFunction for this ScriptEase instance. If the windows was created with MakeWindow() or is already SubClassed then this function will fail. Note that this function may be used (but only once) with the window handle returned by ScreenHandle(). If you want to SubClass the main ScriptEase window, it is best to open another instance of ScriptEase and SubClass that rather than to subclass the instance that is powering your script. (Although it is possible to subclass that window, if you try to do anything with it you'll most likely get caught up in an infinite loop and hang). To undo the window subclassing, or remove WindowFunction from the message loop, then use BreakWindow(). Your WindowFunction() may modify UtilityVar. In your function that handles messages for another process, certain limits are set as to what you can do with system resources. For example, an open file handle will be invalid while processing another program's message, because Windows will map any file handles into a table for that other program. To work around this problem, you may want to send a message to one of your ScriptEase windows to handle the processing; this will switch Windows' tables to your program while handling that SendMessage() to yourself. Returns boolean False if WindowHandle is invalid, was created with MakeWindow(), or is already Subclassed with this function; else return boolean True. The following functions are only valid in OS/2:

    .PMDynamicLink() OS/2
    This function is identical to DynamicLink() except that PMDynamicLink passes DLL calls throught the SEOS2PM.exe gateway program. SEOS2.exe is not a PM program but SEOS2PM is, so SEOS2PM can make these calls for SEOS2.exe. Addresses and buffers are automatically transferred and shared between SEOS2.exe and SEOS2PM.exe, so in most cases your code does not need to concern itself with memory proptection. The exception to this is if one of the arguments to PMDynamicLink() contains or will receive a pointer. In this case you need to put or get that data explicitly by useing PMpeek() and PMpoke() instead of the usual peek() and poke() routines.

    .PMInfo() OS/2
    See the SElib property Info() PMInfo() works identically, but retrieves the infromation for the SEOS2PM.exe gateway function. PMDynamicLink() functions (see above) often must use these values instead of those from Info().

    .PMPeek() OS/2
    PMpeek() is identical to SElib.peek() but it will access memory that is given to SEOS2PM.exe or that may only be accessible from a PM program.

    .PMPoke OS/2
    PMpoke() is identical to poke() but it will access memory that is given to SEOS2PM .exe or may only be accessible from a PM program.

    .processList([boolean IncludeThreadInfo]) OS/2
    This function returns an array of objects containing data for every running process in the system. If IncludeThreadInfo is TRUE, then information is also added for each thread in each process. If IncludeThreadInfo is not supplied then FALSE is assumed, so only Process data is returned.

    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
    DynamicLink() is a flexible method for making calls to dynamic link libraries (DLLs), giving you access to any operating-system function not explicitly provided by ScriptEase. If you know the proper conventions for the call, then you can wrap a ScriptEase routine around a call to DynamicLink, and the call becomes available.

    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,...)
    Library is the name of the dynamic link library that the procedure is located in.

    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:
    CDECLPush right parameter first; Caller pops parameters.
    STDCALLPush right parameter first; Caller pops parameters.
    PASCALPush left parameter first; Callee pops parameters.

    16-bit Windows

    The 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/2

    The 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 Windows

    All 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 Windows

    If 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/2

    For 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);