Displaying a form

A form gets created when the Open() method is invoked for that form. This is very much like a subroutine and an entry is placed on the top of the return stack. A data structure describing the form and it properties is created at this time (this is called instantiation). Until the Open() method is invoked the properties, methods etc. of a form do not exist. Similarly the data structure for the object will be destroyed when the Open() method is exited and those properties will then no longer exist. Because forms can be nested, it is possible to refer to the properties of a previously opened form from with an event handler belonging to a child form.

Locally DIMed variables belonging to the form also get created by the Open() method and any initialization code that immediately follows the DEFFORM will be executed up to the FORM END or the first DEF EVENT. Local variables declared this way may be shared by any of the forms event handlers while the form is open.

KCML will then block awaiting events which will then be processed serially by appropriate event handlers. This continues until an event terminates the form, either explicitly with the Terminate() method or implicitly with the special dismissing buttons OK or CANCEL.

The Open() method returns an integer value which will be 0 if the CANCEL button dismissed the form and 1 if the OK button dismissed it. If the Terminate() method was explicitly invoked then it will be the integer argument passed to this method.

There are some special events that are guaranteed to occur in a specific order, provided handlers have been defined to catch them. Some of these events don't involve the client directly and are not associated with a control, e.g. Enter(), Exit() or Idle(). These are sometimes called server-side events. Others are triggered by a message from the client and are handled in the context of the form control e.g. form.Resize().

Events will occur in the order shown in this table:

Create()

The Create() server-side event takes place entirely on the server before any data structures have been instantiated for the form. It allows the application to dynamically create controls for the form using the CreateControl() method.

Enter()

At this point only server data structures exist and nothing has been sent to the client. If an Enter() event handler exists in the program for the form KCML will then call that subroutine which can manipulate any properties and load any database records that may be required for data awareness. If at any point in this routine the program invokes the Terminate() method then the Open() method will return and the server-side data structures representing the form object will be destroyed. Because the client has not yet been sent the details of the form it is never visible to the user.

On return from any explicit Enter() event handler KCML will call the internal default Enter() handler which will check if there are any data aware controls on the form and update the server-side properties from the database appropriately. It will then send instructions to the client to create and display the form using the current server-side properties. The user will now be able to see the form.

You cannot reference any OCX properties or methods in the Enter() event as the OCX has not yet been started. These must be deferred to the Show() event.

form.Resize()

After the Enter() event completes the server sends the now finalized form definition down to the client allowing it to construct the necessary structures to display it. If a handler is defined and resizing is enabled for the form then the client will compute the size of the form and send an event message back to the server triggering the Resize() event. This event may trigger later in the history of the form if the user manually resizes the form.

Note that this is a client-side event and occurs in the context of the form control.

Show()

If there is a Show() event handler in the program then it will now be executed as a server-side event. The form now exists in the client and its properties are available. This provides an opportunity for the program to reference any OCX controls which will have been instantiated before this event occurs or to raise any error messages in the context of the form as error messages in the Enter() event handler will not have a parent form. At the end of the users Show() event KCML will call the default handler which checks if any data aware controls have had their properties changed by the users handler and it will send any changes to the client to display.

General events

Having processed the initial server-side events, the KCML Open() method will block waiting for events generated by the user interacting with controls on the form. These are queued up and processed in order. Note that the client will only send events to the server if it knows the server has a handler for it. Thus many of the text boxes on the form can be filled in by the user without any server involvement. The only client events that are handled by internal KCML handlers in the absence of a user handler are the OK and Cancel button Click() events and the tab control Exit() event though these events may of course be intercepted by user handlers which take precedence.

If there is an Idle() event handler in the form definition, and if the IdleTimer property is set to a non zero value, then it will be called periodically as a server-side event while the event queue is empty and the return value of the event handler is TRUE.

In general when an event is triggered by the client for a server handler, the client will check all the controls on the form which have had their properties changed since the last server event and will update the server with the new values as part of the event message so the server handler will be able to inspect the current state of the form.

Any event handler can invoke the Terminate() event which destroys the form object on both the server and the client and causes KCML to return from the Open() method.

Exit()

This server-side event occurs when the Terminate() method is called either explicitly in the code of a handler or implicitly as a result of an OK button click or a CANCEL button click. If there is an user event handler for the Exit() event then it will be called after the client form has been destroyed but the server-side properties and local variables will still be available for inspection. On exit from the handler the server object will be destroyed in turn and KCML will return from the Open method. The Exit() event is intended to be used for tidy up code common to all the ways of exiting the form.

You cannot reference OCX controls in the Exit() event as they have already been shutdown by the client as part of the termination procedure before the server triggers this event.