Wilson WindowWare Tech Support

WinBatch WinBatch+Compiler WebBatch
Home | Tech Database | Tech BBS | White Papers | Purchase


List of Fixes and Improvements

WinBatch versions 2001B through 2003B

Keywords:    fixes improvements new releases features

WB 2001B  Feb 27, 2001

  16-bit version is no longer being developed (so no more references to
  "32-bit only").

  Added additional option for IntControl(1007):

      p1   Meaning
      --   -------
       4   Modify currently-running script in the system tray

    If p1 == 4 (modify icon), then p2 can be one or more of the following
    flags, combined with the bitwise OR ("|") operator:

      p2   Meaning
      --   -------
       1   Modify tool tip (p3 specifies the new tool tip)
       2   Modify icon (p4 specifies the new icon file)

  IntControl 1004 now returns a full path for uncompiled WinBatch scripts.

  The extension for extender data files used by the compiler has been
  changed from ".DAT" to ".EXT".

  Fixed some problems with overlapping boxes

  Fixed some problems with button focus in boxes.


DLL 3.2bcb  First showing up in WB 2001B

  *** Important: The following changes alter (break) previous behavior ***

    In DiskFree and DiskSize, the items in "drive-list" can no longer be
    separated with spaces (in order to now support UNC's containing spaces).

    In ItemCount, trailing delimiters are now significant.  This means that
    the comma-delimited list "a,b,c," has 4 items in it.

    In ItemInsert, trailing delimiters are now significant.  This means that
    if you specify a blank item ("") and an offset of -1, a blank item will
    be added to the end of the list, even if the list already has a trailing
    delimiter.

    The following functions no longer add a trailing delimiter to the
    returned list (some of these are "legacy" functions that are no longer
    documented):

      AskFileText
      AskItemList
      ItemSelect
      RegQueryItem
      TextBox
      TextBoxSort
      TextSelect

    Changed the format of the string for OLE return types of VT_DECIMAL
    (this was previously undocumented).  The new format is described below.

    FileExist now returns @FALSE if the file name contains any '/'
    characters (this change was actually made in WB 99M).

  16-bit version is no longer being developed (so no more references to
  "32-bit only").

  New -- user-defined functions!

    WIL now supports user-defined functions (UDF's).  A UDF is defined as
    follows:

      #DefineFunction functname([param1, param2, ..., param16])
        
        Return retval
      #EndFunction

      "#DefineFunction" and "#EndFunction" are the keywords indicating the
      beginning and end of the UDF.

      "functname" is a placeholder for the name of the function.  The
      function name must begin with a letter, can contain letters, numbers,
      and underscores, and can be up to 30 characters long.  You may not
      use a function name that is the same as the name of a WIL DLL function,
      but you may override a function name that's in an extender DLL.

      You may specify up to 16 optional parameters.  "param1" - "param16"
      are placeholders for your actual variable names.  These are the names
      of the variables that your UDF will receive when it is called.

      Between the "#DefineFunction" and "#EndFunction" keywords is the code
      that will get executed when the UDF is called.  It may contain a
      Return command followed by a value (or an expression that evaluates to
      a value), in which case the UDF will end and return this value.  If
      you specify a Return command without a value, the UDF will return 0.
      If a UDF does not contain a Return command, it will execute to the end
      of the UDF and return 0.  An Exit command in a UDF will cause the
      entire script to end, not just the UDF.

    A UDF must be defined anywhere in a script, as long as it is defined
    prior to being used for the first time.  A UDF may be defined or used in
    a separate script that is called with the Call command, as long as it is
    defined before it is used.  You may not have nested UDF definitions (ie,
    each "#DefineFunction" must be followed by an "#EndFunction" as a pair).

    A UDF will not have access to any variables in the main WIL script,
    other than the variables passed as param1 - param16.  Any variables set
    in a UDF will be destroyed when the UDF returns, other than the return
    value of the UDF.  Any percent signs in the UDF code will be expanded at
    runtime (when the code is called), not at define time.

    You may return a file handle, binary buffer, OLE object, or array from a
    UDF using the Return command.  However, if you create one of these types
    of objects in your UDF and do not return it using the Return command,
    you are responsible for freeing it before the UDF returns, using the
    appropriate WIL function (ie, FileClose, BinaryFree, ObjectClose, or
    Drop, respectively); otherwise, the object will become an "orphan" and
    will no longer be accessible and may not be automatically freed when the
    script exits.

    Example:

      ; Define three UDF's

      #DefineFunction Done()
        Message("All done", "Script processing is complete")
      #EndFunction

      #DefineFunction Square(number)
        Return (number * number)
      #EndFunction

      #DefineFunction AddListItem(list, newitem, delimiter)
        list = ItemInsert(newitem, -1, list, delimiter)
        list = ItemSort(list, delimiter)
        Return list
      #EndFunction

      ; Now use them

      list = "apples,bananas,peaches"
      list = AddListItem(list, "cherries", ",")
      Message("New list", list)

      Message("The square of 5 is", Square(5))

      Done()

  New -- arrays!

    WIL now supports arrays.  Arrays are created using the new ArrDimension
    function (see below).  An array may have from 1 to 5 dimensions, and each
    dimension may contain up to 65,535 elements.  Array elements are
    referenced with their subscripts enclosed in square brackets.  If an array
    has more than one dimension, the subscripts are separated with commas.  Eg:

      arrayvar[1]
      arrayvar[1, 1]
      arrayvar[0, 5, 2]

    Array subscripts are 0-based; ie, the first element in an array is array[0].

    Array elements can contain any type of WIL value: string, integer, float,
    etc.  You can have different types of values within an array.

    You may not pass an array as a parameter to a WIL function (except for
    functions which state they accept an array), or use it in any sort of
    operation.  For example, the following are NOT legal:

      arrayvar = 5                   ; NOT legal
      x = arrayvar                   ; NOT legal
      Message("Value is", arrayvar)  ; NOT legal

    On the other hand, the following are all legal:

      arrayvar[0] = 5
      x = arrayvar[0]
      Message("Value is", arrayvar[0])

    You can pass arrays to user-defined functions, and you can return arrays
    with the Return command.

    When you pass an array name (ie, not an array element) as a parameter to
    a function, the array gets passed "by reference".  That is, the function
    receives a pointer to the array, and is therefore able to make changes
    to it "in place".  This is similar to passing a binary buffer handle to
    a function, where the function is then able to make wholesale changes to
    the binary buffer.

    In contrast, passing an array element (ie, with a subscript) to a
    function is like passing a regular string or integer parameter to a
    function -- it gets passed "by value".  Ie, the function receives the
    value of the array element, but is not able to modify the array itself.
    By the same token, when you pass a string to a function like StrUpper:

      newstring = StrUpper(oldstring)

    The function does not modify the variable "oldstring" at all.  If you
    want to modify the existing variable, you can assign to it the return
    value of the function, eg:

      mystring = StrUpper(mystring)
      array[2] = StrUpper(array[2])

  New functions:

    ArrDimension(i:dim1 [, i:dim2 [, i:dim3 [, i:dim4 [, i:dim5]]]])
      Creates an array.

      This function creates an array of 1 to 5 dimensions.  Each dimension
      ("dim1" through "dim5") specifies a dimension size up to 65,535.  At
      least one dimension must be specified; the other parameters are
      optional and will default to 0 (ie, unused dimension).  For example:

        1-dimension array:  array1 = ArrDimension(10)
        2-dimension array:  array2 = ArrDimension(10, 10)
        3-dimension array:  array3 = ArrDimension(10, 10, 10)
        4-dimension array:  array4 = ArrDimension(10, 10, 10, 10)
        5-dimension array:  array5 = ArrDimension(10, 10, 10, 10, 10)

      ArrDimension(10) creates a 1-dimension array with a size of 10 (10
      elements).  Since array subscripts are 0-based, the first element is
      arrayvar[0] and the last element is arrayvar[9].

      An array can theoretically contain up to 200,000,000 elements in total.
      Of course this will be further limited by your available system memory.

      You can not create embedded arrays (ie, an array within an array).

      You can use the Drop command to free an array.  This will also Drop
      any OLE object handles within the array, as well as any WIL string
      variables.  It will NOT close any file handles or binary buffers.

      The return value is the array that was created.

    ArrInfo(a:array, i:request)
      Gets information about an array.

      "array" specifies an array.

      "request" can be one of the following:

        request   returns
        -------   -------
           0      number of dimensions in the array
           1      number of elements in dimension 1
           2      number of elements in dimension 2 (or 0 if unused)
           3      number of elements in dimension 3 (or 0 if unused)
           4      number of elements in dimension 4 (or 0 if unused)
           5      number of elements in dimension 5 (or 0 if unused)
           6      number of elements in the entire array

    ArrInitialize(a:array, i:value)
      Initializes an array.

      "array" specifies an array.

      "value" specifies an integer value.

      This function sets all elements of "array" to "value".

      Returns @TRUE.

    Arrayize(s:list, s:delimiter)
      Converts a delimited list to an array.

        This function takes a delimited list, and creates a one-dimension
        array with the same number of elements as the number of items in the
        list, setting each element to the value of the corresponding item in
        the list.  Ie, it converts a delimited list to an array.

        Returns the array that was created.

    RegOpenKeyEx(i:handle, s:subkey-string, s/i:mode, s:reserved-1, s:reserved-2)
      Opens a registry key with specified access rights.

        "handle"          handle to a registration database key
        "subkey-string"   a path from the key provided to the desired key
        "mode"            access mode (see below)
        "reserved-1"      reserved for future use; should be set to "".
        "reserved-2"      reserved for future use; should be set to "".

      This function is like RegOpenKey, but lets the user specify the desired
      access rights (RegOpenKey opens a key with default access, so may fail
      if the user only has read permission for the key).

      "Mode" may be one of the following pre-defined string values:

        Value     Name                     Meaning (see below for bit descriptions)
        -----     ----                     ----------------------------------------
        "READ"    KEY_READ                 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS |
                                           KEY_NOTIFY | STANDARD_RIGHTS_READ

        "WRITE"   KEY_WRITE                KEY_SET_VALUE | KEY_CREATE_SUB_KEY |
                                           STANDARD_RIGHTS_WRITE

        "FULL"    KEY_ALL_ACCESS           (KEY_QUERY_VALUE | KEY_SET_VALUE |
                                           KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS |
                                           KEY_NOTIFY | KEY_CREATE_LINK |
                                           STANDARD_RIGHTS_ALL) & ~SYNCHRONIZE

      Or, "mode" may be a bitmask comprised of one or more of the following
      integer values, combined using the bitwise OR ('|') operator:

        Value     Name                     Meaning
        -----     ----                     -------
            1     KEY_QUERY_VALUE          Permission to query subkey data.
            2     KEY_SET_VALUE            Permission to set subkey data.
            4     KEY_CREATE_SUB_KEY       Permission to create subkeys.
            8     KEY_ENUMERATE_SUB_KEYS   Permission to enumerate subkeys.
           16     KEY_NOTIFY               Permission for change notification.
           32     KEY_CREATE_LINK          Permission to create a symbolic link.

      Returns a handle to the newly-opened key.

    VarType(s:varname)
      Gets the type of a WIL variable.

      This function returns the type of WIL variable that "varname"
      specifies.  The return value will be one or more of the following type
      flags, combined using the bitwise OR ('|') operator:

        Type   Meaning
        ----   -------
          0    undefined
          1    integer
          2    string
          5    file handle
         17    OLE object
         32    floating point value
         65    binary buffer
        256    array

    RegQueryStr(i:handle, s:subkey)
      Retrieves and expands a string value from the registry.

        This function can be used to read a REG_SZ or REG_EXPAND_SZ value
        from the registry.  If the value is a REG_EXPAND_SZ, any environment
        strings will be expanded to their defined values in the string
        returned by this function (the registry entry itself is untouched).

        See RegQueryValue for parameter information.

        Returns the expanded registry value.

    FileSizeEx(s:file-list)
      Finds the total size of a group of files (including open files).

        This function is like FileSize, but can be used to get the size of
        files that are open by other applications (which FileSize cannot).

        See FileSize for additional information.


    FileCreateTemp(s:prefix)
      Creates a temporary file.

        This function creates a 0-byte file with a unique name, in the
        directory designated for temporary files (as specified by the "TMP"
        or "TEMP" environment variable).

        "prefix" specifies a prefix for the file name, up to 3 characters
        long (the string may be longer than that, but only the first 3
        characters are used).

        The temporary file name will have the form:

          preXXXX.tmp

        Where "pre" is the prefix specified by the user, and "XXXX" is a
        4-character hexadecimal string generated to guarantee a unique file
        name.  The file name will have an extension of ".tmp".

        The return value is the full path name of the temporary file created.

        Note that this file will not be automatically deleted by the system.

    ClipHasFormat(i:format)
      Determines if the clipboard contains a particular format.

        This function returns @TRUE if the clipboard contains data in the
        format specified by "format", or @FALSE if it does not.

        See BinaryClipGet for a list of clipboard formats.

    BinaryTagIndex(s:tag-struct, i:mode)
      Returns the offset of a binary tag in a buffer.

        mode  returns
        ----  -------
          0   offset of text
          1   offset of start tag

        This function can be used after a successful BinaryTagFind, to
        return the offset where the binary tag was found.  It must be used
        before any subsequent BinaryReplace, since BinaryReplace will change
        the tag structure.

        See BinaryTagFind for additional information.

    BinaryTagLen(s:tag-struct, i:mode)
      Returns the length of a binary tag.

        mode  returns
        ----  -------
          0   length of text
          1   length of text + tags

        This function can be used after a successful BinaryTagFind, to
        return the length of the text that was found.  It must be used
        before any subsequent BinaryReplace, since BinaryReplace will change
        the tag structure.

        See BinaryTagFind for additional information.

    BinaryXlate(i:data-buffer, i:table-buffer, i:mode)
      Converts a binary buffer using a translation table.

        "data-buffer" is a binary buffer containing data to be converted.

        "table-buffer" is a binary buffer containing a translation table.

        "mode" can be one of the following:

          Mode  Source buffer  Target buffer  Table size
          ----  -------------  -------------  ----------
            0        byte           byte           256
            1        byte           word           512
            2        word           byte         65536
            3        word           word        131072

        This function looks up a byte or word in "data-buffer", uses that
        number to compute an index into "table-buffer", looks up the byte or
        word there, and places the result in a temporary buffer.  It does
        this for each byte or word in "data-buffer".  When it's finished
        processing "data-buffer", it copies the new (temporary) buffer back
        to "data-buffer", and sets the binary EOD appropriately.

        For mode 1, "data-buffer" must be large enough to hold at least
        twice as much data as is currently in the buffer.

  New IntControls:

    IntControl(69, p1, p2, 0, 0)
      Suspends machine by shutting power down.

        P1   Meaning (NT/2000 only)
        --   -------
         0   hibernate mode
         1   suspend mode

        P2   Meaning
        --   -------
         0   don't force apps to suspend
         1   force apps to suspend

      This IntControl puts the system into standby mode, if supported by the
      hardware and device drivers.

    IntControl(75, p1, 0, 0, 0)
      Gets last dialog coordinates.

        P1   Meaning
        --   -------
         1   Returns last X coordinate
         2   Returns last Y coordinate

      This IntControl returns the X or Y coordinate of the most recently
      displayed dialog (created with the Dialog function), at the time the
      previous dialog was closed.  Coordinates are in dialog units.  Returns
      -1 if there was no previous dialog.

    IntControl(76, p1, 0, 0, 0)
      Sets the computer name.

      This IntControl sets the NetBIOS name of the local computer, specified
      by P1.  The change does not take effect until the computer is restarted.

      The name may not be longer than 30 characters.  It may contain letters,
      numbers, and the following symbols:

        ! @ # $ % ^ & ' ) ( . - _ { } ~

      In Windows 95/98, if the name contains invalid characters, they will
      be replaced with valid characters.  In Windows NT/2000, if the name
      contains invalid characters, the function will fail.

      Returns @TRUE on success, or @FALSE on failure.

    IntControl(77, p1, 0, 0, 0)
      Gets internal operating parameters.

      This IntControl returns internal values which may be useful in script
      debugging.  P1 specifies one of the following request codes:

        Request  Meaning
        -------  -------
            0    total memory allocated for strings, in bytes
           10    number of variables assigned
           11    number of variable slots available
           12    tab-delimited list of variables assigned
           20    number of files open
           21    number of file slots available
           30    number of binary buffers open
           31    number of binary buffer slots available
           40    number of extenders loaded
           41    number of extender slots available
           42    tab-delimited list of extenders loaded
           50    number of extender functions loaded
           51    number of extender function slots available
           60    number of OLE objects open
           61    number of OLE object slots available
           70    current structure depth
           71    current structure slots remaining
           80    current Call level depth
           90    number of UDF's defined
           91    number of UDF slots available
          100    tab-delimited list of WIL function table entries
          101    tab-delimited list of parent application function table entries
          102    tab-delimited list of loaded extender function table entries
          103    tab-delimited list of UDF's

      Requests 101, 102, and 103 return a tab-delimited list of table
      entries.  Each entry consists of a list of fields delimited with an
      ASCII 255 character, as follows:

        index
        entry type:
          0  BINARYOP
          1  UNARYOP
          2  FUNCTION
          3  CONSTANT
          4  COMMAND
          5  COMPOP
          6  FUNCTBYNAME
          7  UNDEFINED
          8  STRUCTOP
        parameter type mask
        parameter count OR constant value
        name length
        name

      Returns the indicated integer or string.

    IntControl(78, 0, 0, 0, 0)
      Frees all UDF's.

      This IntControl frees (undefines) all user-defined functions.  It
      cannot be used while a UDF is currently executing.

      Returns the number of UDF's that were freed.

  Changed RegExistKey and RegQueryItem to work if the current user only has
  read access (not full access) to the specified key.

  IniItemize / IniItemizePvt no longer has a 32K limit on the size of the
  returned list.

  If you specify -1 for the X or Y coordinate of a Dialog, the corresponding
  coordinate (X or Y) from the most recently displayed dialog will be used.
  If there was no previous dialog, the dialog will be centered.

  The file name following an "#include" pre-processor directive no longer
  needs to be quote-delimited.  Any of the following are now permitted:

      #include "filename"
      #include 'filename'
      #include `filename`
      #include filename

    If the file name is not delimited, it may not have any trailing whitespace.

  Can now pass an OLE object handle as a parameter to an OLE function.

  DirItemize wasn't returning directory names beginning with a period.

  Fixed problem with BinaryReplace giving a "Data to store would overrun
  binary buffer" error when replacing a NULL byte.

  In BinaryReadEx, if "file-offset" + "count" is larger than the file size,
  or if "count" is -1, "count" will be ignored and it will be treated as a
  request to read from "file-offset" to the end of the file.

  Debug and DebugTrace modes are now reset to @OFF before a Call command,
  and automatically set back to their previous states after the Call returns.
  You will need to put Debug and/or DebugTrace commands in the Call'ed script
  if you want it to be debugged.

  The Return command can now return a value, by specifying a value (or an
  expression that evaluates to a value) after the "Return" keyword.  The
  value or expression may optionally be enclosed in parentheses.  This
  feature can be used with the Call command, and with the new user-defined
  functions (see above).  It does not affect the Gosub command.

    Examples:

      Return
      Return (10)
      Return "Okay"
      Return myvariable * 10
      Return (ItemCount(list, @TAB))

  A script run with the Call command can now return a value by using a
  Return command with a value (see above).  If a Return command without a
  value is used, or the called script does not contain a Return command, the
  called script will return 0.

    Example:
      result = Call("other.wbt", "")

  ClipPut no longer has a 64K limit.

  Drop and DropWild can accept array names as parameters.

  IsDefined can accept an array name as a parameter.

  Fixed crash problem when doing an ObjectClose (or Drop, or variable
  reassignment) of an OLE object that was assigned to more than one variable
  name and had already been freed.

  OLE objects are now automatically attempted to be closed on shutdown.
  However, if you have a dependent OLE object open (eg, a document within an
  application), it may prevent the application from being closed.

  Fixed a problem where, if you assigned an OLE object handle to a second
  variable and then Drop'ed or reassigned the original variable, the OLE
  object would be closed and the second variable would therefore no longer
  refer to a valid OLE object.

  No longer receive an "unable to process include file" message when running
  an empty script file.

  Fixed problem with WallPaper function using tile and stretch options.

  DiskFree and DiskSize now support UNC's containing spaces (note that the
  items in "drive-list" can be UNC's corresponding to drives, as well as
  drive letters).

  Fixed a problem with AskFileName not bringing the window to the foreground.

  Fixed a problem with the BinaryTag[..] functions when the found text was
  larger than 64K.

  Directory functions now automatically return failure for directory names
  ending with two backslashes.

  Added new "select mode" to AskItemList and AskFileText:

      @extended

    to allow selection of multiple items by extending the selection with the
    mouse or shift key.

  AskItemList and AskFileText now support multiple selection up to 32,767
  items (previous limit was 100 items).

  Added additional special characters to the SendKey (and SendKeysTo and
  SendKeysChild) functions.  These may or may not work for any particular
  application or situation:

    Key          SendKey equivalent
    ---          ------------------
    Ctrl-Break   {CANCEL}
    Pause        {PAUSE}

  OLE now supports return values of type VT_CURRENCY and VT_DECIMAL.  They
  are returned as strings with prefixes:

      "#CURRENCY:value"   (VT_CY)
      "#DECIMAL:value"    (VT_DECIMAL)

    where 'value' is the decimal or currency value, converted to a string.

    You can also pass these types as parameters to an OLE function by
    prefacing the string with the appropriate prefix:

      Type      Name         Format
      ----      ----         ------
      CY        VT_CY        CY:"#CURRENCY:value"
      DECIMAL   VT_DECIMAL   DECIMAL:"#DECIMAL:value"

  For FileOpen, increased the maximum number of open files from 5 to 128.

  For BinaryAlloc, increased the maximum number of current binary buffers
  from 10 to 128.

  WinActivChild has been renamed to WinActiveChild (the old name will
  continue to work).

  Added new request # to IntControl(71):

    P1   Meaning
    --   -------
     3   Dump WIL variable table to the debug log file.

  Added new request # to MouseInfo:

    Req#  Return value
    ----  ------------
      9   WinID of top level parent window under mouse

  Added new flag to AskFileName:

    3 for Save style, with no "Replace" confirmation.

  AskFileText no longer truncates lines at 254 characters.  It now uses the
  line length set by IntControl(65) (4096 characters by default).

  AskFileText now treats line feeds as line terminators, instead of carriage
  returns.  It therefore now supports both DOS files (which have CR/LF
  terminators) and UNIX files (which have LF terminators).

  Cleared up some confusion with AskDirectory by setting the edit field (if
  present) to a blank value, so the user will not try appending a
  subdirectory name to the text in the field.  Any text entered in the edit
  field is treated as a subdirectory name under the selected directory.
  Also added a static text field showing the name of the selected directory.

  In BinaryWriteEx, if you specify -1 for "count", then "handle" and
  "binary-offset" are now ignored (there was previously a discrepency in the
  documentation about this).

  The following functions now return a file time of 1/1/1980 at 00:00:00 if
  the specified file has an invalid time field:

    FileTimeCode
    FileTimeGet
    FileTimeGetEx
    FileYmdHms

  The following file time get functions no longer round the seconds field of
  the file's time stamp to a multiple of 2 seconds, if a more accurate time
  format is supported by the operating system:

    FileTimeGet
    FileTimeGetEx
    FileYmdHms

  The file time compare routines in the following functions no longer round
  the seconds fields of the files' time stamps to a multiple of 2 seconds,
  if a more accurate time format is supported by the operating system.  They
  now compare the full seconds and milliseconds fields of the time stamps:

    FileCompare
    FileCopy
    FileMove
    InstallFile

  Fixed a problem with DebugTrace where if you specified a filename that did
  not include a full path, and then changed directories while the script was
  running, a new debug file would be written in whatever the current
  directory was.

  Changed the output strings for FileTime and TimeDate to more correctly
  reflect the date and time format preferences set through Control Panel.
  This also affects the File Overwrite confirmation dialog displayed by
  FileCopy and FileMove.

  Changed the following error codes from fatal (3000-) to minor (1000-):

    Old   New   Error
    ---   ---   -----
    3393  1393  AddExtender: Too many extenders added
    3394  1394  AddExtender: Extender DLL not found
    3395  1395  AddExtender: Not a valid extender
    3396  1396  AddExtender: Extender table full
    3437  1437  AddExtender: Extender DLL load failed

  Added an optional parameter to AddExtender:

    AddExtender(s:filename [, i:required-version])

      "required-version" is the minimum acceptable version.  If the version
      of the extender being loaded is less than "required-version", the
      AddExtender command will fail.  The default value is 0 (ie, no
      required version).

  IntControl(73) now works with errors from extenders.

  Under Windows NT (and Windows 2000), AppExist and AppWaitClose now try to
  match the root + extension of "program-name", as well as just the root
  part, against any running application module names.  So if you specify
  "program.exe", it will match either a module named "program.exe" or a
  module named "program".

  Now suppressing a Windows crash error that can occur when doing an
  ObjectClose on an object that has already been freed by another process.

  Fixed problem using ObjectOpen after AskFileName.

  Optimized StrFill.

  Fixed problem with "multi-type" WIL variables being passed to OLE
  functions (ie, integers or floating point numbers that had been converted
  to strings, or vice versa).  If a variable has a floating point value, it
  will now be passed as a floating point value (even if it also has a string
  and/or integer value).  If a variable has both an integer and string
  value, it will now be passed as an integer.

  Fixed a string memory leak when converting string variables to integers.


Windows NT extender 32000  First showing up in WB 2001B

  New functions:

    wntLsaPolGet(s:server-name, s:class, i:element)
      Gets LSA (Local Security Authority) policy information.

        "server-name" is the UNC name of the server on which the function
        will execute (eg, "\\MYSERVER"), or a blank string ("") to indicate
        the current machine.

        "Class" is one of the following:

          "AuditEvents"
          "PrimaryDomain"
          "AccountDomain"
          "LsaServerRole"
          "DnsDomain" (Windows 2000 only)

        For each class, the possible elements are shown:

          "AuditEvents"

            -1   Auditing mode (1 if auditing is enabled, 0 if not)
             0   Event count
             1+  Audit Category (depending on NT version, use "Event count" to determine):

                 1  System
                 2  Logon
                 3  ObjectAccess
                 4  PrivilegeUse
                 5  DetailedTracking
                 6  PolicyChange
                 7  AccountManagement
                 8  DirectoryServiceAccess (Windows 2000)
                 9  AccountLogon           (Windows 2000)

              Each audit category returns an integer indicating the
              auditing options for that category:

                0  None
                1  Success
                2  Failure
                3  Success and Failure

          "PrimaryDomain"

            1  Name
            2  Sid

          "AccountDomain"

            1  Domain Name
            2  Domain Sid

          "LsaServerRole"

            1  Server Role (2=backup, 3=primary)

          "DnsDomain" (Windows 2000 only)

            1  Name
            2  Dns Domain Name
            3  Dns Forest Name
            4  Domain Guid
            5  Sid

      Returns a string or integer value.

    wntLsaPolSet(s:server-name, s:class, i:element, s/i:value)
      Sets LSA (Local Security Authority) policy information.

        "server-name" is the UNC name of the server on which the function
        will execute (eg, "\\MYSERVER"), or a blank string ("") to indicate
        the current machine.

        "Class" is one of the following:

          "AuditEvents"
          "PrimaryDomain"
          "AccountDomain"
          "LsaServerRole"
          "DnsDomain" (Windows 2000 only)

        For each class, the possible elements are shown:

          "AuditEvents"

            -1   Auditing mode (1 to enable auditing, 0 to disable it)
             1+  Audit Category (depending on NT version):

                 1  System
                 2  Logon
                 3  ObjectAccess
                 4  PrivilegeUse
                 5  DetailedTracking
                 6  PolicyChange
                 7  AccountManagement
                 8  DirectoryServiceAccess (Windows 2000)
                 9  AccountLogon           (Windows 2000)

              For each audit category, you may specify one of the following
              integer values to set the auditing options for that category:

                0  None
                1  Success
                2  Failure
                3  Success and Failure

          "PrimaryDomain"

            1  Name
            2  Sid

          "AccountDomain"

            1  Domain Name
            2  Domain Sid

          "LsaServerRole"

            1  Server Role (2=backup, 3=primary)

          "DnsDomain" (Windows 2000 only)

            1  Name
            2  Dns Domain Name
            3  Dns Forest Name
            4  Domain Guid
            5  Sid

      Returns 1.

    wntUserSidChk(i:request, s:SID, i:reserved-1, i:reserved-2, i:reserved-3)
      Checks SID's in an access token.

        This function checks whether the current user's access token
        contains a given SID.

        "request":

          Request   Meaning
          -------   -------
             0      Check if the specified SID is present and enabled in the token.

        "SID" specifies a security identifier, in string form (eg, "S-1-5-32-544",
        which is the well-known SID of the local Administrators group).

        The three "reserved" parameters should be set to 0.

      Returns @TRUE or @FALSE;

    wntAccessAdd2(s:server-name, s:resource/share-name, s:user/group name, i:object-type, s:access-string)
      Adds or updates access (permission) records for a resource.

        This function is like wntAccessAdd, but uses a different method of
        updating the access control list that may work better on Windows
        2000 machines.  It can also be used on Windows NT 4.0 machines.

    wntAuditAdd2(server-name, resource/share-name, user/group name, object-type, access-string)
      Adds audit records for a resource.

        This function is like wntAuditAdd, but uses a different method of
        updating the access control list that may work better on Windows
        2000 machines.  It can also be used on Windows NT 4.0 machines.

    wntEventLog(s:server-name, s:text)
      Writes a "WBMSG" entry to the NT application event log.

        "server-name" is the UNC name of the server on which the function
        will execute (eg, "\\MYSERVER"), or a blank string ("") to indicate
        the current machine.

        "text" is a string that will be stored with the event, or "" for none.

      This function will write an event with the message "WBMSG: xxx" to the
      NT application event log on the specified server, with "xxx" being
      replaced by the specified "text" string, and with an EventID of 1.

      This function will attempt to set the following values in the registry
      on the local machine, to specify the location of the message file:

        REGEDIT4
        [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\WBMSG]
        "EventMessageFile"="c:\\program files\\winbatch\\system\\wwwnt32i.dll"
        "TypesSupported"=dword:00000004

      If that key is not writable, or needs to be set on a remote machine,
      you will need to set those values manually before using this function.
      Note that the value "EventMessageFile" must be set to the full path of
      the Windows NT extender DLL.

      The message file is part of the extender DLL itself.  Since the Event
      Viewer locks and caches message files being used, you may need to
      close the Event Viewer before replacing or moving the extender DLL.

      Returns 1.

    wntGroupRen(s:server-name, s:group, i:group-type, s:new-name)
      Renames a group.

        "server" is the UNC name of the server on which the function will
        execute (eg, "\\MYSERVER"), or "" for the local computer.

        "group-type" can be @LOCALGROUP or @GLOBALGROUP.

        "new-name" specifies the new name for the group.

        Note: This function can only be performed by members of the
        Administrators or Account Operators local group.

        Returns 1.

  wntOwnerSet wasn't enabling the SE_RESTORE_NAME privilege to allow you to
  set ownership of an object to a different user.

  Fixed problem with wntUserAddDat("", "") not freeing some global memory.

  Fixed problem with wntUserAddDat possibly overwriting part of a different
  parameter value that had been previously set (with wntUserAddDat).

  Modified wntAccessAdd and wntAuditAdd to be more compatible with Windows
  2000 machines (also see new wntAccessAdd2 and wntAuditAdd2 functions).

  Added new predefined access strings for Windows 2000.  These are the same
  for files and directories:

    Access-string           Meaning          Specific equivalent
    --------------          --------------   -------------------
    "Win2000:Full"          Full Control     "0:3:2032127"
    "Win2000:Modify"        Modify           "0:3:1245631"
    "Win2000:ReadExecute"   Read & Execute   "0:3:1179817"
    "Win2000:List"          List             "0:2:1179817"
    "Win2000:Read"          Read             "0:3:1179785"
    "Win2000:Write"         Write            "0:3:1048854"
    "Win2000:None"          No Access        "1:3:983551"

  wntAccessList now returns a sorted list with no duplicate items.

  wntAccess[..], wntAudit[..], and wntShare[..] functions specifying a
  printer may have returned an "Access Denied" error, because they were
  trying to open the printer with an excessive level of access requested
  (especially under Windows 2000).

  wntPrivAdd and wntPrivDel may have failed with an "Access Denied" error
  because they were trying to open the policy object with an excessive level
  of access requested.

  Fixed problem with wntMemberLst2 returning users with blank names in local
  groups (ie, just "domain\").

  Changed wntServerInfo so that request #'s 1-4 can be called by any user.
  All other request #'s can can only be called by members of the
  Administrators or Account Operators local group, or those with
  Communication, Print, or Server operator group membership.

  Fixed a problem with wntMemberGrps that could have caused the script to
  hang if there were a very large number of groups that needed to be processed.

  Changed wntAccessAdd, wntAccessAdd2, wntAuditAdd, and wntAuditAdd2, so
  that if you specify one of the recursive object types (301, 302, 303, or
  401) and the function is unable to modify one of the objects it attempts,
  it will skip that object and continue, and won't return an error.  The
  function will return 0 if it was unable to modify an object.

  Fixed problem with wntRunAsUser with "allow interactive" flag set, where
  running an application could cause "abnormal termination" error.

  Added an additional flag to wntRunAsUser:

    Flag   Meaning
    ----   -------
      2    Load user profile into HKEY_USERS\

  Fixed problem with wntAcctPolGet and wntAcctPolSet, where request #3 was
  getting/setting the password age in seconds rather than days.

  The wntAccess[..] and wntAudit[..] functions have been improved to work
  better under Windows 2000.


Windows 95 extender 32000  First showing up in WB 2001B

  Fixed a problem with the following enumeration-type functions that could
  have caused the script to hang if there were a very large number of items
  (files or shares) that needed to be processed:

      w95FileClose
      w95FileUsers
      w95ShareList
      w95ShareUsers

    Note that these functions are limited to using 64K buffers.  If that is
    not sufficient to accomodate all items, some items will not be processed.

  Fixed a problem with w95AccessAdd and w95AccessDel not working with a
  remote machine.


Windows 9x extender 32000  First showing up in WB 2001B

  Fixed a problem with w9xMemberGrps that could have caused the script to
  hang if there were a very large number of groups that needed to be processed.


WILX extender 32000  First showing up in WB 2001B

  Removed xCursorSet (not useful in 32-bit versions of Windows).

  Removed xMemCompact (not useful in 32-bit versions of Windows).

  Fixed problem with xGetChildHwnd returning the wrong window handle if
  'child-text' was blank.

  xBaseConvert now properly handles numbers beginning with a leading '-' or
  '+' sign.


WB 2001C  Mar 5, 2001


DLL 3.2ccb  First showing up in WB 2001C

  Fixed a problem with the OK button in AskDirectory being disabled under
  Windows 2000.

  In OLE functions, fixed a problem handling VT_DATE values outside the
  range 1/1/1980 to 12/31/2099.

  RegQueryKeys no longer adds a tab to the end of the list.


Windows NT extender 32001  First showing up in WB 2001C

  Fixed a problem with the wntAccess[..] and wntAudit[..] functions
  returning an Access Denied error.

  Fixed a problem with wntAccess[..] crashing when specifying a file in a
  FAT paartition.


WB 2001D  Mar 6, 2001


Windows NT extender 32002  First showing up in WB 2001D

  Fixed a problem with wntAccessList and wntAuditList adding a tab to the
  end of the list.


WB 2001E  Mar 8, 2001


DLL 3.2ecb  First showing up in WB 2001E

  IniItemizePvt now supports itemizing the sections of Unicode INI files.


Windows NT extender 32003  First showing up in WB 2001E

  Fixed a problem with wntAccessDel and wntAuditDel crashing if the only
  access record for the object was being deleted.

  Fixed a problem with the wntAccess[..] and wntAudit[..] functions
  creating ACL's with access records that were incorrectly sequenced.


WB 2001F  Mar 15, 2001


DLL 3.3fcc  First showing up in WB 2001F

  In Windows 95/98, FILELISTBOX controls in dialogs no longer display files
  or directories marked as hidden or system, unless you first use
  IntControl(5) to enable that behavior.

  In Windows NT/2000, FILELISTBOX controls in dialogs now display files and
  directories marked as hidden or system, if you have first used
  IntControl(5) to enable that behavior.

  Fixed a problem with FILELISTBOX controls in dialogs not displaying
  directories beginning with a '.'.


WB 2001G  Mar 27, 2001

  Fixed a problem with BoxButtonWait failing to wait if you had pressed the
  same button twice without calling BoxButtonStat in between.

  Fixed a problem with areas of the Box windows not getting repainted
  properly when the windows were resized.

  Fixed a problem with OLE objects becoming invalid after being passed as
  parameters to OLE methods or properties.

  In FileMenu, the functions FileItemize(""), FileItemPath(""), and
  DirItemize("") no longer add a trailing delimiter to the list.


DLL 3.3gcc  First showing up in WB 2001G

  Fixed a problem where the floating point number 0.0 was being displayed in
  scientific notation.

  Fixed a problem with IniItemizePvt returning an extra item with stray
  characters when itemizing sections in the file, if the file was over 32K.

  Fixed a problem with the parameter of a Return statement being validated
  even if the Return was in a conditional block that wasn't being executed.

  Fixed a problem with ItemInsert, ItemRemove, and ItemReplace removing
  blank items at the end of the list.

  Fixed a problem with ItemInsert inserting an item at the wrong position if
  it were being inserted between blank items at the end of the list.

  Fixed a problem with ItemReplace not replacing an item following a blank
  item at the end of the list.

  Fixed a problem with ItemSort removing blank items from the list.


Windows NT extender 33001  First showing up in WB 2001G

  Fixed a problem with wntServerList hanging if the list of servers returned
  was larger than 64K.


Windows 9x extender 33001  First showing up in WB 2001G

  Fixed a problem with w9xServerList hanging if the list of servers returned
  was larger than 64K.


WB 2001H  Apr 2, 2001

  Fixed a problem with the compiler not being able to compile extenders into
  a large EXE (introduced in 2001G).


Windows NT extender 33002  First showing up in WB 2001H

  The wntPriv[..] functions can now be used on a local workstation for
  domain accounts, by specifying the user/group name in the form
  "domain_name\account_name".  Note that wntPrivAdd and wntPrivDel require
  administrator privileges on the local workstation.

  Fixed a problem with the wntShare[..] functions failing with "access
  denied" errors when the target object was a printer.


WB 2001J  May 25, 2001

  New functions, only when running as a service:

    SvcSetAccept(i:codes)
      Specifies the control codes that the service will accept.

        "codes" can be 0 to specify that no, or it can be one or more of the following control
        codes, combined using the bitwise OR ('|') operator:

          Value  Controls accepted              Meaning
          -----  -----------------              -------
              1  SERVICE_ACCEPT_STOP            The service can be stopped
              2  SERVICE_ACCEPT_PAUSE_CONTINUE  The service can be paused and continued
              4  SERVICE_ACCEPT_SHUTDOWN        The service is notified when system shutdown occurs
          32768                                 Notify of logoffs.

      By default, a WinBatch service will accept and automatically process
      SERVICE_CONTROL_STOP commands.  If you use the SvcSetAccept function,
      you will be responsible for processing any of the control codes that
      are received, including SERVICE_CONTROL_STOP (ie, it will no longer
      be processed automatically).

      Returns the previous value for "codes", or -1 if not running as a service.

      See also SvcSetState and SvcWaitForCmd.

    SvcSetState(i:state)
      Updates the service control manager's status information for the service.

        "state" can be one of the following service states:

          Value  Service state             Meaning
          -----  ------------              -------
            1    SERVICE_STOPPED           The service is not running
            3    SERVICE_STOP_PENDING      The service is stopping
            4    SERVICE_RUNNING           The service is running
            5    SERVICE_CONTINUE_PENDING  The service continue is pending
            6    SERVICE_PAUSE_PENDING     The service pause is pending
            7    SERVICE_PAUSED            The service is paused

      Returns the previous state, or -1 if not running as a service.

      See also SvcSetAccept and SvcWaitForCmd.

    SvcWaitForCmd(i:timeout)
      Waits or checks for receipt of a service control code.

        "timeout" specifies the timeout flag, in milliseconds.

      If any control codes have been received but not yet processed (using
      this function), this function immediately returns the value of that
      control code.  WinBatch maintains a list of up to 16 unprocessed
      control codes that have been received, and this function returns the
      first (oldest) one in the list, then clears that code from the list,
      so the next time this function is called it will return the next
      control code in the list, if any.

      If there are no unprocessed control codes in the list, the behavior
      depends on the value specified by "timeout".  If "timeout" is -1, the
      function will wait until a control code is received, and then return
      its value.  If "timeout" is 0, the function will immediately return a
      value of 0.  If "timeout" is any other value, then it specifies a
      timeout period (in milliseconds), and the function will wait until
      a control code is received or until the timeout period elapses,
      whichever comes first.  If a control code is received before the
      timeout period elapses, the function will return its value, otherwise
      it will time out and return 0 indicating no control code was received.

      The following control codes may be returned:

          Value  Control code              Meaning
          -----  ------------              -------
              1  SERVICE_CONTROL_STOP      Requests the service to stop
              2  SERVICE_CONTROL_PAUSE     Requests the service to pause
              3  SERVICE_CONTROL_CONTINUE  Requests the paused service to resume
              5  SERVICE_CONTROL_SHUTDOWN  Requests the service to perform cleanup tasks, because the system is shutting down
        128-255                            User-defined control code
          32768                            Logoff notification

      Returns 0 or a control code value, or -1 if not running as a service.

      See also SvcSetState and SvcWaitForCmd.

  The compiler now properly handles "#include" directives with leading
  whitespace (ie, indented with spaces or tabs).

  The compiler now properly handles double byte characters in the
  customizable version strings.


DLL 3.3jcc  First showing up in WB 2001J

  New IntControl:

    IntControl(79, p1, p2, p3, 0)
      Causes a user-defined error.

        P1 = severity, which can be one of the following:

          -1  minor error
          -2  moderate error
          -3  severe error

        P2 = error code, which must be a number between 7000 and 7999.

        P3 = error message, which is a string describing the error.

      Returns 1.

  Fixed a problem with Arrayize crashing with large lists.

  In ItemLocate you can now specify a delimiter of "" to indicate a tab.

  Fixed a problem with Drop not returning a value.  It now returns 1, as
  documented.

  Fixed a problem with AppExist no longer working after being called
  thousands of times.

  The Print command now ignores the "waitflag" parameter, as documented.

  Fixed a problem converting strings like "-.2", where a signed floating
  point decimal value did not have a 0 before the decimal point.

  Fixed a problem handling OLE object names longer than 30 characters where
  the variable name (the part before the '.') contained an underscore.

  ShortcutDir now supports registry strings of type REG_EXPAND_SZ.

  Increased the maximum number of open OLE objects from 20 to 128.


Windows NT extender 33003  First showing up in WB 2001J

  New functions:

    wntAccessMod(server-name, resource, object-type, request, flags)
    wntAuditMod(server-name, resource, object-type, request, flags)

      server-name:

        Same as "server-name" as used in wntAccessAdd() and wntAuditAdd()

      resource:

        For object type 300, a file or folder specified with either a drive
        letter specification or a UNC specification.

        For object type 400, a registry handle that points to
        an open registry key.

      object-type:

        300   file [either a drive letter or a UNC spec]
        400   registry key handle [for a local registry key]

        No other object types are valid with wntAccessMod() and wntAuditMod().

        Please note that registry key handles must have been obtained by opening
        a registry key on the local system.  Registry key handles for registry
        keys on remote systems cannot be processed by this function.  Attempting
        to modify the ACL inheritance flags for a remote registry key will result
        in an error being returned.

      request:

        1     For WinNT, remove all explicit ACEs from all child objects [e.g
              subfolders & files or subkeys] and then re-propagate all inheritable
              ACEs from the specified folder or key to all child objects under the
              specified folder or key.  In effect, this resets the security on a
              tree of folders & files or subkeys and makes it consistent with  the
              DACL or SACL settings of the parent folder at the root of that branch
              of the folder hierarchy on a volume or a branch of the registry.

              For Win2K, re-enable either DACL or SACL inheritance on all child
              objects, remove all explicitly assigned ACEs on all child objects
              then re-propagate all inheritable ACEs to all child objects.

        2     For Win2K only, disable either DACL or SACL inheritance on the specified
              object.  If Bit 0 in the flags mask is clear then all currently inherited
              ACEs will be converted to explicit ACEs.  If Bit 0 in the flags mask is
              set then all currently inherited ACEs will be removed.  All child objects
              will have their DACLs or SACLs updated as necessary to reflect the possible
              changes in their parent object's DACL or SACL w/respect to inheritable ACE
              changes.

        3     For Win2K only, re-enable either DACL or SACL inheritance on the specified
              object.  If Bit 0 in the flags mask is clear then all explicitly asisgned
              ACEs will be kept.  If Bit 0 in the flags mask is set then all explicity
              assigned ACEs will be removed.  All child objects will have their DACLs or
              SACLs updated as necessary to reflect the possible changes in their parent
              object's DACL or SACL w/respect to inheritable ACE changes.

              Please note that Request #3 cannot be used with the root folder of
              a network drive letter that is connected to a share that does not
              share out the root of a physical drive letter.  The reason for this
              is that it is impossible to get the DACL or SACL from the specified
              folder's parent in order to determine if the specified folder should
              inherit any inheritable ACEs from the parent folder's DACL or SACL.
              This same problem will occur if a UNC specification is passed in and
              the UNC spec only contains the server and share information [e.g. no
              subfolder information] and the share does not share the root of a
              physical disk drive on the server.  Attempting to re-enable the ACL
              inheritance for either the DACL or SACL of a folder whose parent
              folder cannot be accessed will result in an error being generated.

              For example, we have a workstation computer named WS1 and server named
              SRV1.  Server SRV1 has a local drive named D: and there is a user share
              named JOHN_DOE that shares out the directory D:\HOME\JOHN_DOE.  If the
              user "johndoe" logs in on WS1 and connects the drive letter H: to the
              share \\SRV1\JOHN_DOE and then tries to use wntAccessMod() with request
              #3 and passes in "H:\" as the value for "resource" then the function
              will return an error.  The reason for this is that it is impossible for
              wntAccessMod() [being executed in a script on WS1] to get the DACL of
              the folder "D:\HOME" on SRV1.  If the DACL of "D:\HOME" on SRV1 is not
              obtainable then wntAccessMod() cannot determine if there any ACEs in
              the DACL of "D:\HOME" on SRV1 that are inheritable by "D:\HOME\JOHN_DOE"
              and thus need to be propagated to the DACL of "D:\HOME\JOHN_DOE".  This
              same problem would occur if the value of "resource" had been specified
              as "\\SRV1\JOHN_DOE" [as opposed to something like "H:\FOLDER1" or
              "\\SRV1\JOHN_DOE\FOLDER1", both of which would be OK because the parent
              of "FOLDER1" could be accessed to find inheritable ACEs to add to the
              DACL or SACL of "FOLDER1"].

      flags:

        This is a bit masked integer value.  The effects caused by having various
        bits set or cleared varies with the particular request # that has been
        specified.  Refer to the documentation of the various request #'s in order
        to determine which flags values are valid in any particular situation.

  wntMemberList() now accepts an optional parameter to allow members of
  local groups to be returned with domain and/or server information (as a
  prefix before the user/group name, e.g. "domain\user",
  "domain\global-group" or "server\user").

  Improved support for managing permissions and auditing of printer objects
  (e.g. traditionally called "printers") and printer shares, and added new
  pre-defined access strings for printer objects and printer shares.

  wntMemberList now properly returns domain names and/or server names for
  standalone systems and workstations.

  wntAccess[..] and wntAudit[..] functions specifying a registry key may
  have returned an "Access Denied" error, because they were trying to open
  the key with an excessive level of access requested.

  Fixed a problem with the wntShare[..] functions, where specifying a
  printer name or printer share as "resource/share-name" didn't work
  properly.


Windows 9x extender 33003  First showing up in WB 2001J

  Fixed a problem with the w9xShare[..] functions, where specifying a
  printer name or printer share as "resource/share-name" didn't work
  properly.


WB 2001K  Jun 1, 2001

  Changed SvcWaitForCmd to use less CPU time.


WB 2001M  Aug 8, 2001

  BoxesUp was returning positive values on success, other than @TRUE.


DLL 3.3mcc  First showing up in WB 2001M

  New function:

    DllLastError()
      Returns the most recent error returned by a DllCall to a Win32 API.

        If you call this function after using DllCall to call a Win32 API
        function which set a "last-error code" value (or another function
        which used the "SetLastError" API to set a last-error code), this
        function will return that value.

        Returns an integer.

  Decimals() was not returning the previous setting.

  IntControl 56 could not be used to kill a service.

  BinaryPeekStr no longer returns an error if "offset" is within the binary
  buffer but "offset + maxsize" is past the end of the binary buffer.

  Statements such as "If x" and "While x", where 'x' is a floating point
  number that is too large or small to convert to an integer, no longer
  return an error.

  Fixed a problem with the Run[..] commands crashing with very long command
  lines.

  Fixed problem with Arrayize with large lists.

  IntControl 45 is now enabled for Windows 95/98/ME, which should result in
  faster SendKey and SendKeysTo to DOS windows on those platforms.  This
  functionality is now the same on all Windows platforms.  If the "SendKey
  speedup" causes a problem, you can turn it off with IntControl(45,0,0,0,0).

  In ArrInitialize, "value" may now be an integer, floating point, or string.

  Fixed problem with Debug and DebugTrace displaying an incorrect result on
  a line of the form "If ... Then Call(...)".

  Fixed problem with DebugTrace causing an "Unrecognised Request" error in
  WIL applications other than WinBatch.


Windows NT extender 33005  First showing up in WB 2001M

  New function:

    wntSecurityGet(server-name, resource, object-type, request, flags)

      server-name:

        Same as "server-name" as used in wntAccessAdd() and wntAuditAdd()

      resource:

        For object type 300, a file or folder specified with either a drive
        letter specification or a UNC specification.

        For object type 400, a registry handle that points to
        an open registry key.

      object-type:

        300   file [either a drive letter or a UNC spec]
        400   registry key handle [for a local registry key]

        No other object types are valid with wntAccessQuery() and wntAuditQuery().

      request:

        1     For Win2K, return @TRUE if the specified object has the protected [D|S]ACL flag
              set.  Please note that top level registry keys and root folders on
              NTFS volumes will generally have this flag enabled, but their children will have
              this flag disabled.  A protected DACL or SACL means that ACEs may not be inherited
              from the object's parent.

              If Bit 0 in the flags mask is clear then the permission [e.g. DACL] protected
              flag value will be queried.

              If Bit 0 in the flags mask is set then the audit [e.g. SACL] protected flag
              value will be queried.

              For WinNT this function will always return @FALSE since ACL inheritance is not
              implemented on WinNT and thus the concept of a protected DACL/SACL does not exist
              on WinNT.


        2     For Win2K, return @TRUE if the specified object has a [D|S]ACL that is marked as
              having been auto-inherited from the object's parent.

              If Bit 0 in the flags mask is clear then the permission [e.g. DACL] auto-inherited
              flag value will be queried.

              If Bit 0 in the flags mask is set then the audit [e.g. SACL] auto-inherited flag
              value will be queried.

              For WinNT this function will always return @FALSE since ACL inheritance is not
              implemented on WinNT and thus the concept of an auto-inherited DACL/SACL does not
              exist on WinNT.


        3     For both WinNT and Win2K, return @TRUE if the specified object has a [D|S]ACL present.

              If Bit 0 in the flags mask is clear then the permission [e.g. DACL] presence flag
              value will be queried.

              If Bit 0 in the flags mask is set then the audit [e.g. SACL] presence flag value
              will be queried.


        4     For both WinNT and Win2K, return @TRUE if the specified object has a default [D|S]ACL.

              If Bit 0 in the flags mask is clear then the permission [e.g. DACL] defaulted flag
              value will be queried.

              If Bit 0 in the flags mask is set then the audit [e.g. SACL] defaulted flag value
              will be queried.


        5     For both WinNT and Win2K, return the number of ACEs present in the [D|S]ACL.  If there
              is no [D|S]ACL present then zero (0) will be returned.

              If Bit 0 in the flags mask is clear then the # of ACEs in the permission list [e.g. DACL]
              will be returned.

              If Bit 0 in the flags mask is set then the # of ACEs in the audit list [e.g. SACL] will be
              returned.


        6     For both WinNT and Win2K, return the number of bytes that are free in the [D|S]ACL.  If
              there is no [D|S]ACL present then zero (0) will be returned.

              If Bit 0 in the flags mask is clear then the # of free bytes in the permission list [e.g.
              DACL] will be returned.

              If Bit 0 in the flags mask is set then the # of free bytes in the audit list [e.g. SACL]
              will be returned.


        7     For both WinNT and Win2K, return the number of bytes that are used in the [D|S]ACL.  If
              there is no [D|S]ACL present then the value that will be returned will be the # of bytes
              that are required to store an ACL structure with zero ACEs in it.

              If Bit 0 in the flags mask is clear then the # of used bytes in the permission list [e.g.
              DACL] will be returned.

              If Bit 0 in the flags mask is set then the # of used bytes in the audit list [e.g. SACL]
              will be returned.


        8     For both WinNT and Win2K, return @TRUE if the group SID value associated with the
              ownership of the object has been supplied through some default mechanism instead
              of having been directly assigned to the object.

              The flags mask value is ignored for this request number.


        9     For both WinNT and Win2K, return @TRUE if the owner SID value associated with the
              ownership of the object has been supplied through some default mechanism instead
              of having been directly assigned to the object.

              The flags mask value is ignored for this request number.

      flags:

        This is a bit masked integer value.  The effects caused by having various
        bits set or cleared varies with the particular request # that has been
        specified.  Refer to the documentation of the various request #'s in order
        to determine which flags values are valid in any particular situation.

  wntAccessMod and wntAuditMod now support registry keys (object type 400)
  on the local system.

  Improved the way the wntAccess[..] and wntAudit[..] functions handle
  registry key branches (object type 401), to solve "Access Denied" errors.

  wntAccessAdd2 and wntAuditAdd2 have been removed.

  Fixed problem accepting the group name "Everyone" as a parameter on
  non-English versions of Windows.


WB 2001N  Aug 31, 2001

  Fixed a resource (handle) leak in SvcWaitForCmd.


DLL 3.3ncc  First showing up in WB 2001N

  BinaryPeekStr now returns a blank string instead of an error if "offset"
  is set to the binary EOD and "maxsize" is 0.

  Fixed a problem with DirSize crashing with excessively long (illegal)
  directory names.  It now ignores (skips) invalid directory names.

  Fixed a problem with ShortcutInfo returning an invalid value for "hotkey"
  if the shortcut had a non-blank description and did not have a hotkey set.

  In ShortcutEdit, you can now specify "-1" for "target", "params", or
  "start-dir" to set NULL values.

  In ShortcutExtra, you can now specify "-1" for "description", "hotkey", or
  "icon-file" to set NULL values.

  In IntControl 34, if you specify -1 for "p1" it will return the string
  corresponding to the last extender error or user-defined error.

  New parameter type "huge number", used by several functions (below).  This
  is a long decimal number string, which may represent a number too large to
  be converted to an integer.  If the number is larger than 2147483647, it
  must be a string.

  Added an optional "format" parameter to DirSize, FileSize, and FileSizeEx:

      DirSize(dir-name, flags [, format])
      FileSize(file-list [, format])
      FileSizeEx(file-list [, format])

    This controls the format in which the size is returned if it is too large
    to be returned as an integer.  The default format, 0, is floating point.
    If you specify "format" of 1, the size will be returned as a huge number.

  BinaryReadEx and BinaryWriteEx now accept a huge number for "file-offset".

  In a Switch statement, a "Case" keyword followed by an invalid expression
  will now cause an error.


WB 2001P  Dec 10, 2001

  Changed the type of icons used by the compiler.  If you are specifying
  custom icons for your compiled EXE's, you should change them to the new
  format, which is an icon group consisting of 6 icon bitmaps:

    16x16,  16 colors
    16x16, 256 colors
    32x32,  16 colors
    32x32, 256 colors
    48x48,  16 colors
    48x48, 256 colors


DLL 3.4pcd  First showing up in WB 2001P

  New function:

    RunWithLogon(s:program-name, s:params, s:directory, i:display mode, i:waitflag, s:username, s:domain, s:password, i:logon-flags) (Windows 2000/XP only)
      Runs a program as a specified user

        "username" specifies the name of the user account to log on to.  If
        you use the UPN format (user@DNS_domain_name), "domain" must be a
        blank string ("").

        "domain" specifies the name of the domain or server whose account
        database contains the "username" account. If this parameter is a
        blank string, "username" must be specified in UPN format.

          Windows XP: If "domain" is ".", the function validates the account
          using only the local account database.

        "password" specifies the password for the "username" account.

        "logon-flags" can be 0, or one of the following values:

          Value  Name                       Meaning
          -----  ----                       -------
            1    LOGON_WITH_PROFILE         Log on, then load the user's profile. Loading the profile
                                            can be time-consuming, so it is best to use this value
                                            only if you must access the user's profile information.

            2    LOGON_NETCREDENTIALS_ONLY  Log on, but use the specified credentials on the
                                            network only. This value can be used to create a process
                                            that uses a different set of credentials locally than it
                                            does remotely. This is useful in inter-domain scenarios
                                            where there is no trust relationship.

      See RunShell for additional information.

  IsDefined and VarType now return -1 (instead of an error) if the specified
  name is a function name or other reserved word.

  New data types for BinaryOleType:

    3  byte array  (VT_UI1 | VT_ARRAY)
    4  I1  pointer (VT_I1 | VT_BYREF)
    5  I2  pointer (VT_I2 | VT_BYREF)
    6  I4  pointer (VT_I4 | VT_BYREF)
    7  UI1 pointer (VT_UI1 | VT_BYREF)
    8  UI2 pointer (VT_UI2 | VT_BYREF)
    9  UI4 pointer (VT_UI4 | VT_BYREF)

  Added support for OLE functions that return byte arrays (variant type =
  VT_UI1 | VT_ARRAY).  In this case, the function will copy the data to a
  newly-allocated binary buffer of the required size, with the binary EOD
  properly set, and the return value will be the binary buffer handle.
  The user is responsible for freeing this binary buffer.

  BinaryReadEx was returning 1 instead of 0 for a 0-byte file.

  If the following clipboard functions are unable to open the clipboard,
  they will now retry for up to 30 seconds:

    BinaryClipGet
    BinaryClipPut
    ClipAppend
    ClipGet
    ClipGetEx
    ClipHasFormat
    ClipPut
    SnapShot

  Added support for OLE variant types VT_I1, VT_UI1, VT_UI2, and VT_UI4.

  Fixed a problem with BinaryReplace replacing text past the binary EOD.

  Fixed a problem with the following functions crashing if the space bar and
  Esc keys were pressed simultaneously:

    AskFileText
    AskItemList
    AskTextBox
    ItemSelect
    TextBox
    TextBoxSort
    TextSelect

  In FileVerInfo, if you specify a blank string for "language-key" it will
  now additionally try to look up the item under the language key
  "000004B0" (Neutral, Unicode).

  Added two optional parameters to ShortcutDir:

    ShortcutDir(s:name [, i:source [, i:add-slash]])

      "source" specifies the location from which the information will be
      retrieved:

        source  location
        ------  --------
           0    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders (default)
           1    HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders

      "add-slash": if @TRUE, a backslash will be appended to the returned
      string if it doesn't already have a trailing backslash.  The default
      is @FALSE.

  Added a new request # to DirWindows:

    2 = shared Windows directory on a multi-user system (Windows 2000 and XP only).

      On other versions of Windows, this will return the same value as request 0.

  Fixed a problem with the StrFix[..] functions with "length" > 64K.

  Changed the behavior of IconReplace and IntControl(37).  Instead of
  replacing an individual icon image in an EXE file, they now replace
  multiple images in an icon group in an EXE file.  An icon group is a set
  of one or more associated icon images, of different dimensions and color
  depths.  An EXE file can contain multiple icon groups; an icon (.ICO) file
  contains a single icon group.  The difference betwwen the two functions is
  that IconReplace will modify the first icon group in the EXE, while
  IntControl(37) lets you specify which icon group to modify.  The "p3"
  parameter in IntControl(37) now specifies the ordinal position of the icon
  group to modify.  In both cases, each icon image in the targeted icon
  group in the EXE file is compared with each icon image in the specified
  .ICO file, and if the .ICO file contains an icon image whose size (and
  dimensions and color depth) is the same as the targeted icon image in the
  EXE, then the targeted icon image in the EXE is replaced with the
  corresponding icon image from the .ICO file.  If no suitable replacement
  icon is found in the .ICO file, then that particular icon image in the EXE
  is left unchanged.  The return value of the function is the number of
  icon images in the EXE that were successfully replaced.

  Added an additional optional parameter to the following shortcut functions:

      ShortcutEdit(link-name, target, params, start-dir, show-mode [, i:shortcut-type])
      ShortcutExtra(link-name, description, hotkey, icon-file, icon-index [, i:shortcut-type])
      ShortcutInfo(link-name [, i:shortcut-type])
      ShortcutMake(link-name, target, params, start-dir, show-mode [, i:shortcut-type])

    "shortcut-type" specifies the type of shortcut, and can be one of the following:

      Type  Meaning
      ----  -------
        0   Normal shortcut (default)
        1   Folder shortcut (Windows 2000/XP only)

    An extension of ".LNK" is assumed for "link-name" for normal shortcuts,
    but not for folder shortcuts.

  In AskFileName, if you specify a blank string ("") for "directory", the
  current working directory will be used.


Windows NT extender 34005  First showing up in WB 2001P

  New function:

    wntLastErrMsg()
      Retrieves the error message text for an extender error.

  Fixed problem with wntShareAdd under non-English versions of
  WinNT/Win2K.

  wntAccessList and wntAuditList now strip off the domain
  "NT AUTHORITY\".

  Added a new optional flag parameter to wnt[Access|Audit][Add|Del|Get].

  Added new flags to wnt[Access|Audit]List.

  Added a new request number (#2) to wntAcctInfo.

  Added a new optional flags parameter to wntAcctInfo.

  Changed wntOwnerSet so that if the 'account-name' parameter's value is an
  empty string [e.g. ""], then the current user's account-name will be used
  as the value for this parameter.

  Improved/corrected the way wntOwnerSet handles folder/file and registry
  key objects under Win2K.

  Changed the flags that are valid for wntOwnerGet.

  Added a new optional flags parameter to wntOwnerSet.

  Added a flag to enable the display of a progress dialog box for
  wnt[Access|Audit][Add|Del|Mod] and wntOwnerSet.

  wntOwnerSet can now perform recursive processing of an entire folder &
  file hierarchy or a branch of the registry, by specifying new object types
  301, 302, 303 and 401.

  wntOwnerGet and wntOwnerSet now support printer objects [object-type =
  200].

  Improved the way wnt[Access|Audit][Add|Del|Mod] and wntOwnerSet handle
  excessively long path names for recursive file object types 301, 302, and
  303.

  wntLsaPolGet and wntLsaPolSet now support named LSA Private Data Objects,
  using the new class name "PrivateData".

  Changed wnt[Access|Audit][Add|Del], wntAccessMod, and wntOwnerSet so that
  recursive operation failures that used to return an error 575 now return 0
  instead.

  Fixed a problem with wntRunAsUser with flag 1 hanging under Windows XP.

  Fixed problem with DLL not loading on NT 3.51.

  For wntShutdown, you can now specify a "timeout" of -1 to indicate that a
  time delayed shutdown request should be aborted, provided that the time
  delay has not already expired.


WB 2002A  Dec 24, 2001

  Added warning message to compiler when attempting to use an improper
  icon.

  Fixed problem in Winbatch Studio with new BinaryBuffer/Array views.


WB 2002B  Jan 22, 2002

  New function:

    BoxBitmap(box ID, coordinates, filename, stretch-mode)
      Displays a bitmap in a WinBatch box.

        (s) "filename" specifies the name of a BMP file.

        (i) stretch-mode specifies the mode to use when resizing the bitmap,
        and can be one of the following:

          Value  Name          Meaning
          -----  ----          -------
            1    BLACKONWHITE  Performs a Boolean AND operation using the color values for the
                               eliminated and existing pixels.  If the bitmap is a monochrome bitmap,
                               this mode preserves black pixels at the expense of white pixels.

            2    WHITEONBLACK  Performs a Boolean OR operation using the color values for the
                               eliminated and existing pixels.  If the bitmap is a monochrome bitmap,
                               this mode preserves white pixels at the expense of black pixels.

            3    COLORONCOLOR  Deletes the pixels.  This mode deletes all eliminated lines of pixels
                               without trying to preserve their information.

            4    HALFTONE      Maps pixels from the source rectangle into blocks of pixels in the
                               destination rectangle.  The average color over the destination block
                               of pixels approximates the color of the source pixels.  Supported on
                               Windows NT/2000/XP only.

          The stretching mode defines how the system combines rows or
          columns of a bitmap with existing pixels.  The BLACKONWHITE and
          WHITEONBLACK modes are typically used to preserve foreground
          pixels in monochrome bitmaps.  The COLORONCOLOR mode is typically
          used to preserve color in color bitmaps.  The HALFTONE mode is
          slower and requires more processing of the source image than the
          other three modes, but produces higher quality images.


DLL 3.5bcd  First showing up in WB 2002B

  New IntControl:

    IntControl(80, 0, 0, 0, 0)
      Waits until no keys on the keyboard are pressed.

        Returns 1.

  IgnoreInput is now supported on Windows 98/ME/2000/XP.  It will return -1
  if run on an unsupported platform.  Also you can now specify a "flag" of
  -1 to query the current state.

  Fixed problem with ArrInitialize not freeing any previous string values in
  the array.

  Added additional special characters to the SendKey (and SendKeysTo and
  SendKeysChild) functions.  These may or may not work for any particular
  application or situation:

      Key                              SendKey equivalent
      ---                              ------------------
      Print Screen                     {PRTSC}

      Left Alt key, standalone         {LALT}
      Right Alt key, standalone        {RALT}
      Left Control key, standalone     {LCONTROL}
      Right Control key, standalone    {RCONTROL}
      Left Shift key, standalone       {LSHIFT}
      Right Shift key, standalone      {RSHIFT}
      Left Windows key, standalone     {LWIN}
      Right Windows key, standalone    {RWIN}
      Applications key, standalone     {APPS}

      Left Alt key, combination        {*LALT}
      Right Alt key, combination       {*RALT}
      Left Control key, combination    {*LCONTROL}
      Right Control key, combination   {*RCONTROL}
      Left Shift key, combination      {*LSHIFT}
      Right Shift key, combination     {*RSHIFT}
      Left Windows key, combination    {*LWIN}
      Right Windows key, combination   {*RWIN}
      Applications key, combination    {*APPS}

    "Standalone" means the key is pressed and then released.  "Combination"
    means the key is held down while the following key is pressed.

    The left and right Alt, Control, and Shift keys can only be
    distinguished on Windows NT/2000/XP.  On other platforms they are
    treated as plain Alt, Control, and Shift keys, respectively.

    The "Windows" and "Applications" keys are on the Microsoft Natural
    keyboaard.

  Fixed a problem with empty WIL scripts causing an error, especially under
  Windows XP.

  Added an optional "format" parameter to DiskFree and DiskSize:

      DiskFree(drive-list [, format])
      DiskSize(drive-list [, format])

    This controls the format in which the size is returned if it is too large
    to be returned as an integer.  The default format, 0, is floating point.
    If you specify "format" of 1, the size will be returned as a huge number.

  Changed error 3385 ("DiskExist: Invalid Disk Argument") to 1385.


Windows NT extender 35001  First showing up in WB 2002B

  New functions:

    wntPrivUsers(server-name, privilege[, output-format-flag])

      This function accepts a privilege name as input and returns a list of
      account names [or SID strings] that have been granted that privilege.

    wntSvcList(server-name, service/group-name, flags)

      This function allows services to be listed.  On Win2K [and newer]
      systems, it is possible to selectively list services based on the
      groups to which they belong, based on the service type, and based on
      the service status.  On WinNT [and newer] systems it is possible to
      list services based on service types and service status.  On WinNT
      [and newer] systems it is possible to list all services [by type and
      status] that are dependent on a specified service.

  The following functions can now accept SID strings in place of group
  names.  They can also return SID strings in place of account names for
  either all SIDs or only for SIDs that cannot be resolved to account names:

      wntMemberDel
      wntMemberGet
      wntMemberGrps
      wntMemberList
      wntMemberSet
      wntGroupDel
      wntGroupEdit
      wntGroupInfo
      wntGroupRen
      wntListGroups
      wntPrivAdd
      wntPrivDel
      wntPrivGet
      wntPrivList
      wntRasUserGet
      wntRasUserSet
      wntUserDel
      wntUserExist
      wntUserGetDat
      wntUserList
      wntUserProps
      wntUserSetDat
      wntUserRename
      wntWtsUserGet
      wntWtsUserSet

  The following functions now accept 2 new object types, 500 and 501:

      wntAccessAdd
      wntAccessDel
      wntAccessGet
      wntAccessList
      wntAuditAdd
      wntAuditDel
      wntAuditGet
      wntAuditList

    Object type 500 is for window station objects and object type 501 is for
    desktop objects.  It is now possible to manipulate the security settings
    on window stations and desktops.  Currently there is no function to
    list/enumerate window stations and desktop on the system, so you have to
    already know the name of the window station &| desktop that you want to
    manipulate.  The default window station associated the keyboard, monitor &
    mouse [e.g. the console window station] is "WinSta0".  The default desktop
    on the console window station named "Default", and it is referred to as
    "WinSta0\Default".  All desktop objects must have their corresponding
    window station name prefixed onto them so that the format of the name is
    "window-station\desktop".

  The functions wntSvcCfgGet() and wntSvcCfgSet() have been modified.  On
  Win2K [and newer systems] they are now capable of getting & setting
  service descriptions and service failure recovery settings.


WB 2002E  Jul 5, 2002

  If you use IntControl 1007 to add an icon to the system tray, and also use
  IntControl 12 to prevent the script from being terminated, attempting to
  terminate the script no longer removes the icon from the system tray.


DLL 3.6ecg  First showing up in WB 2002E

  New functions:

    SysParamInfo(i:request, s/i:value, i:ini-update)
      Gets or sets system informtion.

      This function is like WinParmGet and WinParmSet, but has support for
      many more parameter types.  See WIL help file for documentation.

    ObjectCollectionOpen(i:object-handle)
      Initializes enumeration of an OLE collection object.

        "object-handle" specifies the handle of an OLE object that
        represents a collection of variants, and which supports
        enumeration via the IEnumVARIANT interface.

      This function returns an enumeration handle, which can be used by the
      ObjectCollectionNext function to return items in the collection, one
      at a time.  When you have finished enumeration, use the
      ObjectCollectionClose function to release the enumeration handle.

    ObjectCollectionNext(i:enumeration-handle)
      Continues enumeration of an OLE collection object.

        "enumeration-handle" specifies an enumeration handle returned by
        ObjectCollectionOpen.

      Each time this function is called, it returns an OLE object handle
      representing the next item in the collection.  When enumeration is
      complete, it returns 0 (ie, a NULL object handle).

      Example:
        objFSO = ObjectOpen("Scripting.FilesystemObject")
        objDrives = objFSO.Drives
        hEnum = ObjectCollectionOpen(objDrives)
        While 1
          objDrive = ObjectCollectionNext(hEnum)
          If objDrive == 0 Then Break
          Message("", objDrive.Path)
          ObjectClose(objDrive)
        EndWhile
        ObjectCollectionClose(hEnum)
        ObjectClose(objDrives)
        ObjectClose(objFSO)

    ObjectCollectionClose(i:enumeration-handle)
      Ends enumeration of an OLE collection object.

        "enumeration-handle" specifies an enumeration handle returned by
        ObjectCollectionOpen.

      Returns 0.

    AskColor(s:default-color, s:reg-key, i:format)
      Displays a color selection dialog box, and returns the selected color.

        "default-color" specifies an RGB color value in the form "#RRGGBB",
        where "RR" is the red component in hex (00-FF), "GG" is the green
        component in hex (00-FF), and "BB" is the blue component in hex
        (00-FF).  This will be the color initially selected in the dialog.
        You may specify "" for a default of gray.

        "reg-key" specifies the name of a user-defined registry key under
        "HKEY_CURRENT_USER\Software\Wilson WindowWare" where persistent
        state information will be stored.  It will be created if it does not
        already exist.  If "" is specified, persistent state information
        will not be stored.

        "format" specifies the format in which the selected color will be
        returned:

          Format   Meaning
          ------   -------
             0     RGB color value in the form "#RRGGBB" (see above).

             1     RGB color value in the form "R|G|B", where "R", "G", and
                   "B" are the respective red, green, and blue components,
                   in decimal.

    AskFont(i:type, i:flags, s:reg-key, i:format)
      Displays a font selection dialog box, and returns information on the selected font.

        "type" specifies the type of fonts to be listed, and can be one of
        the following values:

          Value   Meaning
          -----   -------
            0     Screen fonts
            1     Printer fonts
            2     Both screen and printer fonts

          If "type" is 1 or 2, a default printer must be installed,
          otherwise an error will occur.

        "flags" restricts the fonts that are listed, and can be 0 or more of
        the following values combined with the bitwise OR ('|') operator:

          Value   Meaning
          -----   -------
            1     List only script fonts (exclude OEM and Symbol character sets)
            2     List only non-vector fonts
            4     List only fixed-pitch fonts
            8     List only fonts available on both the printer and the display
           16     List only scalable fonts
           32     List only TrueType fonts
           64     List only horizontally oriented fonts

          If flag 8 is specified, "type" will automatically be set to 2.

        "reg-key" specifies the name of a user-defined registry key under
        "HKEY_CURRENT_USER\Software\Wilson WindowWare" where persistent
        state information will be stored.  It will be created if it does not
        already exist.  If "" is specified, persistent state information
        will not be stored.

        "format" specifies the format in which information about the
        selected font will be returned:

          Format   Meaning
          ------   -------
             0     Tab-delimited string in the format:

                     LogFont [@TAB] PointSize [@TAB] Color [@TAB] FontType

                       "LogFont" is a vertical-bar delimited string containing font
                       attributes.  See the "SysParamInfo" function for a description of
                       the LOGFONT format string.

                       "PointSize" is the font size in 1/10 of a point.

                       "Color" is the font color, as an RGB color value in the form
                       "#RRGGBB".  See the "AskColor" function for a description.

                       "FontType" is a bitmask specifying the font type, consisting of
                       one or more of the following values which can be extracted with
                       the bitwise AND ('&') operator:

                         Value   Meaning
                         -----   -------
                           256   The font weight is bold
                           512   The italic font attribute is set
                          1024   The font weight is normal
                          8192   The font is a screen font
                         16384   The font is a printer font
                         32768   The font is simulated by the graphics device interface (GDI)



  New IntControl:

    IntControl(82, p1, 0, 0, 0)
      Sets seed for the Random() function.

      This IntControl sets the seed value used in subsequent calls to Random().

        "P1" specifies a non-negative seed value.  If "p1" == 1, it will
        re-initialize the random number generator.  Otherwise, it will set
        the generator to a random starting point.

  Added support for user-defined functions (UDF's) with global variables,
  defined using the keywords #DefineSubroutine and #EndSubroutine:

      #DefineSubroutine functname([param1, param2, ..., param16])
        
        Return retval
      #EndSubroutine

    This is the same as a regular UDF, except that it will be able to access
    and change variables in the calling script, and any variables it sets
    will not be destroyed when it returns.

  Added a new request # to SnapShot:

    5 = Take snapshot of entire virtual screen (Windows 98/Me/2000/XP only)

      On versions of Windows that do not support virtual screens, this will
      be treated the same as request 0.

  Added a new "method" to IntControl(61) and IntControl(62):

    p1  Method to use
    --  -------------
     5  Display invisible window, then attach to the input thread of the foreground window

      In Windows 2000 and XP, the default method for IntControl(61) is now 5,
      and the default method for IntControl(62) is now 4.

  Fixed problem with StrFill crashing if 0 was specified for "length".

  Fixed an obscure problem with OLE calls erroneously failing.

  AskFileName now returns an error if 'filetypes' contains an odd number of
  items.

  Fixed a syntax problem when embedding an OLE call (with parameters) as a
  parameter within another function.

  Fixed problems with Dialog variables not being set properly if you pressed
  cancel or closed the dialog using the Close button (or system menu item).

  Dialog names can now be up to 19 characters long (was previously 16).

  Fixed a problem with very large encoded scripts causing an
  "Encrypted/Encoded verification failed" error.

  In DiskVolInfo, if the "root-path" parameter does not end with a backslash
  (and is not "") then a backslash will automatically be appended.

  IniItemize / IniItemizePvt no longer has a 32K limit on the size of the
  returned list when itemizing section names or key names.

  When an OLE function returns a byte array and a binary buffer is allocated
  to store it, the buffer type is now automatically set to 103.

  Increased the maximum number of UDF's from 100 to 200.

  Extenders can now have more than 100 functions (supported starting at
  feature level 1003).

  In a DebugTrace log, tick count is now formatted as an unsigned integer.

  Fixed problem with trailing comments on an #EndFunction line.

  If an #include directive specifies a file with a relative path, the file
  will be looked for in the script directory before the current directory.

  Fixed problem with IconReplace and IntControl(37) not working with some
  EXE's (ones whose icon group resources were numbered instead of named).

  If IgnoreInput is enabled, it will be temporarily disabled during SendKey
  (and SendKeysTo and SendKeysChild) functions in Windows 98 and Windows ME.

  Fixed problem with WinActivate in Windows 2000 and XP.

  The cancel handler and error handler modes are now reset to their default
  settings during Call's and UDF's.

  Fixed a problem with the Random() function returning 0 too often.

  Can now assign an OLE object handle to a property.

  Fixed problem with IconReplace and IntControl(37) not working with some
  16-bit EXE's.  Note that with 16-bit EXE's, these functions operate on
  individual icon images and NOT icon groups (ie, the changes made in version
  2002P do not apply to 16-bit EXE's).

  You may now re-assign an array variable.

  Fixed problem with FileExist and FileSizeEx handling open system files
  (like PAGEFILE.SYS).  This will work only if a full path name is specified
  or the file is in the current directory.

  Fixed problem with the script crashing after a 3647 error ("Cannot create
  embedded arrays").

  New data types for BinaryOleType:

    10   R4 pointer (VT_R4 | VT_BYREF)
    11   R8 pointer (VT_R8 | VT_BYREF)

  Fixed problem with Goto and GoSub not ignoring labels inside a
  #DefineSubroutine block.

  Fixed problem with ObjectCollectionNext crashing when given an invalid OLE
  object.

  Message text is now truncated to 20,000 characters in the following functions:

    AskYesNo
    IntControl(1)
    Message
    Pause
    Terminate

  ItemLocate will now successfully find a blank item ("") in a list.


Windows NT extender 37000  First showing up in WB 2002E

  New function:

    wntAcctList(s:server-name, i:request [, i:output-format-flag])
      Rapidly lists accounts on an NT/2K/XP system.

        "server-name" is the UNC name of the server on which the function
        will execute (eg, "\\MYSERVER"), or "" for the local computer.

          Note: to list accounts in a domain, specify a domain controller
          for that domain as "server-name".

        "request" specifies the types of accounts to return in a delimited
        list.  You can specify 0 to include all account types, or specify
        one or more of the following flags, combined using the bitwise OR
        ('|') operator:

          Request #   Meaning
          ---------   -------
              1       Return user accounts.  The results are similar to
                      using wntUserList() with an account type of "2".

              2       Return machine accounts.  The results are similar to
                      using wntUserList() with an account type of  "48"
                      [16 | 32].  Please note that inter-domain trust
                      accounts cannot be returned with wntAcctList(),
                      although they can be returned with wntUserList().

              3       Return group accounts.  The results are similar to
                      using wntListGroups() with a @GLOBALGROUP group type.
                      Please note that local groups cannot be returned with
                      wntAcctList(), although they can be returned with
                      wntListGroups().

        "output-format-flag" [optional parameter] controls the format of the
        account names that are returned.

          Flag   Meaning
          ----   -------
             0   (default) Return actual account name.

             1   Account names will have domain names prefixed on to them,
                 except in cases where the domain name is "BUILTIN" or
                 "NT AUTHORITY".

             2   Account names will have domain names prefixed on to them in all cases.

             4   SID values will be returned in place of account names.

            32   Display a progress dialog when obtaining a large list of
                 accounts.  This allows the script to show its continuing
                 progress even though the extender function has not yet
                 returned control to the script.

            64   Force a 1 second delay between updates to the progress dialog box.

           256   Allows extended information to be returned along with an
                 account name.  The additional information will appear as
                 pipe "|" delimited fields in a record, with each record in
                 the list delimited by a TAB character.

          In the case of a user account, the record format would be:

            "user|comment|full_name|flags|RID"

          In the case of a machine account, the record format would be:

            "machine|comment|flags|RID"

          In the case of a [global] group account, the record format would be:

            "group|comment|RID"

          The flags are the account flags.  Refer to wntUserGetDat() for
          information regarding the various flag bits and their meanings.

          The RID is the Relative Identifier for the account, and it
          uniquely identifies the account within the domain in which the
          account is located.  The RID appears as the very last component in
          the account's SID vaue.

      Returns a tab-delimited list of account names.

      This function performs tasks similar to wntUserList() and
      wntListGroups(), but it uses a different Win32 API function to perform
      these tasks and the type of accounts and the format of the data
      returned by this function differs in some subtle ways as compared to
      the return values of wntUserList() and wntListGroups().  The reason
      that this function exists is that the Win32 API function used by this
      extender function to list accounts on NT/2K/XP systems is highly
      optimized to enumerate [user, machine, group] accounts very quickly
      even when there are 10's of thousands of accounts in a domain.

  Fixed problem with wntSvcCfgGet crashing.

  The following functions now accept 2 new object types, 600 and 601:

      wntAccessAdd
      wntAccessDel
      wntAccessGet
      wntAccessList
      wntAuditAdd
      wntAuditDel
      wntAuditGet
      wntAuditList

    Object type 600 is for service display names and object type 601 is for
    service key names.  It is now possible to manipulate the security
    settings on NT services.

  Fixed problem with wntShareList hanging when specifying a server with
  more than 2044 shares.

  Fixed problem with wntServiceAt crashing when there are a very large
  number of servers.

  Added an optional "display-flags" parameter to wntServiceAt.

  Fixed problem with wntSvcList running in an infinite loop.

  Fixed a bug where any of the wntAccess*()/wntAudit*() functions
  could cause an access violation error if a progress dialog box was being
  displayed.

  Fixed a bug where the permissions of "Everyone" - "Full Control"
  could not be properly deleted from the root folder of a NTFS volume that
  had the default permissions on it that are applied when the volume is
  first formatted.  Code in the extender that automatically fixes security
  descriptors that Win2K has corrupted on its own was not properly
  handling a situation where Win2K corrupts the security descriptor on the
  root folder in a manner different from how it corrupts the security
  descriptor on other folders.  Let's just say that the code handles these
  problems properly now.

  The wntListGroups() and wntUserList() functions now have some new
  output-format-flag bit values that allow multiple fields of group/user
  information to be obtained all at once instead of having to list all
  groups/users and then call wntGroupInfo()/wntUserGetDat(), respectively.
  This should cut down on the time that is required to obtain lists of
  groups/users such that actual group/user names and their corresponding
  descriptions/full-names are obtained for presentation in a GUI dialog
  box control.

  The wntListGroups() and wntUserList() functions now have a new
  output-format-flag bit value that allows a progress dialog box to be
  displayed while the extender is gathering information.  In situations
  where several thousands of group/user accounts are being enumerated,
  these extender functions can execute for very long periods of time
  leading the user to believe that the script has gotten "hung up".  The
  progress dialog box is updated every second to indicate that the
  extender function is still alive and what group/user it has most
  recently enumerated.

  The wntUserList() and wntListGroups() functions have had their performance
  improved by re-writing the internal functions that manage delimited lists.
  This re-write of the list management functions results in a significant
  improvement in the efficiency of the memory allocation/copy/de-allocation
  tasks that are performed while building a delimited list.

  Fixed problem with wntLsaPolSet not properly handling an empty SID string
  value passed in for element #2 in the class "PrimaryDomain".


WB 2002F  Jul 10, 2002


DLL 3.7fcg  First showing up in WB 2002F

  Added new request to IntControl(77):

    Request  Meaning
    -------  -------
       62    tab-delimited list of OLE objects

  In Dialog function, increased item, dropdown, and file list box number of
  items capacity for WinNT/Win2k/XP machines.


WB 2002G  Jul 15, 2002


DLL 3.7gcg  First showing up in WB 2002G

  Fixed problem with Random() function crashing on negative values.

  Fixed problem with variables beginning with high ASCII characters causing
  a crash.

  Changes to the Dialog function and related functions:

    Added code to work around Windows bug that caused hard crash when user
    pressed button accelerator keys that produced dialog termination.

    Added documentation for DialogControlSet/Get request code 13. (Change
    text color.)

    Changed DialgControlGet so that it reports the user's first edit to edit
    box part of drop down list control. (Windows does not report the content
    of the edit box as the selected item the first time the user changes the
    text: go figure.)

    Added workaround for WinXP bug that caused WB crash, if user cancels
    dialog from a Droplist change procedure event.

    Fixed bug in DialogControlState function that would not permit it to set
    the focus (request code 1) to a spinner control.

    Added new request-code to the dialogControlState function.  New request
    returns the number of the control with the focus or 0, if no control has
    the focus.


WB 2002H  Aug 22, 2002

  Fixed problem with some of the Box functions when in a Dialog callback.


DLL 3.8hch  First showing up in WB 2002H

  New functions:

    ObjectType(s:variant-type, s/i:value)
      Creates a WIL variable with a specific OLE variant type.

        "variant-type" can be one of the following:

          Variant-type   Value to specify
          ------------   ----------------
            "I1"         A 1-byte character value
            "I2"         A 2-byte integer value
            "I4"         A 4-byte integer value
            "UI1"        An unsigned 1-byte character
            "UI2"        An unsigned 2-byte integer value
            "UI4"        An unsigned 4-byte integer value
            "BOOL"       A Boolean (True/False) value

            "CY"         A currency value, specified as a string in the form "#CURRENCY:value"
            "DATE"       A date/time value, specified as a string in Ymd or YmdHms format
            "DECIMAL"    A decimal value, specified as a string in the form "#DECIMAL:value"
            "NULL"       A blank string ("")

        Note that "variant-type" may optionally be preceded by the prefix
        "VT_", so for example you could specify either "BOOL" or "VT_BOOL".

      When an OLE method or property returns a value that is one of these
      supported variant types, WinBatch now retains the variant type for the
      returned variable, without having to use the ObjectType function.
      However, if you subsequently assign a new value to that variable using
      a regular WIL assignment operator, the variant type information will
      be lost.  For example:

        visible = ExcelApp.Visible
        ExcelApp.Visible = visible

      The variable "visible" is returned as a VT_BOOL, and is still a
      VT_BOOL when it is passed back to the OLE object.  But here:

        visible = ExcelApp.Visible
        visible = 0
        ExcelApp.Visible = visible

      The assignment "visible = 0" causes "visible" to become an ordinary
      WIL integer, without a variant type.  In that case, if you wanted it
      to be a VT_BOOL you would need to use ObjectType:

        visible = ObjectType("BOOL", 0)
        ExcelApp.Visible = visible

      Or simply:

        ExcelApp.Visible = ObjectType("BOOL", 0)

    ObjectTypeGet(s:varname)
      Gets the OLE variant type of a WIL variable.

      This function returns the "variant-type" string for the specified
      variable name, or "" if it does not have a variant type.  See
      ObjectType for a list of possible "variant-type" strings.

    BinaryChecksum(i:handle, i:request)
      Returns the MD5 digest (fingerprint) or simple CRC of a binary buffer.

        "handle" specifies a binary buffer handle.

        "request" specifies the type of digest or CRC to generate, and can
        be one of the following values:

          Request   Meaning      Return string format (x = hex character)
          -------   -------      ----------------------------------------
             0      MD5 digest   "xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx"
             1      16-bit CRC   "xxxx"
             2      32-bit CRC   "xxxxxxxx"

      Returns a hex-value string.

  New IntControl:

    IntControl(81, p1, 0, 0, 0)
      Sets seed for the Random() function.

      This is identical to IntControl 82.

  Improved WinPlace on multi-monitor systems, but it will only work properly
  if all monitors are the same resolution.

  In the Dialog function, the value of the WIL variable associated with a
  VARYTEXT control is no longer modified by the function.

  Fixed problem wih OLE objects being freed when used on a line like:

    If MyObject

  Fixed problem with BinaryStrCnt and high-ASCII characters.

  You can now pass a VT_NULL as a parameter to an OLE function as:

    NULL:""

  When specifying a variant type for a parameter to an OLE function, you
  can now optionally precede the type with "VT_".  For example, the
  following two lines may be used interchangeably:

    MyObject.Pause(BOOL:0)
    MyObject.Pause(VT_BOOL:0)

  Added new request to IntControl 77:

    Request  Meaning
    -------  -------
       63    reference count of OLE object specified by P2

  Changes to the Dialog function and related functions:

    Added "Number-Only" (64) style for edit controls.

    Added "Add-Item" (14) request code to DialogControlSet function. Allows
    addition of single item to File list, Item List and drop down List
    boxes.

    Added "Remove-Item" (15) request code to DialogControlSet function.
    Allows removal of single items from File List, Item List and Drop-down
    List boxes.

    Added "Disable Input" option code (1000) to DialogProcOptions function.
    When set, user input to dialog is ignored and title bar is "grayed" but
    dialog screen images are redrawn as needed.  If DialogProcOptions' third
    parameter is set to 2 instead of one the "Wait" cursor is also
    displayed.

    "Snap-to-default-button" setting now respected on Windows NT 4.x,
    Windows 2000, and Windows XP machines.

    Added "Set-dialog-background" option code (1001) to DialogProcOptions
    function. Allows user to dynamically change dialog's background bitmap
    or color.

    Improved rendering of bitmaps on palette based display devices


Dialog Editor 2002H  First showing up in WB 2002H

  Bug Fix -"multiple radio buttons with same value" error message appear
  when the condition dose not exist.

  Added check to Dialog Editor that looks at the for dialog function's
  parameter value. Necessary because can cause the creation of WIL reserve
  words as dialog attribute variable names when prefixed to attribute names.

  Bug Fix - picture buttons did not always display the default bitmap when
  created.

  Bug Fix - Added File List Box counting (only one permitted) when templates
  saved to the clipboard.

  User now has option to save a dialog template with errors.

  Added "Number-Only" (64) style for edit controls.

  User menu choices for View->Grid and View->Bitmap menu items are now
  remembered between sessions. Also,view menu settings are respected when
  the dialog background is changed.


Windows NT extender 38001  First showing up in WB 2002H

  In wntAccessMod and wntAuditMod, request #3 (re-enable ACL inheritance)
  was not properly stripping explicitly assigned ACEs from the ACL.


NetWare 4 extender 38000  First showing up in WB 2002H

  Fixed problem with n4MemberDel and n4MemberSet with Novell eDirectory.

  n4MemberDel and n4MemberSet now remove/set the "Equivalent To Me" attribute.


WB 2002J  Dec 2, 2002

  New IntControl:

    IntControl(1009, p1, 0, 0, 0)
      Gets name of current service.

      If the current script is running as a service, this function returns
      the name of the service.  Otherwise it returns a blank string ("").

      "P1" specifies which name to return:

        P1   Meaning
        --   -------
         0   Returns the service name (the actual registry key name)
         1   Returns the display name (the name shown in Control Panel)

  In the compiler, if you press Cancel in the Options dialog it no longer
  resets the target file name to have the same base name as the source file.


DLL 3.9jci  First showing up in WB 2002J

  New functions:

    ItemCountCsv(s:line, i:flags)
      Returns the number of items in a CSV line.

        This function is like ItemCount, but instead of a list it counts
        items in a CSV line.  See ItemExtractCsv for more information.

    ItemExtractCsv(i:index, s:line, i:flags)
      Returns the selected item from a CSV line.

        "index" specifies the ordinal position of the item to be returned.

        "line" specifies a CSV line (see below).

        "flags" can be set to 0, or can specify one or more of the following
        values combined with the bitwise OR ('|') operator:

          Value   Meaning
          -----   -------
            1     treat leading and trailing whitespace as significant

        This function is like ItemExtract, but instead of a list it extracts
        items from a CSV line.  A CSV ("comma separated values") line
        consists of comma-delimited items.  Items may optionally be enclosed
        in quotation marks (aka, "double quotes").  There are two cases
        where an item *must* be enclosed in quotation marks:

          (1) If the item contains a comma
          (2) If the item contains a quotation mark

        Here are some examples:

          1,2,3,4,5
          "January","February","March"
          "Doe, John",20

        In order to embed a quotation mark in an item, you must replace it
        with two quotation marks (ie, add an extra quotation mark).  For
        example, you would specify the item "My Fair Lady" (with quotes) as:

          """My Fair Lady"""

        Each quotation mark is doubled, and the entire item is enclosed in
        a set of quotation marks.

        Normally, whitespace outside of quoted strings is ignored.  The
        following two lines would be considered identical:

          A,B,C
          A, B, C

        But if you specify a "flags" value of 1, then the whitespace will
        be considered part of the items.  Whitespace *inside* a quoted
        string is always preserved, regardless of the "flags" value:

          "   This line has spaces around it   "

        Similarly, whitespace outside of a quoted string is always ignored.
        Ie, the following two lines are considered identical, regardless of
        the "flags" value

          "String 1","String 2","String 3"
          "String 1", "String 2", "String 3"

      The function returns the selected item, with any enclosing quotes
      removed, and any doubled quotation marks converted to normal quotation
      marks.  Leading and trailing whitespace may be stripped out, as
      described above.

  New IntControl:

    IntControl(83, p1, 0, 0, 0)
      Specifies how OLE byte arrays will be handled.

      This specifies how to handle OLE methods and properties that return an
      array of bytes (VT_I1 or VT_UI1).

        P1  Meaning
        --  -------
         0  Return as WIL array (default)
         1  Store in binary buffer
         2  Return as string

      Returns previous setting.

  Fixed problem with WinPlace on multi-monitor systems when using the
  @NORESIZE and @ABOVEICONS constants.

  Labels for Goto and Gosub can now be up to 249 characters (they were
  restricted to 30 characters in version 2002H).

  When the Run[..] functions retrieve command-line parameters from the
  registry, they now support the %* token, which gets replaced by all
  remaining parameters.

  Added an optional parameter to AppExist and AppWaitClose:

    AppExist(s:program-name [, i:current-session-only])
    AppWaitClose(s:program-name [, i:current-session-only])

      If "current-session-only" is @TRUE, and the script is running in a
      Terminal Services environment, then the specified application will
      only match if it is running in the same session as the script.

      If "current-session-only" is @FALSE or omitted, then the specified
      application will match regardless of what session it is running in.

  Added a new parameter to IntControl 56:

    IntControl(56, p1, p2, p3, 0)

      p3 = "current-session-only" flag (applies only if p2 == 1).

        See AppExist for more information.

  The following functions now return an error if "delimiter" is more than a
  single character:

    Arrayize
    AskItemList
    ItemCount
    ItemExtract
    ItemInsert
    ItemLocate
    ItemRemove
    ItemReplace
    ItemSort

  In AskDirectory, fixed problem where "start-dir" specified a UNC.

  StrIndexWild now returns "start" instead of 0 if "pattern" is a blank
  string (unless "start" == 0, in which case it returns 1).

  Fixed problem with TimeDelay at Daylight Savings Time changeover.

  TimeDelay will now always wait at least the specified amount of time.

  Fixed problem with SysParamInfo returning an error if "ini-update" was 3.

  In MousePlay, added support for multiple monitors in Windows 2000 and
  Windows XP.

  Added support for OLE methods and properties that return arrays.  The
  return values will be returned as a WIL array.  Note that byte arrays are
  no longer converted to a binary buffer by default, as in previous versions,
  but this behavior can be changed with the new IntControl 83.

  OLE return types of VT_ERROR are now supported properly.  They now return
  the SCODE associated with the error, instead of 0 as before.

  Changes to the Dialog function and related functions:

    Fixed bug in DialogControlSet function.  Changes to MULTILINE control's
    text now appear immediately.

    Fixed bug in DialogControlGet function.  Request code #13 (Get Text
    Color) now returns correct text color when control also has "DEFAULT"
    background specified.  The function was  returning "DEFAULT" for any
    text color when the control had the "DEFAULT" background.

    Removed limit on the size of individual items in ITEMLIST and
    DROPLISTBOX controls.

    Removed limit on the number of items that can be saved into a ITEMLIST
    control variable on dialog dismissal.

    Fixed bug in automatic sizing of DROPLISTBOX when control has a user
    selected font specified.

    Fixed bug in automatic tab-order reassignment when attempting to
    maintain GROUPBOX member control associations.

    Added 2 new callback request codes for the DialogProcOptions function.
    Callback code 12 produces a user defined dialog procedure callback when
    the dialog's user double-clicks an FILELISTBOX item and callback code 13
    produces a callback when the dialog's user double-clicks an ITEMBOX
    item.

    Extended DialogControlSet/Get request code #10 functionality to
    MUILTLINEBOX controls so control can be scrolled from within a user
    defined dialog procedure.

    Dialog window now will minimize to the windows taskbar.  IntControl(49,
    1, 0, 0, 0) must be used to turn on system menus for this feature to
    take effect.

    Spinner controls no longer permit user to type or paste invalid text
    into control.  Invalid text is text that contains characters other than
    decimal digits and sign (+,-) characters.  As a side effect the control
    no longer considers the thousands separator (,) as valid text.

    Added config varaible to dialog template.  This variable
    controls how the dialog editor creates the "dialog" statement in the
    template.

    Added new "flat" (128) style to dialog push and picture buttons.

    Added support for embedded double quotes in control text attribute.
    Each double quote must be specified by placing two double quotes at the
    desired location of the double quote.  Also the entire text attribute
    must be surrounded by single double quotes.

    "Snap-to-default-button" functionality is now supported on secondary
    monitors of multi-monitor desktops (Windows 2000 and Windows XP only)

    Fixed bug in that caused AskItemList function to fail when called from
    dialog procedure.

    Fixed crash bug that occurred when user dialog procedure returns a
    positive number in response to a DROPLISTBOX change event (Windows XP
    only.)


Dialog Editor 2002J  First showing up in WB 2002J

  Editor changed to display control text as it will appear when the dialog
  is displayed by the dialog function.

  Editor now respects beginning and ending double quotes in the controls
  text attribute.

  Editor changed to automatically add a second set of double quotes to
  template when the text attribute is specified containing double quotes.
  (User only needs to add one double quote in control property sheet.)

  Added checking for invalid values for SPINNER control's pre-selected item
  attribute to editor.  Does not error but does substitute DEFAULT key word
  for invalid value.

  Added ability to move multiple controls simultaneously with either mouse
  or arrow keys.

  Added ability to select multiple controls simultaneously with keyboard by
  using the Control+tab key combination.

  Ok button now has default button style in Dialog Editor's default
  template.

WB 2002K  Dec 6, 2002


DLL 3.9kci  First showing up in WB 2002K

  Fixed problem with TimeWait not working correctly.


WB 2003A  Dec 23, 2002


DLL 4.0ada  First showing up in WB 2003A

  New IntControl:

    IntControl(84, p1, 0, 0, 0) (Windows NT/2000/XP only)
      Itemize desktops, or windows on specified desktop.

      If "p1" is a blank string (""), this returns a tab-delimited list of
      desktops, or a blank string ("") if the function fails.

      If "p1" specifies a desktop name, this returns a tab-delimited list of
      "Window ID's" of all top-level windows on that desktop, or a blank
      string ("") if the function fails.

  Fixed problem with WinPlace using the @NORESIZE and @ABOVEICONS constants.

  Added an optional parameter to ItemCountCsv and ItemExtractCsv:

    ItemCountCsv(s:line, i:flags [, s:delimiter])
    ItemExtractCsv(i:index, s:line, i:flags [, s:delimiter])

      "delimiter" specifies a character used to separate values, instead of
      a comma.  It can be any single character except a space, tab, null, or
      quotation mark (double quote).

  DirMake no longer returns an error if a root directory is specified.

  DirMake now returns an error if the specified directory has more than one
  consecutive slash (other than the two backslashes at the beginning of a UNC).

  Changes to the Dialog function and related functions:

    Fixed bug that causes the edit part of a Spinner control to remain
    visible when the control's state is changed to invisible via a call to
    DialogControlState.

    Changed error message associated with memory allocation errors.

    Dialogs can now be created without any controls
    (NumControls=000 will not cause error.)

    Fixed very rare system access violation error that occurred when
    displaying bitmaps.


Dialog Editor 2003A  First showing up in WB 2003A

  Editor now creates the 2 parameter version of the "Dialog" statement only
  when "Create dialog statement that WinBatch will ignore" is selected on
  the configuration page of the Dialog Attributes property sheet.




Article ID:   W14817