New features

Date: Jul 25, 2019
Version: 6.2.0
For a list of bug fixes see bugfixes.
For a list of upward compatibility issues see compat.
For a list of known issues that are not bugs see issues.

Before upgrading from Sculptor 5.0 or earlier to Sculptor 5.1 or later, please read the Sculptor 5.1 notes about the security features added to kfserver in Sculptor 5.1.

Most new features use new code in the interpreters. A program that uses a new feature will not work with an earlier version of Sculptor. An attempt to run such a program will produce the message “Program code is damaged”.

Programs that are compiled with the latest version of scc but which do not use new features will work with an earlier run-time system.

The Sculptor servers kfserver and kfservnt support connections from earlier client versions of Sculptor. Always upgrade the server first.


  1. General improvements to Sculptor ODBC driver and to the SQL engine:
    • Implemented SQLDescribeParam()
    • Accept the SQL_ATTR_ASYNC_ENABLE in SQL[G|S]etStmtAttr
    • Fixed re-execution of certain prepared statements (fix Access linked table problems)
    • Make possible to use the “DEFAULT” schema and catalog names when referencing tables or columns.
    • Make the SQL Engine more robust against buffer overflow
    • Make possible the use of catalog, schema and table name in ORDER BY fields
  2. Set the default SCULPTOR directory when no SCULPTOR environment variable is found, to be the parent directory of the current executable directory location. Making it easier to not define the SCULPTOR variable and execute differents version of SCULPTOR (greater than Sc62) at the same machine.


  1. A 64-bit version of Sculptor is now available for 64-bit platforms.

  2. Added a simple interface, to send a request to an HTTP server and wait for the response, fulfilling the REST service client role:

    status = http_simple_send(URL, Method, Options, RequestObject, ResponseObject)
    /* Will return the server response code or status */

    Options can be a combination of HTTP_OPTION_ values, that will affect how the RequestObject (information to send) and ResponseObject (container to fill with the response) will be interpreted.

    The content type on the request can be specified with sys.HttpRequestContentType

    The received information content type will be on sys.HttpResponseContentType

    The function returns the http status response value (Wikipedia) from the server (defined for convenience in http.h with prefix SC_), and a readable message in the sys.HttpResponseMessage. Or if a -1 is returned an explaining message will be in the sys.HttpErrorMessage system variable.

  3. Added new support to functions read_json_values, read_xml_values, write_json_values and write_xml_values:

    • Support a channel as well as a filename (just specifing a channel number).
    • Support a memory string as a source (read functions) or destination (write functions), when the new JSONXML_MEMORY option is specified.

    Also the possible options values JSON_MINIFY and XML_MINIFY have been consolidated into JSONXML_MINIFY.

  4. The functions for reading/writing JSON/XML and the nph-srep JSON/XML functions support the use of Sculptor reserved words as JSON/XML tags, defining the !record fields with an initial underscore “_”, like:

    !record Rec {

    Also all the JSON/XML read/write functions treat an ASCII or binary array with a “p” (packed flag) flag as one big field, so that large JSON/XML fields can be read/write, e.g.:

    !record Rec {
  5. Added the ability to define subrecords (nested records) (!record’s inside !record’s)

  6. Records can now have dimensions, like:

    !record recName[2, 3] {
  7. Added redim(fld_rec, dimension, new_length) method to redimension an field or record array dinamically while the program is running. Special considerations:

    • Only field/record dimensions already defined could be changed.

    • The dimension size must be between 1 and 65534.

    • Can’t be used in these types of fields:

      • Sys special variables
      • !file related fields
      • Local function variables
    • Note: In case of an array inside a !record all !record copies are affected (!record rec1 = rec2 case) unless distinct is specified.

  8. Added optional distinct flag to copy record definition. To make both recods independent (no attributes, array sizes,… changed in one recod affect the other)

  9. When assigning two field arrays (fldArr1 = fldArr2) we copy the whole array contents. Only when sys.Col, sys.Row, sys.Plane and sys.Dim4 are set to 0.

    Note: When setting one of the above system variables to a value != 0, and accessing then an array field, the rest is automatically initialised to 1. Meaning that you’ll have to reset the four of them again to 0 if you want the whole array to be copied.

  10. Added an “a” flag to fields, meaning “Autosizeable” field. Can be assigned to array fields and makes the array eligible to automatic redimension in certain cases. In the !record array case a similar RECFL_AUTOREDIM record flag has been added.

  11. Supported a runtime reference to access !record or ![o]file fields or subrecords when using a pointer or function argument.

  12. fromname() supports nested records, records with dimensions and the subscripts can be other field values.

  13. Added pstext() command to srep* to be able to print the elements on the special text section. Defined PSTEXT_EURO to print the Euro sign.

  14. Added latex.s printer parameter file to help printing in LaTeX format (which can then be converted into pdf or other formats)

  15. To enhance the html and latex support new printer standard sequences have been added to printer parameter files.

  16. Incremented the possible number of parameters on the SCFUCNTION sch/scj/scx nph-srep tag from 1 to 32.

  17. Removed !type from the language

  18. Use relative file names on ![ox]file’s when compiling with the “-i” flag.

  19. Added exec_dll_method() function to execute a public/exported method in a dynamic loaded library (dll on Windows and .so in linux). Making it possible to execute methods writen in “C” or other languages.

  20. nph-srep now does also use HTTP_SC_CHDIR, HTTP_SCULPTOR and HTTP_LANG environment variables to be able to work with the apache suexec module that filters normal environment variables while not the ones starting with HTTP_

  21. Added a keyed file client cache service to increase performance in certain scenarios.

  22. Added crash command (can be used to test exception handling)

  23. The Keyed file pure client libraries added server information into their interface (getSrvMainVers,…)

  24. Added i8 and u8 as field type & sizes.

  25. Added SHM_PERSIST and SHM_GLOBAL options which affects create_shared_memory(), link_shared_memory() and unlink_shared_memory().

  26. A new licence/activation key is used from this version onwards, simplifying the number of elements licenced. The scconfig program has been changed acordingly. The new and old licences can coexist to make it possible to run old versions and new versions at the same time.

    One benefit of the new licence system is that it may permit changes to the number of users licenced without the need to edit the values and enter a new activation key.

  27. dir_to_file(): The following extra fields are now recognised if declared in the file that receives the directory listing:

    FileSize,,i4 The file size in bytes
    Created,,i4/td Date and time the file was created
    Updated,,i4/td Date and time the file was last updated
    Accessed,,i4/td Date and time the file was last accessed

    Note that the /td type cannot be specified in the data dictionary. It must be assigned at runtime using the syntax:

    FILEID.Updated->logical_type = LT_DTIME

    These fields are filled only if the corresponding new option flag is set:

    DIRX_SIZE Fills in FileSize
    DIRX_CREATED Fills in Created
    DIRX_UPDATED Fills in Updated
    DIRX_ACCESSED Fills in Accessed
  28. Use relative file names on spd with the “-i” flag.


  1. sys.LinesLeft is now calculated by a more accurate method, based on the size of the current font and the space left on the page. It’s possible that a few old programs rely on the old, incorrect calculation and will no longer start a new page at the required line. In this happens, force the program to revert to the old behaviour by adding the following !compat line:

    !compat linesleft=5    (any value in the range 1 to 5)

SCULPTOR 6.1.6, SCULPTOR 6.0.9 and SCULPTOR 5.9.9

  1. The function set_thread_execution_state(state) has been reinstated in this version as it is supported by Windows XP onwards (it was withdrawn at version 5.6.1).


  1. Consolidate various minor updates added to 6.1.4 after first release.
  2. sys.ServerRetries added:
    • If >= 0 specifies the number of retries to be made when connecting to a Sculptor server.
    • If negative, a default number of retries is used (currently 5).
    • If sys.ServerRetries is in the range 0 to 3, the pop-up window “Connecting to server…” is suppressed.


  1. Implemented some missing features in scdebug like:
    • Add a watched field
    • Watched fields are field breakpoints, which halts the debugger whenever a watched field content changes.
    • Added an option to save the breakpoints on exit


  1. General improvements to Sculptor ODBC driver:
    • Implemented SQLSpecialColumns()
    • Fixed SQLNumResultCols() when returning an empty result set
    • Added more functinality into SQLGetTypeInfo()
    • Make sure SQLColAttribute() is called in the 32 bit driver
    • Increased the tracing messages on the trace version
    • Return better driver version information


  1. Improve installation procedure.


  1. sys.TTYno2 added. On Unix and Linux, this uses a different algorithm to calculate the tty number from the major and minor device numbers and avoids the number becoming negative when using terminal emulators. This is compatible with the modified ttyno variable in Sculptor 2.5d.
  2. OLE controls are supported in nph-srep, sage(c) and srep(c) using the create_object() function. OLE controls are not supported in windows definitions in these versions.


  1. Field level auditing implemented.

  2. Mirror on server configuration.

  3. Sculptor System File Relocation service.

  4. Three Keyed file pure client libraries have been added. In .Net (KfLibDNet), in Java (KfLibJava) and in native C++ (KfLibCpp). These can only access Sculptor files through kfserver/kfservnt.

  5. JSON and XML methods added. These help using REST in nph-srep.

    Read or write a !record from/into a filename.

    One option is available:

    JSON_MINIFY: Removes all unnecessary spaces and characters to reduce the transfered size (in case of read removes the comments as well).

    Read or write a !record from/into a named file.

    One option is available:

    XML_MINIFY: Removes all unnecessary spaces and characters to reduce the transfered size.

    The following methods are only available in nph-srep.

    Print the record content in JSON syntax to stdout (if nph-srep is executed from a web server the response is returned to the client “browser” as the message content).

    One option is available:

    JSON_MINIFY: Removes all unnecessary spaces and characters to reduce the transfered size.

    The output is converted from the system native one to utf8.

    Returns the number of fields printed.

    Print the record content in XML syntax to stdout (if nph-srep is executed from a web server the response is returned to the client “browser” as the message content).

    One option is available:

    XML_MINIFY: Removes all unnecessary spaces and characters to reduce the transfered size.

    The output is converted from the system native one to utf8

    Returns the number of fields printed.

    Read into the record the received stdin JSON content (if nph-srep is executed from a web server the content is received from the client “browser” as the message content in a PUT or POST method).

    One option is available:

    JSON_MINIFY: Removes all unnecessary spaces and characters including comments

    Returns the number of fields read.

    Read into the record the received stdin XML content (if nph-srep is executed from a web server the content is received from the client “browser” as the message content in a PUT or POST method).

    No options available. Returns the number of fields read.

  6. nph-srep only: get_web_method()

    Returns the HTTP method (or verb) that caused the nph-srep call. Possible values (defined in $SCULPTOR/include/www.h):

    !define NO_METHOD       0
    !define METHOD_POST     1
    !define METHOD_GET      2
    !define METHOD_HEAD     3
    !define METHOD_TRACE    4
    !define METHOD_OPTIONS  5
    !define METHOD_PUT      6
    !define METHOD_DELETE   7
  7. nph-srep only: New *.scj and *.scx Sculptor template Files.

    scj: Used to define a json response “template”. Automatically sets the

    content type to “application/json”.

    scx: Used to define a xml response “template”. Automatically sets the

    content type to “application/xml”.

    These templates work and accept the same tags as the normal sch files.

  8. nph-srep only: Fixed the put command to send output to the client browser.

  9. nph-srep only: Make it possible to map .q, .sch, .scx and .scj on the browser.

  10. ScODBC driver support for binary data types.

  11. Sculptor security: New user password hash types in security.h

    !define HAD_SHA0_SC     0   /* SHA0 converted to 15 ASCII values */
    !define HAD_SHA0        1   /* 20 bytes (160 bits) */
    !define HAD_SHA1        2   /* 20 bytes (160 bits) */
    !define HAD_SHA224      3   /* 28 bytes (224 bits) */
    !define HAD_SHA256      4   /* 32 bytes (256 bits) */
    !define HAD_SHA384      5   /* 48 bytes (384 bits) */
    !define HAD_SHA512      6   /* 64 bytes (512 bits) */

    This values can be used on encrypt() (a new optional parameter has been added). The security user.d file has also been modified to support the new algorithms.

  12. Binary field type (b1 - b255) added to keyed files. Used for field level auditing.

  13. Added -i flag to scc to make !include files relative to the including file directory and not the current compilation directory.

  14. Sculptor Server Cache service has been implemented on the SQL Engine.

SCULPTOR 6.1.0 and SCULPTOR 6.0.9

  1. ODBC connection behaviour has changed.

    • If the connection is being made from a Sculptor server, the connection string must be valid, or an error will be returned. Otherwise:
    • If DBFL_DRIVER_COMPLETE is set, Sculptor uses SQL_DRIVER_COMPLETE. This generates a dialog to complete a connection if necessary.
    • If DBFL_DRIVER_COMPLETE is not set, Sculptor uses SQL_DRIVER_PROMPT if the connection string is null, otherwise SQL_DRIVER_NOPROMPT.


  1. Minor improvements to ODBC interface to SQL databases.


  1. There is a new function:

    Forces the specified window into the foreground. Use on return from an executed program to force this program to have the input focus. Normally the user should be allowed to control which program has focus. Use this function only after calling an integrated sub-program, for example a spell checker, when it would destroy continuity if the focus moved to another application. After calling set_foreground_window(), the setfocus command can be used to define which control has focus.

    window_id This must be a window in the current dialog.
    options Normally code as 0. Can be set to 0x01 to activate the last child window.
  2. The cell_width on the cell_properties attribute assigned record on tables has been enhanced to accept a new value TGD_NOCOLUMN (-2) that means the column will not be shown.

  3. The table control has a new style WS_COLUMN_RESIZE which makes the table columns resizeable.

  4. There is a new function:

    Copies the current content of the free textbox into the packed field. Can be used on the callback call due a global mapped key or in another captured events. The function is created because the free format textboxes do not make use of sys.InputBuffer.

    textbox_id Must be a free textbox name
    field_id The field where the textbox content will be copied

SCULPTOR 6.0.5 and SCULPTOR 5.9.8

  1. Added sys.FreeTextInputBuf. This is set to the current text in a free format textbox when a control or function key is pressed (a key that can be trapped using “on global” or by an EV_KEYSTROKE event). Free format textboxes cannot update sys.InputBuf because this is limited to 255 characters.

SCULPTOR 6.0.5 and SCULPTOR 5.9.7

  1. A printer error in the run report command can be trapped by setting the system variable sys.PrinterErrorFunction to point to a function that is called if an error occurs. Example:

    sys.PrinterErrorFunction = &PrinterError
    !function PrinterError(Destination, Location, ErrorCode) {
        prompt "Error " + tostr(ErrorCode) + " printing to " + Destination, \
               "Retry? " button="YES",PERR_RETRY button="NO"
        return 0
        return 1

    Sculptor calls the function with the following arguments:

    Destination The print destination specified in the run report command.
    Location The location number of the error in the run report logic. Currently this is always set to 1.
    ErrorCode The Windows system error code.

    The function should return one of the following values:

    -1 Display a standard Sculptor error message and abandon the report.
    0 Abandon the report without displaying an error message.
    1 Retry the report without displaying an error message. If the report fails again, the error function will be called again unless sys.PrinterErrorFunction has been set to NULL.

    Once the report has been completed or abandoned, the program continues with the statement following the run report command.


  1. There is a new function:

    The sort function sorts an array field or a record containing array fields. In the record case, all array fields in the record that have the same dimension as the first sort field are re-ordered, whether or not they form part of the sort key. Array fields that have a different dimension are not re-ordered. Optionally, an index can be specified with the field or record parameter, in which case the sort starts at that index.


    The number of elements to be sorted (0 = the entire array).


    For a single array field, a text string that specifies the sort order:

    a” = ascending - case sensitive if text
    d” = descending - case sensitive if text
    A” = ascending - case insensitive if text
    D” = descending - case insensitive if text

    For a record, a text string that specifies the fields to be sorted in order of priority. Each field number must be followed by the sort order for that field as above. For example:

    “3a2d” means sort by field 3 ascending, then field 2 descending.


    A Sculptor function that is called to compare values as an alternative to using a keystring. For a record, the first array field in the record specifies the sort dimension and only fields with the same dimension are re-ordered. The function call is:

    func(index1, index2)

    where index1 and index2 are the subscripts of the array values to be compared. The function must return an integer result:

    0   if val1 = val2
    < 0 if val1 < val2
    > 0 if val1 > val2

    The sort command treats a multi-dimension array as a single, large array.

    Overheads with the function option make it much slower than the keystring option, especially with large, multi-dimension arrays.

    For examples, see sort.r and sortbig.r in sculptor\examples.

    Return values:

    0 Successful
    -1 Nothing to sort (check the keystring and other parameters)
    >0 This number of fields specified in the keystring were ignored because they do not exist or because their dimension does not equal the dimension of the first specified sort field.
  2. The commands nextseq and nextsequ have been implemented. These are similar to next and nextu except that they retrieve the next record from the file in an undefined order. The syntax is the same as for next and nextu except that an index= clause cannot be specified. Because they don’t use an index, these commands are faster than next and nextu and are paricularly suitable for reading through an entire file when the order of the records is not important. The commands are implemented for Sculptor Keyed Files and for ODBC databases. The rewind command resets the file position to the beginning for nextseq and nextsequ.

  3. A new !compat has been introduced:

    !compat fontfix=1

    This causes Sculptor to calculate the default size of textboxes in a new way that works better with some fonts. Previously, the default width was too small for some fonts. This flag may be useful when creating new programs. If set in an existing program, the screen layout should be checked. Currently, spd does not detect this setting automatically. Start spd with the -f option to make it compatible with !compat fontfix=1.

  4. spd now changes it’s current working directory to the program file directory. This ensures that it works correctly when “open with” is used. When starting from a command line, use the new -k option if you need to stop spd changing directory.


  1. Transactions have been implemented in SQL and the Sculptor ODBC driver. By default, a statement that updates the database is treated as a single transaction (AUTO_COMMIT=ON). If AUTO_COMMIT is set OFF, a transaction must be ended by a COMMIT or a ROLLBACK. Example:
  1. In Sculptor ODBC, delete, insert and update statements return the number of rows affected.

  2. On 64-bit Windows there are two versions of the Microsoft ODBC (Data Sources) tool, one for 32-bit ODBC drivers and one for 64-bit ODBC drivers. Use the odbc_data_sources.bat file in \Sculptor\bin to start the correct tool.

  3. There are new functions for retrieving and changing process priorities:

    • get_process_priority(server_name, process_handle)

      Returns the priority class of a process. The value returned is one of the PROCESS_PRIORITY defines in sculptor.h. These are equivalent to the priority classes in the Windows API but are not the values used in that API. Administrator privilege may be needed to retrieve the priority class of a process not started by the calling program.

      If server_name is NULL, returns the priority class of the specified local process.

      If process_handle is 0, returns the priority class of the named Sculptor server.

      If server_name is NULL and process_handle is 0, returns the priority class of the calling program.

    • set_process_priority(server_name, process_handle, priority_class)

      Changes the priority class of the specified process.

    • get_thread_priority(server_name)

      Returns the thread priority of this client on the named Sculptor server. The value returned is one of the THREAD_PRIORITY defines in sculptor.h. These are equivalent to the thread priorities in the Windows API but are not the values used in that API.

      If server_name is NULL, returns the thread priority of the calling program.

    • set_thread_priority(server_name, thread_priority)

      Changes the thread priority of this client on the named Sculptor server or the calling program if server_name is NULL.

    On Unix and Linux, the default process “nice” value of 0 is deemed to be PROCESS_PRIORITY_NORMAL and THREAD_PRIORITY_NORMAL. The above functions change the “nice” value according to the following table. This is an approximate equivalent to the behaviour of the Windows API. To map a “nice” value to a priority class and thread priority when these values have not been previously set, Sculptor chooses a sensible fit. Some platforms bias the “nice” value so that it is always positive. In these cases, Sculptor makes the necessary adjustments automatically.

    PROCESS_PRIORITY_IDLE 19 14 12 10 9 8 -13
    PROCESS_PRIORITY_NORMAL 17 2 1 0 -1 -2 -13
    PROCESS_PRIORITY_ABOVE_NORMAL 16 -3 -4 -5 -6 -7 -13
    PROCESS_PRIORITY_HIGH 15 -8 -9 -10 -11 -12 -13
    PROCESS_PRIORITY_REALTIME -14 -15 -16 -17 -18 -19 -20

    Changing the priority class of a process should be done with extreme care as it will affect the performance of other applications. Generally, the priority class should only be lowered. However, it is reasonable to raise the priority class of the Sculptor server, because serving its clients is usually the most important application on a server.

    Thread priorities are used to alter the relative priority of a server’s clients. Use the Sculptor server manager to set the default thread priorities. The listen priority is for the thread on Windows (process on Unix) that listens for new connections. The client priority is for normal Sculptor commands and the SQL priority for SQL queries. An individual client can then use the set_thread_priority() function to change its own priority.

    IMPORTANT: On Unix and Linux only the super user can raise and lower the priority of a process. A normal user can lower their own priority but cannot then restore it to its original value. Also, confusingly, the lower the Unix “nice” value of a process, the higher its priority. If you need the Sculptor server to be able to raise priorities on Unix and Linux, the kfserver program needs to be owned by root and have u+s privilege.

  4. If sys.KeepAliveInterval is non-zero, Sculptor sends keepalive messages on all sockets when there is no other traffic. The interval is in seconds. The maximum time there can be no traffic on a socket is twice the interval. Once this value is set, a timer is started and further changes to the interval are ignored. The default value of sys.KeepAliveInterval is 0. This feature is useful on networks that automatically close a socket connection after a time-out period. This is one cause of socket errors.

  5. To install or update the Sculptor ODBC driver (scodbc6.dll), run the program regsvr_scodbc in the sculptor\bin directory.


  1. Sculptor 6.0.2 does not check for the variables SCULPTOR5, SCDATA5, SAGEDATA5 or SCLOGDIR5. It does check for the suffix 6 variants. These variables are designed to differentiate between Sculptor 2 and Sculptor 5 or 6 on the same system. They are not sufficient to differentiate between Sculptor 5 and Sculptor 6.

    If you have Sculptor 5 and Sculptor 6 installed on the same system, use the following rules to set a different environment for each version:

    1. Use the scconfig program to set different environment variables in the registry for Sculptor 5 and Sculptor 6.
    2. Use Sculptor 6.0.2 or later.
    3. Preferably use Sculptor 5.8.8c or 5.9.5 or later. With other versions of Sculptor 5, you must ensure that the “Current Version” in the registry is always set to 5 when you close scconfig.
  2. Some sql queries optimised to run much faster.

  3. Small improvements to the scconfig and servmgr programs.


  1. The environment variables SCULPTOR6, SCDATA6, SAGEDATA6, SCLOGDIR6 take precedence over the same names with a 5 suffix, which take precedence over the non-version equivalents.

  2. Added the IN and BETWEEN predicates to SQL and the ODBC driver.

  3. Added the “sql” resource to the Sculptor security database. By default, SQL has access to all files and runs in full update mode. Restrictions can be imposed as follows.

    Use sculptor\security\users.q to define users. Each user name must be given a unique, non-zero, userid.

    Use sculptor\security\resource.q to define the resources available to each userid. Note that userid 0 and 1 have special meaning:

    A resource allocated to userid 0 is available to all users.
    A resource allocated to userid 1 is available to all authenticated users.

    An authenticated user is one who has logged on with a valid user name and password.

    The following sql resources can be defined.

    sql:* All tables in all schemas in all catalogs.
    sql:catalog.* All tables in all schemas in this catalog.
    sql:catalog.schema.* All tables in this catalog.schema.
    sql:catalog.schema.table The specified table only.
    sql:DEFAULT.* All tables in all schemas in the DEFAULT catalog.
    sql:DEFAULT.DEFAULT.* All tables in the DEFAULT schema in the DEFAULT catalog.

    When sql security is active, the syntax to connect to a server in the SQL command line program is:

    connect to <server_name> USER <username>/<password>

    When a connection is made without a username, only resources defined for all users are available.

    When connecting to the Sculptor ODBC driver, use the connection string attributes UID=<username> and PWD=<password>.


  1. It’s now possible to connect to a SQL database in the Sculptor server by adding a “SCULPTOR_SERVER=” clause to the start of the source string in an ODBC database declaration. Example:

    +database mydb {
        type = DBT_ODBC
        source = "SCULPTOR_SERVER=myserver;DSN=mydsn"
        riu_timeout = 3

    Example of an alternative form of source string:


    The SCULPTOR_SERVER clause must be the first clause in the source string. Do not use {} to enclose the Sculptor server name as this is not supported. Connection to the ODBC driver is made on the server and all network traffic is handled by Sculptor, making it unnecessary to install the ODBC driver on the client.

  2. A mirrored database can also be declared in the above way, reducing network traffic substantially if the mirrored database is on the same server as the Sculptor database. This is not mandatory. The mirrored database can be local or can be accessed locally even if the source database is on a server. A mirrored database can now be either an ODBC database or a Sculptor database.

  3. If a database is declared as type DBT_SCULPTOR and has a source string, this is prepended to each database filename before it is opened. Example:

    +database mydb1 {
        type = DBT_SCULPTOR
        source = "myserver:c:/app/data/"
        !file FILE1 "file1"
        !file FILE2 "subdir/file2"

    Both file1 and file2 are opened on myserver at run-time. It is of course necesary to ensure that a corresponding path to file1.d and subdir/file2.d exists locally for program compilation purposes.

    Note: Linking from one Sculptor server to another is not supported. The following syntax will cause kfserver to fail at run-time:

    source = "server1:server2:c:/mydir/"
  4. A SQL engine has been implemented in kfserver server or kfservnt service. This engine, permits to access Sculptor keyed files using standard SQL queries. See Getting Started with Sculptor 6 SQL for an introduction and setup information. See Sculptor SQL Engine Features for full details of implemented features. These features can be accesed via a new sql command or a new ODBC driver (both of them connects to the kfserver/kfservnt SQL engine)

    The Sculptor SQL engine has been optmised to use existing indexes and to create and use temporary indexes when necessary. With some queries, for example those that use joins, it is much faster than the old Sculptor 2 SQL. Only the result set is transmitted back over the network, which further improves performance.

  5. The new Sculptor SQL command runs queries in kfserver. Because the new SQL follows the SQL-92 standard it is not fully compatible with the Sculptor 2 SQL program. This can still be used if needed but modifying queries to use the new SQL should be the preferred option.

    Demo programs are in \Sculptor\demo\sql.

  6. Sculptor 6 has a native ODBC driver that uses the same server technology as the new SQL command. As well as providing access to Sculptor files from other applications, it allows the embedded sql command in the Sculptor language to be used with Sculptor files as well as other SQL databases.

    The driver has been tested with Crystal Reports and with client programs coded in C# using .NET development tools. ODBC is a substantial and complex API and many features are optional. Please send a report if you find that this driver does not work with a particular ODBC client.

    To install the driver on a client PC or on a server, use the batch file \Sculptor\bin\install_scodbc.bat. On Windows Vista onwards it is necessary to use “Run as Administrator” with this script.

  7. The tracing environment variable TRACE_NPH-SREP is no longer supported, from now on the nph-srep should be traced using a special tracing nph-srep version configuring the TRACE_WWW and TRACE_PROG_NPH_SREP environment variables.


  1. On Windows, SCTERM defaults to dosbox and SCTERMW defaults to mswin if not otherwise defined.


  1. The exec and execu commands have two new forms:

    exec[u] "--program ..."
    exec[u] "-+program ..."

    These forms are meaningful only on Microsoft Windows. On Unix both work the same as a single “-“. On Windows either form can be used to execute a console program that does not use I/O redirection. Both avoid the flashing effect caused by the appearance of a Windows console.

    The -+ form executes the program as a detached process without a console window but allows the program to create a console later if required. Some programs, such as ssh (Secure Shell), need this option.

    The -- form executes the program without a console window. The program cannot create a console later. This form does not work on Windows 98 or ME.

  2. There is a new function:

    dir_to_file(file_id, directory, pattern, options)

    This is similar to the dir() function except that the filenames are returned by inserting records into the specified Sculptor file, which must be open in create or update mode, This avoids limitations with array sizes in the dir() function. For each filename, this function assigns values to the following “known” fields in the file buffer, then inserts a record into the file:


    An alphanumeric field to receive the filename. If the field is not long enough, the name is truncated.


    The file type code. See the dir() function (u1).


    Incremented by 1 before inserting each new record (i4).

    All fields are optional, though obviously FileName is normally needed. Other fields may exist and should be initialised as required. The Count field should be initialised before calling the function, normally to 0 but another value can be used if required. Any field may be a key field or a data field but either the FileName or the Count field should be in the key to ensure it is unique. Duplicate records are ignored and do not generate an error.

    Normally the file should be created empty before calling this function, though it is possible to design a file that can have records added from different directories.

    Returns the number of files found if successful. Returns a negative value to indicate an error.

  3. There are now two run() functions with identical parameters:

    run(file[, verb, param, dir, show])
    runex(file[, verb, param, dir, show])

    The run() function maps to the Windows function ShellExecute(). This function should be used if the calling program exits immediately after calling run().If the program does not exit, it may regain focus and be on top of the called application.

    The runex() function maps to the Windows function ShellExecuteEx(). This function should be used if the calling program does not exit after calling runex(). If it does exit, the new application sometimes opens with a blank document instead of the supplied document. This appears to be an issue in the Windows API.


  1. The server manager now dislays the number of licensed clients and the number of licensed mobiles currently connected. Note that connections from clients running on the server do not use a license and multiple connections from the same remote client count as one license.


  1. In the table colour_record, Cell[n,5] can now be used to define a transparent colour for table headings.

  2. So far as we have been able to determine, no Sculptor developers were using the Sculptor TAPI functions prior to Sculptor 5.9.1, so in order to improve the interface and fix some issues, the following changes have been made. Any existing programs that use TAPI will need to be modified.

    TAPI versions 1.3 through 2.2 are now supported. DeviceID now counts from 1 to number of devices, instead of from 0.

    The order of arguments has changed for following functions:

    tapiGetValue(DeviceID, Param1[, Param2])
    tapiSetValue(DeviceID, Param1, Param2)

    When DeviceID is not relevant, any value can be supplied.

    When the callback function receives a message with handle, it must pass this back to Sculptor using one of the following function calls:

    tapiSetValue(DeviceID, TAPI_VAR_CALL_HANDLE, Handle)
    tapiSetValue(DeviceID, TAPI_VAR_LINE_HANDLE, Handle)

    It is the application’s responsibility to determine the handle type from the message context. See the demo program \SCULPTOR\demo\tapi\tapi.f for some examples.

  3. A new function has been added to help debug Sculptor programs:


    This function appends a message record to a Sculptor Keyed File when the following conditions are both true:

    1. The program was compiled with the line: !compat enable_debug=integer and integer is non-zero.
    2. The Keyed File %SCULPTOR%\debug\dbgmsg exists.

    The keyed file is created when you run the following program:

    srepwc %SCULPTOR%\debug\dbgmsg

    Start this program before starting the program that you want to debug. The debug messages appear in a table in the program. Turn the refresh option off when you need to scroll back to see earlier messages and on again to see new messages. You can debug multiple interacting programs using this tool.


  1. Environment variables can be embedded in font strings. Examples:

    label_font = "$MYFONT@12"
    data_font = "$MYFONT@$MYFONT_SIZE"

    An environment variable name must be terminated by a punctuation character or end of string. Use $$ if a $ is required.

  2. In a table, the heading_type field in the cell_properties record can be one of:

    THCT_BUTTON Standard button with text
    THCT_IMAGEBUTTON Image only button
    THCT_TEXTIMAGEBUTTON Image button with text
    THCT_COLOURBUTTON Coloured button with text

    The button type above can be ored with TBHT_FLAG_FLATBORDER to specify a button with a flat border.

    The following new alpha fields can be defined in the cell_properties record:


    In the table colour_record, the foreground and background colours of the text on a button is defined in Cell[n,3] and Cell[n,4].

  3. General improvements to the server manager. The option “Don’t use the Sculptor security database” has been added. If this option is checked, the Sculptor server does not use Sculptor’s security database to verify client requests.

  4. New system variable:


    A pointer to the first window in the program. This will be one of the pre-defined windows. sys.FirstWindow can be assigned to another pointer field as shown in the following example:

    !temp pwindow,,p
    pwindow = &sys.FirstWindow

    Use the function nameof(pwindow) to get the name of a window.

  5. Windows and window controls have two new read only attributes:

    xorig The original value of xreate for the control.
    yorig The original value of yreate for the control.

  6. New functions:

    first_control(window_id | wingrp_id | menu_id)

    Returns a pointer to the first control in a window or window group, or to the first menuitem in a menu, or NULL if the object has no controls. Use typeof(pcontrol) to get the type of an object:


    Assign the return value to a pointer field as in the following example:

    !temp pcontrol,,p
    pcontrol = &first_control(wintask)


    Returns a pointer to the first child window in a window or NULL if the window has no child windows. Example:

    !temp pchild,,p
    pchild = &first_child(mywindow)


    Returns a pointer to the first menu in a window or NULL if the window has no menus. Example:

    !temp pmenu,,p
    pmenu = &first_menu(pwindow)


    Returns a pointer to the next object at the same level or NULL if there are no more objects at the same level.

    If pobject points to a menu, the next object is the next menu the same window.

    If pobject points to a menuitem, the next object is the next menuitem in the same menu.

    If pobject points to a child window, the next object is the next child window in the same window.

    If pobject points to a window control or a group, the next object is the next control or group in the same window at the same level. Note that if pobject points to a group, the next object is not a control inside the group. Use the following example to step through all the controls in a window, including controls inside groups:

    !temp pcontrol,,p
    !temp pingroup,,p
    pcontrol = &first_control(mywindow)
    while (isnull(pcontrol) == FALSE) {
        switch (typeof(pcontrol)) {
        case == OT_BUTTON:
        case == OT_TEXTBOX:
        case == OT_LISTBOX:
        case == OT_OLE:
        case == OT_TABLE:
        case == OT_GRAPHIC:
        case == OT_WINTEXT:
        case == OT_WINGRP:
            pingroup = &first_control(pcontrol)
            while (isnull(pingroup) == FALSE) {
                pingroup = &next_object(pingroup)
                switch (typeof(pingroup)) {
                case == OT_BUTTON:
                case == OT_TEXTBOX:
        pcontrol = &next_object(pcontrol)


  1. The index= clause in a !drive declaration can now be assigned to a pointer field:

    !temp idxptr,,p
        idxptr = &MYFILE.index2
    !report myrep {
    !drive MYFILE index=idxptr
  2. The following changes have been made to kfserver and kfservnt:

    For kfserver, the log file is now $SCULPTOR/log/kfserver.log instead of /tmp/kfserver.log.

    For kfservnt, the log file is now %SCULPTOR%/log/kfservnt.log instead of \kfservnt.log.

    The log file contains more details for a client connection that has been terminated abnormally.

    The following command line options can be used with both kfserver and kfservnt:


    Debug mode. Writes client connections and disconnections to the log file. On Unix, writes the stdout and stderr outputs of all executed child processes to the files:


    respectively unless these are redirected elsewhere in the execute command. These files are always recreated empty when kfserver is started with the -d option.

    -l Debug locks. Makes file and record locking details available in the remote monitor program.
    -n Creates a new empty log file. If this option is not used, messages are appended to the existing log file.


  1. If newkf is used to recreate an existing file and neither -s nor -b is specified, the type of the new file is the same as the old file.
  2. If “openfile … create” is used to recreate an existing file, the type of the new file is the same as the old file. The createbig keyword can be used to force a big file. There is no createsmall keyword.


  1. The programs servmgr.exe, kfserver.exe and kfservnt.exe now request Administrator privilege. The servmgr program should always be used to to start the Sculptor server manager. The program kfsmonw.q should not be run directly as it may then run without required permissions and may be unable to communicate with the server.
  2. When printing to a window, the size of the window is adjusted automatically to fit the report and the page length is restricted to the screen height. The visible area of the screen window can be forced larger by setting sys.PageLength and sys.PageWidth but Sculptor prevents the window size from exceeding the screen size.
  3. The maximum length of a long text field has been increased to 132,000.


  1. Added sql command line program. This supports SQL queries on Sculptor files. This is an interim version. Joins are very slow on large files. An improved version is being developed.
  2. iODBC is supported on many Linux and Unix platforms.


  1. The program servmgr.exe is now a stub that runs “srepwc kfsmonw”.


  1. The following functions enable Sculptor programs to communicate with C programs and with other Sculptor programs using shared memory segments. See “Shared Memory Functions.doc” for full details.

    shm_id = create_shared_memory(share_name, record_id, perms, options)
    shm_id = link_shared_memory(share_name, record_id, perms, options)
    nbytes = read_shared_memory(shm_id, offset, len, options)
    nbytes = write_shared_memory(shm_id, offset, len, options)
  2. On Microsoft Windows, standard Windows messages can be sent to C programs:

    result = send_message(hwin, msg, wparam, lparam)
    result = post_message(hwin, msg, wparam, lparam)

    Parameters, behaviour and return values for these functions are as described for the corresponding functions in the Windows API. The Sculptor program needs to obtain a Window handle from the C program. This could be supplied in a file or in a shared memory segment. These functions are for advanced use. They can be executed on Unix versions of Sculptor but have no effect.

  3. On Unix and Linux, standard Unix messages can be sent to C programs:

    msg_id = create_msg_queue()
    msg_id = link_msg_queue()
    result = read_msg_queue()
    result = write_msg_queue()
    result = remove_msg_queue()

    See “Unix Message Functions.doc” for full details.

  4. There are new control features in kfserver and new kfserver management programs have been introduced.

    On Unix, the C program kfsmon has been replaced by a shell script of the same name. This starts the new Sculptor server monitor for Unix:


    On Unix, kfserver can be started and stopped as before by using the shell script startkfs and the C program stopkfs, or it can be started and stopped from the new monitor program.

    On Windows, a new batch file kfsmon.bat starts the new Sculptor server monitor for Windows:


    On Windows, kfserver can be started from the command line as before and stopped from its own menu option, or it can be started and stopped from the new monitor program, which can also create, start and stop the Sculptor service version kfservnt.

    The new server monitor provides more details and better control of connected clients. Details of all connections are shown in a table (on Windows) or a listbox (on Unix). This is refreshed automatically at a user selected interval. A line in the table can be expanded by double clicking it. A line in the listbox can be expanded by tabbing into the listbox, using the arrow keys to select the line and then pressing RETURN. In the window that opens there is an option to disconnect the selected client. Note that the automatic refresh is suspended while focus is in the table or the listbox.

    The new monitor program has a Server Options button. This opens a window with checkbox options. If the remote management checkbox is ticked (+ sign on Unix), a snapshot of all client connections is written to a Sculptor file each time the client list is refreshed. This file can be viewed over a network by running the new remote management program on a Windows client:


    If the Sculptor server allows connections from the Internet, this makes it possible to manage kfserver connections on a remote client site. The remote management option can be turned on and off at any time. It is not necessary to restart kfserver.

    There is also an option to start kfserver in lock debugging mode. In this mode details of all locks held by all connected clients are written into a Sculptor file. A table of locks can be viewed in the remote management program remmon.q. Although this program is designed to run on a remote client, it can also be run on the server itself. Note that lock debugging mode cannot be selected or deselected once kfserver is running. This mode can only be changed by stopping and restarting kfserver. Lock debugging mode has a performance overhead, so it should only be used to diagnose locking issues.

    When kfserver is started from the command line, lock debugging mode can be selected by using the command line option -l. The service version kfservnt now also honours command line options.

  5. It is now possible to trap a TCP/IP socket error in a Sculptor program by by setting the system variable sys.ServerErrorFunction to point to an event function that is called if an error occurs. Example:

    sys.ServerErrorFunction = &ServerError
    !function ServerError(server, errcode, dirn, maincode, subcode) {
        error "Error " + tostr(errcode) + " on server " + server
        return 1

    Sculptor calls the function with the following arguments:

    server The name of the server
    errcode The system error code
    dirn 0 if error on sending a command to the server 1 if error on reading response from the server
    maincode The Sculptor main command code
    subcode The Sculptor sub command code

    The dirn, maincode and subcode values are provided for diagnostic purposes. Whatever the dirn value, the command may or may not have reached the server. The best way to guard against application errors caused by socket errors is to wrap related updates between calls to the begin() and commit() functions.

    The function can exit the program or return one of the following values:

    < 0 Display a standard socket error message and abort the program.
    = 0 Continue running the program. The command or function that was being executed when the error occurred will return with an error if possible (e.g. if it has an err= trap), otherwise with a null result. Continuing is not normally a viable option, since the program’s connection to the server has been lost and the command or function that was being executed has failed. However, it is technically possible to restablish a connection if the cause of the error has been corrected. Note that a program cannot issue a rollback() on a new connection. When the previous connection times out, kfserver will issue an automatic rollback().
    > 0 Abort the program without displaying an error message.
  6. There are two new functions that Sculptor programs can use to control client connections:

    get_client_info(server, port, client_id, random_id)

    Connects to the specified Sculptor server if not already connected and then returns connection information in the supplied fields:

    port The TCP/IP port number of the connection (u2 or longer).
    client_id A unique client id number allocated by the server (i4).
    random_id A random id number allocated by the server (i4).

    Valid port and client_id numbers are always non-zero.

    Function return values:

    < 0 Cannot connect to server
    = 0 Successful
    > 0 Not used, treat as error

    disconnect_client(server, port, client_id, random_id)

    Connects to the specified Sculptor server if not already connected and then sends a disconnect client request. The supplied port, client_id and random_id numbers must match a triplet returned by the get_client_info() function. If successful, the designated client is forcibly disconnected by kfserver. If that client had an open transaction, the transaction is rolled back. A program cannot use this function to disconnect itself.

    Function return values:

    < 0 Cannot connect to server
    = 0 Successful
    > 0 Port or client_id not valid

    A program could use these two functions to recover after a socket error. After connecting to a server, the program calls get_client_info() and saves its port and id values in a local file. Before exiting it clears these values. If, on starting, the program finds these values still set, it calls the disconnect_client() function to reconnect itself and to make sure that its previous instance is no longer running. If disconnect_client() returns > 0, the program should assume that the previous connection has already timed out.

  7. A new set of built-in functions enable Sculptor programs to create and manage Windows Services. This is an advanced feature. To use these functions, it will be necessary to read the Windows API documentation on the equivalent Service Management functions. Manifest constants used with the service management functions are defined in <services.h>.

    result = close_service_handle(handle)

    Closes a handle obtained from the create_service() or open_scmanager() functions. A handle should be closed when it is no longer required.

    Returns 0 if successful or non-zero if an error occurs. The Windows error code is in sys.Errno.

    result = control_service(service_handle, code)

    Sends a control code to the specified service.

    service_handle A handle returned by create_service() or open_service().
    code The control code to be sent to the service. Some standard codes (see the Windows API for full list): | SERVICE_CONTROL_CONTINUE | SERVICE_CONTROL_INTERROGATE | SERVICE_CONTROL_PAUSE | SERVICE_CONTROL_PARAMCHANGE | SERVICE_CONTROL_STOP | Codes 128 - 255 are for application use.

    Returns 0 if successful or non-zero if an error occurs. The Windows error code is in sys.Errno.

    service_handle = create_service(manager_handle, \
                                    service_name, \
                                    display_name, \
                                    description, \
                                    pathname, \
                                    dependencies, \
                                    account_name, \
                                    password, \
                                    access_rights, \
                                    service_type, \
                                    start_type, \

    Creates a Windows service and adds it to the service control manager database. See CreateService() in the Windows API.

    manager_handle A handle obtained by a previous call to open_scmanager().
    service_name Internal name for the service (cannot include / or \).
    display_name Display name for the service in Windows Service Manager.
    description A short description of the service (can be a null string).
    pathname Full path to the executable program. If the name contains a space it must be quoted. Arguments may follow the name.
    dependencies The service names of other services on which this service depends. Separate each name with a comma and avoid spaces. If this service has no dependencies, supply a null string.

    The name of the account under which the service is to run. If a null string is supplied, the service runs in the LocalSystem account. Other standard accounts are:


    The double \ is needed because \ is an escape character in Sculptor string constants. It becomes a single \ in the compiled program.

    password The password for the specified account. Supply a null string if the account has no password or the service runs in the LocalSystem, LocalService or NetworkService account.
    access_rights Desired access to the service. See the Windows API for full details. SERVICE_ALL_ACCESS can be used if the user running the program has Administrator priviliges.
    One of:
    One of:
    One of:

    Returns a service_handle if successful (store in i4 field) or 0 if the service cannot be created. The Windows error code is in sys.Errno.

    result = delete_service(service_handle)

    Marks the service for deletion from the service control manager database. The service is not deleted until all handles open to it are closed and the service is not running.

    service_handle A handle returned by create_service() or open_service().

    Returns 0 if successful or non-zero if an error occurs. The Windows error code is in sys.Errno.

    manager_handle = open_scmanager(machine_name, access_rights)

    Opens the service manager on a specified computer.

    machine_name The name of the target computer. A null string means the local computer.
    access_rights Desired access to the service. See the Windows API for full details. SC_MANAGER_ALL_ACCESS can be used if the user running the program has Administrator priviliges.

    Returns a manager_handle if successful (store in i4 field) or 0 if the manager cannot be opened. The Windows error code is in sys.Errno.

    service_handle = open_service(manager_handle, service_name, access_rights)

    Opens a service for control purposes.

    manager_handle A handle obtained by a previous call to open_scmanager().
    service_name The name of the service.
    access_rights Desired access to the service. See the Windows API for full details. SC_MANAGER_ALL_ACCESS can be used if the user running the program has Administrator priviliges.

    Returns a manager_handle if successful (store in i4 field) or 0 if the manager cannot be opened. The Windows error code is in sys.Errno.

    result = start_service(service_handle, arg_string)

    Starts the specified service.

    service_handle A handle returned by create_service() or open_service().

    A list of arguments to be passed to the service in standard command line format. Supply a null string if there are no arguments. An argument that contains embedded spaces must be quoted. Example:

    "-v \"-m=this is a test\""

    Returns 0 if successful or non-zero if an error occurs. The Windows error code is in sys.Errno.

    result = query_service_config(service_handle, record_id)

    Queries the configuration of the specified service.

    service_handle A handle returned by create_service() or open_service().

    A Sculptor !record that defines the required information fields. Fields must be named exactly as shown below. It is only necessary to define the fields whose values are required.


    Returns 0 if successful, in which case the service status information has been stored in the supplied fields. See the Windows API for details of the values stored in these fields.

    Returns non-zero if an error occurs. The Windows error code is in sys.Errno.

    result = query_service_status(service_handle, record_id)

    Queries the current state of the specified service.

    service_handle A handle returned by create_service() or open_service().

    A Sculptor !record that defines the required information fields. Fields must be named exactly as shown below. It is only necessary to define the fields whose values are required.


    Returns 0 if successful, in which case the service status information has been stored in the supplied fields. See the Windows API for details of the values stored in these fields.

    Returns non-zero if an error occurs. The Windows error code is in sys.Errno.

    result = add_account_privilege(computer, account, privilege)
    computer The name of a computer on the network. Use “” for the local computer.
    account The name of the account to which the privilege is to be added. Can be in the form domain\account.
    privilege The name of the privilege to be added. Refer to Microsoft documentation for a full list.


    add_account_privilege("", ".\\MyAccount", "SeServiceLogonRight")
    add_account_privilege("", "MyDomain\\MyAccount", "SeServiceLogonRight")

    Returns 0 if successful. Returns non-zero if an error occurs. The Windows error code is in sys.Errno.

  8. Standard Sculptor keyed files hold a maximum of 16,777,215 records. On Microsoft Windows and on Unix and Linux platforms that support large files, it is now possible to create a keyed file up to 128Gb in size with up to 134,217,727 records. A “big” file has a different format to a standard Sculptor keyed file and requires more disk space for the same number of records. Both file types can be used in the same program. To create a big file, use the openfile command with the createbig option:

    openfile file_id ... createbig

    or create the file with newkf -b:

    newkf -b filename

    The default mode in !file and !ofile can also be createbig but note that using the create or createbig option in the openfile command overrides the default mode. The mode specified in !file is used only if the file is opened automatically.

    By default, the kfcopy and reformat programs create the new file in the same format as the old file. The -b option forces the new file to be a big file. The -s option forces the new file to be a standard file:

    kfcopy -b old_filename new_filename
    reformat -b old_filename new_filename
    kfcopy -s old_filename new_filename
    reformat -s old_filename new_filename

    If the old index exists, the kfri program always creates a new index of the same type as the old index. If the old index does not exist, a big file index can be forced by using the -b option. The kfri program must not be used to change a file from standard type to big type or vice-versa. The -b option must be used only if the file is already a big file type.

  9. The function sendmail(record) opens the default email program on the host computer and starts an email. The argument is the name of a !record with some or all of the following fields:

    !record Email {

    Each field can be any alphanumeric size. The a80 sizes above are only examples. A long text field can be used and may be particularly useful for the body. Also, any dimension can be used for FileNames and Body fields, as needed.

    All non-blank elements of the FileNames field are the names of files to attach. The filenames may have full or relative pathnames. Sculptor converts the pathnames to standard full pathnames before passing them to the email program.

    sendmail() returns 0 if successful or non-zero if the default email program cannot be started or a specified attachment does not exist. This function works only on Microsoft Windows operating systems.

    See SCULPTOR\demo\misc\sendmail.f for an example program.


  1. This version is available for devices running Windows CE, such as PDA’s, Smartphones and Scanning Devices.

  2. It is now possible to change the xcreate and ycreate attributes of a window or control that is in the created state. This does not move the object. It only affects the position if the object is recreated.

  3. If a dotted IP address (e.g., is used for the server name, the Sculptor client now connects to the Sculptor server even if no DNS (domain name service) is available to the client. This is particularly useful when the client is a PDA or mobile phone connected to a wireless LAN.

  4. An EV_RESTORE event is sent to a window’s event function when the window is restored from a maximised size back to its previous size. This is a default event.

  5. When a tab window is resized, Sculptor now repaints the window without destroying and recreating the tabs. This is visually smoother.

  6. Files have a new property, report_mode, that can be set at run-time. If a !drive or !xfile has report_mode = 0 (default), its records are locked when read automatically during a report, but if report_mode = FOM_READ, the records are read unlocked, even if the file is open update. This applies only to an automatic read generated by a !drive or !xfile. A normal read command still locks the record. A file’s report_mode can be changed at any time, even in the middle of a report:

    file_id->report_mode = FOM_READ
  7. Sculptor has a new function that supports system tray icons:

    system_tray_icon(opcode, window, icon, tip)

    opcode is one of:

    STI_ADD Add an icon to the system tray
    STI_MODIFY Modify an icon in the system tray
    STI_DELETE Delete an icon in the system tray
    window The window whose event function receives events from this system tray icon. Normally use wintask but can be another window.
    icon An icon image file (.ico). If NULL, the standard Sculptor icon is used.
    tip Text for the tip. NULL if a tip is not required.

    A system tray icon can generate the following events. Note that a double event code is used to distinguish from the same event in the window itself.


    A single left click on the system tray icon. This is a default event.


    Double left mouse click on the system tray icon. This is a default event.


    Right mouse button up on the system tray icon. This is the preferred event for responding to right mouse clicks. This event is not sent by default and must be enabled.


    Right mouse button down on the system tray icon. Rarely used. This event is not sent by default and must be enabled.


  1. The maximum length of a long text field has been increased to 65500.


  1. The following environment variables, which have the main Sculptor version number appended, take precedence over the non-version equivalents:


    A Sculptor 2 update that supports this feature is available. This makes it easier to run Sculptor 2 and Sculptor 5 on the same system.


  1. The EV_CHANGE event that is sent when a window is being resized has been improved by adding a fifth argument that describes the resize event in more detail. The arguments are now:

    EventFunc(EV_CHANGE, win_id, drag_width, drag_height, event_detail)

    event_detail is one of:


    The window has been resized.

    If “Show window contents while dragging” is checked in the user’s display effects, this is an interim event that is sent each time the window has a new size during a drag opeation.

    If “Show window contents while dragging” is unchecked, this event is sent only once when the user has finished resizing the window because in this case the user is resizing only the border rectangle.

    This event provides the option to show new content in the window in accordance with the user’s preferences.

    If the programmer needs to scroll a window that is being resized, this must be done in the EV_CHANGE_SIZING event and/or the EV_CHANGE_END_SIZE event. The window must not be scrolled during its EV_CHANGE_NEW_SIZE event.


    The window has been resized. This is an interim event that is sent whether or not “Show window contents while dragging” is checked. The user is still dragging the window border.


    The window has been resized and the user has released the left mouse button. This event is sent whether or not “Show window contents while dragging” is checked.

    Note that EV_CHANGE events are not default events. They must be enabled.


There are two backward compatibility issues in this release. Please read compat for details.
  1. New function:

    setlocale(category, locale)

    Sets the required locale or returns the current locale.


    Use LC_ALL for all categories. See sculptor.h for other values.


    The required locale. This can be a full locale string that specifies the language, country and code page required, e.g. “French_France.1252” or just the language, e.g. “French”, in which case the default full string for the specified language is used.

    Returns the full name of the new locale. If the supplied value of locale is NULL or “”, returns the full name of the current locale.

    See example program: \sculptor\examples\setlocale.r

  2. There are two new edit modes for use with editable tables:


    The current line is never highlighted. Only a cell can be focused. There is still a current line and the is_selected() and set_selected() functions work as before.


    The current line is not highlighted when a cell has focus. A line can be highlighted by clicking on a non-editable cell.

  3. The do_drag_drop() function now has three optional parameters.

    do_drag_drop(object[, format[, width, height]])

    If width and height are specified, these define the size of the dragged rectangle in pixels.

  4. There is a new Sculptor debug tool called scdebug.exe. Please see the reference manual for usage information. Programmers who have beta versions of this program should remove their existing sculptor\debug directory completely and replace it with the one in this release. Also, use Task Manager to check for and end any sagewcd or srepwcd processes that are running before using scdebug. If a source file does not display correctly in the debug program, run it through the Sculptor cvteol program. Note that several features have not yet been implemented in the debugger and there is no need to report features that simply don’t work yet.

  5. Various bug fixes and enhancements have been made to ddeditor, proggen and file manager. There is a new command line syntax for proggen. See the reference manual for details.

  6. Sculptor can keep an ODBC database automatically synchronised with a Sculptor database. Read commands work from the Sculptor database, which is deemed to be the master. Update commands (insert, write and delete) are applied automatically to both databases.

    The Sculptor database can be an explicitly defined +|-database of type DBT_SCULPTOR, with its own set of !file declarations, or the default Sculptor database, which contains all independent !file declarations.

    The ODBC database must be declared using a -database declaration with type DBT_ODBC. This is a template database. It should not be opened and should not contain any !file declarations. It must have a valid source clause defined at compile time or set dynamically at run-time before being used. Other database properties such as flags and riu_timeout can also be specified but riu_timeout should normally be 0, otherwise there is the risk that an update to the SQL database will be missed simply because the server is busy.

    Any valid source string is acceptable. Examples:

    source = "DSN=mydatasource"
    source = "DRIVER=SQL Server;SERVER=myserver;DATABASE=master;\

    To use this mirroring feature, a program must first call the set_mirror_source() function to define the Sculptor and ODBC databases:

    set_mirror_source(sculptor_db, template_db, logfile, options, callback)

    sculptor_db An explicitly declared database of type DBT_SCULPTOR or NULL for the default Sculptor database that contains all files declared outside a database declaration.
    template_db The template ODBC database. If NULL, any existing mirror operation stops.
    logfile The full pathname to a logfile or “” if a logfile is not required. Errors in the mirror operation are logged to this file. Example: “myserver:/home/sculptor/log/mirror.log”

    Zero or one or more flags combined using |. Only one flag is currently implemented:

    Forces a new, empty logfile. If not set, error messages are appended to an existing logfile and a new logfile is created only if one does not already exist.
    callback NULL or the name of a user written !function. If a function name is supplied and Sculptor later loses the connection to the SQL database, this function is called once so that the program knows an error has occurred and the mirror operation has stopped. The function is called with a single argument - the id of the template_db.

    After calling set_mirror_source(), use the mirror command to specify the Sculptor files whose updates are to be mirrored to the ODBC database:

    mirror file_id1, file_id2, file_id3, ...

    Any number of mirror commands can be executed. It is not necessary to specify all the files in one command but updates to a file will not be mirrored until that file has been specified in a mirror command.

    Every time a record is updated in the Sculptor database, Sculptor applies the same update to the ODBC database. Sculptor also automatically inserts records and creates tables that are missing in the ODBC database.

  7. spd now has a settings option to specify whether or not a blank line is required between controls.


  1. The function set_thread_execution_state(state) has been withdrawn in this version as it is not supported by Windows NT4.


In the beta versions of 5.6.0, the directories ddeditor, manager and proggen each had a “Files” sub-directory. These sub-dictories are no longer used and should be deleted.

The debug programs sagewcd.exe and srepwcd.exe are not supplied with Sculptor 5.6.0. A new debug tool is being prepared and will be supplied in a future upgrade.

The Sculptor ODBC interface has been improved and performance is significantly better, especially with SQL Server. Some compatibility issues between SQL databases and Sculptor keyed files have been removed. There are also some useful new features. Existing ODBC based applications should be re-tested before using this release.

Early beta versions of the new program design tool were named scIDE.exe. This program is now spd.exe (Sculptor Program Designer). If you have been working with scIDE.exe, remove the following files before updating to this release:

In \SCULPTOR\default, remove all user sub-directories (Administrator and any other login names). These will be recreated with default settings when you start spd.exe. It will be necessary to redefine any projects you had created, so you may wish to run scIDE.exe and make a note of existing project settings before doing this.

descw.exe has been replaced by ddeditor.bat, which runs the Sculptor program \SCULPTOR\ddeditor\ddeditor.q

spg.bat has been replaced by proggen.bat, which runs the Sculptor program \SCULPTOR\proggen\proggen.q

The batch file \SCULPTOR\runme.bat removes obsolete files and moves obsolescent files (such as descw.exe) to \SCULPTOR\obsolete.

New features in Sculptor 5.6.0 are listed below. Full documentation for these can be found in the Sculptor Reference Manual.

  1. table_set_key(table_id, topline, row)

    For use with tables whose source_object is a Sculptor Keyed File. Scrolls the table so that the record whose key matches the current values in the file’s default record buffer is displayed on the specified row of the table (1 to table_id->rows). If the source_object is an index, the key values for that index must be set in the record buffer before calling this function. If a record with the specified key does not exist, the table is scrolled to the record with the next higher key. The topline argument determines the position of the vertical scroll bar. If this is not known a reasonable estimate should be provided or the nextkey command used to count this key’s position from the start of the file.

    One use for this function is to restore a table to a previously saved position. Since the table_get_key() function only returns the values for the main key fields, code similar to the following must be used to save the current position when the source_object is an index:

    !record save_fileid = fileid
    !temp save_topline,,i4
    table_get_key(table_id, 1)        /* Get key for current top line */
    readu fileid nsr=IGNORE           /* (if source_object is an index) */
    save_fileid = fileid              /* Save the current values */
    save_topline = table_id->topline  /* Save the current top line */
    fileid = save_fileid
    table_set_key(table_id, save_topline, 1)
  2. table_check_input(table_id, option)

    Checks a table for unsaved input in a textbox cell. Options:

    TABLE_TEST_INPUT Returns TRUE if there is unsaved input in a cell, otherwise FALSE. Does not save the input.

    If there is unsaved input in a cell, attempts to save it and returns:

    0 There is no input to save.
    1 Input saved.
    -1 There is invalid input that cannot be saved.

    A typical use for this function is during a right mouse event where it might not be safe to open a popup menu if a cell contains unsaved input.

  3. A cell in an editable table can now be a checkbox. Define the cell type as TCT_CHECKBOX. The box is ticked when the corresponding field in the source object is non-zero. If the user ticks or unticks the box, an EV_VALIDATE event is sent. The new value is Arg5 in the event function.

  4. spw.exe has been replaced by spd.exe (Sculptor Program Designer). Early beta versions were called scIDE.exe. This and $SCULPTOR\text\scide.eng should be deleted. Any projects that exist in $SCULPTOR\default\username for scIDE should be deleted and recreated using File->New Project and then Options->Settings in spd.

  5. bin\descw.exe has been replaced by ddeditor\ddeditor.q. If $SCULPTOR\bin is in the search path, this can be started from a DOS prompt by typing “ddeditor” or “ddeditor <dotdfile>”.

  6. bin\spg.g has been replaced by proggen\proggen.q. If $SCULPTOR\bin is in the search path, this can be started from a DOS prompt by typing “proggen” or “proggen <dotdfile>”.

  7. There is a new tool manager\kfman.q. This is the Sculptor File Manager. If $SCULPTOR\bin is in the search path, this can be started from a DOS prompt by typing “kfman”.

  8. The file $SCULPTOR\runme.bat deletes obsolete files and moves obsolescent files such as bin\descw.exe and default\spw.cfg to corresponding sub-directories in $SCULPTOR\obsolescent. To continue using one of these files, move it back to its normal place.

  9. There is a new printer property called PP_DEFAULTSOURCE. This is the user selected print bin and is returned by SelectPrinter(). See printer.h for a list of values (PR_DMBIN_…). Call SetPrintProperty() to select this bin.

  10. New command: writekl (write keep lock). This is identical to the write command except that the record remains locked. On some SQL databases, using writekl instead of write can substantially improve performance. See the notes on improving performance with SQL databases for details.

  11. New command: closefile file_id[,file_id]… Closes the specified files, resets the file positions and releases other information about the files currently cached on the server. The closefile command is preferred to the generic close command, which for historical reasons closes the system file handles but retains the file position and other information cached on the server.

  12. The sql command now has an optional err=label clause. This traps an error in the sql statement and passes control to the label instead of generating an ODBC debug message. The err= clause must be the last clause in the statement. When the err= trap occurs, Sculptor returns error information in the following system variables:

    sys.Error The native database error code (i4).
    sys.SQLState The SQL state code (a5).

    For SQLState codes, see the Microsoft ODBC documentation. For sql commands that have no select or parameter variables, the statement is executed using the ODBC function SQLExecDirect(), otherwise the statement is prepared using SQLPrepare() and then executed using SQLExecute().

  13. New function: sql_set_stmt_attr(cursor_id, attr_id, value) Sets a statement attribute for an ODBC cursor. Some useful attribute id’s are defined in sculptor.h (SQL_ATTR_). Associated values are defined below these. This function is for advanced use with the sql command. See the Microsoft ODBC documentation for SQLSetStmtAttr() for further details.

  14. nph-srep now supports the execute() function.

  15. The Sculptor interpreter now traps a GPF, issues a message and exits gracefully.

  16. The function table_focus_cell() has an optional fourth parameter:

    table_focus_cell(table_id, row, col[, view_row])

    view_row is a visible row number in the range 1 to table_id->rows If possible, the line that contains the focused cell is positioned on view_row. For example, if the table has 5 rows and view_row=3, the selected row will be the middle row.

  17. The EV_RIGHT_MOUSE_UP and EV_RIGHT_MOUSE_DOWN events are now sent for a static text control if enabled.

  18. Windows and groups can have an options= clause. Valid options, which are defined in sculptor.h, can be combined using the | operator:

    OPT_NOCOLOURED Valid for a tab window. The tab does not inherit the background colour of the tab window. This makes it possible to have a set of tab windows, each with a different background colour, but with their tabs having the same, default window background colour.
    OPT_TABOUT Can be set for a group. If a control in the group has focus and the user presses the tab key, focus moves the first control outside the group instead of to the next control in the group.
  19. The data type of a field can be retrieved at run-time using:


    The data type of b4, i4, n4 and u4 fields can be interchanged:

    field_id->datatype = new_datatype

    The following changes are valid:


    All other changes are ignored. No attempt is made to convert the value in the field.

    When a datatype is changed, the number of implied decimal places is reset to zero. For n4 fields only, the number of implied decimal places can then be set using:

    field_id->impdp = number

    One use of the above features would be to define an i4 field in a data dictionary and then change it at run-time to a type not supported in the .d file, such as n4.1 or n4.3.

  20. The “name=” clause in an openfile command can contain a SQL database connection string as an alternative to a pathname. Examples:

    openfile FILE1 \
      name="DBID=db1;DRIVER=SQL Server;SERVER=myserver;DATABASE=master;" create
    openfile FILE2 \
      name="DBID=db1;DRIVER=;...;UID=username;PWD=password;" update

    The first field=value pair must be “DBID=database_id;” where database_id is a database declared in the Sculptor program. This informs Sculptor that the table is to be attached to that database. All other field=value pairs are standard. If a value parameter contains non-alphanumeric characters, it should be enclosed in {}. Example:

    openfile FILEID name="DBID=db1;...;SERVER={myserver-001};...;" update

    The table name is taken from the !file declaration. Sculptor ignores any path information and extracts only the base filename for use with ODBC.

    For a complete definition of an ODBC connection string, see the MSDN documentation for the function SQLDriverConnect().

    You don’t need UID and PWD if you are using Windows Authentication and a trusted connection but you need them if you are using SQL Server authentication.

    There is no need to define an ODBC data source. The following database definition is sufficient:

    -database db1 {
        type = DBT_ODBC
        flags = DBFL_CASE_SENSITIVE    /* This clause is optional */
    !file FILE1 "file1"
    !file FILE2 "file2"

    –database must be used because the database can’t be opened until the first openfile command has supplied the connection information.

    When this type of openfile command is used, the files can be declared inside the database structure as above or outside as below:

    -database db1 {
        type = DBT_ODBC
        flags = DBFL_CASE_SENSITIVE    /* This clause is optional */
    !file FILE1 "mydata/file1"
    !file FILE2 "mydata/file2"
  21. Because SQL Server waits on a locked record and does not return a record in use status, a timeout option has been introduced in the database structure. If a timeout occurs, it triggers the riu trap:

    -database mydb {
        riu_timeout = 5    /* Value in seconds */

    The riu_timeout value can be changed at run-time:

    mydb->riu_timeout = 0

    A value of zero means no timeout and SQL Server will wait indefinitely for a locked record.

  22. Sculptor keyed files sort positive integer key values first, followed by negative key values. SQL databases sort negative values first. The Sculptor sequence is historical but some applications rely on it. If the SQL database supports binary fields, it’s possible to sort one or more key fields in the same way as Sculptor. To do this, the SQL database must be created in Sculptor with one or more flags set. Once the table has been created, the sort sequence is fixed, so the flags are not needed when opening an existing table.

    To make a specific i2 or i4 key field sort positive values first, set its “U” flag at run-time before creating the table:

    fldname->flags = "U"    (the U must be upper case)

    To make all main index key fields sort positive values first, set the following database flag before creating the table:


    DBFL_UNSIGNED_KEYS has no effect on secondary index key fields, so the “U” flag must be set for these if required.

    When Sculptor creates the table, it makes the i2 or i4 field a binary(4) field in the SQL data dictionary. Sculptor then handles all translations between integer and binary automatically.

    To make it easy to use a non-Sculptor reporting tool, Sculptor creates a second, computed SQL field for each such binary field (but only if the SQL database supports computed fields). These fields are given the same name as their corresponding Sculptor fields but have the prefix “int_”. When these fields are retrieved in a reporting tool, their values are returned as normal integers. Computed fields are read-only and cannot be updated.

  23. The Microsoft Access ODBC driver is not multi-user safe and we advise using Access in single user mode only. If it is essential to work with Access in multi-user mode, set the following flag in the database declaration:


    This tells Sculptor to perform updates to an Access database in a slower but more reliable way. This technique has proved reliable in tests but safe multi-user operation cannot be guaranteed. This flag must also be set if you are using an Access data dictionary that contains a key field of type AutoNumber.

  24. New command: sync_indexes file_id[, file_id]…

    Synchronises the current file position of all secondary indexes for the specified file to the current main index file position. Otherwise, each index maintains its own file position. The sync_indexes command affects a subsequent next[u], nextkey, prev[u] or prevkey command on a secondary index. Note that if the user defined key for a secondary index is not unique, the read[u] and readkey commands on that index always return the first record that has the supplied secondary index key - the current values in the main key fields are not taken into account.

  25. To obtain maximum database compatibility, the batch_read flag is now OFF by default for both Sculptor and ODBC files. Setting this flag can improve performance substantially. Setting this flag is recommended in most circumstances. See the Reference Manual for guidelines.

  26. New function: set_thread_execution_state(state) Sets the execution state of the current program. Some power save settings cause the execution of a background process to pause until the user moves the mouse or presses a key. This function can be called to inform Windows that this program must be kept running. Normal, interactive programs do not need to call this function. For details, please see the documentation for the function SetThreadExecutionState() in the Windows API. States are defined in sculptor.h beginning ES_. The return value is the previous state (i4).



  1. The directory name in the dir() function can be on a server and can contain environment variables.

  2. array_to_text(start_element, count)

    Extracts characters from an array starting at the specified element. Continues across element boundaries until ‘count’ characters have been extracted or the end of the array is reached. The array can have multiple dimensions. Returns a long text string.

    !temp LongText,,a200[10],,p
    !temp TextArray,,a100[20,1000]
    LongText = array_to_text(TextArray[10,1], 2000)
  3. text_to_array(start_element, count, text)

    Copies characters from a text string, which can be long text, to an array starting at the specified element. Continues across element boundaries until ‘count’ characters have been copied or the end of the array is reached. The array can have multiple dimensions.

    text_to_array(TextArray[10,1], 2000, LongText)
  4. The style WS_THEMED has been introduced for static text. This style should be set for static text that is used as a control label. When the program is running in a themed environment, Sculptor draws the text using the theme style and colour. It is not possible to override the foreground colour of themed text. If a foreground colour is specified, it is ignored in a themed environment and used only in a classic environment. If a background colour is specified, it is used in both environments but specifying a background colour for themed text is not recommended as it may clash with the selected theme. Also, in a themed environment, Windows draws standard control labels two pixels left of the position it draws them in a classic environment. For this reason, programs that use themed text are best designed on a themed platform, especially if themed text needs to be aligned with standard control labels. To compensate for this difference, Sculptor positions themed text two pixels right of its defined x coordinate when the program is running on a classic Windows platform.

  5. If the user clicks a window’s close button while a textbox has focus and in the EV_CLOSE event the program exits, then by default any value typed into the textbox is not saved. This allows a program to be closed even though invalid data has been typed into the textbox. If the program requires the value to be saved, subject to validation, then it can now execute the save_text command in the EV_CLOSE event.

SCULPTOR 5.5.1 and 5.5.2


  1. In a program compiled with scc 5.5 or later, a menu defined in a child window with style WS_OWNED now appears in the child window instead of the parent. If an existing program relies on this behaviour, the menu should be moved to the parent window before recompiling the program. If this is inconvenient, add or uncomment the line “!compat childmenu=4” in the standard header file $SCULPTOR/include/local.h.

  2. The quality of scaled images has been improved.

  3. Buttons are now supported as headings for table columns. The following fields have been added to the cell_properties record for a table:


    This can be 0 (for the standard, text heading) or TCT_BUTTON (for a push button).


    This defines the event function for the heading control. For TCT_BUTTON, the only event sent is EV_BUTTON_CLICKED but the event code should be checked because new events may be added in the future. Note that this is a pointer field. The following syntax should be used to set the required event function:

    heading_event[col] = &EventFunc

    The event sent is:

    EventFunc(EventCode, Object, Line, Col)

    Object is the table id, Line is 0, Col is the column number.

  4. An EV_MOUSE_OVER event can be enabled for a window or control:

    event_enable = EV_DEFAULT | EV_MOUSE_OVER

    If enabled, the object receives a stream of EV_MOUSE_OVER events as the mouse passes over it. These events are only received if the program is in a dialog. The event function is called as follows:


    func(event_code, table_id, line, column, xctl, yctl, xwin, ywin, virtkey)

    line The line number clicked (0=headings, -1=below last line)
    column The column number clicked (0=left of first, -1=right of last)

    Other arguments as for other controls below:

    func(event_code, object_id, xctl, yctl, xwin, ywin, virtkey)

    xctl X position in pixels relative to the control.
    yctl Y position in pixels relative to the control.
    xwin X position relative to the control’s effective, parent window. In pixels or characters depending on the program grid.
    ywin Y position relative to the control’s effective, parent window. In pixels or characters depending on the program grid.
    virtkey A virtual key code that indicates the state of mouse buttons, the shift key and the control key. See the defines prefixed MK_ in SCULPTOR\include\sculptor.h for bit values that can be tested using the & operator.

    The effective parent is the highest window in the parent window chain that has no further parent or has style WS_OWNED.

  5. A browse_for_folder() function has been introduced. This creates a browse dialog that uses a tree view control and returns a selected folder name. It can also be used to select a filename.

    browse_for_folder(window_id, parameter_record)

    The dialog is opened relative to this window.


    The name of a !record structure defined as follows:

    !record <name> {

    Fields that are not required can be omitted, in which case their value, if required, is taken to be zero or blank.


    A text string that is displayed above the tree view control in the dialog window. Can be used to provide instructions such as “Please select a folder to save this document.” The a80 size is arbitrary. The field can be larger or smaller.


    Receives the name of the selected file or folder without path information. Blank if the user cancels the dialog. The a80 size is arbitrary but the field needs to be large enough to receive the name of any object that can be selected.


    Zero for default options, otherwise one or more of the !define flags prefixed BIF_ in SCULPTOR\include\files.h, combined using the | operator. If the BIF_BROWSEINCLUDEFILES flag is set, the dialog allows files as well as folders to be selected but the program must then determine the type of the returned object. The Sculptor function fileinfo() can be used for this purpose.


    An integer value that identifies the root folder for the dialog. If zero, the root folder specified in RootPath is used, otherwise this should be one of the !define values prefixed CSIDL_ in SCULPTOR\include\files.h identifying a standard, Windows folder. If the standard folder does not exist on the system, the default root path (the desktop) is used.


    If RootIDl is 0, the pathname to be used as the root folder. Either ‘/’ or ‘' can be used as a directory separator but note that in a string constant, ‘' must be escaped by typing “\”.

    browse_for_folder() returns the full pathname of the selected file or folder. If the user selects a special object, such as a computer name, the returned pathname is blank and the object name is in the DisplayName field. This is only possible if the root path allows access to such an object. If the user cancels the dialog, both the return value and DisplayName are blank.

    browse_for_folder() is a direct interface to a Windows control that can behave differently depending on the version of Windows and in some cases the version of Internet Explorer that is installed. In general, simple browsing for a file or directory with the default flags works the same on all systems but for more complex folder browsing, refer to the Microsoft documentation for the SHBrowseForFolder() function and test on all the Windows platforms that you need to support. One point worth noting is that the BIF_NEWDIALOGSTYLE flag creates a “New Folder” button on platforms that support it but the BIF_NOWNEWFOLDERBUTTON flag, which omits this button, is not supported on some platforms that support BIF_NEWDIALOGSTYLE.

    The sample program browse_for_folder.r in SCULPTOR\examples can be used to test all combinations of flags and root pathnames.

  6. The current text in a textbox, including a textbox that is the currently focused cell in an editable table, can be retrieved by calling the function get_text(control_id). This is particularly useful inside an event function. For a button, this function returns the label. For other controls get_text() currently returns a null string but this may change in the future.

  7. The system variable sys.UseTheme (u1) has been added. A non-zero value indicates that Sculptor is using a Windows Theme. A zero value indicates that it is using a classic style. “!compat notheme=0|1” has also been introduced. Setting this non-zero forces the program to use a classic style even if the user has selected a theme for the desktop. On versions of Windows that support themes, sys.UseTheme can be changed at run-time. BUG: The windows and controls are repainted but a slight remnant from the previous style exists. This is being investigated.

  8. The Sculptor File Manager has been released. This program, written in Sculptor, is a front end for the keyed file utilities kfcheck, kfri, newkf and reformat. The output of the utilities is displayed in a table, which can be printed or saved to a file. The program also contains options to move, rename, copy or delete a Sculptor keyed file and all associated files and directories. File Manager also acts as a front end for the Sculptor directory copying program kcopydir. The File Manager program is called kfman.q and it is located in the directory $SCULPTOR\manager.


  1. There are functions to convert between pixel and character co-ordinates:

    cols_to_pixels(window_id, ncols)
    rows_to_pixels(window_id, nrows)
    pixels_to_cols(window_id, npixels)
    pixels_to_rows(window_id, npixels)

    Each function converts the supplied value and returns the result. The window_id is needed because the character grid is based on the window’s data font.


  1. Considerable functionality has been added to nph-srep. For details, see “Special tags for HTML files” in the Sculptor Reference Manual.


  1. There is a new function that provides advanced execution and control of child processes:

    execute(server, command, directory, flags, show[, stdin, stdout, stderr])

    server Name of server. NULL or a null string for the local machine.
    command The program to be executed and any arguments. Prefix the command with “-” to avoid getting a command shell. A command shell is needed if the command contains I/O redirection. On Unix but not on Windows, a shell is needed if there any wildcard arguments. A trailing “&” is optional because execute() always runs the child process concurrently.
    directory Directory in which program starts. NULL or null string for the current working directory of the parent program.
    flags On Windows, this is passed as the creation flags argument to the CreateProcess() function. Not used on Unix. Use 0 for standard options. Some of the more useful flags are defined in sculptor.h beginning EXEC_. This is an advanced feature for special requirements. Please read the Microsoft documentation before using. Multiple flags are combined using the | operator.
    show Requested show option for the child process. This must be one of the AA_ flags defined in sculptor.h. If there is no special requirement, AA_SHOWNORMAL is recommended. Do not code as 0 (AA_HIDE) unless you want the child process to be hidden. Some programs will override this flag when they start.

    If non-zero, specifies a channel number. Sculptor creates a pipe that connects this channel in the parent program to the standard input channel of the child process. The commands put #stdin and putfield #stdin can then be used to write messages to the child’s standard input (where stdin is this channel number).

    The channel number specified for stdin must not be open when execute() is called and must be closed using close #stdin when it is no longer required.

    If the child process is a Sculptor program, it can open its standard input channel as follows:

    open #channel, "stdin" read

    A Sculptor program can also read from its standard input using get #0 and getfield #0. Channel 0 should not be opened or closed.


    If non-zero, specifies a channel number. Sculptor creates a pipe that connects this channel in the parent program to the standard output channel of the child process. The commands get #stdout and getfield #stdout can then be used to read the child’s standard output messages (where stdout is this channel number).

    The channel number specified for stdout must not be open when execute() is called and must be closed using close #stdout when it is no longer required. stdout cannot be the same as stdin.

    If the child process is a Sculptor program, it can open its standard output channel as follows:

    open #channel, "stdout" create

    A Sculptor program can also write to its standard output using put #0 and putfield #0 but this method is not recommended because put #0 writes to the current report output when used inside a “run report” command.

    Messages written to stdout are buffered by the operating system and are only flushed when the buffer is full, the program exits, the channel is closed or an explicit flush command is called. Programs that communicate through pipes must ensure that any output to a pipe is flushed before they wait for input on another pipe. This can be done with the command:

    flush #channel

    If non-zero, specifies a channel number. Sculptor creates a pipe that connects this channel in the parent program to the standard error channel of the child process. The commands get #stderr and getfield #stderr can then be used to read the child’s standard error messages (where stderr is this channel number).

    The channel number specified for stderr must not be open when execute() is called and must be closed using close #stderr when it is no longer required. stderr cannot be the same as stdin but it can be the same as stdout and this is often the most useful option.

    If the child process is a Sculptor program, it can open its standard error cahnnel as follows:

    open #channel, “stderr” create

    The comments above about flushing stdout also apply to stderr.

    stdin, stdout and stderr are not yet supported for programs executed on a server.

    If execute() fails, it returns -1 and stores the current system error code in sys.Errno but there can be many reasons for failure and some may not generate a meaningful error code.

    If execute() is successful, it returns a handle to the child process. The execute() function does not wait for the child process to exit. The handle must be stored in an i4 field and can be used to get information about and to control the child process. The close_handle() function must be called when the handle is no longer required, otherwise system resources allocated to the child process will not be freed, even after the process has exited.

  2. The following new functions work with handles:

2.1 exitcode(server, child_handle, wait_msecs)

server Name of server. NULL or a null string for the local machine.
child_handle A field containing a value returned by execute().
wait_msecs Milliseconds to wait. If wait_msecs is 0, exitcode() returns the current state of the child process immediately, otherwise it waits until the child process terminates or the specified number of millisconds has elapsed, whichever occurs first.

exitcode() returns the child’s exit code (0-255) or one of the following sepcial values, defined in sculptor.h:

CHILD_PROCESS_INTERRUPTED -2 Terminated by an interrupt.
CHILD_PROCESS_FAILED -1 The execute() was not successful.

If the process exit code is above 255, only the low order byte is returned. This is a system limitation on both Unix and Windows.

If the Window’s Task Manager is used to end a process, it seems to exit with 1 (if “End Task” is used) or 0 (if “End Process” is used) but this has been determined by experiment and not found in any documentation.

It is bad practice to use a wait time longer than a few seconds because this prevents Sculptor from processing messages. Windows programs should process messages at frequent intervals to prevent undesirable effects such as not repainting a revealed window. On the other hand, a pure code loop wastes CPU time that can be better allocated to other tasks. Best practice is to use a delay loop as shown in the following example:

do {
    tmp.ExitCode = exitcode(NULL, tmp.ChildHandle, 300)
} while (tmp.ExitCode == CHILD_PROCESS_RUNNING)

2.2 end_process(server_name, child_handle, exitcode)

server Name of server. NULL or a null string for the local machine.
child_handle A field containing a value returned by execute().
exitcode Required exit code (Windows) or interrupt number (Unix).

Forces the specified process to terminate. On Windows, the process exits with the specified exit code. On Unix, this value is the interrupt to be sent to the process (0 means use the default, which is SIGTERM).

2.3 close_handle(server_name, child_handle)

server Name of server. NULL or a null string for the local machine.
child_handle A field containing a value returned by execute().

Closes the specified handle and sets the value of the handle field to -1. This function must be called when the handle is no longer needed, otherwise resources remain allocated to the child process even though it has exited.

  1. server_info(server, rec_id)

    Returns information about the named server and places it in fields in the supplied record buffer. Some or all of the following fields can be defined. The order of the fields in the record is not important. Other fields not used by this function can also be defined.

    rec_id.MaxUsers The number of licensed users on the server.
    rec_id.Platform The server platform: 1=Windows, 2=Unix.
    rec_id.ScMajorVersion The major version number of the Sculptor server.
    rec_id.ScMinorVersion The minor version number of the Sculptor server.
    rec_id.ScFixVersion The fix version number of the Sculptor server.
    rec_id.ScDateVersion The release date of the Sculptor server.

    server_info() Returns 0 if the call is successful or -1 if the specified server cannot be contacted.

  2. nap(millisecs)

    Suspends the calling program for at least the specified number of milliseconds but sometimes for longer due to clock granularity and task switching.

  3. When Sculptor starts a concurrent (background) child process on Windows, it normally calls a Windows function that waits for the child process to finish initialising. A timeout of 30 seconds is used. The parent program does not continue until the child process is “waiting for user input with no input pending” or 30 seconds has elapsed. This gives the child process time to start up and gain focus. This causes an undue delay if the child process does not normally interact with the user or has substantial work to do before interacting with the user. To avoid this delay, put “&&” at the end of the command line. This is valid with exec, execu and execute().

  4. Two new functions are available that make it easier to mix the drawing functions with standard Sculptor print commands:

    getprintxy(fld_xpos, fld_ypos)

    fld_xpos and fld_ypos receive the current x and y position in device units associated with the Sculptor print[h] command. These values can be used to determine suitable co-ordinates to use with a drawing function.

    setprintxy(expr_xpos, expr_ypos)

    Sets a new x and y origin for the next Sculptor print[h] command. Sculptor resets it’s current column and line numbers to match, rounding up to the next whole character and line position if necessary. Example:

    print "This line precedes the formatted text"
    print tab(0);   /* Move to start of left margin */
    sys.Unit = 0    /* Work in device units */
    getprintxy(xpos, ypos)
    yinc = DrawFormattedText(NULL, xpos, ypos, packed_text, "Arial@10", \
                             80 * sys.AvgCharWidth, 4 * sys.LineHeight, \
                             DT_WORDBREAK | DT_EDITCONTROL)
    setprintxy(xpos, ypos+yinc)
    print "This line follows the formatted text"

    The field “packed_text” in the above example would be an array field with format “p” used to store text typed into a free format, multiline textbox.

  5. Sculptor now conforms to the Windows XP Theme when that is selected. At present, image and coloured buttons do not adopt the XP theme. These controls will be enhanced in a later release.

    NOTE: Sculptor support for the Windows XP theme is now built in. Any existing files in the SCULPTOR\BIN directory with extension .manifest should be deleted.

  6. When an EV_KEYSTROKE event or a function called by an “on local” or “on global” command sets focus to a new control, any new content that was typed into a textbox is not saved. This is useful because it is possible to trap a keystroke and cancel the input. To validate and save the input before the new control gains focus, use the new “save_text” command inside the function. Note that this command does not save the text immediately. It gets saved when the function returns provided that the input is valid. If the textbox has a validation function, this will be called first. Example:

    on global KEY_PGDN PageDown
    !function PageDown() {
         switch (sys.CurrentControl) {
         case ?= TextBox1:
            return TextBox2
         case ?= TextBox2:
            return TextBox3
  7. sys.InputRow has been introduced. Sculptor sets this to the current row number when it saves text in sys.InputBuf. This applies to standard, multi-row textboxes, not to free format textboxes.

  8. The system handle for a window or control can be obtained from its window_handle property. This read only property can be used to set an OLE control property that requires a window handle. Example:

    oleMPlayer->"hWndDisplay" = winVideo->window_handle
  9. Normally, Sculptor keeps a bitmap permanently allocated for each table but if the environment variable SC_CONSERVE_MEMORY is set, this bitmap is destroyed and recreated as needed. This variable is provided for use when several large programs need to run concurrently and the physical memory pool is being exhausted, causing swapping. Typically, this will only be an issue in a terminal server environment, such as Citrix. Screen drawing is slower when this variable is set. (To use SC_CONSERVE_MEMORY, set its value to 1. Sculptor does not check the value at the moment but in the future, the value 0 may be interpreted as false.)

  10. The event EV_CHANGE is sent to a window event function after the user has resized the window:

    EventFunc(EV_CHANGE, window_id, old_width, old_height)

    The new width and height are in window_id->view_width and view_height. This event must be enabled (event_enable = EV_DEFAULT | EV_CHANGE).

  11. fontmetrics(FontDefn, AverageCharWidth, CharHeight)

    This function takes a font definition, e.g. “Arial@8” and returns the average character width and the character height in pixels in the fields provided. In a program that uses pixel co-ordinates, these values could be used to set a window width and height to suit a user selected font:

    window_id->max_width = AverageCharWidth * 120   /* 120 columns */
    window_id->max_height = CharHeight * 40         /* 40 rows */
  12. The system temp sys.LoggedOnUser is a variable length, alphanumeric field that is initialised to the name of the logged on user the first time its value is read. The name is available on M/S Windows and Unix and is obtained from an operating system call, not from the environment variable LOGNAME. This makes sys.LoggedOnUser more secure than sys.UserName. On some Unix systems this call is very slow, which is why the value is not initialised automatically when the program starts. Since the field length is 0 until it has been read for the first time, a textbox that is linked to this field must be created after retrieving the value. The following code can be used:

    !temp Dummy,,a1    /* Field size not important for this purpose */
       tmp.Dummy = sys.LoggedOnUser
       create tbLoggedOnUser
       display tbLoggedOnUser
  13. When a report is run using ppf=”winrtf”, Sculptor creates a temporary file and opens it with the default or a specified viewer program. Sculptor then waits for the viewer to close the file in order to delete it. Some viewers keep the file open, forcing Sculptor to wait until the program exits. There has also been a report that on multi-processor systems, the file can be deleted before the viewer program has opened it. To resolve these issues, a new program, waitdel.exe, is now supplied with Sculptor. After passing an rtf file to a viewer, Sculptor runs this program in the background. The program waits for 30 seconds so that the the viewer program has had time to load the file, then waits until it is able to delete the file. This resolves both the above issues.


  1. Tables and listboxes now support the tooltip clause.


  1. It is no longer necessary to destroy and recreate a table in order to change the colour properties of headings, labels, etc.

  2. There is an optional, sixth argument to the fileinfo() function:

    fileinfo(pathname, size, date_created, date_accessed, date_updated[, mode])

    The mode field contains bits that define file type and permissions. See $SCULPTOR/include/files.h for details.

  3. To make it easier to debug Internet applications, a trace option has been added to nph-srep. To use this, set the environment variable TRACE_NPH-SREP to the full path to a file, e.g. C:/TMP/nph-srep.txt. This variable must be set at system level and the system rebooted because nph-srep inherits its environment from a web server that starts running when the system is booted. If this variable is defined, nph-srep creates the file and writes debugging information to it, such as its working directory and the values of web parameters. If this file is not created, then either nph-srep has not been called or you are using an old version. Check that you have nph-srep.exe version 5.3.2d or later in your cgi-bin directory by running it with no arguments from a DOS command. Later versions display their version number and the value of TRACE_NPH-SREP. The file xerces-c_1_3.dll must also be in the cgi-bin directory. Check that this file is not named incorrectly as xerces_c_1_3.dll. The new version of nph-srep also writes some error messages into the web page that previously were lost.

  4. There are two new functions to control the formatting of text drawn with the DrawText() function. These are:

    GetTextAlign(window_id) SetTextAlign(window_id, flags)

    GetTextAlign() returns the current formatting options as bit flags in an i4 integer. SetTextAlign() defines a new value and returns the previous value. If window_id is NULL, it refers to the current report. Bit flags are combined using the bitwise or operator (|). The following flags are defined in $SCULPTOR/include/draw.h:

    TA_LEFT             /* Align left */
    TA_RIGHT            /* Align right */
    TA_CENTRE           /* Align centre */
    TA_TOP              /* Align top */
    TA_BOTTOM           /* Align bottom */
    TA_BASELINE         /* Align to baseline */
    TA_RTLREADING       /* Right to left reading (Arabic and Hebrew) */
    TA_REPORTDEFAULT    /* Default in printed reports */
    TA_SCREENDEFAULT    /* Default in screen windows */

    TA_LEFT informs DrawText() that xpos is the co-ordinate for the left end of the text. Text printed with the same xpos co-ordinate is left aligned.

    TA_RIGHT informs DrawText() that xpos is the co-ordinate for the right end of the text. Text printed with the same xpos co-ordinate is right aligned.

    TA_CENTRE (or TA_CENTER) informs DrawText() that xpos is the co-ordinate for the centre of the text. Text printed with the same xpos co-ordinate is centre aligned.

    TA_TOP informs DrawText() that ypos is the co-ordinate for the top of the text. Text printed with the same ypos co-ordinate is aligned along the top regardless of its font height. This is the default for text drawn in a window.

    TA_BOTTOM informs DrawText() that ypos is the co-ordinate for the bottom of the text. Text printed with the same ypos co-ordinate is aligned along the bottom regardless of its font height. This is the default for text drawn in a report and is compatible with the Sculptor print command.

    Note that TA_LEFT and TA_TOP are defined as 0. Conflicting combination such as TA_LEFT | TA_RIGHT and TA_TOP | TA_BOTTOM cause the non-zero value to take precedence.

    To retain compatibility with other Sculptor code, programs should reset the text align flags to TA_SCREENDEFAULT or TA_REPORTDEFAULT.

  5. There is a new function called DrawFormattedText(). This draws text in a window or report using various formatting options and is more powerful than DrawText(). It can format text on a single line or wrap it over multiple lines. The syntax is:

    DrawFormattedText(window_id, xpos, ypos, text, font, width, height, format)

    xpos and ypos specify the co-ordinates of the top left corner of a rectangle with the specified width and height. The width and height parameters must be supplied to DrawFormattedText(). The text is formatted into this rectangle. If window_id is NULL, the text is drawn in the current report.

    The xpos, ypos co-ordinates and the width, height values are in the unit specified by sys.Unit. If sys.Unit is zero, device units are used. If sys.Unit is non-zero its values is the required unit in inches. Some useful values are defined in $SCULPTOR/include/draw.h.

    Because xpos and ypos refer to a rectangle that can span more than one line, DrawFormattedText() always uses the TA_LEFT and TA_TOP text alignment flags. This means that text drawn in a report with DrawText() and default alignment will be about one line higher than text drawn with DrawFormattedText() at the same ypos co-ordinate.

    Format flags are combined using the bitwise or (|) operator. They are the defined in $SCULPTOR/include/draw.h and begin with DT_. Example:

    DrawFormattedText(NULL, 1.4, 2.5, text, font, 5.0, 4.5, \
                       DT_EDITCONTROL | DT_NOPREFIX | DT_NOCLIP)

    DrawFormattedText() returns the height of the text in the current unit unless DT_VCENTRE or DT_BOTTOM is specified, in which case the return value is the offset from ypos to the bottom of the text.


  1. rename(oldname, newname)

    Renames a file.

    Returns 0 if successful or a negative value if an error occurs and stores the system error code in sys.Errno. If oldname refers to a file on a server then newname must refer to the same server or omit the server name, in which case it is assumed to refer to the same server. Pathnames can be absolute or relative to the current working directory but it is generally necessary to use absolute pathnames when renaming files on a server.

    A file can be renamed to a different directory. A directory can be renamed but cannot be moved to a new node in the file system tree. Examples:

    rename("c:/olddir/fileoldname", "c:/newdir/filenewname")

    The following two calls are equivalent:

    rename("myserver:c:/app/data/old.d", "c:/app/data/new.d")
    rename("myserver:c:/app/data/old.d", "myserver:c:/app/data/new.d")
  2. isnull(ptr)

    Returns TRUE if the specified pointer field (!temp type p) is null, i.e. does not point to another object, otherwise FALSE. This makes it possible to distinguish between the pointer itself being null and the object being pointed to having a null value.

  3. The OpenIndex() and IndexFieldProp() functions have been implemented. See readdotd.doc for details.

  4. The EV_RIGHT_MOUSE event sends extra arguments and the order of arguments has changed for tables:


    func(event_code, table_id, line, column, xctl, yctl, xwin, ywin)

    line The line number clicked (0=headings, -1=below last line)
    column The column number clicked (0=left of first, -1=right of last)

    Other arguments as for other controls below.

    Windows and other controls:

    func(event_code, object_id, xctl, yctl, xwin, ywin)

    xctl X position in pixels relative to the control.
    yctl Y position in pixels relative to the control.
    xwin X position relative to the control’s effective, parent window. In pixels or characters depending on the program grid.
    ywin Y position relative to the control’s effective, parent window. In pixels or characters depending on the program grid.

    The effective parent is the highest window in the parent window chain that has no further parent or has style WS_OWNED. This is the window in which a popup menu should be opened. Example code:

    Character Grid:

    at xwin, ywin in parent_id
    open popup_id

    Pixel Grid:

    move cursor to xwin, ywin in parent_id
    open popup_id
  5. In an RTF printer parameter file, such as winrtf.s, it is now possible to specify the word “default” (case insensitive) to indicate that the RTF file produced by a report should be opened with the default application for this file type. This avoids the need to specify a program pathname, which can vary between different Windows platforms. If the output is to a temporary file (no “to filename” clause), the temporary file is deleted automatically by Sculptor when the application closes it. In the case of Wordpad, this happens as soon as the file has been read but since Microsoft Word keeps the file open, Sculptor has to wait until Word exits or the user closes the file.

  6. The following editmodes have been added to LIST_EDIT controls:

  7. The event codes EV_RIGHT_MOUSE_DOWN and EV_RIGHT_MOUSE_UP have been added. If these ecents are required, they must be enabled using the event_enable clause. Popup menus should be opened when the up event is received, so the old event code EV_RIGHT_MOUSE is now an alias for EV_RIGHT_MOUSE_UP.

  8. The copyfile() function has a new option: COPY_MAKEPATH. If this flag is specified, all missing directories in the destination path are created.

  9. When Sculptor updates application programs to the $SCULPTOR\APP directory (or to $SCLOCALBIN), printer parameter files to $SCULPTOR\PRINT and terminal parameter files to $SCULPTOR\TERM, it now creates all directories in the target path that do not already exist. This makes it possible, for example, to store application programs in $SCULPTOR\APP\MYAPP\BIN without having to create any part of this path first.

  10. If the new flag EM_SYNC_SOURCE is set for the mode of a table, both the source and display objects are updated when a cell loses focus instead of just the display object.

  11. The argument to record_count() can now be a file_id, index_id or filename.

  12. A “-F <filename>” option has been added to kfbuild, kfcheck, kfcopy, kfdet, kfri and reformat programs. This places all messages that would otherwise go to the terminal into the named file. It also suppresses all questions. The main purpose of this option is to enable these programs to be called from a Windows front end. A suitable front end is being developed and will be available soon.


  1. The behaviour of the left and right arrow keys in a textbox group has changed in programs compiled with Sculptor 5.3. In programs compiled with scc 5.1 or earlier, the arrow keys navigate as before - at the end of a textbox, the right arrow key moves to the next textbox in the group and at the start of a textbox, the left arrow key moves to the previous textbox in the group. In programs compiled with scc 5.3 or later, the left and right arrow keys stay in the same textbox, unless the program contains the line “!compat arrowkeys=N” where N is a digit less than 5.

  2. A table has a new property called “cell_properties” to which a record structure can be assigned as shown below.

    !record CellProperties {
    !table mytable ... {
        cell_properties = CellProperties

    numcols is the number of columns in the table. The record does not have to have the name CellProperties; any valid object name can be used. Also, it is only necessary to define the fields that the program uses.

    To set the properties of a cell at run-time, assign the required values to the appropriate field elements before the cell gains focus. If the required values are set in this record, it is not necessary to call the table_set_type() function. The list_size property sets the maximum size for the list. This is useful if the list_field is an array but not all elements are to be listed.

    The cell_width field defines the required cell width. Zero is the default, based on the heading and the linked field. Greater than zero is the required width in pixels. Negative values are reserved for future use. NOTE: spw has not yet been updated to take account of this new feature.

    Although most values in the cell properties record are for use with editable tables, the cell_width field can also be used with a non-editable table.

  3. The column clicked has been added as the fifth argument to the EV_SELECT event for an editable table.

  4. sys.HTMLHeader has been added. This specifies whether or not nph-srep should output standard, cgi header information. In general, this should be ON if nph-srep is running as a CGI program on a web server or OFF it’s output is being redirected to a file for later use as an HTML page. The default is ON.

  5. The utility program kcopydir is now supplied. Full documentation is in the HTML manual SCULPTOR\HELP\sc5ref.chm.

  6. On Windows NT, 2000 and XP, Sculptor now supports read locks and write locks, which has always been the case on Unix platforms. Windows 95, 98 and ME do not support read locks so all locks obtained locally on these platforms are write locks. However, a Sculptor client program that is running client/server on Windows 95, 98 or ME and accessing files via kfserver on Windows NT, 2000, XP or Unix has the benefit of both read locks and write locks. This is not the case if the program uses standard, Windows networking to access the files.

  7. The value CURSOR_DEFAULT is now a valid argument to setcursor(). It selects the user’s default cursor icon.

  8. There is a new function:

    isblank(field_id | record_id)
    isblank(field_id[index] | record_id[index])

    If there is no index, checks all elements of the specified field or all elements for all fields in the specified record. Returns TRUE if all values are null. For numeric fields, zero is the null value. For alpha fields, all spaces is the null value and for binary fields, all bytes binary zero is the null value.

    If an index is specified, checks that element only. In the case of a record, checks only those fields whose dimension >= index. (The behaviour is undefined for fields that have more than one dimension.)

  9. The command getfield # can be used to read fields from a sequential file:

    getfield #channel, field_id[,field_id]… [err=label] [traps=label]

    Unlike get #, which reads a line at a time and then parses it into the supplied fields, getfield #, reads only the number of fields specified, so it can be used to read one field at a time if required.

    A field is text delimited by any character in sys.Separator. The default setting for sys.Separator is “,” and this value should be used when reading standard csv (comma separated value) files. However, it is possible to set sys.Separator another character or to a list of separator characters if required.

    Each time getfield # is executed, the character that terminated the last field is stored in sys.LastSeparator (a1). The special values CHAR_EOL (end of line) and CHAR_EOF (end of file) are defined in sculptor.h. The value of CHAR_EOF is 255. In the extremely unlikely event that this is also a valid separator, check the value in sys.Error, which will be 0 for the character 255 and non-zero for end of file.

    getfield # honours the following csv conventions:

    1. Quoted text is read as a single field. Text is deemed to be quoted if the first non-blank character is a quotation mark.
    2. Within quoted text, two consecutive quotation marks are treated as a single, embedded quotation mark.
    3. Leading spaces before each field are ignored (unless in quotes).

    For example, the line:

    123,"embedded,comma", just text, "embedded""quote",not"quoted

    parses into the separate field values:

    just text
  10. The command putfield # can be used to write values to a sequential file.

    putfield #channel, expr[:format][,expr[:format]]… [err=label] [traps=label]

    The comma after expr outputs the text in sys.Separator. If there is no comma after the last field, a newline is output. When writing standard csv files, set sys.Separator to “,” or, for more readable output, to “, “.

    The optional format string can be used to format numeric values or to modify the output of alphanumeric text. If expr is a simple field, the field’s own format string is used if there is no attached format. Leading and trailing spaces are removed from all values except alphanumeric text that has the letter “k” (keep spaces) in its format.

    putfield # honours the following csv conventions:

    1. Values that have the first character in sys.Separator or a quotation mark embedded in their text are automatically enclosed in quotation marks.
    2. Inside a quoted value, an embedded quotation mark is output twice.
  11. In programs compiled with scc 5.3.0 or later, tables with mode EM_MULTIPLE send a different event when Shift+Click is used to select a block of lines:

    EventFunction(EventCode, Table, FirstLine, State, LastLine)

    If EventCode is EV_MULTIPLE_SELECT, FirstLine and LastLine are the first and last lines in the selected block. Previously, the event EV_SELECT was sent separately for each selected line. There were two problems with this approach:

    1. Sculptor’s internal event stack overflowed, so the event was only sent for the first 255 lines.
    2. Sending this many events degraded performance and any fix would make this worse if a very large number of lines was selected.

    Sculptor recommend that programs using tables with EM_MULTIPLE are modified to make use of EV_MULTIPLE_SELECT before recompiling with the latest version of scc. If this is not practical, add the line:

    !compat evselect=4

    to the program or to a common include file such as local.h if all programs are to retain backward compatibility.

    EV_MULTIPLE_SELECT is enabled by default.
    EV_SELECT (=EV_SINGLE_CLICK) is still sent when a single line is selected.
  12. If an alpha array field has the flag character “p” (packed text) set, it becomes a long text field that can store dim * length characters where dim is the array size and length is the element length. For example, the field:

    !temp LongText,,a200(40),,p

    can store up to 8000 characters as a single text string. Database fields can be made into long text fields by placing “p” in their format string. The compiler recognises this format and sets the field’s “p” flag. The maximum length of a long text field is 60000 characters.

    Sculptor treats a long text field as a non-array field. The individual elements should not be referenced directly. Sculptor does not allow the “p” flag to be set or cleared at run-time. The statement field_id->flags = “…” can be used to set other flags but the state of the “p” flag will be preserved. Functions such as getstr(), getbyte(), setstr(), setbyte() and instr() all work with long text fields and these should be used to extract and modify parts of the text.

    Long text fields are null terminated unless the full length is used. When a value is stored in a long text field, Sculptor sets all unused bytes to null, so If setbyte() or setstr() is used to store new text at the end of the current text, this must start at the first null character.

    In general, Sculptor’s built-in functions and operators all work on the full length of long text fields. Long text can also be used with ODBC and assigned to and from OLE fields and the clipboard. Long text is truncated to a maximum of 255 characters when retrieved for any of the following purposes:

    1. For the name of any object.
    2. For filenames and pathnames.
    3. For headings, titles, labels, etc.
    4. For text passed across the DDE interface.
    5. In the chain and exec commands.
    6. In commands like caption, error, info and prompt.
    7. TAPI strings.
    8. Web strings such as cookie values.
    9. XML attributes.

    Some of the above restrictions may be removed in the future.

    Long text fields are supported from Sculptor 5.3. Programs must be compiled and run with this or a later version to work correctly. If a program defines a !temp as long text, the compiler flags it as suitable for running only with Sculptor 5.3 or later. This is not done for database fields because it is not practical for the compiler to determine whether or not a field is referenced in the program. For safety, programs that make use of long text fields should declare at least one !temp field with the “p” flag even if it is not used.

  13. Long text fields are ideal for use as the linked field in a free format textbox. The text is stored as a packed string, so it is not possible to type more characters into the textbox than can be stored in the field. Hard line fields (newlines typed by the user) are stored in the standard DOS format as a carriage return, line feed pair (0x0d, 0x0a). Soft line feeds (generated by automatic word wrap) are not stored. If the same text is displayed in a free format textbox with a different width, the word wrap changes to match the new width but user-typed line feeds are preserved.

    Long text that has been stored in a database field from a free format textbox should not be used in programs running with earlier versions of Sculptor. The text will not display correctly and can be corrupted if saved.

  14. By default, the open file dialog in spw now lists both .f and .r files.

  15. There are new functions for use with tables whose source_object is a file. These are based on keys instead of line numbers and avoid the anomalies in the line-based functions which occur only when the source object is a file. They also make it possible to use editmode EM_MULTIPLE with file driven tables. See the index entry “tables, functions” in the HTML manual SCULPTOR\HELP\sc5ref.chm.

  16. Pre and post increment and decrement operators have been added to the language:

    field_id++ Adds 1 to a numeric field after using its value.
    field_id`–` Subtracts 1 from a numeric field after using its value.
    ++field_id Adds 1 to a numeric field before using its value.
    --field_id Subtracts 1 from a numeric field before using its value.

    The above statements can be used alone or in an expression. The ++ and -- operators have the same priority as unary minus (group 1). Example:

    field1 = field2++ + --field3

    is equivalent to the following statements:

    field3 = field3 - 1
    field1 = field2 + field3
    field2 = field2 + 1
  17. It is now possible to print directly to a file for a named printer:

    run report report_id to "PRINTER:printername:filename" [ppf=...]

    This outputs the report to the specified file without user dialog - equivalent to using Print Manager and checking the “Print to file” checkbox. The file is only suitable for the named printer and can be printed later with the DOS “type” command:

    type /b filename PRN

    This feature is also useful for creating PDF format files, since it is possible to obtain print drivers that output in PDF format. When printing in PDF format, use ppf=”winpm” or an equivalent Windows printer parameter file. Example:

    run report rep_pdf \
    to "PRINTER:BroadGun pdfMachine:c:/myapp/pdf" ppf="winpm"

    Note that / is recommended in quoted pathnames. This works on DOS/Windows and avoids the need to use \.

    Not all PDF drivers support printing to a file programmatically. Some only work correctly through a dialog. Sculptor has briefly checked the following PDF drivers but the tests were not exhaustive, so always test a driver with your application before committing to it.

    BroadGun pdfMachine (

    Prints directly to a specified output file, otherwise requests a filename. Reasonably priced for commercial use, especially for multiple licences. Free trial version available. This places a watermark on the page but is otherwise the same as the full version. The best driver found so far for use with Sculptor. Feedback would be useful.

    DocuCom PDF Driver (

    Always produces a user dialog with the report_id name as the default filename (run report report_id …). If an output filename is specified, this is created empty but the report is not written to it. Standard text is feinter than with other drivers. Standard and server versions available with trial versions of each. Trial versions produce an order/registration dialog every time they are used.

    pdf995 (

    Does not work if an output filename is specified. Free version available but this starts an HTML advert page every time it is used.

    Information on other drivers would be very welcome.

  18. The hide and show commands now work with menus and menu items.

  19. The style= clause has been added to top-level menus and the style WS_POPUP can be set to make a menu a pop-up menu. Use the “at” command to specify where the menu is to pop up, followed by the “open” command to make the menu appear. A program will normally do this in response to an EV_RIGHT_MOUSE event. Note that EV_RIGHT_MOUSE is not a default event and must be enabled. If the user the selects an item from the menu, the menu closes and the item’s select function is called. If the user clicks outside the menu, it closes without calling any select function. The following code fragments show how to use this feature:

    +window MyWin ... {
        event_enable = EV_DEFAULT | EV_RIGHT_MOUSE
        menu PopUp {
            style = WS_POPUP
    !function MyWinEvent(EventCode, Object, X, Y) {
        switch EventCode {
        case == EV_RIGHT_MOUSE:
            at X,Y in MyWin
            open MyWin.PopUp
  20. A function has been added that returns the width and height of a text string in a given window or the selected printer in the current report.

    TextSize(window_id, text, font, width, height)

    Calculates the width and height, in the units expressed by sys.Unit, for the supplied text in the given font. The window_id is the identifier of the window in which the text would be placed. For the current report, specify NULL instead of a window_id.

    The font parameter has the same syntax as a window font clause. If a valid font specification is not provided, the default specified in Section 1.4 (Default font) of the terminal parameter file is used. The standard terminal parameter file for all versions of Windows is $SCULPTOR/term/mswin.s. If no default font is defined, then “Courier New@10” is used.

    The width and height parameters can be NULL or can be fields. If they are fields, the function sets them to the actual width and height (in the logical units specified by sys.Unit) of the rectangle containing the text.

  21. It is now possible for the width of a cell in an editable table to be less than the width of the linked field. The text scrolls horizontally.

  22. Timer events have been introduced. These are controlled using the following new functions, defined in sculptor.h:

    CreateTimer(event_function, millisecond_interval[, option_flags])

    Creates a new timer. Multiple timers can be created and can run concurrently.


    The name of an event function to be called every time the specified interval elapses.


    The event interval in milliseconds.


    The only flag implemented at the moment is TIMER_START. If this argument is omitted or is 0, the timer is created but does not start running until the StartTimer() function is called.


    Stops the timer if it is running and then destroys it, releasing the system resources that have been allocated to it.

    StartTimer(event_function[, millisecond_interval])

    Starts the timer. If the millisecond_interval is not specified, the interval specified in the CreateTimer() function is used.


    Stops the timer. The timer can be restarted later.

    The above functions return 0 if successful or a negative value if they fail.

    Note that a timer is identified by its event_function. If multiple timers are created, each must have a different event function.

    The timer event function is called each time the specified interval elapses. Timer events are subject to CPU time being available to the process. Events can be delayed or missed if the system is busy. A timer event function can return CLOSE_DIALOG or CANCEL_DIALOG if required.

    On Unix, the millisecond_interval is rounded up to the next second because most Unix system clocks run with granularity of 1 second.

    On Windows, the millisecond_interval is used.

    Timers do not work in the DOS version of Sculptor.

  23. The reference manual is now supplied in compiled HTML format in the file SCULPTOR\HELP\sc5ref.chm. This HTML manual is up to date. The old manual, sc5ref.hlp, is also supplied because it contains sections called by descw and spw. The old manual is not being updated and should not be referenced directly.


This was an experimental version and will not be released. The next version will be 5.3.


  1. The program template default\sp.f used by spw has been improved and spw has been changed so that at startup, either an existing program must be loaded or File->New selected.


  1. A new flag character “c” can be used with fields to indicate that the text is to be centred within its print column when using the print and printh commands. This flag can be defined with the field or appended to a print item:

    print fieldname::"c"
  2. There is a new function defined in <draw.h> that returns the default width and height for an image drawn in a given window:

    ImageSize(window_id, imagefile, x, y)

    Stores the default size into the fields x and y. The unit is defined by sys.Unit (default is pixels). If window_id is 0, values are returned for the selected printer.

  3. A new event, EV_SELECT_TAB, has been introduced. This is sent to the tab control window’s event function when a new tab is selected.

    EventFunc(EV_SELECT_TAB, control_window, selected_tab, selected_tab->xposn)
  4. On Windows, text that is printed below the bottom of the current page is lost. This can happen if the “need” command is not called at the correct time. To check for this happening, set entry number 3 in the INFO section of the printer parameter file to “Y” and use the comprint program to recompile the printer parameter file:

    3: Print overflow text on next page (Y/N) = Y

    The default is N because many existing programs print an extra blank line at the bottom of the page. Setting this entry to “Y” will then generate a blank page.

  5. The controls in a window have a new property called “tab_order”. This is an ordinal number that defines the control’s position in the tab sequence of it’s parent window. It is possible to store a new value for a control’s tab_order. This moves the control to that position in the tab order and renumbers the tab_order for other controls in the window.

  6. The Tab, BackTab, Control+DownArrow, Control+UpArrow, Control+NextPage and Control+PrevPage keys move between the editable cells in an editable table. The Control+Tab and Control+BackTab keys move to other controls.

  7. The move command can place the cursor at a given pixel position in a window:

    move cursor to x,y in window_id

    The “at” command always works in character positions.

  8. The begin, commit and rollback commands that wrote markers to the transaction log file but had no effect on the files being used by the program, have been replaced by the functions begin(), commit() and rollback().

    For upward compatibility, The old commands have been renamed begin_mark, commit_mark and rollback_mark but these should be regarded as obsolescent. Programs compiled with scc 5.0 and earlier map begin, commit and rollback to begin_mark, commit_mark and rollback_mark so that they work as before. In order to recompile programs with scc 5.1, append “_mark” to these commands, in which case they will work as before or append “()” to get the new functionality, which is the recommended option.

    begin() starts a transaction. All records that are inserted, deleted or updated remain locked until either commit() or rollback() is called. If a program attempts to read a record that it has deleted in a transaction, it gets a “no such record status” as expected and can re-insert the record. Other programs see the record as still existing but locked; this prevents them from inserting the record until the transaction has been committed.

    If commit() is called, all records locked by the transaction are unlocked and the updates become permanent. If rollback() is called, the updates are reversed and the records are unlocked.

    Both commit() and rollback() return 0 if successful or -1 if they fail. With Sculptor files, commit and rollback should always work. With some SQL databases, especially if optimistic locking is used, the commit() function can return an error. This indicates that the transaction could not be committed because it’s updates conflict with another transaction. It’s not obvious why rollback() might fail with SQL databases but the option for this operation to return an error does exist in ODBC.

    Transactions should be reasonably short and quick so that multiple records are not kept locked for a long time. There is also a greater scope for deadlocks to occur when multiple records are kept locked, so transactions must be designed to avoid this.

    Note: Large transactions (greater than a few thousand updates) are very slow with Sculptor Keyed Files at the moment. This will be fixed in a future release.

  9. If a program accesses a closed file, Sculptor opens the file automatically using the mode in the !file declaration or update mode if a mode is not specified. This behaviour was introduced in Sculptor 3. To get a warning when this happens, set sys.Warn >= 4 (default value is 2).

  10. The up, down, left and right arrow keys can be used to move a selected object one pixel at a time in the screen designer.

  11. The DrawImage() function now accepts a jpg file as well as bmp file.

  12. Sculptor 5.1 supports XML. See the file xml.rtf for details.

  13. There is a new Sculptor Program Generator that replaces sg and rg. This is written in Sculptor. The source code is supplied in DEMO\SPG, so that it can be modified if required. To call the generator, run the batch file “spg” in SCULPTOR\BIN.

  14. The scroll command scrolls the top line of a listbox or table to a given row:

    scroll table_id | listbox_id to row_number

    This command is in Sculptor 4.2 but was previously undocumented.

  15. Security features have been added to kfserver and kfservnt. These are documented in the file security.txt. The new versions of kfserver and kfservnt will not work until you copy the supplied SCULPTOR/security directory to your server. For backward compatibility, this security database is supplied with a single, default entry that permits all operations. To implement secure server operations, delete this entry and add specific entries as required.

  16. The installation procedure now registers .g and .q files so that Windows knows how to run them. Since this includes Internet Explorer, an href on a web page on a Windows server that has Sculptor installed can point to a Sculptor file. Example: href="http://server/file.q".

  17. The load_picture() function can load an image from a server and AVI files can be run from a server. In both cases, Sculptor first copies the file to the $SCULPTOR/temp directory on the client. The next time the file is accesssed, it is copied only if it’s timestamp indicates that it has been updated on the server.

  18. A set of functions has been introduced to read Sculptor .d files. See “Data dictionaries, retrieving information about” in the HTML manual SCULPTOR\HELP\sc5ref.chm.

  19. An automatic currency conversion feature has been introduced. See “currency conversion” in the HTML manual SCULPTOR\HELP\sc5ref.chm.

  20. It is now possible to trap OLE errors. First register a trap function with the statement:

    on ole_error funcname

    If an OLE error occurs, the function is called with the following arguments:

    funcname(obj_id, hResult, Source, Description, HelpContext, HelpFile)

    obj_id The OLE object that caused the error.
    hResult The error number.
    Source The function or property that caused the error (text).
    Description Error description if available, otherwise blank (text).
    HelpContext Context id on help file if available. Can be used with the help file to show an explanation of the error.
    HelpFile Pathname to the help file.

    If an OLE error function has not been registered, a normal debug message is displayed if an OLE error occurs.

  21. When the EV_KEYSTROKE event is called for an editable table, the program has been compiled with scc version 5.1.0 RC2 or later and the interpreter is version 5.1.0 RC2 or later, the function arguments are:

    EventFunc(EventCode, Object, Row, Col, Keycode)

    This change has been made to make the editable table event function consistent. If Sculptor 5.1.0 RC2 or later is used to run a program compiled with an earlier version of Sculptor, the arguments are:

    EventFunc(EventCode, Object, Keycode, Row)
  22. The path for an avi file can be on a server. Sculptor copies the file to the directory $SCULPTOR/TEMP and runs it from there. On subsequent use, the file is copied again only if it has been updated on the server.

  23. The WS_PLAIN style can be used with image buttons. It creates the button with no border or shadow. Image buttons are a useful alternative to graphic images because they receive events such as gain and lose focus, which are not available with graphic images.

  24. The colours and font of window captions can be set using the new window properties caption_bgc, caption_fgc and caption_font. The font used is the default font modified by any style, size or family set using the caption_font clause. Colour is decided as follows:

    1. If the current control has a caption_pen, that is used.
    2. Otherwise, caption_bgc and caption_fgc are used if the colours are active (RGB_ACTIVATE set).
    3. Otherwise, if the window has a palette, that is used with PEN_CAPTION.
    4. Otherwise, the system default colours for captions are used.
  25. AVI files can have a transparent background. The avi control interprets the upper-left pixel of the first frame as the background colour. If an active, transparanet colour is defined for the parent window, the control remaps the avi background colour to the window background colour. The actual colour defined to be transparent is not relevant but it must be active (RGB_ACTIVATE set).

  26. The EV_CHANGE event has been added to list edit controls. This is sent after each character typed into a list edit control. This event is not sent by default. To receive it, add EV_CHANGE to the event_enable clause of the control. For example:

    event_enable = EV_DEFAULT | EV_CHANGE

    To retrieve the value typed into a list edit control, either call the listbox_get_selected() function in the EV_LOSE_FOCUS event or in each EV_CHANGE event, as preferred.

  27. clear record_id[subcript] clears the specified element of array fields in record_id. Non-array fields are not cleared. Record are not unlocked. CARE: This code works from Sculptor 5.1 release version only. If the program is run with an earlier version of Sculptor, the entire record will be cleared.

  28. The debug versions have a dialog to locate source files if they are not present in the directory in which they were compiled.

  29. Foreground and background colours can be defined on a “put” command using the clauses bgc= and fgc=.

  30. The table_focus_cell() function returns more useful values (defined in sculptor.h):

    < 0

    Error (parameter out of range).


    Focus was refused (e.g. the gain focus event returned ERROR).


    The cell was focused and was in view.


    The cell was focused by scrolling it into view.

  31. The style WS_CLICKONLY can be used with any control. It allows the control to gain focus when it is clicked but to be skipped when the user is navigating with the TAB and BACKTAB keys.

SCULPTOR 5.0.1 - 10 April 2001

  1. Some speed improvements have been made to the ODBC interface to SQL databases, especially SQLServer.

SCULPTOR 5.0.0 - 2 February 2001

Starting with Sculptor 5.0, a number replaces the date that was used in previous versions to identify bug fixes. The initial release is 5.0.0. Bug fix releases will be numbered 5.0.1, etc. and will be documented in the file bugfixes.

Sculptor 5.0 introduces Sculptor HTML files. See the file internet.doc for details.

The variable SC_PROG that was used in Beta 1 has been renamed SCPROG. Please edit any Internet pages that you have created.

  1. There are new clauses that provide full foreground and background colour selection for windows and controls. It is also possible to specify a transparent colour for graphics images, which allows the window background colour to show through the specified transparent colour.

    The clause are bgc= (background colour), fgc= (foreground colour), data_bgc=, data_fgc=, label_bgc=, label_fgc=, title_fgc= and transparent=. The bgc= clause defines a window’s background colour.

    A sample set of RGB color values is defined in rgb.h. The most significant byte of each value contains option flags and an RGB value must have the flag RGB_ACTIVATE set to switch the colour on. The next three bytes are the intensity values for blue, green, red (the order required by Microsoft functions), not for red, green, blue might be expected.

    The best way to select colours and to see which clauses are supported by which controls is to use the screen painter. Typing a ? in a colour property opens a colour selection dialog. If a standard colour is selected, spw writes the corresponding RGB definition from rgb.h into the clause in the code. If a non-standard colour is selected, spw writes a hex value.

    Clauses specified at window and group level are inherited by child windows and controls. The special value RGB_DEFAULT can be used in a child window or control to select the user’s default preference instead of the inherited colour.

  2. The function SetBrushColor() now takes either two or three arguments:

    SetBrushColor(Window, Foreground | Background)

    works as before and is limited to the FORE_ and BACK_ colours defined in SCULPTOR/include/draw.h.

    SetBrushColor(Window, Foreground_RGB,  Background_RGB)

    sets the brush’s foreground and background colours to the specified RGB values.

  3. The functions SetOutlineColor(), SetOutlineWidth() and SetOutlineType() work as before but are obsolescent. They have been replaced by SetPenColor(), SetPenWidth() and SetPenType(). The function SetPenColor() takes an RGB value:

    SetPenColor(Window, RGB)

    The functions SetPenWidth() and SetPenType() are equivalent to the old functions SetOutlineWidth() and SetOutlineType() but have new names for consistency.

  4. Text, line graphics and graphic images can now be drawn in a window or printout using drawing modes that merge the output with the existing background in a variety of different ways.

    The required mode is defined in a system variable. There are two new variables, one for text and line graphics and one for graphic images:


    When using a Sculptor drawing function to draw text or a line graphic, this variable defines how to combine the text or line graphic with the existing background. There are two possible values, defined in draw.h:

    TRANSPARENT The line graphic or text is drawn on top of the existing background, ignoring the background color and style defined in the current brush. For example, if a retangle is drawn, the inside retains the existing background.
    OPAQUE Uses the background color and style defined in the current brush. For example, if a retangle is drawn, the inside is filled according to the current brush. This is the default value.


    When using a Sculptor function to draw a graphic image, this variable defines how the graphic bitmap is combined with the existing background. Possible values, defined in draw.h, are:

    Value Description
    BLACKNESS Sets the existing background black.
    MERGECOPY Combines the current pattern brush with the graphic using a boolean AND operation and copies the result over the existing background.
    MERGEPAINT Inverts the graphic then combines it with the existing background using a boolean OR operation.
    NOTSRCCOPY Inverts the graphic then copies it over the existing background.
    NOTSRCERASE Combines the graphic with the existing background using a boolean OR operator and then inverts the result.
    PATCOPY Copies the current pattern brush over the existing background.
    PATINVERT Combines the current pattern brush with the existing background using a boolean XOR operation.
    PATPAINT Inverts the graphic and combines it with the current pattern brush using a boolean OR operation, then combines the result with the existing background using a boolean OR operation.
    SRCAND Combines the graphic with the existing background using a boolean AND operation.
    SRCCOPY Copies the graphic over the existing background. This is the default value.
    SRCERASE Inverts the existing background then combines the graphic with the result using a boolean AND operation.
    SRCINVERT Combines the graphic with the existing background using a boolean XOR operation.
    SRCPAINT Combines the graphic with the existing background using a boolean OR operation.
    WHITENESS Sets the existing background white.
  5. The function activate_app() has an optional, third argument:

    activate_app(class, title, option)

    Option must be one of:

    AA_HIDE Hide the window and activate another
    AA_SHOWNORMAL Activate and show in normal size and position
    AA_SHOWMINIMIZED Activate and show minimized
    AA_SHOWMAXIMIZED Activate and show maximized
    AA_SHOWNOACTIVATE Show in normal size and position, don’t activate
    AA_SHOW Activate and show in current size and position
    AA_MINIMIZE Minimize the window and activate another
    AA_SHOWMINNOACTIVE Show minimized, don’t activate
    AA_SHOWNA Show in current size and position, don’t activate
    AA_RESTORE Activate and show in previous size and position
    AA_SHOWDEFAULT Show in default state set by parent task

    If the option argument is omitted, AA_RESTORE is used. If the option used is one that activates the window, the window is also brought to the foreground if possible but note that Windows 98 and 2000 allow this only if one of the following is true:

    • The process is the foreground process.
    • The process was started by the foreground process.
    • The process received the last input event.
    • There is no foreground process.
    • The foreground process is being debugged.
    • The foreground is not locked.
  6. The environment variable SCMASTERBIN can be set on a client to specify the directory from which to download a program if the following syntax is used:

    sagewc|srepwc :program

    If SCMASTERBIN is not set and SCMASTER is set then programs are downloaded from the directory $SCMASTER/app.

    If SCMASTERBIN is set, SCMASTER can still be set to specify the master Sculptor directory for terminal and printer parameter files that are referenced with a leading :.

  7. The environment variable SCLOCALBIN can be set on a client to specify the directory in which to store a downloaded program. If SCLOCALBIN is not set, the directory $SCULPTOR/app is used.

  8. New Internet functionality is included using the interpreter nph-srep. An outline specification of the new Internet routines is in the file internet.doc in this directory. Note: If a printer parameter file is not specified for nph-srep, either on the command line or in a “run report” command, the default is “nullp” not “printer”.

    See SCULPTOR/DEMO/INTERNET/SHOP and SCULPTOR/DEMO/INTERNET/SCH for demonstration applications.

  9. The new window properties:


    contain the current position, in pixels, of the horizontal and vertical scroll bars in a window that has scroll bars. Changing a value, moves the corresponding scroll bar. One use is to save and restore the positions of the scroll bars when a window needs to be destroyed and re-created.

  10. Optionally, one or more columns in a table can be edited.

    By default, the columns in a table are type TCT_READONLY, which means that the cells in that column cannot be edited. The type of a column can be changed by calling the function table_set_type() after the table has been created::

    table_set_type(table_id, column, type [, drop_size, list_field])

    This sets the type of the specified column (counting from 1) to one of the following:

    TCT_TEXTBOX Edit using a textbox.
    TCT_DYNAMIC The type will be set when the cell receives focus.
    TCT_LISTEDIT Edit using a LISTEDIT type listbox.
    TCT_LISTBUTTON Edit using a LISTBUTTON type listbox.
    TCT_READONLY Set read only.

    The drop_size and list parameters are required for types TCT_LISTBUTTON and TCT_LISTEDIT. The drop_size specifies the number of visible rows in the listbox (default 5). The list_field must be an array field that contains the list of permitted values.

    table_set_type() returns < 0 if an error occurs (invalid argument).

    Three new events have been introduced in the table event function:

    TableEventFunc(EV_FOCUS_CELL, table_id, row, col, type)

    The EV_FOCUS_CELL event is sent when the user clicks on a cell that can be edited. The row and col arguments are the co-ordinates of the cell, counting from 1. The type argument is the current type of the column (TCT_).

    This function is not called if the type is TCT_READONLY.

    If the type is TCT_DYNAMIC, the program must call the function table_set_type() to set another type before returning.

    The function must return OKAY to give focus to the cell or ERROR to refuse it.

    TableEventFunc(EV_NOFOCUS_CELL, table_id, row, col)

    Called when a cell loses focus. Can be used to reset the type to TCT_DYNAMIC if required. The return value should be OKAY, which is the default.

    TableEventFunc(EV_VALIDATE, table_id, row, col, data)

    Called before the EV_NOFOCUS_CELL event. The data argument contains the value in the cell, which may have changed. The function should return OKAY if the content is valid, otherwise ERROR, in which case focus is locked and the user must enter another value.

    There are two other new functions that can be used with tables:

    table_focus_cell(table_id, row, col)

    Sends the focus to the specfied cell, which should be visible on the screen. Returns < 0 if an error occurs.

    table_set_default_data(table_id, col, data)

    Sets a default value that replaces the current value whenever a cell in the specified column is edited. If desired, can be called during an EV_FOCUS_CELL event to reset the default value to one that is appropriate for the cell receiving focus.

    See the sample program DEMO\CONTROLS\etable.f

  11. There is a new function that deletes a directory:


    The directory must be empty. The pathname can reference kfserver. Returns 0 if successful. Returns non-zero if an error occurs (see sys.Errno).

  12. Sculptor 5 introduces pixel positions and sizes for all windows and controls. It also supports character positioning and sizing for backward compatibility.

    There is an automatic conversion procedure that can be used to convert programs to pixel positioning. There is no automatic conversion back from pixels to characters, so it is very important to back up all source files before starting the conversion process.

    To convert a suite of programs to pixel positioning, first edit every include file in the suite and append the line !ctp (convert to pixels). It is not nececessary to add this line to include files that don’t contain windows but it does harm to do so. Do not add the line !ctp to top level program files (.f and .r). Make sure that all include files that contain !ctp can be upodated, i.e. they are not read only. Note that include files in <> brackets are always treated as read-only by spw. The compiler does not recognise the line !ctp, so once this has been added to include files, they must be converted.

    To convert a program from characters to pixels, load it into spw and check Options->Positioning->Pixel in the menu. All windows and controls in the program file and in the include files that contain !ctp are converted. The !ctp lines are removed to prevent the include files from being converted again when processed in the conversion of another program.

    spw convertes all positions and sizes in window and control declarations. It cannot convert values that are coded into the program logic so these must be converted manually. To make this process easier, the “at” command still works in characters and there is a new command:

    cursor to x,y in window_id

    that is equivalent to “at” except that it works in pixels.

    The “move” command now works in pixels but there is a new command “charmove” that has the same syntax and still works in characters. You can either modify the co-ordinates of existing move commands or change the command to charmove.

    Programs that use pixel co-ordinates and sizes must be compiled using scc version 5.0 Beta 4 or later. All earlier compilers assume a character grid.

    By default, the Sculptor 5 compiler assumes a pixel grid. To select a character grid, place the following declaration in a program:

    !chargrid ON

    In order to make existing programs compile correctly, this declaration has been added to the standard include file <local.h>. This overrides the new default. There are two ways to take advantage of pixel positioning:

    1. Remove the “!chargrid ON” declaration from <local.h> and convert all or most programs to pixels. Add “!chargrid ON” to any programs that you don’t want to convert.
    2. Leave “!chargrid ON” in <local.h> and add “!chargrid OFF” to the programs that you convert, after !include <sculptor.h> - spw does this automatically. This works because spw and scc honour the last !chargrid declaration that they encounter.
  13. There is a new function to starts the default web browser and passes it a url:


    Returns 0 if successful, otherwise the system error code.

    Example: url_exec("")

  14. There is a new function that runs a Windows file using its default, application binding. The function can also be used to run an installed Windows executable program without the need to know its location.

    run(file_name, verb, params, dir, show)

    The first syntax runs the file with all defaults. The second syntax provides the following options:

    verb The action to be taken (open, edit, print, etc.). For parameter values refer to the application’s documentation. Pass 0 for the default.
    params Some applications accept parameters. See the application documentation for details. Pass 0 for the default.
    dir The directory in which the command is to start. Pass 0 for the application default.
    show One of the AA_ defines in sculptor.h. Determines the mode in which the application starts. Default is AA_SHOWNORMAL.


    run("myletter.doc") opens myletter.doc using the application that is associated with .doc files.

    run("winword.exe") starts M/S Word with a blank document.

  15. In the debug versions sagewcd, srepwcd, etc. it is possible to change the value of a field at run-time. Press the Add button in the Watch Field window. This opens the Select Field window. Select a field and type the required value in the textbox.

  16. In spw, the menu item Edit->Layout in spw can be used to move, align and change the size of multiple controls. This is an essential tool when pixel positiong is used. Full details are in the Sculptor Reference Manual.

  17. There is a lasso option in the screen designer menu that allows multiple controls to be selected using a dragged rectangle.

  18. The screen designer now allows the colour and pattern of the selection border to be changed and saved by saving the current configuration.

  19. A set of functions has been introduced to support TAPI (telephony API).

  20. If the “open #” command is used to open a serial port (COM1 to COM9), all I/O on that port is now unbuffered. This makes it possible to use a serial port to send messages between two computers. To set the baud rate and handshaking parameters, execute the DOS “mode” command before opening the port. Parameters must be identical on both the sending and receiving computers. To see the full syntax of the mode command, type “mode /?” at a DOS prompt.

    A program must make its own arrangements to detect end of message. See the sample programs in \SCULPTOR\DEMO\COMPORTS, which demonstrate one way to achieve this.

  21. Drag and Drop is supported. There are demo programs in the directory \SCULPTOR\DEMO\DRAGDROP. Full documentation will follow shortly.

  22. The style WS_HLIGHT_DARKEN can be used with tables to make the selected row darken instead of changing to white on blue. This can look better when using colours in table fields.

  23. The following new system temp has been added:

    sys.ScFixVersion (type u1) contains the Sculptor ‘fix’ version number. The version number syntax is now main_vers.sub_vers.fix_vers.

    Starting with Sculptor 5.0, sys.ScDateVersion will always return the initial release date.

SCULPTOR 4.3 - 11 June 2001

  1. The setting of the batch_read flag is now ignored for ODBC databases. The performance improvements that it provided are now standard.

SCULPTOR 4.3 - 28 March 2001

  1. Some speed improvements have been made to the ODBC interface to SQL databases, especially SQLServer.

SCULPTOR 4.3 - 16 February 2000

  1. In order to get adequate performance, the batch_read flag is now ON by default for ODBC databases. This requires MDAC version 2.6 or later or SQLServer Service Pack 3. (MDAC = Microsoft Data Access Components).

  2. Some ODBC database types do not automatically refresh a read only cursor when the database is updated. This means that an update (delete, insert or write) may not be seen by a subsequent readu, nextu, prevu, findu or matchu command, even in the same program. So far, this behaviour has been seen only with Oracle. To avoid it, put each set of updates between begin and commit or use the flush command on the affected file:

    flush file_id

SCULPTOR 4.3 - 12 October 2000

  1. There is an option to force optimistic locking with an ODBC database. This is done by setting the DBFL_OPTIMISTIC_LOCKING flag in the database definition:

    +database db1 {
        type = DBT_ODBC

    Optimistic locking is the default for the Microsoft Access driver and the native, Oracle driver. Pessimistic locking is the default for the Microsoft SQLServer driver and the Microsoft driver for Oracle. In these cases, the DBFL_OPTIMISTIC_LOCKING flag can be set to force optimistic locking. Updates are generally faster when optimistic locking is used.

    With optimistic locking, records that are read for update are not locked. Instead, when the record is written back, the driver checks to see if another user has updated the record since it was last read. If so, the write is refused and Sculptor returns a UE (update error) trap. This trap can occur on delete and write commands.

  2. If file_id->batch_reads = ON for an ODBC file, a forward only cursor is used for the nextu, nextkey, prevu, prevkey and findu/matchu commands. This type of cursor is usually very fast. Despite its name, a forward only cursor can be used with the prevu and prevkey commands.

    NOTE: Sculptor does not use this type of cursor with Microsoft Access because in some Access drivers it seems to work very slowly.

SCULPTOR 4.3 - 12 September 2000

  1. Sculptor 4.3 is identical to Sculptor 4.2 except that the ODBC interface has been improved substantially. Overall performance is better and some multi-user conflicts have been resolved. Applications that use ODBC with Sculptor 4.2 or earlier should be re-tested with Sculptor 4.3.

    Careful coding can improve performance in a program that uses ODBC. The following example shows how a program that uses the next command to step through a file to update some but not all records can be coded to improve performance:

    while (TRUE) {
    nextu FILE nsr=BREAK        /* Don't lock unless updating */
    if (update needed) {
        read FILE nsr=CONTINUE
        write FILE

    Unless all the records will be updated, the above code is faster than::

    while (TRUE) {
    next FILE nsr=BREAK
    if (update needed) {
        write FILE

    Even better is to enclose an update loop between begin and commit:

    while (TRUE) {
    next FILE nsr=BREAK
    if (update needed) {
        write FILE

    This is the fastest option but suffers from the disadvantage that all the records read remain locked until the commit is executed. This is inherent in the way that begin and commit work. Adding an unlock command does not help because unlock must be ignored inside a transaction.

SCULPTOR 4.2 - 11 June 2001

  1. The compiler now accepts the commands begin_mark, commit_mark and rollback_mark, which are synonomous with begin, commit and rollback. This makes it easier to prepare code changes required by Sculptor 5.1.

SCULPTOR 4.2 - 20 December 2000

  1. The maximum number of characters than can be read in a single get # command has been increased from 1000 to 4000.

SCULPTOR 4.2 - 1 November 2000

  1. Three system temps have been added:

    sys.ScMajorVersion (type u1) contains the Sculptor major version number.
    sys.ScMinorVersion (type u1) contains the Sculptor minor version number.
    sys.ScDateVersion (type i4/dn) contains the Sculptor date version.

    For example, Sculptor 4.2 (1 November 2000) sets:

    sys.ScMajorVersion = 4
    sys.ScMinorVersion = 2
    sys.ScDateVersion = 1/11/00

    Suffix letters, such as 4.2a, are no longer used.

SCULPTOR 4.2 - 12 October 2000

  1. The style WS_FIXEDWIDTH has been added for tab windows. It makes all tabs the same width.

SCULPTOR 4.2 - 12 September 2000

  1. scconfig has been enhanced so that it is possible to install Sculptor without user intervention, the licence details being read from a file. There are two new options:

    scconfig -c filename

    The -c option starts scconfig in normal interactive mode but when the program exits, it saves the licence information that has been entered or viewed to the specified file as well as updating the registry.

    scconfig -f filename

    The -f option reads licence information from the specified file and updates the registry. This is a quiet mode operation. The information in the file must be valid. There are no error messages.

    In both cases, the filename can be a valid path to kfserver/kfservnt, which must be running on the referenced server.

SCULPTOR 4.2 - 26 June 2000

  1. By default on Unix and Linux, programs that are executed by kfserver now have stdin set to /dev/null and stdout and stderr redirected to the file /tmp/kfserver.log. This avoids problems with programs that read or write these channels by mistake. The standard channels can still be redirected elsewhere in the normal way on the command line. On Windows the error log file is \kfservnt.log.

SCULPTOR 4.2 - 30 May 2000

NOTE 1: To avoid a !define conflict, the FILE_EXISTS, FILE_CANREAD, FILE_CANWRITE and FILE_CANEXEC definitions in the beta release have been changed to TEST_EXISTS, TEST_CANREAD, TEST_CANWRITE and TEST_CANEXEC. These are used with the new access() function.

Sculptor 4.2 contains major improvements and several bug fixes so it is essential that applications are fully verified for operation with this version. Bug fixes and improvements are always capable of breaking application code that uses an undocumented feature or has a coding error that is benign on an earlier version of a product.

  1. Sculptor 4.2 supports the use of the Windows registry and the registry should be used instead of the environment. An emulation of the registry is provided on other platforms, such as Unix. Each Sculptor version has its own set of variables in the registry. These are keyed on the Sculptor major version number, ignoring any minor version number and suffix letter. Thus, there is a set of variables for version 4. A variable can be defined at both system level and login user level (the local user). A variable is first checked for at user level. If it does not exist at this level, the system value is used. In most cases it will only be necessary to define a variable at system level. If an environment variable is set, this takes precedence over the registry but it is recommended that the environment is not used, except for temporary changes during development.

    When a Sculptor program runs it picks up the registry variables that correspond to its major version number. Sculptor 4.2, 4.2a, 4.2b etc. will all pick up the version 4 variables. Suffix letters indicate bug fixes and essential minor enhancements.

    When a new version of Sculptor is installed, it creates a new set of registry variables for that major version if none exist or, if registry variables exist for a previous version of Sculptor, takes a copy of these and modifies them as necessary.

    The user can set their own variables in the Sculptor registry at both system level and user level. The program scconfig is used to do this on Windows or chconfig on other platforms, including 16-bit DOS. The Sculptor function getenv() checks the environment, the local user’s registry and the system registry in that order.

    There is a new Sculptor licensing system that uses the registry. The scconfig program must be used to input a licence number and activation key. Once this has been done, all Sculptor programs that are valid under the licence will run. There is no need to serialise individual programs. Valid updates will also run without the need to edit the key. A change to the licence, such as the number of run-time users, can be made by running scconfig or chconfig and entering a new key supplied by Sculptor.

    To set up or edit a licence on Windows, proceed as follows:

    1. Run scconfig and click the Reg button.
    2. Type in the supplied serial number.
    3. Tick the boxes relevant to your licence (Development, Runtime, Server, etc.) and enter the correct number of users against each option.
    4. Enter the activation key supplied by Sculptor. Spaces are ignored but can be used to improve readability. The digit 0 and the letter O are equivalent but the digit 1 and the letter l are not. Case is not significant.

    On Unix and other platforms, run chconfig and reply to the questions.

    If scconfig is executed with a -q (quiet) option, information messages are suppressed. This is useful when running scconfig as part of an application installation procedure; only the licence information needs to be entered.

  2. The Sculptor keyed file routines have been improved substantially. The changes increase performance, especially in client/server mode. Also, although reliability has not been a problem, the new routines will be more robust and the file system better able to survive a machine or network failure. The overall speed improvement cannot be quantified because it varies with application code.

  3. There is now no specific limit to the number of Sculptor keyed files that can be open concurrently, available memory being the only limiting factor. Exception: Clients who connect to kfserver from an earlier version of Sculptor are still limited to 400 open files or less, depending on the client version.

  4. An option is available to further increase performance in client/server mode on specified files by reading records in batches. This option must be used carefully because in some cases it can have a negative effect on performance and in other cases it can change the behaviour of the application. This feature is intended for use when records are being read sequentially and not locked or only locked occasionally. The driving file of a report is frequently a suitable candidate. The batch_read property can be set with the file open or closed:

    file_id->batch_read = ON | OFF

    By default, this property is OFF. If it is turned ON and the file is open or is later opened on a server (running kfserver or kfservnt), then executing any of the following commands twice consecutively, using the same index, causes Sculptor to perform a read ahead operation and to obtain a batch of records or keys from the server:

    nextu, prevu, nextkey, prevkey

    The matchu command also performs a read ahead, the findu command being taken to be the first of the pair. If the file is open read only, the next, prev and match commands also read batches.

    Once a batch of records has been read, all subsequent commands that do not lock a record, including the read, readu, readkey and testkey commands, read the required record from the local batch if present instead of reading it from the server.

    If a command that locks a record is executed and the record is in the batch buffer, the record is read again from the server and the batch buffer is updated. If the record is later written back, it is sent to the server and the batch buffer is updated. The batch buffer is cleared or refreshed as appropriate when one of the following occurs:

    1. An insert or delete command is executed.
    2. A record is read that is not in the batch buffer.
    3. A write command is executed that updates the index by which the records in the batch buffer are sequenced.
    4. A read command is executed that uses a different index to the one by which the records in the batch buffer are sequenced.
    5. An incompatible command is issued such as a request for a record when the batch buffer contains only keys or a next/prev command when the buffer contains a find/match batch.
    6. The programmer explicitly clears the batch buffer using the command:
      clearbatch file_id[, file_id]…
    7. The batch_read property is turned OFF.
    8. The file is closed.

    It is important to realise that some code will not work as expected when the batch read feature is enabled. The following is an example:

    nextu file1
    nextu file1
    while (file1.flag == 0) {
        readu file1
        sleep 2

    The readu in the above code will read the same record from the batch buffer and never see an update made by another process.

    Memory for a batch buffer is allocated when the file is open and the batch_read property is ON. This memory is released if the batch_read property is turned OFF or the file is closed. Sculptor calculates an optimum size for the batch buffer based on the record length, the network packet size and the fact that there is no significant benefit above a certain size. All memory overhead is on the client side. There is no overhead on the server.

    The smaller the record length, the greater the gain in performance because more records are stored in each network packet. There is still a useful improvement if the record length exceeds the network packet size because there is less network handshaking.

    For 64-byte records, the buffer is about 1.5K and the number of records per batch is 21. For 1024-byte records, the buffer is about 12K and the number of records per batch is 11.

    A test program that reads sequentially through 50,000 records showed the following improvement in elapsed time on a local area network:

    64-byte records: Reduced from 38 seconds to 7 seconds. 1024-byte records: Reduced from 69 seconds to 52 seconds.

  5. Window and control clauses that take a bitmap now accept either a bitmap or a jpeg file. The correct file extension (.bmp, .jpg or .jpeg) must be specified.

  6. There is support for sockets and named pipes in open#, get#, put#, etc. These allow Sculptor programs to communicate with programs written in other languages. Sockets are supported on all 32-bit Windows platforms, most Unix platforms and can be used across a network. Named pipes are supported by most Unix platforms and Windows NT but not Windows 95/98.

    Open a named pipe:

    open #<integer>, "|pipename" ... create | read | update

    Open a socket:

    open #<integer>, "[server:]<socket number>:" ... read | update

    Note that UPDATE is not the same as the APPEND mode that can be used with sequential files.

    A server program omits the “server:” part of the open command because it listens for any client to connect on the specified socket. A client program must specify the server name and the socket number that it wishes to connect to. Normally, both server and client will use update mode, though a socket can be opened in read only mode if required.

    Check if bytes are available on a sequential file, socket or pipe:

    check #<integer> ni=label err=label traps=label

    The check# command continues with next statement if input is available on a pipe or socket and stores the number of bytes in:


    If end of file is detected, sys.AvailableBytes is set to -1 and execution branches to the err trap if present. Otherwise, if no bytes are available, execution jumps to the ni label. A get# command waits if no input is available. The general traps clause can also be used.

  7. A parent program can talk to the stdin and stdout channels of a child process using get# and put#.

    exec ... stdin=#<integer> stdout=#<integer>

    stdin is the child’s stdin channel (use put#). stdout is the child’s stdout channel (use get#). Different channels must be used for stdin and stdout.

  8. The open and close listbox_id commands now open and close the drop down list if “!compat open=3” is not specified in programs compiled with scc 4.2. Remove “!compat open=3” from <local.h> to use this feature. The comands show and hide should be used to make a listbox or any other control or window visible and invisible.

  9. Improved error messages when opening files, including the case when the number of licensed users on kfserver has been exceeded.

  10. A standard integer format such as “#####0” can be used with elapsed time fields as an alternative to the “hH:MM” type format. This displays the value in its base unit (eg seconds for logical type es).

  11. The source object of a table can now be a secondary index identifier. If two or more files use the same secondary index name, the name must be qualified by using the syntax file_id.index_id.

  12. Characters typed into textboxes that are linked to numeric fields are now validated immediately for obvious errors, so an alpha character is refused.

  13. The getinfo and putinfo commands now work in GUI mode by emulating a command line dialog in wintask. These commands are provided so that converted Sculptor 2 programs still work. They are obsolescent and should not be used in new programs.

  14. If wintask is declared as -wintask and the program is compiled and run with Sculptor 4.2, then wintask is no longer created when the program starts. Either “create wintask” or “show wintask” will create the window. See the file compat for a backward compatibility option.

  15. With the exception of the xcreate, ycreate and winclass properties, it is no longer necessary to destroy a window or control in order to change a property value. If possible, Sculptor changes the property without destroying the control, otherwise if the control is in the created state, Sculptor destroys and recreates it with the new property.

  16. put #0 now outputs !temps of type b and fields that have the b flag set in binary. Note that put #0, field:”b” does not output a binary value since the “b” here is a format string, not a flag. Multi-byte, numeric fields are output in the order most significant byte to least significant byte. Examples of fields that are output in binary:

    !temp MyInt,,u1,,b
    !temp MyBinary,,b6

    During a report, put #0 now always sends its output to the printer. Previously this worked only if !compat report=2 was set and the output was redirected to a file or device. If the printer is a Windows printer and the printer parameter file has Print Mode set to S (Standard) instead of W (Windows), the Windows GUI print mechanism is bypassed and the printer can be controlled directly. Printer control sequences can be defined in the printer parameter file or output using put #0 with binary fields. For this to work properly, the Generic/Text Only print driver should be used. Other print drivers may not support this feature.

  17. The commands enable_tabstop and disable_tabstop have been added. These operate on a list of controls, a group or an entire window.

  18. If the style WS_LJD is used with a graphic image, the image is aligned at the top left corner of its start character position instead of the middle of the character. This makes it possible to create graphics that line up with buttons and other controls.

  19. The put command now supports an optional font=”font_definition” clause.

  20. The screen painter can be configured not to create .bak files.

  21. The EV_KEYSTROKE event now receives all key presses, not just function and control keys. Ordinary keys send positive ASCII values. Special keys send negative codes as before.

  22. The command raise <control_id> has been added. This raises the specified control above its siblings and can be used to bring an overlapped control to the top.

  23. In a textbox group, the up and down arrow keys no longer move between textboxes in programs that have been recompiled with scc version 4.2. See the file compat for more information and a way to retain backward compatibility if required.

  24. The new style WS_SCALE can be used with graphics images. If set and if only width or height is defined but not both, the other dimension is scaled so that the aspect ration of the image is maintained. This stops the image from appearing distorted.

  25. The screen painter now prevents buttons from being resized with the mouse to the value height=1. This value can now be set only in the property sheet. The same applies to the rows= value of a textbox. Previously it was very easy to change uninentionally the height of a button or the number of rows in a textbox from 0 to 1.

  26. New functions:

    access(pathname, mode)

    Checks the existence or access permission of a file or directory. Mode values are defined in <files.h>:

    TEST_EXISTS Tests if the files exists.
    TEST_CANEXEC Tests if the current user has execute permission.
    TEST_CANREAD Tests if the current user has read permission.
    TEST_CANWRITE Tests if the current user has write permission.

    The mode TEST_EXISTS must be tested on its own. Other modes can be combined using the | operator.

    Returns 0 if the file exists or the current user has the specified permissions, otherwise returns -1 and sets sys.Errno to the operating system error code.

    NOTE: Previous release notes said incorrectly that this function returned TRUE if okay, FALSE if error.

    chmod(pathname, mode)

    Sets the access permissions on a file or directory. Only the existing owner or the superuser can change permissions. Mode values are defined in <files.h> and are combined using the | operator:

    PERMS_RDOWNER Gives owner read permission.
    PERMS_WROWNER Gives owner write permission.
    PERMS_EXOWNER Gives owner exec permission.
    PERMS_RDGROUP Gives group read permission.
    PERMS_WRGROUP Gives group write permission.
    PERMS_EXGROUP Gives group exec permission.
    PERMS_RDOTHER Gives others read permission.
    PERMS_WROTHER Gives others write permission.
    PERMS_EXOTHER Gives others exec permission.

    Unix supports all the above modes. If mode is 0, all permissions are removed. DOS/Windows supports PERMS_RDOWNER and PERMS_WROWNER; all other modes are ignored. Files can always be read on DOS/Windows, so the mode PERMS_RDOWNER is always set, whether or not it is specified.

    Common combinations of these values (PERMS_…) are defined in <files.h>.

    Returns 0 if successful, otherwise returns -1 and sets sys.Errno to the operating system error code.

    fileinfo(pathname, size, date_created, date_accessed, date_updated)

    Gets information about the specified file or directory and stores it in the supplied arguments:

    size The file size in bytes.
    date_created The date and time the file was created.
    date_accessed The date and time the file was last accessed.
    date_updated The date and time the file was last updated.

    The date variables should be logical type ‘td’. Unix returns local time but DOS/Windows returns GMT. A future release of Sculptor will probably convert all times returned by this function to GMT so that cross platform comparisons are possible.

    Returns 0 if successful, otherwise returns -1 and sets sys.Errno to the operating system error code.

    mkdir(pathname, mode)

    Creates the specified directory. The user must have permission to create files in the parent directory. Mode is the required access permission and takes the same values as for the chmod() function. On Unix, a directory must have execute permission for the user to get a list of files in the directory.

    Returns 0 if successful, otherwise returns -1 and sets sys.Errno to the operating system error code.

    putenv(name, value)

    The arguments name and value are text strings. Sets the environment variable name to value. If name does not exist, a new environment variable is created. If name already exists, its value is changed. Returns 0 if successful or non-zero if there is an error (insufficient memory). The new value is available to the calling process and to any child processes that it creates.

    Returns 0 if successful, otherwise returns -1 and sets sys.Errno to the operating system error code.

    textlength(text, text_font, data_font)

    Returns the number of character positions that the specified text will occupy if it is displayed in text_font in a window whose font is data_font. The font strings should be standard Sculptor font specifications, e.g. “Arial@12,b”.

  27. There are seven new system variables:


    When sys.AutoCancel is ON, automatic validation and the calling of textbox validation functions is suppressed when the cancel button is clicked or cancel dialog is triggered by the ESC key. The cancel button is a button with style WS_CANCEL_BUTTON. In programs compiled by scc version 4.2 or later, sys.AutoCancel is ON by default. In programs compiled with earlier versions of scc, it is OFF by default. In the unlikely event that you wish to retain the old default in newly compiled programs, add the line “sys.AutoCancel = OFF” to the Sculptor include file <local.h>.

    sys.AvailableBytes is set by the check # commands when it is used to check for unread bytes on a pipe or socket.

    sys.HostName is the network name of the computer on which the program is running. This is an alpha field whose length is the length of the name. sys.IPAddress is the computer’s network address as an i4 field. The dotted address can be obtained as follows:

    !temp NetAddress,,a15
    tmp.NetAddress = tostr(getbyte(sys.IPAddress, 1)) + "." \
                   + tostr(getbyte(sys.IPAddress, 2)) + "." \
                   + tostr(getbyte(sys.IPAddress, 3)) + "." \
                   + tostr(getbyte(sys.IPAddress, 4))

    The values in sys.HostName and sys.IPAddress are only set in sagewc and srepwc. They are null in sagew and srepw.

    sys.PrintOptions can be used to specify options for the Windows Print Dialog. It is used when a report is run to PrintManager and when a printer is seleted using the SelectPrinter() function. By default, sys.PrintOptions is 0. To modify the dialog, set one or more of the following flags, which can be combined using the | operator.


    Disables the Print to File check box.


    Hides the Print to File check box.


    Hides and disables the Network button.


    Disables the Pages radio button and the associated edit controls.


    Disables the Selection radio button.


    Prevents warning message from being displayed when there is no default printer.


    If this flag is set, the Pages radio button is selected.


    If this flag is set, the Print to File check box is selected. Setting this flag causes the print subsystem to query the user for the name of the output file.


    If this flag is set, the Selection radio button is selected. If neither PD_PAGENUMS nor PD_SELECTION is set, the All (pages) radio button is selected.

    On Windows, sys.ScreenWidth and sys.ScreenHeight return the current screen resolution in pixels. In character mode they return the width and height in columns and rows.

  28. There is a new Sculptor include file called <local.h>. This file is included by sculptor.h. The intention is that each user should maintain their own version of local.h and should save and restore this file when upgrading to a new version of Sculptor. Local alternatives to Sculptor defaults can be stored in local.h.

  29. The “tooltip=” clause has been added to graphics images.

  30. Windows that have scroll bars now scroll smoothly instead of a page at a time.

  31. The clause “index=” is now valid in a textbox. It links the textbox to the specified element of a subscripted field. The index value can be read or updated at run-time using the “textbox_id->index” property.

  32. It is now possible to specify a subscript when assigning records. In all cases, fields that are non-array fields in both the source and destination record are always assigned, regardless of any specified subscripts. For array fields, the rules are:

    rec1 = rec2 Fields that are arrays in both records are assigned for all common subscripts. Fields that are arrays in rec1 only, assign rec1.fld[1] = rec2.fld. Fields that are arrays in rec2 only, assign rec1.fld = rec2.fld[1].
    rec1 = rec2[i] Fields that are arrays in both records are assigned for all common subscripts. If this is not required use rec1[i] = rec2[i]. Fields that are arrays in rec1 only, assign rec1.fld[1] = rec2.fld. Fields that are arrays in rec2 only, assign rec1.fld = rec2.fld[i].
    rec1[i] = rec2 Fields that are arrays in both records are assigned for all common subscripts. If this is not required use rec1[i] = rec2[i]. Fields that are arrays in rec1 only, assign rec1.fld[i] = rec2.fld. Fields that are arrays in rec2 only, assign rec1.fld = rec2.fld[1].
    rec1[i] = rec2[j] Fields that are arrays in both records assign rec1.fld[i] = rec2.fld[j]. All other subscripts are ignored. Fields that are arrays in rec1 only, assign rec1.fld[i] = rec2.fld. Fields that are arrays in rec2 only, assign rec1.fld = rec2.fld[j].
  33. If the get_filename() function is called with the GFN_GETSAVEFILE flag and a list of extension filters and the user types a filename without an extension, the extension for the currently selected filter is now appended to the returned name. If the current filter contains multiple extensions, the first extension is appended.

  34. In the screen designer, when an OLE specific property is clicked in the property window of an OLE control, the control’s short help text is displayed on the caption bar. If full help is available, it can be displayed by clicking the ? icon and dragging it to the property. Short help, where available, is also displayed when a standard property is clicked.

  35. spw can manipulate multiple items:

    More than one item can be selected by using the Shift or Control key in conjunction with the mouse. When a click on an item is detected and the Shift or Control key is pressed, the clicked-on item is toggled (i.e. selected or deselected depending on its previously selected state). The last item selected is the Primary selected item and other items selected are Secondary selected items. The Primary selected item can be identified by its selection border (the corner handles of the primary selected item are black, whereas those for secondary selected item(s) are white).

    The rules for multiple selection are:

    1. Only windows, buttons (all types), textboxes, listboxes, OLE controls, graphics, tables and static text can be part of a multiple selection.
    2. All selected items must have a common parent window. This allows buttons and textboxes to be selected together, regardless of whether they are grouped or top-level.
    3. If an invalid item is selected an alarm is sounded and the selection is treated as a single selection.
    4. Items selected from the menu are treated as single selection.
    5. The last item selected is identified as the Primary selected item.
    6. The property window reflects the properties of the primary selected item (only).
    7. When multiple items are selected none of them can be resized by clicking down on the border. Resizing is only enabled when a single item is selected.
    8. A single click on an item that is already selected makes it the Primary selected item.

    The properties in the property window are those of the Primary selected item. The primary selected item has special meaning in some of the new layout functions (see below for details).

  36. A new Layout menu item has been added to the spw Edit menu. This has has four Popup menus: Align, Make Same Size, Space Evenly and Centre in Window.

    The Align menu has six functions to align the left, horizontal centre, right, top, vertical centre and bottom. All align functions operate on two or more selected items and reposition the selected items with respect to a primary selected item. Perfect alignment cannot always be guaranteed because items are positioned according to a character grid and exact alignment of right, bottom and centre of items is not always possible. Alignment of top and left is always possible except for graphics that are aligned to the centre of the character grid cell.

    Space Evenly is currently not implemented and these functions are disabled at present.

    Make Same Size has three functions to alter the width, height and both the width and height of selected items. All of these functions operate on two or more items and alter the dimensions of selected items to match the size of the primary selected item. Identical sizes may not be possible with controls of different types or with different fonts.

    Centre in Window has three functions to centre vertical, horizontal and both vertical and horizontal. All selected items are centred.

  37. Colour control has been added to tables. The required colours are defined in a colour record linked to the table definition. Where relevant, the compiler accepts the spelling color or colour.

    NOTE: Following comments that, intuitively, the subscripts in the array Cell were the wrong way round, they have been changed to [N,2] instead of [2,N].

    /* Colour record */
    !record record_id {
    /* Table definition */
    +|- table table_id at x,y {
        colour_record = record_id

    The required fields in a colour record are pre-defined and must be named exactly as specified. Unrecognised fields are ignored. For tables, the field “Cell” defines the required foreground and background colours for each cell across one row. These are 24-bit, RGB values. Some useful colours are defined in the file <rgb>.h, which is included automatically by <sculptor.h>. New fields to control the colours in other parts of a table will be added in the future.

    The value of Cell[N,1] defines the foreground colour and the value of Cell[N,2] the background colour for cell N, where N is 1 to the number of fields in the display record. If “Cell” has a single dimension, it defines foreground colours only and all background colours have the default value. “Cell” must have a dimension, even if it is 1.

    An RGB value has the form 0x80bbrrgg, where bb is blue intensity, rr is red intensity and gg is green intensity. The top bit (0x80xxxxxx) must be set to activate the colour. This is a Sculptor feature that makes it possible to switch pre-defined colours on and off by setting and clearing the top bit (defined as RGB_ACTIVATE). If a colour is not active, the appropriate default colour is used. Without this feature, there would also be no easy way to distinguish between 0x00000000 (the default colour) and 0x80000000 (black).

    If all lines are to use the same colours, it is only necessary to initialise the colour record before the table is created. To set different colours on each line, set the required colours into the field “Cell” during the new EV_SUPPLY_COLOUR event:

    event_function(EV_SUPPLY_COLOUR, table_id, line)

    This event is sent to the table’s event function when the table is being created and scrolled. If the source object is a function, the EV_SUPPLY_COLOUR event follows the EV_SUPPLY_VALUE event.

    When the EV_SUPPLY_COLOUR event is called, the display record contains the values for the current line. Also, if the source object is a file, the file’s default record buffer contains the corresponding record from the file. This is a temporary assignment and the default record buffer is reset to its previous value when the EV_SUPPLY_COLOUR event returns.

  38. There is a new function table_get_key() that can be used with a table whose source_object is a file:

    table_get_key(table_id, row)

    This function copies the key of the record whose fields are displayed on the specified row into the source file’s default record buffer. The program can then read the record locked or unlocked or just use the key values as required. The row argument specifies a row on display in the range 1 to table->rows, not a line number in the entire table. The function returns OKAY if successful or ERROR if row is out of range or the table’s source_object is not a file.

  39. The on local and on global commands can be used to trap the F10 and Shift F10 keys. When trapped, these keys no longer move focus to a menu. Note that the F10 and Shift F10 keycodes are not sent to a keystroke event function because at present this would prevent their default behaviour. This may change in a future version of Sculptor. In order to allow for future enhancements, a keycode event should always return OKAY or just return with no explicit return value.

  40. There are now two ways to specify a Sculptor server in a pathname:

    1. “server:…”
    2. “//server:…”

    Prior to Sculptor 4.2, only the first syntax could be used.

    The ‘:’ at the end of the server name tells Sculptor to use kfserver or kfservnt on the specified server. The second syntax must be used if the server name is a single character, otherwise it is taken to be a drive letter on the local machine. The text that follows the ‘:’ is passed to kfserver as the required path on the remote machine. On Windows, this should be a drive letter and full pathname and on Unix a full pathname, otherwise the path is relative to kfserver’s current working directory, which cannot be relied upon. Examples:


    Note that either ‘/’ or ‘' can be used on Windows but that all ‘' characters in a quoted string must be doubled, since this is the standard escape character.

    If the syntax “//server/d/myapp/data/myfile” is used, the file will be opened by Windows, not by kfserver. This is valid for program names and text files but is not safe for Sculptor Keyed Files.

  41. The default height of a LIST_BUTTON or LIST_EDIT control is several pixels greater than a textbox. The height of a textbox was chosen so that Sculptor 2 programs designed for a standard 80 x 25 character screen fitted onto a 640 x 480 Windows screen. The style WS_COMPACT makes the height of a listbox two pixels smaller, which is close to that of a textbox and makes some screen layouts look better. However, doing this clips the descenders on lower case characters with some data fonts.

  42. By default, the utility programs kfcopy, newkf and reformat all write to the transaction log file if it is present in $SCULPTOR/recover. Note that earlier versions of newkf did not do this. The command line option -l can be used to turn transaction logging off in these programs. Any scripts that re-initialise files by calling newkf before they run the transaction recovery program should be modified to use the -l option.

  43. The function record_count() now works with ODBC. It’s efficiency will depend on the underlying database engine.

SCULPTOR 4.1e - 14 March 2000

A new trap has been added to the write and delete commands. The full syntax of these commands is now:

write record_id [nrs=label] [re=label] [ue=label] [traps=label]
delete record_id [nrs=label] [ue=label] [traps=label]

The ue (update error) trap can occur only when using an ODBC database that does not support standard (pessimistic) record locking. This is the case with Microsoft Access, which allows two ODBC clients to read the same record for update. If both clients then attempt to write or delete the record, only the first succeeds. The ue trap allows Sculptor to notify the second user that the operation has failed. If this error is not trapped, Sculptor displays the default error message:

"Update refused - record updated by another user"

(We have checked this issue with Microsoft who have confirmed that Access “does no record locking for an ODBC client”.)

This situation does not occur with SQL Server, which waits for a locked record to be released before a second user is allowed to read it for update. However, since SQL Server does not return to the client until the record is available and because it does not provide an option to return if a record is locked, an riu trap cannot occur.

Programmers should be aware that all database products have different features and that even if a database has a particular feature, it will not necessarily be supported by its ODBC driver. It is essential to ensure that a specific database and ODBC driver combination supports all the features that your application needs.

SCULPTOR 3.4d/4.1d - 31 January 2000

kfserver has been improved to handle unexpected errors better. This includes client side crashes and manual termination of a client process. Unexpected system errors on the server, such as insufficient memory are now logged in the file /tmp/kfserver.log on Unix and generate an error dialog on Windows.

SCULPTOR 3.4d/4.1d - 1 December 1999

The maximum number of keyed files that can be open concurrently has been increased from 350 to 400. Note that Sculptor 4.2 removes this limit and can open as many files as the operating system permits.

SCULPTOR 3.4d/4.1d - 1 September 1999

The program srep.exe is now distributed with the Windows version of Sculptor. This is a 32-bit, DOS version, currently at 3.4d revision level. A 4.2 equivalent version will be introduced later. The getinfo command reads from standard input. The default print stream is standard output. The debug version, srepdb.exe, is also supplied.

SCULPTOR 3.4d/4.1d - 18 August 1999

This release has improved error messages for printer failures and for a failed connection to kfserver when the user licence has been exceeded.

SCULPTOR 3.4d/4.1d - 14 June 1999

  1. New function:

    copyfile(destination_path, source_path, options)

    Copies a file. Either file can be on the client or a server. The following option flags can be used (combine with the | operator):

    COPY_BINARY Copy a binary file.
    COPY_TEXT Copy a text file.
    COPY_UPDATE Copy only if the source file is newer or the destination file is missing.

    It is recommended that either COPY_BINARY or COPY_TEXT is always specified. If not, a future release will try to determine the file type but this feature is not yet implemented.

    Return values:

    -1 An error occurred. See sys.Errno.
    0 No need to copy the file. COPY_UPDATE was specified and the source file is not newer.
    1 File copied.

SCULPTOR 3.4c/4.1c - 6 April 1999

  1. New function:


    Returns the number of records in a Sculptor keyed file. Fast on data files unless they have a large number of deleted records that have not been re-used. Slower on index only files because each index block must be read.

  2. The styles WS_INDENT, WS_STANDOUT and WS_PLAIN now work on GUI windows as well as character windows. WS_STANDOUT is the default.

  3. When printing, the field flag “n” indicates that the value should be treated as numeric for alignment purposes, which causes the text to be right aligned within its nominal column width. Because the text does not have to be numeric, the “n” flag can be used to right align any print value.

    Previously, this flag was honoured only if it was defined in a data dictionary field or a !temp declaration. It can now be attached to any print value:

    print fieldname::"n"
    print "abc"+"123"::"n"

    However, if the text in the field contains trailing spaces, the result will be a ragged right edge unless all values have the same number of trailing spaces. To move the trailing spaces to leading spaces, use the function right():

    print right(expression)::"n"

SCULPTOR 4.1b - 24 February 1999

  1. CLOSE_DIALOG and other special return values now work in an OLE event function. To return a value to the OLE control use the new syntax:

    return OKAY, <value for control>

SCULPTOR 3.4b/4.1b - 24 February 1999

  1. spw accepts program files that end with ^Z.
  2. The programs descw, spw and the debug versions of sagew and srepw contain various small improvements.

SCULPTOR 4.1a - 14 January 1999

  1. It is possible to use a text value as a subscript for an OLE control. See the file ole.doc for details.

SCULPTOR 3.4a/4.1a - 14 January 1999

  1. There is a new function for use with Windows printers:

    num_forms = EnumPrintForms(printer, form_names, form_numbers)

    For details see the file $SCULPTOR/DOC/print.doc, which has been generally updated.

  2. The debug versions sagewd, srepwd, etc. have been improved:

    The tooltip that displays the value of a field now evaluates subscripts (except expression).

    The tooltip also displays the value of object->property.

    There is a hot button that halts an executing program and returns control to the debugger.

  3. Hotkeys now work with tab windows. (title = “Tab &One”).

  4. If an attempt to connect to a server is delayed, a message is displayed until the connection succeeds or times out (GUI clients only).

  5. A function has been introduced that sets the current font in a report. This is an alternative to setting sys.PageWidth:

    setfont(name, size, style)
    name The name of the font, e.g. “Arial”. Specify sys.FontName to keep the current font.
    size The required point size. Specify sys.FontSize to keep the current size.

    The required style flags. Specify sys.FontFlags to keep the current style. Valid flags are defined in <sculptor.h> and can be combined using the binary | operator:

  6. The function DrawImage() can be called to print or display a bitmap. For details see the file $SCULPTOR/DOC/draw.doc, which has been generally updated.

  7. The following system temps have been added:


    Can be used to force text printed in a proportional font to fit its natural width. Default is 0 (OFF). Other values:

    sys.AutoFit = 1 Apply the function fit(field) to all print items that are file or temp fields but not to quoted text strings or text expressions.
    sys.AutoFit = 2 Apply the function fit(item) to all printed text.

    To maximise the space available for each field, set sys.Gap=1. See fit() below for further information.


    Default is ON, which tells Sculptor to restore focus to the previous application when the program exits. Set OFF to stop this happening. You might want to do this after using exec or chain to start a new program.


    Read only. Set to the average width in pixels of a character in the current print font.


    Read only. Set to the width in pixels of a numeric character in the current print font.


    Read only. Set to the maximum width in pixels of a character in the current print font.


    Read only. Set to the name of the current print font.


    Read only. Set to the point size of the current print font.


    Read only. Set to the style flags of the current print font. A style flag can be tested using the binary & operator:

    if (sys.FontFlags & FONT_BOLD) ...

    Read only. TRUE if running on Windows NT, otherwise FALSE.


    Read only. The major version number of Windows. (4 for NT 4.0).


    Read only. The minor version number of Windows. (0 for NT 4.0).

  8. There is a new sub-directory in $SCULPTOR called APP that can be used for application binaries. If the program name passed to sage or srep begins with a ‘:’, the program is loaded from $SCULPTOR/APP. Examples:

    sagew :myform
    srepwc :myapp/myreport
  9. There is a new environment variable called SCMASTER. If set, this specifies a master Sculptor directory, which can be on a remote server. Whenever Sculptor loads a program from $SCULPTOR/APP, it first checks the timestamp of the same program on $SCMASTER/APP.

    If the program exists on $SCMASTER/APP and has a later timestamp than the version on $SCULPTOR/APP, or if the program does not yet exist on $SCULPTOR/APP, Sculptor copies it from $SCMASTER/APP to $SCULPTOR/APP before running it.

  10. Terminal parameter files can be loaded from a server by specifying the appropriate full path. Example:

    set SCTERMW=myserver:/usr/SCULPTOR/term/mswin

    If the terminal name begins with a ‘:’ and the environment variable SCMASTER is defined, the file in $SCULPTOR/TERM is updated from $SCMASTER/TERM if the latter has a later timestamp. Example:

    set SCTERMW=:mswin
  11. Printer parameter files can be loaded from a server by specifying the appropriate full path. Example:

    run report myreport to "PrintManager" \

    If the printer name begins with a ‘:’ and the environment variable SCMASTER is defined, the file in $SCULPTOR/PRINT is updated from $SCMASTER/PRINT if the latter has a later timestamp. Example:

    run report myreport to "PrintManager" ppf=":winpm"
  12. In a remote pathname, the characters $$ are passed to the server as $. This allows the pathname to reference an environment variable on the server. Example: "myserver:$$MYDIR/data/file".

  13. The flush command can be used on Sculptor keyed files:

    !file MYFILE "../data/myfile" update
    flush MYFILE

    This forces any outstanding data in the operating system buffers for the data file and its index file to be written to disk.

  14. The new command


    flushes all sequential files and all Sculptor files to disk.

  15. The new function

    playsound(filename, flags)

    plays a sound file with a “.wav” extension. The following flags are defined in <sculptor.h> and can be combined using the | operator:

    SND_SYNC Play synchronously (wait).
    SND_ASYNC Play asynchronously (no wait).
    SND_NODEFAULT Don’t play default sound if not found.
    SND_LOOP Repeat sound until stopped.
    SND_NOSTOP Don’t stop currently playing sound.
    SND_PURGE Stop sound events for this task.
    SND_APPLICATION Use application specific association.
    SND_NOWAIT Don’t wait if the driver is busy.
    SND_ALIAS Name is a registry alias.
    SND_ALIAS_ID Name is a predefined sound identifier.
    SND_FILENAME Name is a filename.

    The following combinations are pre-defined:


    A sound that is playing asynchronously can be stopped with the command

  16. If the source object in a !table declaration specifies a record that has subscripted fields, the table is populated from the array fields such that row N of the table displays the values for subscript N. The display object does not need to be specified.

  17. Using the new function fromname(object_name), it is possible to reference an object from an alpha field or text string that specifies its name:

    display fromname("textbox_name")

    Because parsing the name at run-time is a relatively slow operation, it is better to assign a pointer to the object if more than one reference will be made:

    !temp ptr,,p
    ptr = &fromname("field_name")
    ptr = ptr + 1
  18. In a relational expression, the compiler accepts == as an alternative to = but this is not stated in the manual. Programmers who are familiar with the C language may prefer this symbol.

  19. The best way to activate another program in Windows is to use the activate_app() function with a window class name. This means knowing the class name of the window that is to be activated.

    By default, Sculptor assigns a class name to each window in a program but there is no easy way to know this name. The clause

    winclass = "name"

    can be used to give a window a known class name. This allows a program to check if it is already running and, if it is, to activate the running instance instead of starting a new one. Example:

    -window winmain at 0,0 {
        winclass = "ProgName"
    /* Before creating the main window, see if we are already running */
    if (activate_app(winmain->winclass, NULL) == OKAY) {
        sys.RestoreFocus = OFF
    create winmain

    The above code does not work if the main windows is wintask because this window is always created. However, it can be destroyed before calling activate_app():

    destroy wintask
    if (activate_app(wintask->winclass, NULL) == OKAY) {
        sys.RestoreFocus = OFF
    create wintask

    Note that a window icon is a property of the window class, not the actual window, so when using winclass=, make sure that you don’t use the same class name for two windows that have different icons.

  20. The style WS_NOTABSTOP can be used with any window control to stop that control receiving focus. The TAB and BACKTAB keys skip the control and a mouse click is ignored.

21: The style WS_HOTBUTTON specifies that the button’s event function is

to be called when the button is pressed, even if the program is not in a dialog. A typical use for this style is a cancel button that interrupts a non-interactive operation.

When the button is clicked, the program is interrupted at a random place in the executing code, so great care must be taken inside the event function not to execute any command that could damage the program logic. Sculptor only saves and restores the critical variables sys.Error, sys.Errno, sys.Status and sys.Traps. However, future versions of Sculptor may save more standard temps, so these should not be used to communicate between the event function and the main code.

The best way to use this feature is to have a flag variable that the event function sets. The main program should check this flag from time to time so that it can take the required action at a safe point.

If the main program is sleeping when a hot button is clicked, the sleep will continue for its remaining time when the event function returns. The command

wakeup 0

can be used inside the event function to terminate the sleep command.

  1. In tables and also in the print and printh commands, Sculptor aligns numeric fields to the right and alpha fields to the left. Sometimes, an alpha field contains a numeric value and needs to be right aligned. This can be achieved by specifying the field flag “n”, either when the field is declared or as a property change. Examples:

    !temp fieldname,"Heading",a8,,n
    fieldname->flags = "n"
    printh fieldname::"n"
  2. With radio buttons and checkbox buttons it is now possible to specify the value to be assigned to a linked field when the button is checked and unchecked. Examples:

    checked_value = "Y"
    unchecked_value = "N"
    checked_value = "3"
    unchecked_value = "0"

    Note that the value must be specified as a text string. If the linked field is numeric, the value is converted at run-time.

    The clauses button_id->checked_value and button_id->unchecked_value can also be used.

  3. It is now possible to use a field= clause at group level for radio buttons and checkbox buttons. This field is set as follows.

    For radio buttons, the ordinal number of the currently checked button, counting from one.

    For checkbox buttons, a bit string that indicates all checked buttons:

    if (field & 0x01) info "First checkbox button is checked"
    if (field & 0x02) info "Second checkbox button is checked"
    if (field & 0x04) info "Third checkbox button is checked"
    if (field & 0x08) info "Fourth checkbox button is checked"
    if (field & 0x10) info "Fifth checkbox button is checked"
  4. The following logical field types have been added:

    LT_EMICS Elapsed microsecs.
    LT_TMILS Clock time in milliseconds.

    For the time being, these types can only be set at run-time:

    fieldname->logical_type = ...
  5. The setfocus command can be used to set focus to a given row in a multi-row textbox:

    setfocus textbox_id[row]

    This works for traditional, multi-row textboxes (those with a rows= clause and no height= clause).

    It also works for free format textboxes (those with a height= clause), provided that a rows= clause is also defined.

  6. The ODBC database flag DBFL_AUTOLOG has been withdrawn and replaced by one of opposite meaning: DBFL_MANLOG. Programs that were compiled with earlier versions of scc still work correctly.

    If DBFL_MANLOG is not specified, Sculptor commits each update as a single transaction.

    If DBFL_MANLOG is specified, the program must use the commit and abort commands to commit or abort transactions as required. In particular, the program must commit or abort the last transaction before closing the database or terminating the program, otherwise an ODBC error may occur.

    NOTE: Not used since Sculptor version 5.

  7. When using a proportional font, the command spc(N) causes the next print field to be aligned to its nominal start position. Prior to Sculptor 3.4a, this works only if N >= 1. It now works for N >= 0, which can save space if it is known that the actual width of the next print field will always be less than its allocated print width.

  8. When printing in a proportional font, Sculptor must use a nominal character width so that the tab() function works consistently and the report can be printed in columns.

    Sculptor uses the width of the ‘0’ character as the nominal character width. This is perfect for numeric data because even in a proportional font, all digits are the same width.

    It also works well for most text fields because the average text character is narrower than a digit, so the extra space that is available can be used for text values that are wider than average.

    However, a problem arises when a text value is much wider than average. The text gets overwritten by the field that follows it or is truncated by the edge of the page.

    A new print function can be used to avoid this problem:

    fit(field [, width])[:format[:flags]]

    The fit function forces the text into its allocated space. It does this by automatically reducing the font size until the text fits. The width parameter can be less than or greater than the nominal field width. If the width parameter is omitted, the nominal field width is used.

    If a text value that is printed without using the fit() function is wider than average, it first overflows into any white space that exists between the print fields. This never happens when the fit() function is used, so it is usually best to use “; spc(1); ” after fit() or to set sys.Gap to 1 and to add spaces between other fields as required.

    You can even use “; spc(0); ” if you know that the next field cannot fill its allocated space. This is the case with numeric fields that contain a decimal point. Because the ‘.’ character is narrower than a digit, a field with the format “#0.00” always uses less space than its allocated width of “00000”.

  9. The print function asp(N) prints N normal spaces. Thus, asp(1) is equivalent to ” “.

  10. The info and error commands now accept multiple text lines. Example:

    info "Line one of message", \
         "Line two of message", \
         "Line three of message"

SCULPTOR 4.1 - 10 October 1998

  1. The clause “prog_id=” used in the beta version of Sculptor 4.0 has been changed to “ole_id=”. Source code programs must be changed to use the new syntax before they will recompile.
  2. Various new features have been added to OLE and Active X support. See the file ole.doc for details.

SCULPTOR 3.4/4.1 - 9 October 1998

  1. There are two new functions for use with Windows printers:

    default_printer = DefaultPrinter(properties_array)

    For details see the file $SCULPTOR/DOC/print.doc

  2. Client/server performance has been significantly improved, especially with secondary indexes but this benefit is obtained only by using Sculptor 3.4 or 4.1 with kfserver 1.3. (Note that kfserver uses a different version numbering system to other Sculptor programs. This makes it easier to identify which versions are compatible.)

    • Sculptor 3.3 and 4.0 work with kfserver 1.3 but in this configuration performance can be slightly worse.
    • Sculptor 3.4 and 4.1 do NOT work with kfserver 1.2.

    To upgrade a site safely, install kfserver 1.3 first.

  3. There are two new temps for use in reports:


    Specifies the height of the current font in device units (normally pixels) and is updated automatically whenever the font changes. This variable is read only.


    If set non-zero, specifies the required height of each print line in device units. If set to zero (default), Sculptor sets the line height for each print line to the tallest font used on that line.

    Changing sys.LineHeight causes sys.PageLength to change to suit the new line height. sys.LinesLeft and footnote logic are also updated.

    If you set sys.LineHeight and then print text that is taller than the line, it will overlap the line above.

    If you change sys.LineHeight several times in the same line, the last value set takes effect.

  4. The layout of tables has changed. Column widths now take into account the width of the heading as well as the width of the data. The gap between columns is smaller. Numeric fields and text fields that have flags d, m or n are right justified. These changes make tables look better when proportional fonts are used.

    In order to avoid upward compatibility problems, old programs can be forced to use the old layout. See the file compat34.txt for details.

  5. The debug versions sagewd, srepwd, etc. have several improvements. In particular, once a breakpoint has been reached, the value of a field can be displayed in a tool-tip window simply by moving the cursor over the field’s name in the source code window. This feature is still being improved. In future it will also be possible to view the values in function arguments and of control properties (id->name).

SCULPTOR 4.0 - 20 July 1998

In Sculptor 4.0, the interpreters are available for Windows platforms only. All keyed file utilities, kfserver and the compiler are still available for other platforms. Sculptor 4.0 runs programs that have been compiled with Sculptor 3.
  1. Active X and OLE controls are supported.

    See the file $SCULPTOR/doc/ole.doc for full details.

    See the programs in $SCULPTOR/demo/ole for examples.

  2. There is a new built-in function to load a graphic image:


    where image_file is the pathname to a suitable bitmap. Examples:


    load_picture() can be an argument to an OLE control method function.

    The return value is an image object that can be assigned to an OLE control property.

  3. There is a new temporary field type:

    !temp fieldname,,o

    This can be used to store a reference to an OLE object or to an image object returned by the load_picture() function.

SCULPTOR 3.3/4.0 - 19 July 1998

  1. The mouse shape can be changed using the function ‘setcursor’.

    setcursor(window_id, cursor_id)

    where cursor_id is one of the cursor shapes defined in sculptor.h. Examples:

    setcursor(wintask, CURSOR_WAIT)     /* Hourglass */
    setcursor(wintask, CURSOR_ARROW)    /* Standard arrow */
  2. Graphic style GT_ANIMATE is an animation. An image= clause is required. This must be a AVI file with no sound; the file will not display if it includes a sound track. The WS_INVISIBLE style and the show and hide commands are supported. The following functions can be called:

    AnimatePlay(graphic_id [, ntimes [, from_frame [, to_frame]]])

    Plays the animation. If ntimes is omitted or is -1, the animation repeats until stopped. If from_frame is omitted or is 0, it plays from the first frame. If to_frame is omitted or is -1, it plays to the last frame. Animations play in a separate thread, so the program continues to execute.


    Stops the animation.

    AnimateSeek(graphic_id [, frame])

    Shows the specified frame. If frame is omitted or is 0, the first frame is displayed.

    An example file is supplied in the directory $SCULPTOR/AVI. AVI files can be created using a third part product such as GIF Animator.

    Demo program: $SCULPTOR/DEMO/TESTPROG/wintest.f

  3. Graphic style GT_PROGRESS is a progress bar. If height=0 or there is no height= clause, a small bar is created. Use height=1 or height=2 to obtain taller bars. If there is no width= clause, the default width suits the range 0-100 in 5% increments (height < 2) or 10% increments (height >= 2). The WS_INVISIBLE style and the show and hide commands are supported. The following functions can be called:

    SetProgressRange(graphic_id [, min_value [, max_value]])

    Sets the current range of values. Defaults are 0, 100.

    SetProgressPosition(graphic_id, value)

    Sets the position of the bar within the current range.

    Demo program: $SCULPTOR/DEMO/TESTPROG/progress.f

  4. There is an extensive set of drawing functions that can be used to draw graphics in a window and on a printed report. See the file draw.doc which can be read using M/S Word or M/S WordPad. The constants which were named EDG_* in early beta releases of Sculptor 3.3 have been renamed EDGE_*.

    Any program which uses these functions must include <draw.h>.

  5. The Windows print dialog can be called to select a printer before running a report and the printer’s properties can be retrieved and changed. The following syntax can be used to run a report to a specific printer:

    run report to "printer:PrinterName"

    where “PrinterName” is the name of a Windows printer.

    Full information is in the M/S Word format file print.doc.

    Note that the syntax of the function SelectPrinter() has changed since the first beta release of Sculptor 3.3.

    Demo program: $SCULPTOR/DEMO/SREP/winprint.r

    The old demo program report3.r should be deleted.

  6. A top level window in another application can be activated and brought to the foreground:

    activate_app(window_class, window_title)

    window_class is the class name of the top level window to be activated. All Sculptor programs have class name “ScWin”. The Spy tool supplied with Microsoft C can be used to determine the class name of a window. This argument is mandatory.

    window_title is the title of the window to be activated and can be used to distinguish between different windows in the same class. This argument can be NULL, in which case the first window found in the specified class is activated. Otherwise, the exact text of the window title is required. Care: Some programs change window titles dynamically.

    Returns 0 if successful, otherwise non-zero.

    This function does not start an application. It must be running. Example:

    activate_app("WordPadClass", NULL)
  7. In response to several requests, the print and printh commands have been substantially improved to make it easy to write reports which use proportional fonts. The new rules, which have no affect on fixed fonts, are as follows:

    1. The spc() function is internally converted to a tab position and all tab positions are based on the width of the ‘0’ character. The actual amount of space printed depends on the width of the preceding text.
    2. Spaces that are generated by the comma separator in print and printh commands and those generated by the printh command in order to align column headings with data are also converted to a tab position.
    3. When a numeric field is printed, leading spaces are the same width as the ‘0’ character, which ensures that the value is right aligned.
    4. Spaces in alpha fields and in quoted strings are natural and are not converted to tab positions.
    5. There is a new print function nsp(n) which prints n spaces, each the width of the ‘0’ character. This should be used where a fixed gap is required between print items. In a proportional font, a space generated by nsp() is not the same as a space generated by ” “. The latter is smaller and can be used for fine adjustments.

    With these enhancements, most existing reports that use a fixed font will need little or no change to print correctly with a proportional font.

    Two new printer parameter files have been supplied, arial.s and timesnr.s. These use proportional fonts. The printer parameter file winpm.s has been improved but still selects a fixed font. The program wintest.r which is in $SCULPTOR/print demonstrates different parameter files.

    Different fonts, both fixed and proportional, can be used in the same report by creating a suitable printer parameter file.

  8. The debug versions of sagew and srepw have been improved. On ending a debug session, there is now an option to save or delete the current debug settings (breakpoints and watched fields). Breakpoints are saved by prepending source code lines with the token “_bp”. This ensures that the breakpoints are preserved on the correct lines even if the file is edited. The “_bp” token is ignored by scc. Manually adding breakpoints to source code files does not always work because the debugger also saves the names of the source files that contain breakpoints.

    There is an option to search the source code files for a given string.

  9. The file named in a “to” clause in a “run report” command can be on a remote server. Example:

    run report myreport to "myserver:/usr/tmp/myreport.txt" ppf=...

    Existing code that writes to a device name with a colon suffix such as “PRN:” or “COM1:” will now fail because the name looks like a server. To fix, remove the colon which is not needed.

  10. Printing to a window in GUI mode has been improved. If a report is run without a “to” clause, a temporary window is created which has “Next Page” and “Cancel” menu items. The “Cancel” changes to “End” on the last page. This is an easy way to run a report to the screen. If a “to window_id” clause is specified, the report is run to that window. If the report runs to more than one page, a small control window with next and cancel image buttons is opened over the top left corner of the report window. This allows a report to placed on the background of an existing window. There is no longer a prompt at the end of the report - see the file compat33.txt for a possible upward compatibility issue related to this feature.

  11. The file named in image= and icon= clauses can be on a remote server.

  12. The new command “opendb” can be used to open a database:

    opendb database_id [err=label]

    If an error trap is specified and the database cannot be opened, execution branches to the specified label. The system error code is in sys.Errno and a Sculptor error code is in sys.Error.

  13. Year 2000 compliance is implemented with a breakpoint value which can be absolute or relative, plus an option to force 4-digit years to be input. Options are specified in the file $SCULPTOR/default/dates.cfg:

    Breakpoint=integer          (default 10)
    ForceDigits=Y|N             (default N)

    Case is not significant in the above statements.

    See the file dates.txt for full details.

  14. There is a new version of the Sculptor Keyfile Server that runs as a service on Windows NT. A service can be set to start automatically when the system is booted and does not require a user to be logged on.

    The program kfserver.exe is the non-service version that can be used on Windows 95, 98 or NT. It can only be started by a logged on user and that user must remain logged on while kfserver is running.

    The service version consists of two programs:

    kfservnt.exe, which runs in the background and processes connections from Sculptor clients.

    servmgr.exe, which is used to create, delete, start, stop and control the Sculptor Keyfile Service. Once created, the service can be set to start automatically when the system is booted.

    For information on how to setup the service, run servmgr.exe and browse the Help option.