BYU Home pageBRIGHAM YOUNG UNIVERSITY
  Office of Digital Humanities
Back     BYU LiveCode Lessons Gateway

Digital Humanities & Technology 210

Messages in LiveCode

Objectives

By the end of this reading you should know the following:

  1. Know what a message is.
  2. Be able to name four message that are generated by mouse actions.
  3. Be able to tell when the following messages are sent: openCard, closeCard, preOpenCard, openStack, closeStack, preOpenStack.
  4. Know when an openField message is sent.
  5. Know the difference between closeField and exitField.
  6. Be able to name at least two messages generated by keyboard events.
  7. Understand that you may cause messages to be sent beyond the current handler using the pass and send commands.
  8. Understand that you can add to LiveCode’s built in messages by writing custom message handlers.

What is a Message?

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

where

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.

Mouse Messages

There are several messages associated with mouse clicks:

These mouse click messages are less commonly used, but still very useful:

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:

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.

Mouse Messages and Fields

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 mouseUp, mouseDown, mouseRelease, mouseDoubleDown, and 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 mouseUp, mouseDown, 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:

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.

Other Open/Close Messages

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.

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:

Keyboard Messages

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:

Pass

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:

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

The 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 if-control structure.

Send

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

where
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

Custom Messages: Creating Your Own Commands

LiveCode does not just limit you to using the built-in messages like mouseUp and 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.

Messages Exercise


Back     BYU LiveCode Lessons Gateway
Maintained by Devin Asay.
Copyright © 2005 Brigham Young University