haiku-website/static/legacy-docs/bebook/TheApplicationKit_Messaging...

388 lines
51 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>The Be Book - System Overview - The Application Kit</title><link rel="stylesheet" href="be_book.css" type="text/css" media="all" /><link rel="shortcut icon" type="image/vnd.microsoft.icon" href="./images/favicon.ico" /><!--[if IE]>
<link rel="stylesheet" type="text/css" href="be_book_ie.css" />
<![endif]--><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="Access, BeOS, BeBook, API" /><link rel="start" href="index.html" title="The Be Book" /><link rel="up" href="TheApplicationKit_Overview.html" title="The Application Kit" /><link rel="prev" href="TheApplicationKit_Overview_Introduction.html" title="Introduction" /><link rel="next" href="TheApplicationKit_Scripting.html" title="Scripting" /></head><body><div id="header"><div id="headerT"><div id="headerTL"><a accesskey="p" href="TheApplicationKit_Overview_Introduction.html" title="Introduction"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a accesskey="u" href="TheApplicationKit_Overview.html" title="The Application Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a accesskey="n" href="TheApplicationKit_Scripting.html" title="Scripting"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="headerTR"><div id="navigpeople"><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div><div class="navigboxed" id="navigindex"><a accesskey="i" href="ClassIndex.html" title="Index">I</a></div><div class="navigboxed" id="naviglang" title="English">en</div></div><div id="headerTC">The Be Book - System Overview - The Application Kit</div></div><div id="headerB">Prev: <a href="TheApplicationKit_Overview_Introduction.html">Introduction</a>  Up: <a href="TheApplicationKit_Overview.html">The Application Kit</a>  Next: <a href="TheApplicationKit_Scripting.html">Scripting</a></div><hr /></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging"></a>Messaging</h2></div></div></div><p>The Application Kit provides a message-passing system lets your
application send messages to and receives messages from other
applications (including the Be-defined servers and apps), and from other
threads in your own application.</p><p>The primary messaging classes are:</p><dl class="variablelist"><dt><span class="term"><a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a></span></dt><dd><p>Represents a message.</p></dd><dt><span class="term"><a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a></span></dt><dd><p>Defines hook functions that are called to handle in-coming messages.</p></dd><dt><span class="term"><a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a></span></dt><dd><p>Runs a loop that receives in-coming messages and figures out which
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
should handle them.</p></dd><dt><span class="term"><a class="link" href="BMessenger.html" title="BMessenger"><code class="classname">BMessenger</code></a></span></dt><dd><p>Represents a message's destination (a combination of
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> and
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>),
whether it's local or remote. The object is most useful for sending
messages to other applications—you don't need it for local calls.</p></dd></dl><p>The other messaging classes are:</p><dl class="variablelist"><dt><span class="term"><a class="link" href="BMessageQueue.html" title="BMessageQueue"><code class="classname">BMessageQueue</code></a></span></dt><dd><p>Is a <acronym class="acronym" title="First In-First Out">FIFO</acronym> that holds a
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>'s
in-coming messages.</p></dd><dt><span class="term"><a class="link" href="BMessageFilter.html" title="BMessageFilter"><code class="classname">BMessageFilter</code></a></span></dt><dd><p>Is a device that can examine and (potentially) reject or re-route
in-coming messages.</p></dd><dt><span class="term"><a class="link" href="BInvoker.html" title="BInvoker"><code class="classname">BInvoker</code></a></span></dt><dd><p>Is a convenience class that lets you treat a message and its target (the
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
that will handle the message) as a single object.</p></dd><dt><span class="term"><a class="link" href="BMessageRunner.html" title="BMessageRunner"><code class="classname">BMessageRunner</code></a></span></dt><dd><p>Lets you send the same message over and over, at regular intervals.</p></dd></dl><p>The rest of this chapter looks at…</p><ul class="itemizedlist"><li><p>The essential features of the four fundamental classes. (
"<a class="link" href="TheApplicationKit_Messaging.html#TheApplicationKit_Messaging_Features" title="Features of the Fundamental Classes">Features of the Fundamental Classes</a>")</p></li><li><p>How a
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>
decides which
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
should handle an in-coming message.
("<a class="link" href="TheApplicationKit_Messaging.html#TheApplicationKit_Messaging_FromLooperToHandler" title="From Looper to Handler">From Looper to Handler</a>")</p></li><li><p>The different methods for sending messages and receiving replies.
("<a class="link" href="TheApplicationKit_Messaging.html#TheApplicationKit_Messaging_SendingAMessage" title="Sending a Message">Sending a Message</a>").</p></li></ul><p>and describes how the classes fit together in the messaging system with an
emphasis on what you can do in your application to take part.</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_Features"></a>Features of the Fundamental Classes</h3></div></div></div><p>Looked at collectively, the four fundamental messaging classes comprise a
huge chunk of API. Fortunately, the essential part of this API is pretty
small; that's what we're going to look at here.</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_BMessage"></a>The BMessage Class</h4></div></div></div><p>In the
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
class, there's one essential data member, and two essential functions:</p><ul class="itemizedlist"><li><p>The
<a class="link" href="BMessage.html#BMessage_what" title="what"><code class="varname">what</code></a>
data member is an arbitrary
<span class="type">uint32</span> value that describes (symbolically) what the message
is about. You can set and examine <code class="varname">what</code>
directly—you don't have to use functions to get to it. The
<code class="varname">what</code> value is called the object's command constant.
The BeOS defines some number of command constants (such as
<a class="link" href="TheApplicationKit_MessageConstants.html#B_QUIT_REQUESTED" title="B_QUIT_REQUESTED"><code class="constant">B_QUIT_REQUESTED</code></a>,
and <a class="link" href="TheInterfaceKit_MessageConstants.html#B_MOUSE_DOWN" title="B_MOUSE_DOWN"><code class="constant">B_MOUSE_DOWN</code></a>),
but you'll also be creating constants of your own. Keep
in mind that the constant's value is meaningless—it's just a code
that identifies the "intent" of the message (and it's only meaningful
if the receiver recognizes the constant).</p></li><li><p>The two essential functions are
<a class="link" href="BMessage.html#BMessage_AddData" title="AddData(), AddBool(), AddInt8(), AddInt16(), AddInt32(), AddInt64(), AddFloat(), AddDouble(), AddString(), AddPoint(), AddRect(), AddRef(), AddMessage(), AddMessenger(), AddPointer(), AddFlat()"><code class="methodname">AddData()</code></a> and
<a class="link" href="BMessage.html#BMessage_FindData" title="FindData(), FindBool(), FintInt8(), FindInt16(), FindInt32(), FindInt64(), FindFloat(), FindDouble(), FindString(), FindPoint(), FindRect(), FindRef(), FindMessage(), FindMessenger(), FindPointer(), FindFlat()"><code class="methodname">FindData()</code></a>. These
functions add data to a message you're about to send, and retrieve it
from a message you just received. A
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
can hold any amount of data; each data item (or "field") is
identified by name, type, and index. For example, you can ask a message
for the third boolean value named "IsEnabled" that it contains.
In general, you use type-specific functions such as
<code class="methodname">Add/FindString()</code> and
<code class="methodname">Add/FindInt32()</code> rather than
<code class="methodname">Add/FindData()</code>.
The query we just posed would actually look like this:</p><pre class="programlisting example cpp"><span class="comment">/* The args are: name, index, value (returned by
reference) */</span>
<span class="type">bool</span> <code class="varname">returnValue</code>;
<code class="varname">aMessage</code>.<code class="methodname">FindBool</code>("IsEnabled", 2, &amp;<code class="varname">returnValue</code>);</pre></li></ul><p>In summary, a <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> contains
(1) a command constant and (2) a set of data fields. Every
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
that's used in the messaging system must have
a command constant, but not every object needs to have data fields.
(Other parts of the BeOS use <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>s
for their data only. The
<a class="link" href="BClipboard.html" title="BClipboard"><code class="classname">BClipboard</code></a> object, for example,
ignores a <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>'s command constant.)</p><div class="admonition note"><div class="title">Note</div><div class="graphic"><img class="icon" alt="Note" width="32" src="./images/admonitions/Info_32.png" /><div class="text"><p>When discussing system-generated <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
objects, we refer to the
object by its command constant. For example, "a <code class="constant">B_MOUSE_DOWN</code>" means "a
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
that has <code class="constant">B_MOUSE_DOWN</code> as its command constant".</p></div></div></div><p>Notice that a <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> doesn't
know how to send itself. However, as we'll
see later, it does know how to reply to its sender once it's in the hands
of the recipient.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_BLooper"></a>The BLooper Class</h4></div></div></div><p><a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>'s
role is to receive messages and figure out what to do with
them. There are four parts to this job, embodied in these functions:</p><ul class="itemizedlist"><li><p>Every <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> spawns a
thread in which it runs a message loop. It's
in this thread that the object receives messages. But you have to kick
the <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> to get it to run;
you do this by calling the <a class="link" href="BLooper.html#BLooper_Run" title="Run()"><code class="methodname">Run()</code></a>
function. When you're done with the obejct—when you no longer
need it to receive messages—you call
<a class="link" href="BLooper.html#BLooper_Quit" title="Quit()"><code class="methodname">Quit()</code></a></p></li><li><p>Although you never invoke it directly,
<a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a> is the guts
of the message loop. All messages that the looper receives show up in
individual invocations of <a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a>. The function decides where
the message should go next, which is mostly a matter of deciding
whether (1) the message should be handled by a system-defined hook
function, or (2) passed to <a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>'s
<a class="link" href="BLooper.html#BLooper_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a> function (which
we'll talk about in a moment). Three other important aspects of
<a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a> are…</p><div class="orderedlist"><ol><li><p>It runs in the <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>'s message thread (or message loop); this is a
separate thread that the object spawns specifically to receive
in-coming messages.</p></li><li><p>Individual <a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a> invocations are synchronous with regard
to the loop. In other words, when a message shows up, <a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a>
is called and runs to completion before the next message can be
processed. (Messages that show up while <a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a> is busy
aren't lost—they're queued up in a
<a class="link" href="BMessageQueue.html" title="BMessageQueue"><code class="classname">BMessageQueue</code></a> object.)</p></li><li><p>It's fully implemented by
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>
(and kit classes derived from
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>).
You should rarely need to override it in your application.</p></li></ol></div></li><li><p>The <a class="link" href="BLooper.html#BLooper_PostMessage" title="PostMessage()"><code class="methodname">PostMessage()</code></a>
function delivers a message to the <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>. In
other words, it invokes <a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a> in the looper's message
thread. You call <a class="link" href="BLooper.html#BLooper_PostMessage" title="PostMessage()"><code class="methodname">PostMessage()</code></a> directly in your code. For example, here
we create a <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> and post it to our <a class="link" href="BApplication.html" title="BApplication"><code class="classname">BApplication</code></a> object
(<a class="link" href="BApplication.html" title="BApplication"><code class="classname">BApplication</code></a> inherits from <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>):</p><pre class="programlisting example cpp"><span class="comment">/* This form of the <code class="classname">BMessage</code> constructor sets the command constant. */</span>
<code class="classname">BMessage</code> *<code class="varname">myMessage</code> = new <code class="classname">BMessage</code>(<code class="constant">YOUR_CONSTANT_HERE</code>);
<code class="varname">be_app</code>-&gt;<code class="methodname">PostMessage</code>(<code class="varname">myMessage</code>)</pre></li></ul><p>The
<a class="link" href="BApplication.html" title="BApplication"><code class="classname">BApplication</code></a>
and <a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a> classes inherit from
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_BHandler"></a>The BHandler Class</h4></div></div></div><p><a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a> objects are called upon
to handle the messages that a <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>
receives. A <a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a> depends on
two essential function:</p><dl class="variablelist"><dt><span class="term"><a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a></span></dt><dd><p>Is the function that a <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> calls
to dispatch an in-coming message to the
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a> (the
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> is passed as the
function's only argument). This is a hook function that a
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
subclass implements to handle the different types of messages that it
expects to receive. Most implementations examine the message's command
constant and go from there. A typical outline looks like this:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyHandler</code>::<code class="methodname">MessageReceived</code>(<span class="type">BMessage*</span> <code class="parameter">message</code>)
{
<span class="comment">/* Examine the command constant. */</span>
switch ( <code class="parameter">message</code>-&gt;<code class="varname">what</code> ) {
case <code class="constant">YOUR_CONSTANT_HERE</code>:
<span class="comment">/* Call a function that handles this sort of message. */</span>
<code class="methodname">HandlerFunctionA()</code>;
break;
case <code class="constant">ANOTHER_CONSTANT_HERE</code>:
<span class="comment">/* ditto */</span>
<code class="methodname">HandlerFunctionB()</code>;
break;
default:
<span class="comment">/* Messages that your class doesn't recognize must
* be passed on to the base class implementation. */</span>
<span class="emphasis"><em><code class="classname">baseClass</code></em></span>::<code class="methodname">MessageReceived</code>(<code class="parameter">message</code>);
break;
}
}</pre></dd><dt><span class="term"><a class="link" href="BLooper.html#BLooper_AddHandler" title="AddHandler(), RemoveHandler(), HandlerAt(), CountHandlers(), IndexOf()"><code class="methodname">BLooper::AddHandler()</code></a></span></dt><dd><p>Is <a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>'s other essential
function and is defined by <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>. This
function adds the (argument) <a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
object to the (invoked-upon) <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>'s
list of candidate handlers (its handler chain). If a
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a> wants to handle messages that are
received by a <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>, it must
first be added to the <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>'s handler
chain.</p><p><a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> inherits from
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>, and automatically
adds itself to its own handler chain. This means that a
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> can handle the messages that it
receives—this is the default behaviour for most messages. We'll
examine this issue in depth later in this chapter.</p></dd></dl><p>The other classes that inherit from
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a> are
<a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> and
<a class="link" href="BShelf.html" title="BShelf"><code class="classname">BShelf</code></a> (both
in the Interface Kit).</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_BMessenger"></a>The BMessenger Class</h4></div></div></div><p>A <a class="link" href="BMessenger.html" title="BMessenger"><code class="classname">BMessenger</code></a>'s
most important feature is that it can send a message to a
remote application. To do this takes two steps, which point out the
class' essential features:</p><ul class="itemizedlist"><li><p>You identify the application that you want to send a message to (the
"target") in the
<a class="link" href="BMessenger.html" title="BMessenger"><code class="classname">BMessenger</code></a>
constructor. An application is identified by its app signature (a
<acronym class="acronym">MIME</acronym> string).</p></li><li><p>The <a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>
function sends a message to the target.</p></li></ul><p><a class="link" href="BMessenger.html" title="BMessenger"><code class="classname">BMessenger</code></a>s can also be used
to target local looper/handler pairs.</p></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_FromLooperToHandler"></a>From Looper to Handler</h3></div></div></div><p>A <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> pops a message
from its message queue and, within its
<a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a>
function, dispatches the message by invoking a
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
function. But (1) which <a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a> and (2) which function?</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_FindingAHandler"></a>Finding a Handler</h4></div></div></div><p>First, let's answer the "which <a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>"
question. To determine which
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a> should handle an in-coming message, a
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> follows these
steps:</p><div class="orderedlist"><ol><li><p>Does the <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> target a specific
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>? Both the
<a class="link" href="BLooper.html#BLooper_PostMessage" title="PostMessage()"><code class="methodname">BLooper::PostMessage()</code></a>
and
<a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">BMessenger::SendMessage()</code></a>
functions provide additional arguments that let you specify a target handler that you want
to have handle the message (you can also set the target in the
<a class="link" href="BMessenger.html" title="BMessenger"><code class="classname">BMessenger</code></a>
constructor). If a <a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
is specified, the <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
will show up in that object's
<a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
function (or it will invoke a message-mapped hook function, as explained below).</p></li><li><p>Does the <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> designate a preferred handler? Through its
<a class="link" href="BLooper.html#BLooper_SetPreferredHandler" title="SetPreferredHandler(), PreferredHandler()"><code class="methodname">SetPreferredHandler()</code></a>
function, a <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> can designate one of the
objects in its handler chain as its preferred handler, and passes all
messages to that object.</p></li><li><p>The <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> handles the <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> itself. If there's no target
handler or preferred handler designation, the <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> handles the message
itself—in other words, the message is passed to the <a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>'s own
<a class="link" href="BLooper.html#BLooper_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
function (or message-mapped hook).</p></li></ol></div><p>We should mention here that both the
<a class="link" href="BApplication.html" title="BApplication"><code class="classname">BApplication</code></a> and the
<a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a> class
fine-tune this decision process a bit. However, the meddling that they do
only applies to system messages (described below). The messages that you
define yourself (i.e. the command constants that your application
defines) will always follow the message dispatching path described here.</p><div class="admonition note"><div class="title">Note</div><div class="graphic"><img class="icon" alt="Note" width="32" src="./images/admonitions/Info_32.png" /><div class="text"><p>If you look at the
<a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a>
protocol, you'll notice that it
has a <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> and a
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a> as arguments.
In other words, the "which handler" decision described here is actually made before
<a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a>
is called. In general, this is an implementation detail
that you shouldn't worry about. If you want to think that
<a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a>
makes the decision—and we've done nothing to
disabuse you of this notion—go ahead and think it.</p></div></div></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_FindingAFunction"></a>Finding a Function</h4></div></div></div><p>As described above, a
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a> passes a
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> to a
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a> by invoking
the latter's
<a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
function. This is true of all messages
that you create yourself, but it isn't true of certain messages that the
system defines and sends. These system-generated messages (or system
messages)—particularly those that report user events such as
<code class="constant">B_MOUSE_DOWN</code> or <code class="constant">B_APP_ACTIVATED</code> -
invoke specific hook functions.</p><p>For example, when the user presses a key, a
<code class="constant">B_KEY_DOWN</code> message is sent to the active
<a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a> object..
From within its
<a class="link" href="BLooper.html#BLooper_DispatchMessage" title="DispatchMessage()"><code class="methodname">DispatchMessage()</code></a>
function,
<a class="link" href="BWindow.html" title="BWindow"><code class="classname">BWindow</code></a>
invokes the
<a class="link" href="BView.html#BView_MouseDown" title="MouseDown()"><code class="methodname">MouseDown()</code></a>
function of the <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a> that currently
holds keyboard focus. (When a <a class="link" href="BView.html" title="BView"><code class="classname">BView</code></a>
is made the focus of keyboard events, its window promotes it to preferred
handler.)</p><p>So the question of "which function" is fairly simple:
If the <a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a> is
a system message that's mapped to a hook function, the hook function is
invoked. If it's not mapped to a hook function, the
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>'s
<a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
function is invoked.</p><p>Each chapter contains a list of system messages and the hook functions
that they're mapped to. Note that not all system messages are mapped to hook functions; some
of them do show up in
<a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_Inheritance"></a>Inheritance and the Handler Chain</h4></div></div></div><p>Let's look at
<a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
again. It was asserted, in a code snippet shown earlier, that a typical
<a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
implementation should include an invocation of the base class' version of the
function:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">MyHandler</code>::<code class="methodname">MessageReceived</code>(<span class="type">BMessage*</span> <code class="parameter">message</code>)
{
switch ( <code class="parameter">message</code>-&gt;<code class="varname">what</code> ) {
<span class="comment">/* Command constants that you handle go here. */</span>
default:
<span class="comment">/* Messages that your class doesn't recognize must be passed
* on to the base class implementation. */</span>
<span class="emphasis"><em><code class="classname">baseClass</code></em></span>::<code class="methodname">MessageReceived</code>(<code class="parameter">message</code>);
break;
}
}</pre><p>This isn't just a good idea—it's an essential part of the messaging
system. Forwarding the message to the base class does two things: It lets
messages (1) pass up the class hierarchy, and (2) pass along the handler
chain (in that order).</p><p>Passing up the class hierarchy is mostly straight-forward—it's no
different for the
<a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
function than it is for any other
function. But what happens at the top of the hierarchy—at the
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
class itself—adds a small wrinkle.
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>'s
implementation of
<a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
looks for the next handler in the
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>'s
handler chain and invokes that object's
<a class="link" href="BHandler.html#BHandler_MessageReceived" title="MessageReceived()"><code class="methodname">MessageReceived()</code></a>
function.</p></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_SendingAMessage"></a>Sending a Message</h3></div></div></div><p>There are two functions that send messages to distinct recipients:</p><dl class="variablelist"><dt><span class="term"><a class="link" href="BLooper.html#BLooper_PostMessage" title="PostMessage()"><code class="methodname">BLooper::PostMessage()</code></a></span></dt><dd><p>Can be used if the target (the
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>
that the
<a class="link" href="BLooper.html#BLooper_PostMessage" title="PostMessage()"><code class="methodname">BLooper::PostMessage()</code></a>
function is invoked upon) lives in the same application as the message sender.</p></dd><dt><span class="term"><a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">BMessenger::SendMessage()</code></a></span></dt><dd><p>Lets you send messages to remote
applications. The <a class="link" href="BMessenger.html" title="BMessenger"><code class="classname">BMessenger</code></a>
object acts as a proxy for the remote app.
(<a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>
can also be used to send a message to a local
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>,
for reasons that we'll discuss later.)</p></dd></dl><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_PostMessage"></a>The PostMessage() Function</h4></div></div></div><p>You can post a message if the recipient
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>
is in your application:</p><pre class="programlisting example cpp"><code class="varname">myLooper</code>-&gt;<code class="methodname">PostMessage</code>(new <code class="classname">BMessage</code>(<code class="constant">DO_SOMETHING</code>), <code class="varname">targetHandler</code>);</pre><p>As shown here, you can specify the handler that you want to have handle a
posted message. The only requirement is that the
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
must belong to the
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>.</p><p>If the handler argument is <code class="constant">NULL</code>, the message
is handled by the looper's <span class="emphasis"><em>preferred handler</em></span></p><pre class="programlisting example cpp"><code class="varname">myLooper</code>-&gt;<code class="methodname">PostMessage</code>(new <code class="classname">BMessage</code>(<code class="constant">DO_SOMETHING</code>), <code class="constant">NULL</code>);</pre><p>By using the default handler, you let the looper decide who should
handle the message.</p><div class="admonition note"><div class="title">Note</div><div class="graphic"><img class="icon" alt="Note" width="32" src="./images/admonitions/Info_32.png" /><div class="text"><p>The creator of the
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
retains ownership and is responsible for deleting it when it's no
longer needed.</p></div></div></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_SendMessage"></a>The SendMessage() Function</h4></div></div></div><p>If you want to send a message to another application, you have to use
<a class="link" href="BMessenger.html" title="BMessenger"><code class="classname">BMessenger</code></a>'s
<a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>
function. First, you construct a
<a class="link" href="BMessenger.html" title="BMessenger"><code class="classname">BMessenger</code></a>
object that identifies the remote app by signature…</p><pre class="programlisting example cpp"><code class="classname">BMessenger</code> <code class="varname">messenger</code>("application/x-some-app");</pre><p>…and then you invoke
<a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>:</p><pre class="programlisting example cpp"><code class="varname">messenger</code>.<code class="methodname">SendMessage</code>(new <code class="classname">BMessage</code>(<code class="constant">DO_SOMETHING</code>));</pre><div class="admonition note"><div class="title">Note</div><div class="graphic"><img class="icon" alt="Note" width="32" src="./images/admonitions/Info_32.png" /><div class="text"><p>The creator of the
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
retains ownership and is responsible for deleting it when it's no longer
needed.</p></div></div></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_HandlingAReply"></a>Handling a Reply</h4></div></div></div><p>Every
<a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>
that you send identifies the application from which it was sent. The
recipient of the message can reply to the message whether you (the sender)
expect a reply or not. By default, reply messages are handled by your
<a class="link" href="BApplication.html" title="BApplication"><code class="classname">BApplication</code></a>
object. If you want reply messages to be handled by some other
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>,
you specify the object as a final argument to the
<a class="link" href="BLooper.html#BLooper_PostMessage" title="PostMessage()"><code class="methodname">PostMessage()</code></a> or
<a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>
call:</p><pre class="programlisting example cpp"><code class="varname">myLooper</code>-&gt;<code class="methodname">PostMessage</code>(new <code class="classname">BMessage</code>(<code class="constant">DO_SOMETHING</code>), <code class="varname">targetHandler</code>,
<code class="varname">replyHandler</code>);
<span class="comment">/* and */</span>
<code class="varname">myMessenger</code>.<code class="methodname">SendMessage</code>(&amp;<code class="varname">message</code>, <code class="varname">replyHandler</code>);</pre><p>The reply is sent asynchronously with regard to the
<a class="link" href="BLooper.html#BLooper_PostMessage" title="PostMessage()"><code class="methodname">PostMessage()</code></a>
/
<a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>
function.</p><p><a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>
(only) lets you ask for a reply message that's handed back synchronously in the
<a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>
call itself:</p><pre class="programlisting example cpp"><code class="classname">BMessage</code> <code class="varname">reply</code>;
<code class="varname">myMessenger</code>.<code class="methodname">SendMessage</code>(&amp;<code class="varname">message</code>, &amp;<code class="varname">reply</code>);</pre><p><a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>
doesn't return until a reply is received. A default message
is created and returned if the recipient doesn't respond quickly enough.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_ReceivingAMessage"></a>Receiving a Message</h4></div></div></div><p><a class="link" href="BMessage.html" title="BMessage"><code class="classname">BMessage</code></a>'s
<a class="link" href="BMessage.html#BMessage_SendReply" title="SendReply()"><code class="methodname">SendReply()</code></a>
function has the same syntax as
<a class="link" href="BMessenger.html#BMessenger_SendMessage" title="SendMessage()"><code class="methodname">SendMessage()</code></a>,
so it's possible to ask for a synchronous reply to a message that is itself
a reply,</p><pre class="programlisting example cpp"><code class="classname">BMessage</code> <code class="varname">message</code>(<code class="constant">READY</code>);
<code class="classname">BMessage</code> <code class="varname">reply</code>;
<code class="varname">theMessage</code>-&gt;<code class="methodname">SendReply</code>(&amp;<code class="varname">message</code>, &amp;<code class="varname">reply</code>);
if ( <code class="varname">reply</code>-&gt;<code class="varname">what</code> != <code class="constant">B_NO_REPLY</code> ) {
. . .
}</pre><p>or to designate a
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
for an asynchronous reply to the reply:</p><pre class="programlisting example cpp"><code class="varname">theMessage</code>-&gt;<code class="methodname">SendReply</code>(&amp;<code class="varname">message</code>, <code class="varname">someHandler</code>);</pre><p>In this way, two applications can maintain an ongoing exchange of
messages.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_HandlerAssociations"></a>Handler Associations</h4></div></div></div><p>To be notified of an arriving message, a
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
must "belong" to the
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>;
it must have been added to the
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>'s
list of eligible handlers. The list can contain any number of objects, but
at any given time a
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
can belong to only one
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>.</p><p>Handlers that belong to the same
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>
can be chained in a linked list. If an object can't respond to a message, the
system passes the message to its next handler.</p><p><a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>'s
<a class="link" href="BLooper.html#BLooper_AddHandler" title="AddHandler(), RemoveHandler(), HandlerAt(), CountHandlers(), IndexOf()"><code class="methodname">AddHandler()</code></a>
function sets up the looper-handler association;
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>'s
<a class="link" href="BHandler.html#BHandler_SetNextHandler" title="SetNextHandler(), NextHandler()"><code class="methodname">SetNextHandler()</code></a>
sets the handler-handler link.</p></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_MessageFilters"></a>Message Filters</h3></div></div></div><p>The
<a class="link" href="BMessageFilter.html" title="BMessageFilter"><code class="classname">BMessageFilter</code></a>
class lets create filtering functions that examine and
re-route (or reject) incoming messages before they're processed by a
<a class="link" href="BLooper.html" title="BLooper"><code class="classname">BLooper</code></a>.
Message filters can also be applied to individual
<a class="link" href="BHandler.html" title="BHandler"><code class="classname">BHandler</code></a>
objects.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="TheApplicationKit_Messaging_MessageProtocols"></a>Message Protocols</h3></div></div></div><p>Both the source and the destination of a message must agree upon its
format—the command constant and the names and types of data fields.
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.</p><p>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.</p></div></div><div id="footer"><hr /><div id="footerT">Prev: <a href="TheApplicationKit_Overview_Introduction.html">Introduction</a>  Up: <a href="TheApplicationKit_Overview.html">The Application Kit</a>  Next: <a href="TheApplicationKit_Scripting.html">Scripting</a> </div><div id="footerB"><div id="footerBL"><a href="TheApplicationKit_Overview_Introduction.html" title="Introduction"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a href="TheApplicationKit_Overview.html" title="The Application Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a href="TheApplicationKit_Scripting.html" title="Scripting"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="footerBR"><div><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div></div><div id="footerBC"><a href="http://www.access-company.com/home.html" title="ACCESS Co."><img alt="Access Company" src="./images/access_logo.png" /></a></div></div></div><div id="licenseFooter"><div id="licenseFooterBL"><a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/" title="Creative Commons License"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by-nc-nd/3.0/88x31.png" /></a></div><div id="licenseFooterBR"><a href="./LegalNotice.html">Legal Notice</a></div><div id="licenseFooterBC"><span id="licenseText">This work is licensed under a
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/">Creative
Commons Attribution-Non commercial-No Derivative Works 3.0 License</a>.</span></div></div></body></html>