895 lines
64 KiB
HTML
895 lines
64 KiB
HTML
<?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>-><code class="methodname">PostMessage</code>(&<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 & 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 & 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 <Application.h>
|
||
#include <Window.h>
|
||
#include <View.h>
|
||
#include <MenuBar.h>
|
||
#include <Menu.h>
|
||
#include <MenuItem.h>
|
||
#include <string.h>
|
||
</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>) < 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>-><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>-><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>-><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>-><code class="methodname">AddSeparatorItem</code>();
|
||
|
||
<code class="varname">menu</code>-><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>-><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>-><code class="methodname">AddSeparatorItem</code>();
|
||
|
||
<code class="varname">menu</code>-><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>-><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>-><code class="methodname">AddSeparatorItem</code>();
|
||
|
||
<code class="varname">menu</code>-><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>-><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>-><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>-><code class="methodname">AddItem</code>(<code class="varname">item</code>);
|
||
<code class="varname">menubar</code>-><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>-><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>-><code class="methodname">FindPointer</code>("source", (void **) &<code class="varname">item</code>);
|
||
if (<code class="varname">item</code>-><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>-><code class="methodname">SetString</code>(<code class="varname">s</code>);
|
||
<code class="varname">item</code>-><code class="methodname">SetMarked</code>(<code class="varname">mark</code>);
|
||
<code class="varname">helloview</code>-><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>-><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>-><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>
|