The Application Kit

The Application Kit is the starting point for all applications. Its classes establish an application as an identifiable entity--one that can cooperate and communicate with other applications (including the Browser). It lays a foundation for the other kits. Before designing and building your application, you should secure a breathing familiarity with this basic Kit.

There are four parts to the Application Kit:

The messaging framework and the fundamentals of setting up a Be application are described in the following sections of this introduction. The BApplication class is documented beginning on page 21. The other classes follow in alphabetical order.


Messaging

At minimum, a messaging service must provide the means for:


Messages

BMessage objects are parcels of information that can be transferred between threads. The message source constructs a BMessage object, adds whatever information it wants to it, and then passes the parcel to a function that delivers it to a destination.

A BMessage can hold structured data of any type or amount. When you add data to a message, you assign it a name and a type code. If more than one item of data is added with the same name and type, the BMessage creates an array of data for that name. The name and an index into the array are used to retrieve the data from the message.

The object also contains a command constant that says what the message is about. It's stored as a public data member (called what). The constant may:

  • Convey a request of some kind (such as B_ZOOM or BEGIN_ANIMATION ),

  • Announce an event (such as RECEIPT_ACKNOWLEDGED or B_WINDOW_RESIZED), or

  • Label the information that's being passed (such as PATIENT_INFO or NEW_COLOR).
  • Not all messages have data entries, but all should have a command constant. Sometimes the constant is sufficient to convey the entire message.

    Message Protocols

    Both the source and the destination of a message must agree upon its format --the command constant and the names and types of data entries. They must also agree on details of the exchange--when the message can be sent, whether it requires a response, what the format of the reply should be, what it means if an expected data item is omitted, and so on.

    None of this is a problem for messages that are used only within an application; the application developer can keep track of the details. However, protocols must be published for messages that communicate between applications. You're urged to publish the specifications for all messages your application is willing to accept from outside sources and for all those that it can package for delivery to other applications. The more that message protocols are shared, the easier it is for applications to cooperate with each other and take advantage of each other's special features.

    The software kits define protocols for a number of messages. They're discussed in the Message Protocols appendix.

    Message Ownership

    Typically, when an application creates an object, it retains responsibility for it; it's up to the application to free the objects it allocates when they're no longer needed. However, BMessage objects are an exception to this rule. Whenever a BMessage is passed to the messaging mechanism, ownership is passed with it. It's a little like mailing a letter --once you drop it at the post office, it no longer belongs to you.

    The system takes responsibility for a delivered BMessage object and will eventually delete it--after the receiver is finished responding to it. A message receiver can assert responsibility for a message--essentially replacing the system as its owner--by detaching it from the messaging mechanism (with BLooper's DetachCurrentMessage() function).


    Message Loops

    In the Be model, messages are delivered to threads running message loops . Arriving messages are placed in a queue, and are then taken from the queue one at a time. After getting a message from the queue, the thread decides how it should be handled and dispatches it to an object that can respond. When the response is finished, the thread deletes the message and takes the next one from the queue--or, if the queue is empty, waits until another message arrives.

    The message loop therefore dominates the thread. The thread does nothing but get messages and respond to them; it's driven by message input.

    BLooper objects set up these message loops. A BLooper spawns a thread and sets the loop in motion. Posting a message to the BLooper delivers it to the thread (places it in the queue). The BLooper removes messages from the queue and dispatches them to BHandler objects. BHandlers are the objects ultimately responsible for received messages. Everything that the thread does begins with a BHandler's response to a message.

    Two hook functions come into play in this process--one defined in the BLooper class and one declared by BHandler:

    There's a close relationship between the BLooper role of running a message loop and the BHandler role of responding to messages. The BLooper class inherits from BHandler, so the same object can fill both roles. The BLooper is the default handler for the messages it receives.

    To be notified of an arriving message, a BHandler must "belong" to the BLooper; it must have been added to the BLooper's list of eligible handlers. The list can contain any number of objects, but at any given time a BHandler can belong to only one BLooper.

    While