By the end of this reading you should know the following:
openCard, closeCard, preOpenCard, openStack, closeStack, preOpenStack.
openFieldmessage is sent.
LiveCode is what is called an “event driven” programming environment. When events happen in the LiveCode environment–things like mouse clicks, key presses, and movement between cards—messages are generated and sent to your stack, much like a compulsive play-by-play announcer describing everything that happens in the sporting arena. As a LiveCode programmer, you write message handlers that intercept these messages and execute various commands and functions. The syntax for intercepting and using messages sent in LiveCode is this:
on message statement(s) end message
message is any message generated in LiveCode.
statement(s) is one or more LiveCode statements or commands that should be executed when the message is sent.
There are several messages associated with mouse clicks:
mouseUpmessage. This is the most commonly used message handler in button object scripts. The
mouseUpmessage is sent on the up part of a click.
mouseDownmessage is sent on the down part of a click. Thus every click generates first a
mouseDownmessage, then a
mouseUphandlers are often used in pairs to do one thing when the mouse button is clicked down and something else when it is released.
mouseReleasemessage is sent to the control that received the
mouseDownwhen the user releases the mouse outside the clickable area of the object. In this case, no
mouseUpmessage is sent.
These mouse click messages are less commonly used, but still very useful:
mouseDoubleUpmessage is sent on the up part of the second click. A
mouseUpmessage will still be sent on the first click.
mouseDoubleDownmessage is sent on the down part of the second click. Every double click generates first a
mouseDoubleDownmessage, then a
mouseDownmessage will still be sent on the first down click.
mouseStillDownmessage is sent repeatedly while the mouse button is held down after the initial
mouseStillDownmay be used to do something repetitively as long as the mouse is held down. (Note: A
mouseStillDownis not sent after a double click. It only occurs during a single click cycle.)
There are four other messages associated with the mouse. These have to do only with the location of the mouse pointer— no click is required to generate them:
mouseLeavemessages are often paired together, since they represent reciprocal actions. They are particularly useful for creating dynamic “rollover” actions. A rollover action is when something visually changes about an object when the mouse points to it.
mouseWithinmessage is sent repeatedly after the initial
mouseEnterwhile the cursor remains within the rectangular area of an object. A
mouseWithinhandler behaves much like
mouseStillDown, but is sent repeatedly whether or not the mouse button is down.
mouseMovemessage is sent whenever the user moves the mouse.
Theoretically, these messages can be handled by any object with a proper handler. While this is generally true, reality sometimes paints a different picture. Some types of object may not handle messages exactly the same as other types object. You'll have to experiment to discover what works and what doesn't. See the next section, for instance, to see differences in how fields handle various messages.
Because the purpose of fields is different from the purpose of buttons, fields can respond differently to some mouse messages as compared to buttons. The main difference is seen when a field is unlocked. A locked field responds to all mouse click messages in the same way a button does; that means a locked field can have
mouseDoubleUp handlers, and mouse clicks will trigger all of them, just as in a button.
The situation changes when a field is unlocked. Unlocked fields do not receive mouse click messages at all, so handlers like
mouseDoubleUp,etc. are ignored when a field is unlocked. However, once unlocked, fields receive other messages that locked fields do not. These have to do with the fact that the user can choose selection and insert points and change the field text by using the mouse. Instead of the mouse click messages, these messages are sent to unlocked fields:
openFieldmessage is sent to an unlocked field when you click or select text within that field, or when the field receives focus by “tabbing” through a series of fields.
closeFieldmessage is sent to a field when the cursor is removed from that field and the field's contents have been changed. If there has been no change made to whatever the field contains, then no
closeFieldmessage is sent.
exitFieldmessage is generated and sent to the field.
These messages allow you to monitor the state of text in a field. For instance, you could enable a Save button if the text of the field has changed, and disable it if it hasn't. It might look something like this:
on closeField enable button "save" end closeField on exitField disable button "save" end exitField
In a similar way, you could use a
selectionChanged handler to enable a cut/copy menu based on whether some text was selected when the selection is changed.
Open and close messages are sent when objects are "opened" and "closed"; that is, when they first come into view (as in the case of cards and groups); or receive "focus"; that is when the mouse or keyboard causes them to become the target object (as in the case of fields.) You have seen how open and close messages work with fields. There are three other object types in LiveCode for which open and close messages are generated—stacks, cards, and background groups.
Open handlers can be used to do things like initial layout setup, showing introduction fields, etc., for when the object first appears. Close handlers are typically used for things like saving answers and generally cleaning up the environment after the current user is finished.
openCardmessage is sent to a card when you arrive at that card, and the
closeCardmessage is sent to the card when you leave for another card.
openStackmessage is sent to the destination card right after you open a stack. The
closeStackmessage is sent to the current card when the stack closes (either by quitting the application or by closing the stack window).
openBackgroundmessage is sent to the destination card right after you go from a card that does not have a specific background-style group to a card that does have the group. The
closeBackgroundmessage is sent to the current card when leaving a card that has a background group to go to one that doesn't have that group.
Closely related to open/close messages are the suspend and resume messages. But instead of being generated when a stack has been opened or closed, they are sent when the user changes from one stack to another, as happens when you click on a stack window to bring it to the front:
closeStackand are normally used in conjunction with each other. The
resumeStackmessage is sent to the current card when a stack window is brought to the front. The
suspendStackmessage is sent to the current card when something makes its stack no longer the active window.
This class of messages is sent to the active/focused control when keys on the keyboard are pressed. If no control is active or focused these messages are sent to the card:
For most LiveCode messages we've talked about, when there is no handler to handle the message as it passes through the hierarchy, it gets ignored. However, there are a few LiveCode messages that have a default behavior:
keyDownIf the active cursor is in an unlocked field, this message causes the character assigned to the key pressed to be entered into the field.
tabKeyMoves the insertion point into first (next) editable field.
arrowKeysNavigates the user forward/backward between cards (assuming the "Arrow keys navigate through cards" setting is checked in LiveCode's preferences and the cursor is not in a text field.)
When there is a handler for a message like
arrowKey, it intercepts the message and overrides the default behavior. After LiveCode has executed a handler, it considers its task finished and the message which triggered the handler “dies”, that is, it doesn’t continue up the message hierarchy. In some cases this may be what you want. Writing an
arrowKey handler, for example, could prevent users from using arrow keys to navigate into parts of your stack you want to keep secure. However, sometimes you actually want LiveCode to execute a object's handler and then perform its default behavior or execute another handler located further up in the hierarchy along the message path right after that. To make that happen, you would do something similar to this in the object's script:
on mouseUp beep pass mouseUp end mouseUp
pass command means that after the object has handled the message, it will be passed to the next level of the hierarchy along the message path for a
mouseUp handler, which could be that in a group or card script, for example. If an appropriate handler is found, it will then execute that handler in the group or card script and stop moving up the levels unless there is also a pass command in that handler.
Note: When the pass command is executed, any remaining statements in the handler are skipped, so this command is almost always placed at the end of a handler or within an
This command is used to send a message to an object. In this respect it is similar to the pass command. However, with
send you can override the normal message path, allowing greater flexibility with where messages are sent. It also differs from pass in that once the command is executed and the message is sent, the rest of the handler is still executed. The basic syntax is:
send message to object
message is any message, sent as a literal string, and
object is any object.
A practical example of this command would look something like this:
on mouseUp hide image "flowers" send "mouseUp" to button "Reset" show field "Instructions" end mouseUp
This handler would first hide the image, then send the
mouseUp message to button "reset" (or any other given object). That button would then execute the
mouseUp handler in its script. After that had finished, the original handler would continue executing its handler and would show the image. The strength of this command lies in its ability to provide access to handlers in objects outside the normal message hierarchy. Note that you are not limited to sending the same message as in the enclosing handler. For example, you could also say:
send "openCard" to this card
LiveCode does not just limit you to using the built-in messages like
openCard. You can also write custom handlers that you can name anything you want. Let’s say, for example, that you wanted a certain number of things to be done when you first come to a card, to set it up for the user. You might also want to have a button on the card that allows the user to reset the controls on the card. We could write a handler like this in the card script:
on resetAll put "Click Start to begin." into field "instruction" enable button "start" hide field "feedback" disable button "nextQuestion" end resetAll
By writing this handler you have essentially created a new command that you can call from anywhere on this card. So in the card script you could do this:
on preOpenCard resetAll end preOpenCard on resetAll put "Click Start to begin." into field "instruction" enable button "start" hide field "feedback" disable button "nextQuestion" end resetAll
Significantly, you could also use this new command from a button on the card. Let’s say you create a button called “reset” on this card. You could write a handler for that button like this:
on mouseUp resetAll end mouseUp
Can you see how this can simplify your scripting and extend the power of LiveCode? By “bundling” commands into custom handlers you can execute batches of commands by simply “calling” the new handler from anywhere in the hierarchy of the object that whose script contains the handler.
We will learn more about writing custom message handlers in a later lesson.