Event functions


Event function clauses

Applicable to

event = func_id

windows, buttons, graphics, listboxes, OLE controls, static text, tables, textboxes

help = func_id

buttons, listboxes, menu items, tables, textboxes

validate = func_id

textboxes

select = func_id

menu items

source_object = func_id

tables

DEFAULT

In all cases, if a function is not defined for a particular event and control, no action is taken when the event occurs.

Function clauses specify the name of a function to be called whenever a particular event happens to a control. The event = clause defines a general event function which covers several different events which may happen to a control; the other function clauses each relate to a specific event.

Whenever such an event occurs, Sculptor checks to see if a user function has been defined for this event by one of the function clauses listed above. If so, the function is called. If no function has been defined for this event, no action is taken.

Functions are basically called as follows:

func_id(event_code, object_id)

Certain control types have more arguments available. All the arguments are assigned automatically whenever the function is called.

The event codes are defined as manifest constants in the file $SCULPTOR/include/sculptor.h. See Event codes for a list of the codes available.

The events which are to be sent to a window or window control may be specified by means of the event_enable = clause. If the clause is omitted, the standard events for the object type are sent.

The validate =, select = and source_object function clauses are specific to a particular control type and are therefore not documented in detail in this section. The more general event = and help = clauses are documented below.


Event functions

event = func_id

This clause covers a number of different events which may happen to an object, such as it being destroyed or created, or gaining or losing focus. The possible events differ from one object to another and are listed separately in the section on each object.

If an event = clause is defined for an object, the function is called whenever any of the possible events occurs. The event code is automatically assigned as the first argument to the function and is tested within the function. If statements have been defined for this event and control, they are executed.

For details of the event function codes available for windows and for each control type, see:

Window events and functions

Button events and functions

Graphic events and functions

Listbox events and functions

Menu events and functions

OLE control events and functions

Static text events and functions

Table events and functions

Textbox events and functions


Help functions

help = func_id

This clause defines the function to be called if the user presses the HELP (F1) key while the object has focus. If no help function is assigned, the F1 key causes the caption (defined in the caption = clause) to be displayed, if one has been assigned. The function is called with the event code EV_HELP. So, for example, for a button the function call would be:

func_id(EV_HELP, button_id)


Function return values

Event functions, including textbox validation functions and menu selection functions, may return one of several values which control the way the dialog proceeds thereafter:

OKAY

Continue normally.

ERROR

Lock focus on this object.

CLOSE_DIALOG

Close the dialog. Execution continues with the statement which follows the dialog command.

CANCEL_DIALOG

Cancel the dialog. The program branches to the line label specified in the cancel = label clause if present; otherwise execution continues with the statement that follows the dialog command.

control_id

The name of the control to receive focus next. The control must be enabled in the current dialog.

In an OLE event function, a value may also be returned to the OLE control using the syntax

return Sculptor_value, OLE_value

The setfocus command is also provided for the purpose of specifying the control which is to have input focus when an event function called during a dialog returns. It has the syntax:

setfocus control_id[[row]]

The row number may be specified if the control is a multi-row textbox; the default row is 1.


Testing which object has generated a function

To test the object_id within the function, use the ?= operator, which returns TRUE if the objects being compared are the same object:

!function func_id(arg1, arg2) {
     switch(arg2) {
     case ?= object_id :
          statements
          break
     case ?= object_id:
          ...

Or, use the nameof() function on the second argument, as follows:

!function func_id(arg1, arg2) {
     switch(nameof(arg2)) {
     ...

This enables considerable flexibility in the structuring of functions. As both the object identifier and the event code are sent as arguments, the same function can be used for several objects and for several event codes, if desired. Thus it is perfectly feasible to use the same function as a help function and as an event function; the event code EV_HELP, which is sent by help functions, may simply be included in the possible events processed by the function.


Interactive commands in functions

Care must be taken when interactive commands such as prompt are placed within event functions. A double click of the mouse causes Windows to generate a single click event followed by a double click event. If a click is executed, the double click event is lost. Therefore interactive code should never be placed in the function for any event which is triggered by a single mouse click if a double click is also required. An example of this occurs in tables, where a single click on a line generates the EV_SELECT event, while a double click generates EV_SELECT followed by EV_DOUBLE_CLICK. A prompt executed in the EV_SELECT function will cause the double click event to be lost.


Saving and restoring a function at run time

A function can be assigned at run time in the same way as any other property, e.g.:

object_id->event = func_id

The existing event function can, if required, be saved in a pointer field and reassigned to the control later.

Note that a leading ampersand character (“&”) must be used to set the pointer field:

!temp saved_event_func,,p
     saved_event_func = &control_id->event
     ...
     control_id->event = saved_event_func

If the ampersand is omitted, the meaning of this statement is “save the event function in the field that ‘saved_event_func’ currently points to”. In the above example, it has not been set to point to anything and so the statement would have no effect.

RELATED TOPICS

Pointer (p) type fields


EXAMPLE

  1. In this example the function WinEvent is a general window event function, with switch statements testing the window identifier and the event code. This is only one possible style; a different function may be allocated to each window, to each event, or to each window and event combination.

    !function WinEvent(event_code, win) {
    
         switch (win) {
         case ?= Window1 :
              switch (event_code) {
              case = EV_DESTROY:
                   statements
                   break
    
              case = EV_CREATE:
                   statements
                   break
    
              /* other event codes */
              }
    
         case ?= Window2:
              switch (event_code) {
              case = EV_DESTROY:
                   statements
                   break
    
              /* other event codes */
              }
    
            /* other windows */
         }
    }
    
  2. In the example below, the function BoxEvent is used as both a textbox help function and event function, with a different case of a switch statement being used for each textbox. In practice it is probably easier to assign a different function to each textbox, if not to each textbox and event; the example merely shows what can be done. If the textbox has more than one row, or if the linked field is subscripted, the row and subscript may also be tested. In this example the subscript and row arguments are not declared, because the function does not reference them. They could also be declared and ignored.

    +textbox Box1 at 4,9 {
         help = BoxEvent
         event = BoxEvent
         ...
    }
    
    !function BoxEvent(event_code, obj) {
    !temp objname,,a20
    
        objname = nameof(obj)
    
         switch (obj) {
         case ?= Box1 :
              switch (event_code) {
              case = EV_HELP:
                   statements
                   break
    
              case = EV_CREATE:
                   statements
                   break
    
              /* other event codes */
              }
              break
    
         case ?= Box2:
              switch (event_code) {
              case = EV_HELP:
                   statements
                   break
    
               /* other event codes */
              }
              break
    
         /* other boxes */
         }
    }
    

RELATED TOPICS

Property clauses

The event_enable clause