haiku-website/static/legacy-docs/benewsletter/Issue3-13.html

895 lines
64 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>Be Newsletters - Volume 3: 1998</title><link rel="stylesheet" href="be_newsletter.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_newsletter_ie.css" />
<![endif]--><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="Be Newsletters" /><link rel="up" href="volume3.html" title="Volume 3: 1998" /><link rel="prev" href="Issue3-12.html" title="Issue 3-12, March 25, 1998" /><link rel="next" href="Issue3-14.html" title="Issue 3-14, April 8, 1998" /></head><body><div id="header"><div id="headerT"><div id="headerTL"><a accesskey="p" href="Issue3-12.html" title="Issue 3-12, March 25, 1998"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a accesskey="u" href="volume3.html" title="Volume 3: 1998"><img src="./images/navigation/up.png" alt="Up" /></a> <a accesskey="n" href="Issue3-14.html" title="Issue 3-14, April 8, 1998"><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="naviglang" title="English">en</div></div><div id="headerTC">Be Newsletters - Volume 3: 1998</div></div><div id="headerB">Prev: <a href="Issue3-12.html">Issue 3-12, March 25, 1998</a>  Up: <a href="volume3.html">Volume 3: 1998</a>  Next: <a href="Issue3-14.html">Issue 3-14, April 8, 1998</a></div><hr /></div><div class="article"><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="Issue3-13"></a>Issue 3-13, April 1, 1998</h2></div></div></div><div class="sect1"><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="Engineering3-13"></a>Be Engineering Insights: News From the Front</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">William</span> <span class="surname">Adams</span></span></div></div></div><p>
When I was dating my now wife Anita way back when, she bet me that I
couldn't stop making jokes for 30 minutes. I buttoned up my wit and
buckled down for a half hour of witless conversation. At the end of the
allotted time, I burst forth with a stream of jokes and witticisms like
an uncorked fire hydrant. Well, I haven't written a Newsletter article
for quite a few months now and I'm brimming with so many ideas I hardly
know where to start...
</p><p>
I've been training for a triathlon for the past few weeks, and a couple
of times I've taken my daughter Yasmin along on 20 mile bike rides. Let
me tell you, that's no easy feat! Up and down hills, huffing and puffing,
Yasmin poking me in the butt, kicking the backs of my feet, making it
harder. But just when I think I have no more energy left, the end is in
sight. I make it up the last hill and look back across the landscape of
miles, puff out my chest and crow with the knowledge that at least Yasmin
thinks I'm a major stud muffin. Speaking of stud muffins, have you been
programming the BeOS and using threads lately?
</p><p>
If you've done any BeOS programming, you've probably been using threads
whether you intended to or not. A much-utilized mechanism for
communicating actions in a BeOS program is the
<code class="classname">BLooper</code> object. <code class="classname">BLooper</code>
greatly simplifies life, and in conjunction with <code class="classname">BHandler</code>, is the basis
of our messaging and scripting capabilities. You have probably seen or
used a number of times some code that looks like this:
</p><pre class="programlisting cpp">
<code class="classname">BMessage</code> <code class="varname">msg</code>('doit');
<code class="varname">aLooper</code>-&gt;<code class="methodname">PostMessage</code>(&amp;<code class="varname">msg</code>);
</pre><p>
Also, in the looper or handler of your choice, there is similar code in
<code class="code"><code class="methodname">MessageReceived</code>(<code class="classname">BMessage</code>* <code class="varname">msg</code></code>)
that does something interesting in
response to the particular message. Using <code class="classname">BLooper</code> and posting messages is
a good thing to do in many situations because it keeps the threading and
deadlocking model pretty straight. No fuss, no muss, no dirty semaphores.
But as our mantra goes, the BeOS offers pervasive multithreading,
symmetrical multiprocessing, etc. So aren't you anxious to spread your
threads and bring your machine to its processing knees cleanly?
</p><p>
Many times when you program with <code class="classname">BLooper</code> you're engaging in a design
pattern known as observer/observable. That is, you have some data that
changes from time to time, and you want various other components to
notice the changes and react accordingly. I have found it useful to
explicitly name this interface and create a couple of classes to
implement it. First, the <code class="classname">BObservable</code> class:
</p><p>
I've left out the constructor and a couple other things to save space.
</p><pre class="programlisting cpp">
virtual <span class="type">status_t</span> <code class="methodname">SendNotificationOf</code>(<span class="type">constint32</span> <code class="parameter">notice</code>,
<span class="type">void *</span><code class="parameter">data</code>);
<span class="type">status_t</span> <code class="methodname">AddObserver</code>(<span class="type"><code class="classname">BObserver</code> *</span>, <span class="type">void *</span><code class="parameter">data</code>);
<span class="type">status_t</span> <code class="methodname">RemoveObserver</code>(<span class="type"><code class="classname">BObserver</code> *</span>, <span class="type">void *</span><code class="parameter">data</code>);
</pre><p>
A <code class="classname">BObservable</code> is any object that wants other objects to know what it's
doing. In the Model/View/Controller world of SmallTalk, this would
probably be the Model. One example of an observable object might be a TV
tuner. Whenever the channel changes, some other object, notably a display
object, might be interested so that it can display a new channel number.
The Observable would call its <code class="methodname">SendNotification()</code>
method and the <code class="classname">BObserver</code>
will have its <code class="methodname">ReceiveNotice()</code> method called.
Speaking of <code class="classname">BObservable</code>,
here is its interface:
</p><pre class="programlisting cpp">
virtual <span class="type">bool</span> <code class="methodname">IsInterestedIn</code>(<span class="type">constint32</span> <code class="parameter">notice</code>,
<span class="type"><code class="classname">BObservable</code> *</span><code class="parameter">observable</code>);
virtual <span class="type">void</span> <code class="methodname">ReceiveNotice</code>(<span class="type">constint32</span> <code class="parameter">notice</code>,
<span class="type"><code class="classname">BObservable</code> *</span><code class="parameter">observable</code>,
<span class="type">void *</span><code class="parameter">data</code>);
</pre><p>
The primary thing to note is the <code class="methodname">ReceiveNotice()</code> method. This is similar
to a message filter in that a single integer value is sent. One
difference from a <code class="classname">BMessageFilter</code> is
that a <code class="classname">BObserver</code> can tell a
<code class="classname">BObservable</code> what messages it wants by using the
<code class="methodname">InterestedIn()</code> method. The
<code class="classname">BObservable</code> can call this at any time, and
the <code class="classname">BObserver</code> can report <code class="constant">true</code>
or <code class="constant">false</code> as to whether it is currently interested in receiving such
notifications. Another difference from a <code class="classname">BMessageFilter</code> is that
<code class="classname">BObserver</code>s can be hooked up to as many BObservable objects as they want.
You'll notice that one of the parameters to <code class="methodname">ReceiveNotification()</code> is the
<code class="classname">BObserver</code> that sent the message. Using
this, the <code class="classname">BObserver</code> can perform
appropriate actions based on which <code class="classname">BObservable</code> sent the message.
</p><p>
The interfaces of <code class="classname">BObservable</code> and
<code class="classname">BObserver</code> say absolutely nothing about
threading. Where and when threads are used is completely left up to the
individual implementations. Is this good or bad? Well, it gives you some
choices, and with choices come responsibilities. Here's the scissors --
please don't run with them.
</p><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id677696"></a>How About Another Example</h3></div></div></div><p>
I have a CD Player. There is one object, <code class="classname">BCDROMDrive</code>, which can act as
the Observable model. It will send out notices whenever a disk changes,
tracks change, or any of the other transport commands are activated.
</p><pre class="programlisting cpp">
enum <span class="type">ECDNotices</span> {
<code class="constant">CD_STOPPED</code>,
<code class="constant">CD_PLAY</code>,
<code class="constant">CD_FASTFORWARD</code>,
<code class="constant">CD_REWIND</code>,
<code class="constant">CD_CHANGED</code>
...
};
</pre><p>
There is no visual interface within this object. Then there is the
<code class="classname">BCDROMObserver</code>, which is responsible for displaying up to date disk
information. I don't want the Observer to slow down the Observable in any
way, so I've decided that when I receive notifications, I'll just put
them in a local queue, and return immediately so the Observable can carry
on with what it was doing:
</p><pre class="programlisting cpp">
<span class="type">void</span>
<code class="classname">BCDROMObserver</code>::<code class="methodname">ReceiveNotice</code>(<span class="type">constint32</span> <code class="parameter">notice</code>,
<span class="type"><code class="classname">BObservable</code> *</span><code class="parameter">observable</code>,
<span class="type">void *</span><code class="parameter">data</code>)
{
<code class="varname">fMessageQueue</code>.<code class="methodname">push</code>(<code class="parameter">notice</code>);
}
</pre><p>
Separately, I have a thread that is running in a loop,
pulling messages off the queue:
</p><pre class="programlisting cpp">
<span class="type">void</span>
<code class="classname">BCDROMObserver</code>::<code class="methodname">Run</code>()
{
while(!<code class="varname">timeToQuit</code>)
{
<code class="varname">fMessageQueue</code>.<code class="methodname">wait</code>();
<span class="type">int32</span> <code class="varname">aMsg</code> = <code class="varname">fMessageQueue</code>.<code class="methodname">pop</code>();
<span class="comment">// Massive switch statement to do things</span>
<span class="comment">// based on what the message is.</span>
}
}
</pre><p>
There are two things of note here. My message queue implementation is
thread safe, so I don't have to explicitly lock and unlock the queue to
do the push and pop. Also, there is other code that makes the <code class="methodname">Run()</code>
method occur in its own thread.
</p><p>
In essence, this gives you behavior similar to that of <code class="classname">BLooper</code>, with a
little bit more control of what type of messages you send around, and
where you use threads, ports, and semaphores. In this particular case my
messages are always just a 32-bit integer. Speed and memory management
are a concern, so I wanted tighter control of when and where things are
allocated and how much data is being passed around. Also, this
application does not receive messages from the outside world, nor does it
try to send them outside, so leaving <code class="classname">BLooper</code> is a reasonable thing to do.
</p><p>
Some sample code that uses this technique can be found at:
ftp://ftp.be.com/pub/samples/R3/support_kit/observable.zip
</p><p>
There's the <code class="classname">BObserver</code>/<code class="classname">able</code>
code, some threading code, some thread safe
queue code, and a little sample app that actually uses it. I would love
to write more, but as any good comedian knows, get off the stage while
they're still laughing.
</p></div><p>
But before I go, I've been working on some lightweight UI type things. If
you are a developer who has an interface which is highly customized with
lots of artwork, and you're wondering how to make nice sliders, buttons,
and other doohickeys, and keep it all fast and responsive, please drop me
e-mail, we may have something you can use: wadams@be.com.
</p><p>
That's all the news from the front.
</p></div><hr class="pagebreak" /><div class="sect1"><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="Marketing3-13"></a>Getting Press</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Dave</span> <span class="surname">Johnson</span></span></div></div></div><p>
Here is another in my series on making money by developing products for
the BeOS. Getting press is an important subject so I have promised not to
include weird jokes, not to knock Apple, and not to use the word "skank."
</p><p>
In order for you to make money selling your software, your potential
customers need to find out about your product. Aside from placing a demo
of your product on the BeWare web site, the most effective and least
costly way to get info about your product out to customers is through
magazine articles and reviews, TV and radio mentions, newspaper articles,
and articles in trade journals and targeted publications in specific
market segments. An example of an article in a targeted publication would
be an article about a new BeOS MIDI sequencer in a publication of
interest to musicians rather than a general computer magazine.
</p><p>
I can't encourage you strongly enough to make an effort to reach the
press. When the customer gets information from the press it comes with
greater credibility than when it comes from you. And if you are sending
press releases this helps bring attention to the BeOS in general as well
as letting the world know that there are lots of great applications
available. The more the BeOS becomes well known the better that helps you
with your product sales.
</p><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id677988"></a>Who Is This Article For?</h3></div></div></div><p>
This article is for freeware and shareware authors as well as commercial
publishers. Freeware authors want press because you can put it on your
resume. Shareware and commercial publishers will benefit because
increased exposure means increased sales. And Be benefits when you get
press attention as long as they spell our name right (which isn't hard to
do).
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678006"></a>How To Get Press Attention</h3></div></div></div><p>
To get press attention you send press releases to editors and reporters,
and follow up.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678018"></a>The Format of the Press Release</h3></div></div></div><p>
Press releases follow a standard format. At the top you should put
contact information, name, phone and e-mail. If you are sending
information that can be released immediately, you should put "For
Immediate Release" at the top.
</p><p>
You should have a headline, and possibly a sub-headline. The content of
the press release consists of several paragraphs of information, often
ending with general information about your company. The bottom of the
first page should either have a centered "MORE" if there is another page,
or "###" if it is the end of the press release. The top of the next page
should have the title and page number.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678044"></a>Writing a Press Release</h3></div></div></div><p>
Your press release serves two purposes. It is your chance to get the
interest of a busy editor or reporter, and it provides the necessary
information while framing the story.
</p><p>
Think of a press release as a form of direct mail advertising but not as
an ad. The structure and requirements are actually very similar to a
direct mail piece. Like a direct mail piece, your press release is going
to be quickly skimmed and then a decision is made whether to write a
story. The editor/reporter is reading and thinking "Is this a story that
will interest my readers?" But...
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678069"></a>A Press Release is Not an Ad!</h3></div></div></div><p>
You want to provide information, not do a hard sell. It is bad form to
try to do a sell job on the press. Working with the press is about
getting accurate information to the reader, and editors and reports will
appreciate that.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678084"></a>The Headline</h3></div></div></div><p>
When viewed in this direct mail context you can see that the headline can
be the most important part of your press release. It must entice the
editor or reporter to read further, while accurately conveying your
message. The headline should be a very short and to-the-point statement
telling what the press release is about while maintaining the interest of
the reader. You should think of it as a headline in a newspaper—as the
way you want your story to appear in the publication.
</p><p>
You can also have a sub-headline that conveys more information or
additional information.
</p><p>
Note: Use "BeOS" somewhere in the headline. The BeOS is hot right now;
editors are interested in it and they know their readers are interested
in it. Normally you would be competing with hundreds of press releases
for attention. Putting "BeOS" in the title should help you break through
the clutter.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678117"></a>The Content</h3></div></div></div><p>
The first paragraph has to contain the important information of interest
to the reader. If the headline is interesting enough for the
reporter/editor to read further you want to clinch it with the 1st
paragraph. It begins with a location and a date in parenthesis. "Menlo
Park, CA, (March 31, 1998)." You should tell your story quickly, briefly
and interestingly while providing necessary information. You've got
interest if they're reading this paragraph and you need to turn the
interest into a desire to write a story.
</p><p>
If it is decided that a story will be written, the press release will be
read more closely and will serve to frame the story. The content must
satisfy the customer who is interested in what you're selling and
reading. It no longer needs to be enticing, just informative. If the
reader is looking at this part at all it's likely an article will be
forthcoming.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678137"></a>Is Everything In There?</h3></div></div></div><p>
Be sure that your press release contains all the necessary information.
Does it tell the version and price of the product? Do you make clear the
availability—when and where and how to order or get more information.
Is there a demo available? Special hardware requirements? Be sure to
include your web address and please mention Be's BeWare page address.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678154"></a>Include A Blurb About The BeOS!</h3></div></div></div><p>
The BeOS is new, so not everyone is going to know what you're writing
about when you say your product runs on the BeOS. Along with "BeOS" in
the title you should include a paragraph describing the BeOS, where to
get more info about it, and where to get it. And it certainly doesn't
hurt if you describe the various ways your application runs better on the
BeOS.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678172"></a>A Blurb About The BeOS</h3></div></div></div><p>
The BeOS (available from Be, Inc. at the be web site ) is a new, modern,
high-performance, media-optimized personal computer operating system that
runs on Intel Pentium-based and PowerPC desktop computers. The BeOS
incorporates pervasive multithreading, symmetric multiprocessing,
protected memory, a 64-bit journaling file system, client-server based
architecture and an object-oriented API. The BeOS delivers the
performance required for multimedia applications, with unprecedented user
responsiveness and enabling real-time manipulation &amp; feedback
capabilities in applications.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678183"></a>End With General Company Info</h3></div></div></div><p>
Often press releases end with general information about your company
itself. When was the company established, markets, products, personnel,
etc...
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678197"></a>Where to Send the Press Release</h3></div></div></div><p>
Send the press release to the publications where you hope to see articles
about your product. Remember to include special-interest publications as
well as computer publications. If you have a fishing product send the
press release to Field &amp; Stream as well as ALL the computer magazines.
</p><p>
There are several approaches to this. One approach is to get a general
press list and send the press release to everyone on the list. DP
Directory is an excellent source of press lists and I have included their
URL below. You can get lists for e-mailing or postal mailing from them.
We have used these lists and we recommend them.
</p><p>
Another way is to purchase a copy of each publication you wish to target
and locate the masthead. The masthead is a page that lists the editors
and reporters that put the publication together. Often they list the area
of specialty for each editor. You can send the press release to everyone
on the list or only to selected people. You can call the publication and
ask who the right editor would be for your information.
</p><p>
Some PR experts suggest that you send press releases to only one person
at each news source, others say you it is a good idea to make sure
everyone knows about you. My feeling is that the more people that know
about your products the better. They will be writing articles in the
future and might remember your product, they might even move on to new
publications and introduce your product to new people there.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678243"></a>Be Available</h3></div></div></div><p>
After the press release goes out be sure you are available in case you
get calls. Give priority to editors who say they are "on deadline."
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678257"></a>Press Tracking Chart</h3></div></div></div><p>
You can wait and be pleasantly surprised by any articles that appear or
you can be proactive and take command of the effort. Set up a press
tracking chart listing each publication and contact, and call them to
find out what is scheduled with what publication dates. (The call can
also serve as a nudge to please put you on the schedule.)
</p><p>
You can also assign yourself certain important targets that you deem
necessary for your PR effort. These targets can then be contacted until
you can get a commitment for something to appear in the publication.
</p><p>
After a while a picture will emerge of what press attention is coming
over time. With the knowledge of what articles will appear and when they
will be published you can coordinate your marketing efforts, such as what
months you want to have your product advertised in software catalogs,
etc...
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678289"></a>Never Lie or Mislead</h3></div></div></div><p>
Honest information is the Big Kahuna of press relations. If you mislead
the press you lose your credibility and they will not forgive you. This
is not the way to handle problems that come up. Don't try to cover up
problems, just admit them and talk about what you plan to do about them.
Don't try to be clever. Remember that the press is about getting accurate
information to the readers. If you are going to be in business for the
long term you have to keep the respect of the press.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678309"></a>Reviews</h3></div></div></div><p>
The press release should tell who editors should contact to obtain review
copies of your product.
</p><p>
When sending out review copies it's a good idea to provide a reviewer's
guide. A reviewer's guide is a document describing important features,
what you think the customer will use the product for, and other things
you want to be sure a reviewer knows. It might contain a script for use
of the product, like a demo script
</p><p>
A review is usually objective and fair. And sometimes a review turns out
to be an opportunity for you to learn new ways that your product needs
improvement. :-) A fair reviewer will call you if problems come up and
give you an opportunity to explain a possible misunderstanding.
</p><p>
Often when an article is underway you will be asked if you can provide
the names of some customers. Writers like to get the customer's
perspective and some good quotations because the reader can relate to
other users.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678346"></a>Tips</h3></div></div></div><p>
If you are new to this, you don't need to be afraid to ask editors
questions about how to talk to them, and what you should do to get
articles scheduled. This is about building a relationship with the press.
But here's some tips. After you have sent the press release it's useful
to follow up with a quick call—but respect deadlines. When a deadline
approaches everyone at a publication gets extremely busy. If you call
someone and they say they are under deadline don't try to press your
point. Ask them when to call and then get off the phone.
</p><p>
Learn a publication's deadlines. It is useful to know when information
needs to arrive at a publication and the lead time of the publication.
Magazines can have lead times of several months. Weeklies have a cutoff
day the preceding week—nothing gets into the publication after that
day. If you want something in the next week's issue you need to know what
day the info needs to be there.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678367"></a>Demo Tours</h3></div></div></div><p>
If you want to make a more serious effort to get press attention you
should schedule a "demo tour." This is where you schedule to visit a
publication. Contact the appropriate editor and ask if you can schedule
to come visit and demonstrate your product and discuss it with one or
more members of the staff of the publication. Often you'll find yourself
with several people in attendance. This is a good way of establishing a
good personal relationship with members of the press.
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678386"></a>Your Web Site</h3></div></div></div><p>
Finally, you should establish a press section of your web site. For ideas
on how to set this up check out Be's press page located at:
www.be.com/aboutbe/pressreleases/index.html and Microsoft's press page
located at: www.microsoft.com/corpinfo/todaynews.htm
</p></div><div class="sect2"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id678402"></a>Additional Resources</h3></div></div></div><p>
Here are some URLs of good information about working with the press:
</p><ul class="itemizedlist"><li><p>
<a class="ulink" href="http://www.dpdirectory.com">http://www.dpdirectory.com</a>—A great place to get press lists!
</p></li><li><p>
<a class="ulink" href="http://www.dpdirectory.com/prtab1.htm">http://www.dpdirectory.com/prtab1.htm</a>—Tutorial on writing press releases.
</p></li><li><p>
<a class="ulink" href="http://www.newstips.com/newsrlse.htm">http://www.newstips.com/newsrlse.htm</a>—A sample press release from
Newstips, a PR newsletter.
</p></li><li><p>
<a class="ulink" href="http://www.smalloffice.com/guru/archive/mgrescre2.htm">http://www.smalloffice.com/guru/archive/mgrescre2.htm</a>—A sample press
release with some comments. There are other interesting articles on
marketing at this site.
</p></li><li><p>
<a class="ulink" href="http://www.prweb.com/coach/970722a.htm">http://www.prweb.com/coach/970722a.htm</a>—Press release how-to's.
</p></li><li><p>
<a class="ulink" href="http://www.smartbiz.com/sbs/cats/pr.htm">http://www.smartbiz.com/sbs/cats/pr.htm</a>—Links to LOTS of "How To" PR and
marketing sites.
</p></li><li><p>
<a class="ulink" href="http://www.smartbiz.com/sbs/arts/bly6.htm">http://www.smartbiz.com/sbs/arts/bly6.htm</a>—Good article on how to PR.
</p></li><li><p>
<a class="ulink" href="http://www.prweb.com/">http://www.prweb.com/</a>—A very good site, check out their "PR Coach" page.
</p></li></ul></div></div><hr class="pagebreak" /><div class="sect1"><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="DevWorkshop3-13"></a>Developers' Workshop: BeOS Programming Basics, Part 2</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Eric</span> <span class="surname">Shepherd</span></span></div></div></div><p>
In my last article, "BeOS Programming Basics, Part 1", we looked at
creating a basic BeOS application with a single window containing a
single view. This week, we'll expand on that a bit by adding a menu bar
to our window and showing how to handle user selections in menus.
</p><p>
Before we get to that, though, I thought I'd begin by clarifying a point
that often confuses people, and briefly review the coordinate system the
BeOS uses. If you have a rectangle:
</p><pre class="programlisting cpp">
<code class="varname">rect</code>.<code class="methodname">Set</code>(0, 0, 5, 7);
</pre><p>
This rectangle's top-left corner is at (0, 0) and its bottom-right corner
is at (5,7). It looks something like this:
</p><pre class="screen">
012345
******0
******1
******2
******3
******4
******5
******6
******7
</pre><p>
Because the coordinates you specify are inclusive, the top row of the
rectangle contains the points (0,0), (1,0), (2,0), (3,0), (4,0), and
(5,0). If you add those up, you can see that the rectangle is six pixels
wide and eight pixels high.
</p><p>
If you call <code class="methodname">Width()</code> on this rectangle, the result will be 5 (5-0).
<code class="methodname">Height()</code> returns 7 (7-0). This is the source of most of the confusion. If
you want to know the actual width or height in pixels of a rectangle, you
need to add one to the result of these two functions.
</p><p>
Now on to this week's project: Menu World. Menu World is based on the
Hello World code from my last article; in fact, if you haven't read that
article, I recommend you visit the Be web site and read it (once again,
that's at:
www.be.com/aboutbe/benewsletter/volume_II/Issue7.html#Workshop. You might
also want to download the source code for Hello World and have a look at
that as well:
ftp://ftp.be.com/pub/samples/intro/obsolete/helloworld_article.zip
</p><p>
Also, before we get started, I should point out that this article uses
<code class="classname">BMessage</code>s (which is how user interactions are reported to your
application) without going into a lot of detail on how they work. The
next article in this series will discuss messaging in more detail.
</p><p>
Here are the includes for Menu World:
</p><pre class="programlisting cpp">
#include &lt;Application.h&gt;
#include &lt;Window.h&gt;
#include &lt;View.h&gt;
#include &lt;MenuBar.h&gt;
#include &lt;Menu.h&gt;
#include &lt;MenuItem.h&gt;
#include &lt;string.h&gt;
</pre><p>
Let's start with <code class="function">main()</code>, which is very simple and self-explanatory. The
only reason I'm including it is because it's slightly different from what
it was when I wrote the previous article—it now allocates the <code class="classname">HelloApp</code>
object on the stack, which is the C++-approved way of doing things (I
love progress). Note that because it's allocated on the stack, we don't
have to remember to delete it, because it's done automatically when
<code class="function">main()</code> returns.
</p><pre class="programlisting cpp">
<span class="type">void</span> <code class="function">main</code>(<span class="type">void</span>) {
<code class="classname">HelloApp</code> <code class="varname">theApp</code>; // The application object
<code class="varname">theApp</code>.<code class="methodname">Run</code>();
}
</pre><p>
We also use the following constants for the <code class="classname">BMessage</code> command codes for
each of the menu items that Menu World will provide:
</p><pre class="programlisting cpp">
<span class="type">constuint32</span> <code class="constant">MENU_FILE_NEW</code> = 'MFnw';
<span class="type">constuint32</span> <code class="constant">MENU_FILE_OPEN</code> = 'MFop';
<span class="type">constuint32</span> <code class="constant">MENU_FILE_CLOSE</code> = 'MFcl';
<span class="type">constuint32</span> <code class="constant">MENU_FILE_SAVE</code> = 'MFsv';
<span class="type">constuint32</span> <code class="constant">MENU_FILE_SAVEAS</code> = 'MFsa';
<span class="type">constuint32</span> <code class="constant">MENU_FILE_PAGESETUP</code> = 'MFps';
<span class="type">constuint32</span> <code class="constant">MENU_FILE_PRINT</code> = 'MFpr';
<span class="type">constuint32</span> <code class="constant">MENU_FILE_QUIT</code> = 'MFqu';
<span class="type">constuint32</span> <code class="constant">MENU_OPT_HELLO</code> = 'MOhl';
</pre><p>
Now let's take a look at the <code class="classname">HelloView</code> class, which has one new method
and some private data added since last time. This isn't very exciting
stuff yet, but we'll experiment with menus a bit when we get to that
point:
</p><pre class="programlisting cpp">
class <code class="classname">HelloView</code> : public <code class="classname">BView</code> {
public:
<code class="methodname">HelloView</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>);
virtual <span class="type">void</span> <code class="methodname">Draw</code>(<code class="classname">BRect</code> <code class="parameter">updateRect</code>);
<span class="type">void</span> <code class="methodname">SetString</code>(<span class="type">const char *</span><code class="parameter">s</code>);
private:
<span class="type">char</span> <code class="varname">message</code>[128];
};
</pre><p>
The <code class="methodname">SetString()</code> function has been added to let you configure what message
the <code class="classname">HelloView</code> class draws. The message is stored in the
<code class="varname">message</code> string,
as follows:
</p><pre class="programlisting cpp">
<span class="type">void</span> <code class="classname">HelloView</code>::<code class="methodname">SetString</code>(<span class="type">const char *</span><code class="parameter">s</code>) {
if (<code class="function">strlen</code>(<code class="parameter">s</code>) &lt; 127) {
<code class="function">strcpy</code>(<code class="varname">message</code>, <code class="parameter">s</code>);
}
}
</pre><p>
<code class="methodname">SetString()</code> just makes sure the string isn't too long, then copies it
into the message field.
</p><p>
The <code class="methodname">Draw()</code> function has to be changed
to use the <code class="varname">message</code> string:
</p><pre class="programlisting cpp">
<span class="type">void</span> <code class="classname">HelloView</code>::<code class="methodname">Draw</code>(<code class="classname">BRect</code> <code class="parameter">updateRect</code>) {
<code class="methodname">MovePenTo</code>(<code class="classname">BPoint</code>(20,75)); // Move pen
<code class="methodname">DrawString</code>(<code class="varname">message</code>);
}
</pre><p>
Finally, the <code class="classname">HelloView</code> constructor has to be updated to initialize the
message string:
</p><pre class="programlisting cpp">
<code class="classname">HelloView</code>::<code class="methodname">HelloView</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>)
: <code class="classname">BView</code>(<code class="parameter">frame</code>, "HelloView", <code class="constant">B_FOLLOW_ALL_SIDES</code>,
<code class="constant">B_WILL_DRAW</code>) {
<code class="methodname">SetString</code>(<code class="constant">STRING_HELLO</code>);
}
</pre><p>
Things start to get really interesting when we look at the updated
<code class="classname">HelloWindow</code> class:
</p><pre class="programlisting cpp">
class <code class="classname">HelloWindow</code> : public <code class="classname">BWindow</code> {
public:
<code class="methodname">HelloWindow</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>);
virtual <span class="type">bool</span> <code class="methodname">QuitRequested</code>();
virtual <span class="type">void</span> <code class="methodname">MessageReceived</code>(<span class="type"><code class="classname">BMessage</code> *</span><code class="parameter">message</code>);
private:
<span class="type"><code class="classname">BMenuBar</code> *</span><code class="varname">menubar</code>;
<span class="type"><code class="classname">HelloView</code> *</span><code class="varname">helloview</code>;
};
</pre><p>
In the <code class="classname">HelloWindow</code> class, the
<code class="methodname">MessageReceived()</code> function is new since
last time. Notice also that we now have fields for stashing pointers to
the menu bar and the <code class="classname">HelloView</code> attached to the window.
</p><p>
Let's go through these methods one by one. The constructor has been
updated to create and install the menu bar. Here it is:
</p><pre class="programlisting cpp">
<code class="classname">HelloWindow</code>::<code class="methodname">HelloWindow</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>)
: <code class="classname">BWindow</code>(<code class="parameter">frame</code>, "MenuWorld", <code class="constant">B_TITLED_WINDOW</code>,
<code class="constant">B_NOT_RESIZABLE</code> | <code class="constant">B_NOT_ZOOMABLE</code>) {
<code class="classname">BRect</code> <code class="varname">r</code>;
<span class="type"><code class="classname">BMenu</code> *</span><code class="varname">menu</code>;
<span class="type"><code class="classname">BMenuItem</code> *</span><code class="varname">item</code>;
<span class="comment">// Add the drawing view</span>
<code class="varname">r</code> = <code class="methodname">Bounds</code>();
<code class="varname">r</code>.<code class="varname">top</code> = 20;
<code class="methodname">AddChild</code>(<code class="varname">helloview</code> = new <code class="classname">HelloView</code>(<code class="varname">r</code>));
<span class="comment">// Add the menu bar</span>
<code class="varname">r</code>.<code class="varname">top</code> = 0;
<code class="varname">r</code>.<code class="varname">bottom</code> = 19;
<code class="varname">menubar</code> = new <code class="classname">BMenuBar</code>(<code class="varname">r</code>, "menu_bar");
<code class="methodname">AddChild</code>(<code class="varname">menubar</code>);
</pre><p>
This isn't as complicated as it looks at first glance, since most of the
content is very repetitive.
</p><p>
We start by getting the bounds window rectangle, just as we did for Hello
World. We want to create our <code class="classname">HelloView</code>. However, to make room for the
menu bar, we set the top edge of the rectangle to 20 (the menu bar will
be 20 pixels tall and placed above the <code class="classname">HelloView</code>). Then we create and add
the <code class="classname">HelloView</code> to the window. Notice that we also store a pointer to the
view in the member variable <code class="varname">helloview</code>.
</p><p>
Then we create the menu bar and add it to the window. We set <code class="varname">r.top</code> to 0
and <code class="varname">r.bottom</code> to 19, to indicate that the menu bar should take up the top
20 pixels of the window, and create a <code class="classname">BMenuBar</code>
named <code class="varname">menu_bar</code>. A
pointer to the menu bar is stored in the variable <code class="varname">menubar</code>. Then the menu
bar is added to the window by calling <code class="methodname">AddChild()</code>.
</p><p>
Note that at this point, our window has two views in it: one is the
<code class="classname">HelloView</code>, and one is a <code class="classname">BMenuBar</code>
(which is derived from <code class="classname">BMenu</code>, which is
derived from <code class="classname">BView</code>).
</p><p>
The File menu is created next:
</p><pre class="programlisting cpp">
<code class="varname">menu</code> = new <code class="classname">BMenu</code>("File");
</pre><p>
This line just creates an empty menu named "File." Then it's time to add
the items to the menu, as follows:
</p><pre class="programlisting cpp">
<code class="varname">menu</code>-&gt;<code class="methodname">AddItem</code>(new <code class="classname">BMenuItem</code>("New",
new <code class="classname">BMessage</code>(<code class="constant">MENU_FILE_NEW</code>), 'N'));
</pre><p>
This line of code adds the "New" option (with the keyboard shortcut key
<span class="keysym">Command</span>+<span class="keycap">N</span>)
to the menu by creating a new <code class="classname">BMenuItem</code> object and adding it
to the menu using the <code class="methodname">AddItem()</code> call.
</p><p>
When the user selects a menu item, a <code class="classname">BMessage</code> is sent to the window
containing the menu item (the target for the message can be changed, but
let's not get ahead of ourselves). The message that's sent to the window
is created by copying the model message specified when you create the
<code class="classname">BMenuItem</code>.
</p><p>
In this case, we specify a model message with the command code
<code class="constant">MENU_FILE_NEW</code>. We'll look at messages in more detail in my next article.
</p><p>
We continue adding the rest of the menu items. Note that the keyboard
shortcut argument to the <code class="classname">BMenuItem</code> constructor is optional; if you don't
specify it, the menu item won't have a keyboard shortcut. Also, we use
the <code class="methodname">AddSeparatorItem()</code> function to add dividing lines here and there, to
make the menu easier to read:
</p><pre class="programlisting cpp">
<code class="varname">menu</code>-&gt;<code class="varname">AddItem</code>(new <code class="classname">BMenuItem</code>("Open" <code class="constant">B_UTF8_ELLIPSIS</code>,
new <code class="classname">BMessage</code>(<code class="constant">MENU_FILE_OPEN</code>), 'O'));
<code class="varname">menu</code>-&gt;<code class="varname">AddItem</code>(new <code class="classname">BMenuItem</code>("Close",
new <code class="classname">BMessage</code>(<code class="constant">MENU_FILE_CLOSE</code>), 'W'));
<code class="varname">menu</code>-&gt;<code class="methodname">AddSeparatorItem</code>();
<code class="varname">menu</code>-&gt;<code class="varname">AddItem</code>(new <code class="classname">BMenuItem</code>("Save",
new <code class="classname">BMessage</code>(<code class="constant">MENU_FILE_SAVE</code>), 'S'));
<code class="varname">menu</code>-&gt;<code class="varname">AddItem</code>(new <code class="classname">BMenuItem</code>("Save as" B_UTF8_ELLIPSIS,
new <code class="classname">BMessage</code>(<code class="constant">MENU_FILE_SAVEAS</code>)));
<code class="varname">menu</code>-&gt;<code class="methodname">AddSeparatorItem</code>();
<code class="varname">menu</code>-&gt;<code class="varname">AddItem</code>(new <code class="classname">BMenuItem</code>("Page Setup" B_UTF8_ELLIPSIS,
new <code class="classname">BMessage</code>(<code class="constant">MENU_FILE_PAGESETUP</code>)));
<code class="varname">menu</code>-&gt;<code class="varname">AddItem</code>(new <code class="classname">BMenuItem</code>("Print" B_UTF8_ELLIPSIS,
new <code class="classname">BMessage</code>(<code class="constant">MENU_FILE_PRINT</code>), 'P'));
<code class="varname">menu</code>-&gt;<code class="methodname">AddSeparatorItem</code>();
<code class="varname">menu</code>-&gt;<code class="varname">AddItem</code>(new <code class="classname">BMenuItem</code>("Quit",
new <code class="classname">BMessage</code>(<code class="constant">MENU_FILE_QUIT</code>), 'Q'));
</pre><p>
Once all the items have been added to the menu, we add the menu to the
menu bar by calling the <code class="classname">BMenuBar</code> class'
<code class="methodname">AddItem()</code> function:
</p><pre class="programlisting cpp">
<code class="varname">menubar</code>-&gt;<code class="methodname">AddItem</code>(<code class="varname">menu</code>);
</pre><p>
Then we create the Options menu, which only has one item in it.
</p><pre class="programlisting cpp">
<code class="varname">menu</code> = new <code class="classname">BMenu</code>("Options");
<code class="varname">item</code> = new <code class="classname">BMenuItem</code>("Say Hello",
new <code class="classname">BMessage</code>(<code class="constant">MENU_OPT_HELLO</code>));
</pre><p>
The "Say Hello" menu item is used to toggle between two strings that
might appear in the <code class="classname">HelloView</code> in our window:
"Hello World" and "Goodbye
World." This menu item has a check mark next to it if "Hello World" is
displayed, and no check mark if "Goodbye World" is displayed. Let's make
"Hello World" the default and make sure the "Say Hello" item is initially
checked:
</p><pre class="programlisting cpp">
<code class="varname">item</code>-&gt;<code class="methodname">SetMarked</code>(<code class="constant">true</code>);
</pre><p>
Passing <code class="constant">true</code> to <code class="methodname">SetMarked()</code>
puts a check mark in front of the menu item,
while passing <code class="constant">false</code> removes the check mark.
</p><p>
Then we add the "Say Hello" item to the menu and add the Options menu to
the menu bar.
</p><pre class="programlisting cpp">
<code class="varname">menu</code>-&gt;<code class="methodname">AddItem</code>(<code class="varname">item</code>);
<code class="varname">menubar</code>-&gt;<code class="methodname">AddItem</code>(<code class="varname">menu</code>);
</pre><p>
Finally, we make the window visible by calling <code class="methodname">Show()</code>.
</p><pre class="programlisting cpp">
<code class="methodname">Show</code>();
}
</pre><p>
<code class="methodname">QuitRequested()</code> is unchanged from Hello World.
</p><p>
<code class="classname">MessageReceived()</code> is where the heavy lifting of handling and dispatching
user selections in the menu bar is done. When the user selects a menu
option, an appropriate <code class="classname">BMessage</code> is created and sent to the window
containing the menu. The window's <code class="methodname">MessageReceived()</code> function receives the
message and handles it:
</p><pre class="programlisting cpp">
<span class="type">void</span> <code class="classname">HelloWindow</code>::<code class="methodname">MessageReceived</code>(<span class="type"><code class="classname">BMessage</code> *</span><code class="parameter">message</code>) {
switch(<span class="type">message</span>-&gt;<code class="varname">what</code>) {
case <code class="constant">MENU_OPT_HELLO</code>:
<span class="comment"><span class="comment">/* see below for the code that goes here */</span></span>
break;
default:
<code class="classname">BWindow</code>::<code class="methodname">MessageReceived</code>(<code class="parameter">message</code>);
break;
}
}
</pre><p>
One of the public fields of a <code class="classname">BMessage</code>
object is called <code class="varname">what</code>; it
contains the command code that was specified when creating the <code class="classname">BMessage</code>.
We can therefore tell what kind of message the <code class="classname">BMessage</code> represents by
looking at the value of the <code class="varname">what</code> field.
</p><p>
For now, the only message we handle is <code class="constant">MENU_OPT_HELLO</code>, which is sent when
the user selects the "Say Hello" item in the Options menu (if you look in
the <code class="classname">HelloWindow</code> constructor, the model
<code class="classname">BMessage</code> for the "Say Hello" item
has this command code). All other messages are forwarded to
<code class="methodname">BWindow::MessageReceived()</code> for further processing.
</p><p>
The "Say Hello" item toggles the text displayed in the view between
"Hello World" and "Goodbye World." It also adds a checkbox to the menu
item if "Hello World" is displayed, and removes it if "Goodbye World" is
displayed. Let's have a look at the code.
</p><pre class="programlisting cpp">
case <code class="constant">MENU_OPT_HELLO</code>:
{
<span class="type"><code class="classname">BMenuItem</code> *</span><code class="varname">item</code>;
<span class="type">const char *</span><code class="varname">s</code>;
<span class="type">bool</span> <code class="varname">mark</code>;
<code class="parameter">message</code>-&gt;<code class="methodname">FindPointer</code>("source", (void **) &amp;<code class="varname">item</code>);
if (<code class="varname">item</code>-&gt;<code class="methodname">IsMarked</code>()) {
<code class="varname">s</code> = <code class="constant">STRING_GOODBYE</code>;
<code class="varname">mark</code> = <code class="constant">false</code>;
}
else {
<code class="varname">s</code> = <code class="constant">STRING_HELLO</code>;
<code class="varname">mark</code> = <code class="constant">true</code>;
}
<code class="varname">helloview</code>-&gt;<code class="methodname">SetString</code>(<code class="varname">s</code>);
<code class="varname">item</code>-&gt;<code class="methodname">SetMarked</code>(<code class="varname">mark</code>);
<code class="varname">helloview</code>-&gt;<code class="methodname">Invalidate</code>();
}
break;
</pre><p>
The <code class="classname">BMessage</code> that's received by your
<code class="methodname">MessageReceived()</code> function when the
user selects a menu item is the model message specified when the menu
item was created, with three additional fields added to it:
</p><p>
The <code class="varname">when</code> field contains a
<code class="constant">B_INT64_TYPE</code> value that specifies the time
the item was selected, measured in terms of the number of microseconds
since 12:00:00 AM on January 1, 1970.
</p><p>
The <code class="varname">source</code> field contains a <code class="constant">B_POINTER_TYPE</code> value that's a pointer to
the <code class="classname">BMenuItem</code> object itself.
</p><p>
The <code class="varname">index</code> field contains a
<code class="constant">B_INT32_TYPE</code> value that specifies the
ordinal position of the selected menu item within the menu, where 0 is
the first item in the menu.
</p><p>
In order to toggle the check mark next to the menu item, we need a
pointer to its <code class="classname">BMenuItem</code> object. We could have cached it in our window
object, but it's more interesting from a sample code standpoint to fetch
it from the "source" field in the
<code class="classname">BMessage</code>, so that's what we do. We use
the <code class="methodname">FindPointer()</code> function to get the pointer out of the message and
store it in the variable called <code class="varname">item</code>.
</p><p>
We then call <code class="code"><code class="varname">item</code>-&gt;<code class="methodname">IsMarked()</code></code>
to determine whether the menu item is
currently checked or not. If it's checked, <code class="methodname">IsMarked()</code>
returns <code class="constant">true</code> (which
means the text in the view is currently "Hello World." We set up a
pointer to the string "Goodbye World," and set the variable mark to
<code class="constant">false</code>. If <code class="methodname">IsMarked()</code>
returns <code class="constant">false</code> (meaning that "Goodbye World" is
displayed), we set the string pointer to "Hello World"
and <code class="varname">mark</code> to <code class="constant">true</code>.
</p><p>
Then we call the <code class="classname">HelloView</code>'s
<code class="methodname">SetString()</code> function to change the text
being displayed, and call <code class="code"><code class="varname">item</code>-&gt;<code class="methodname">SetMark()</code></code>
to turn on or off the check
mark; if <code class="varname">mark</code> is <code class="constant">false</code>, the check mark is
removed. If <code class="varname">mark</code> is <code class="constant">true</code>, the
check mark is added.
</p><p>
Then we invalidate the <code class="classname">HelloView</code>. Invalidating a view causes the
application server to <code class="methodname">Draw()</code> the entire view. This is necessary to
refresh the view's contents.
</p><p>
The <code class="classname">BMenuItem</code> class has some other functions you might want to experiment
with, such as <code class="methodname">SetEnabled()</code> and
<code class="methodname">IsEnabled()</code>, which let you control whether
or not a menu item is disabled (dimmed and unselectable), or <code class="methodname">SetLabel()</code>
and <code class="methodname">Label()</code>, which let you set and retrieve the current text displayed
for the menu item when it's drawn.
</p><p>
To make life easier, you can download the complete source code for this
week's project:
ftp://ftp.be.com/pub/samples/intro/obsolete/menuworld_article.zip
</p><p>
Since this week's article has opened the <code class="classname">BMessage</code> can of worms, I think
it's only proper that part three of the BeOS Programming Basics series
cover message services on the BeOS in a little more detail. For now, play
with the <code class="classname">BMenuBar</code>, <code class="classname">BMenu</code>,
and <code class="classname">BMenuItem</code> classes and see where you can go
with it. See you again in six weeks or so.
</p></div><hr class="pagebreak" /><div class="sect1"><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="Gassee3-13"></a>Early Impressions</h2></div><div xmlns:d="http://docbook.org/ns/docbook"><span xmlns="http://www.w3.org/1999/xhtml" class="author">By <span class="firstname">Jean-Louis</span> <span class="surname">Gassée</span></span></div></div></div><p>
Two weeks ago, we were preparing for our BeDC, our developers' conference
in Santa Clara, and we were unusually nervous. What was unusual was that
we felt reasonably well-prepared this time, unlike our August '97
conference in Boston, for instance. And, happily, most everything worked
this time, with very few glitches.
</p><p>
I won't go into details but I'd like to thank those participants who gave
us feedback and suggestions for improving the formula or the execution.
Speaking of which, it felt a little strange, at first, having court
reporters in the sessions, but their purpose was non-prosecutorial.
Transcripts of the presentations will be preserved for posterity on our
site, with appropriate beautification from our embalming editors, I hope.
</p><p>
I had a good time. Developer conferences motivate me, because they are a
great opportunity to meet the most important people in our life --
developers. True blue capitalists will argue that shareholders are the
most important constituency we serve, they have a point, but without
developers, shares in an operating system aren't worth much.
</p><p>
In any event, we value the opportunity to stand in front of a jury of our
peers and present our work and our plans for the future. At the same
time, one of the high points for me at the BeDC was watching the Masters
Awards ceremony. I remember the old joke in the early difficult days of
the Macintosh: there are three forms of lying, action, omission, and
there is software for the Macintosh.
</p><p>
Seeing the quality and abundance of applications rewarded, not just
submitted, I feel (cautiously) optimistic about our prospects. Please
point your browser to
www.be.com/aboutbe/pressreleases/98-03-19_beos_masters.html for details.
And please don't ask me which program I prefer. I've excluded myself from
the judging because I'm a little too enthusiastic. I also remember the
first part of 1985 when everyone was so down on the Macintosh, and I got
a nice job out of the common and unwarranted pessimism.
</p><p>
Back at the office, we got a good dose of cold water. Early orders for
Release 3 were coming in at a nice clip, so nice, in fact, that it
quickly revealed an embarrassing bug in our order taking system. Somehow,
we managed to drop the last digit of credit card numbers and we were
faced with having to call over fifteen hundred customers, apologize for
our mistake, expose our mastery of computer technology, and sheepishly
ask for their credit card number again.
</p><p>
Fortunately, Ron Theis, our Web Master, found an algorithm to recalculate
this last digit. It worked for about 70% of cases. For the other 30%,
this turned into an opportunity to deal with another issue: hardware
configurations. Even if we take precautions on our Web site, in the
documentation, and in any medium we can find, if our customer orders the
BeOS and can't run it on his/her machine, we're going to create
frustrations and bad word-of-mouth.
</p><p>
So, as we called customers, we checked, and the good news is a very high
proportion indeed have hardware we support at this time and are clearly
of the geek persuasion. We know we need to broaden the range of
configurations we support and we acknowledge we need to make the
installation process smoother, so we were relieved to see our early
customers were quite patient with our imperfections. Our thanks to them,
and our apologies to those we didn't satisfy as much and as quickly as
they expected. We now have a clear picture of what we have to do.
</p></div></div><div id="footer"><hr /><div id="footerT">Prev: <a href="Issue3-12.html">Issue 3-12, March 25, 1998</a>  Up: <a href="volume3.html">Volume 3: 1998</a>  Next: <a href="Issue3-14.html">Issue 3-14, April 8, 1998</a> </div><div id="footerB"><div id="footerBL"><a href="Issue3-12.html" title="Issue 3-12, March 25, 1998"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a href="volume3.html" title="Volume 3: 1998"><img src="./images/navigation/up.png" alt="Up" /></a> <a href="Issue3-14.html" title="Issue 3-14, April 8, 1998"><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>