The Be Book The Application Kit The Application Kit Index

BApplication

Derived from: BLooper > BHandler
Mix-in classes: BArchivable
Declared in:  be/app/Application.h
Library: libbe.so
Summary:  more...


The BApplication class defines an object that represents your application, creates a connection to the App Server, and runs your app's main message loop. An app can only create one BApplication object; the system automatically set the global be_app object to point to the BApplication object you create.

A BApplication object's most pervasive task is to handle messages that are sent to your app, a subject that's described in detail below. But message handling aside, you can also use your BApplication object to...

be_app and Subclassing BApplication

Because of its importance, the BApplication object that you create is automatically assigned to the global be_app variable. Anytime you need to refer to your BApplication object—from anywhere in your code—you can use be_app instead.

Unless you're creating a very simple application, you should subclass BApplication. But be aware that the be_app variable is typed as (BApplication *). You'll have to cast be_app when you call a function that's declared by your subclass:

((MyApp *)be_app)->MyAppFunction();

Constructing the Object and Running the Message Loop

As with all BLoopers, to use a BApplication you construct the object and then tell it to start its message loop by calling the Run() function. However, unlike other loopers, BApplication's Run() doesn't return until the application is told to quit. And after Run() returns, you delete the object—it isn't deleted for you.

Typically, you create your BApplication object in your main() function—it's usually the first object you create. The barest outline of a typical main() function looks something like this:

#include <Application.h>

main()1
{
   2new BApplication("application/x-vnd.your-app-sig")3;
   /* Further initialization goes here -- read settings, set globals, etc. */
   be_app->Run()4;
   /* Clean up -- write settings, etc. */
   delete be_app;
}

1    The main() function doesn't declare argc and argv parameters (used for passing along command line arguments). If the user passes command line arguments to your app, they'll show up in the ArgvReceived() hook function.

2    Why no pointer assignment? The constructor automatically assigns the object to be_app, so you don't have to assign it yourself.

3    The string passed to the constructor sets the application's signature. This is a precautionary measure—it's better to add the signature as a resource than to define it here (a resource signature overrides the constructor signature). Use the FileTypes app to set the signature as a resource.

4    As explained in the BLooper class, Run() is almost always called from the same thread in which you construct the BApplication object. (More accurately, the constructor locks the object, and Run() unlocks it. Since locks are scoped to threads, the easiest thing to do is to construct and Run() in the same thread.)

Application Messages

After you tell your BApplication to run, its message loop begins to receive messages. In general, the messages are handled in the expected fashion: They show up in BApplication's MessageReceived() function (or that of a designated BHandler; for more on how messages are dispatched to handlers, see <x>).

But BApplication also recognizes a set of application messages that it handles by invoking corresponding hook functions. The hook functions are invoked by DispatchMessage() so the application messages never show up in MessageReceived().

Overriding the hook functions that correspond to the application messages is an important part of the implementation of a BApplication subclass.

In the table below, the application messages (identified by their command constants) are listed in roughly the order your BApplication can expect to receive them.

Command Constant Hook function Description
B_ARGV_RECEIVED ArgvReceived() Command line arguments are delivered through this message.
B_REFS_RECEIVED RefsReceived() Files (entry_refs) that are dropped on your app's icon, or that are double-clicked to launch your app are delivered through this message.
B_READY_TO_RUN ReadyToRun() Invoked from within Run(), the application has finished configuring itself and is ready to go. If you haven't already created and displayed an initial window, you should do so here.
B_APP_ACTIVATED AppActivated() The application has just become the active application, or has relinquished that status.
B_PULSE Pulse() If requested, pulse messages are sent at regular intervals by the system.
B_ABOUT_REQUESTED AboutRequested() The user wants to see the app's About... box.

The protocols for the application messages are described in "General Messages".

For more information on the details of when and why the hook functions are invoked, see the individual function descriptions.

A BApplication can also receive the B_QUIT_REQUESTED looper message. As explained in BLooper, B_QUIT_REQUESTED causes Quit() to be called, contingent on the value returned by the QuitRequested() hook function. However, BApplication's implementation of Quit() is different from BLooper's version. Don't miss it.

Other Topics


Hook Functions

AboutRequested()

AppActivated()

ArgvReceived()

Pulse()

ReadyToRun()

RefsReceived()


Constructor and Destructor


BApplication()

BApplication(const char *signature)
BApplication(const char *signature, status_t *error)
BApplication(BMessage *archive)

The constructor creates a new object, locks it, sets the global variable be_app to point to it, and establishes a connection to the Application Server. From this point on, your app can receive messages, although it won't start processing them until you call Run(). You can also begin creating and displaying BWindow objects—even before you call Run().

The signature constructors assign the argument as the app's application signature. The argument is ignored if a signature is already specified in a resource or attribute of the application's executable (serious apps should always set the signature as both an attribute and a resource). The signature is a MIME type string that must have the supertype "application". For more information on application signatures and how to set them, see <x>.

If you specify error, a pointer to a status_t, any error that occurs while constructing the BApplication will be returned in that variable. Alternately, you can call InitCheck() to check the results. If an error is returned by the constructor, you shouldn't call Run().

The archive constructor is an implementation detail; see the BArchivable class.


~BApplication()

virtual ~BApplication()

Closes and deletes the application's BWindows (and the BViews they contain), and severs the application's connection to the Application Server.

Never delete a BApplication object while it's running—wait until Run() returns. To stop a BApplication (and so cause Run() to return), send it a B_QUIT_REQUESTED message:

be_app->PostMessage(B_QUIT_REQUESTED);


Static Functions


AppResources()

static BResources *AppResources(void)

Returns a BResources object that's configured from your application's executable file. You may read the data in the BResources object, but you're not allowed to write it; see the BResources class for details. The BResources object belongs to the BApplication class and mustn't be freed.

You needn't have a be_app object to invoke this function.


Instantiate()  see BArchivable::Instantiate()


Member Functions


AboutRequested()

virtual void AboutRequested(void)

Hook function that's invoked when the BApplication receives a B_ABOUT_REQUESTED message, undoubtedly because the user clicked an About... menu item. You should implement the function to put a window on-screen that provides the user with information about the application (version number, license restrictions, authors' names, etc).


AppActivated()

virtual void AppActivated(bool active)

Hook function that's invoked when the application receives a B_APP_ACTIVATED message. The message is sent when the app gains or loses active application status. The active flag tells you which way the wind blows: true means your app is now active; false means it isn't.

The user can activate an app by clicking on or unhiding one of its windows; you can activate an app programmatically by calling BWindow::Activate() or BRoster::ActivateApp(). (With regard to the latter: This function is called only if the app has an "activatable" window—i.e. a non-modal, non-floating window).

During launch, this function is called after ReadyToRun() (provided the app is displaying an activatable window).


Archive() see BArchivable::Archive()


ArgvReceived()

virtual void ArgvReceived(int32 argc, char **argv)

Hook function that's invoked when the application receives a B_ARGV_RECEIVED message. The message is sent if command line arguments are used in launching the app from the shell, or if argv/argc values are passed to BRoster::Launch().

This function isn't called if there were no command line arguments, or if BRoster::Launch() was called without argv/argc values.

When the app is launched from the shell, ArgvReceived()'s arguments are identical to the traditional main() arguments: The number of command line arguments is passed as argc; the arguments themselves are passed as an array of strings in argv. The first argv string identifes the executable file; the other strings are the command line arguments proper. For example, this...

$ MyApp file1 file2

...produces the argv array {"./MyApp", "file1", "file2"}.

BRoster::Launch() forwards its argv and argc arguments, but adds the executable name to the front of the argv array and increments the argc value.

Normally, the B_ARGV_RECEIVED message (if sent at all) is sent once, just before B_READY_TO_RUN is sent. However, if the user tries to re-launch (from the command line and with arguments) an already-running app that's set to B_EXCLUSIVE_LAUNCH or B_SINGLE_LAUNCH, the re-launch will generate a B_ARGV_RECEIVED message that's sent to the already-running image. Thus, for such apps, the B_ARGV_RECEIVED message can show up at any time.


CountWindows()  see WindowAt()
DispatchMessage()  see BLooper::DispatchMessage()


GetAppInfo()

status_t GetAppInfo(app_info *theInfo) const

Returns information about the application. This is a cover for

be_roster–>GetRunningAppInfo(be_app->Team(), theInfo);

See BRoster::GetAppInfo() for more information.


GetSupportedSuites()

virtual status_t GetSupportedSuites(BMessage *message)

Adds the scripting suite "suite/vnd.Be-application" to message. See "Scripting Suites and Properties" for the suite's properties. Also see BHandler::GetSupportedSuites() for more information on how this function works.


HideCursor()  see SetCursor()
IsCursorHidden()  see SetCursor()


IsLaunching()

bool IsLaunching(void) const

Returns true if the app is still launching. An app is considered to be in its launching phase until ReadyToRun() returns. Invoked from within ReadyToRun(), IsLaunching() returns true.


MessageReceived()  see BHandler::MessageReceived()
ObscureCursor()  see SetCursor()


Pulse() , SetPulseRate()

virtual void Pulse(void)
void SetPulseRate(bigtime_t rate)

Pulse() is a hook function that's called when the app receives a B_PULSE message. The message is sent once every rate microseconds, as set in SetPulseRate(). The first Pulse() message is sent after ReadyToRun() returns. If the pulse rate is 0 (the default), the B_PULSE messages aren't sent.

You can implement Pulse() to do whatever you want (the default version does nothing), but don't try to use it for precision timing: The pulse granularity is no better than 100,000 microseconds.

Keep in mind that Pulse() executes in the app's message loop thread along with all other message handling functions. Your app won't receive any Pulse() invocations while it's waiting for some other handler function (including MessageReceived()) to finish. In the meantime, B_PULSE messages will be stacking up in the message queue; when the loop becomes "unblocked", you'll see a burst of Pulse() invocations.


Quit()  see Run()


QuitRequested()

virtual bool QuitRequested(void)

Hook function that's invoked when the app receives a B_QUIT_REQUESTED message. As described in the BLooper class (which declares this function), the request to quit is confirmed if QuitRequested() returns true, and denied if it returns false.

In its implementation, BApplication sends BWindow::QuitRequested() to each of its BWindow objects. If they all agree to quit, the windows are all destroyed (through BWindow::Quit()) and this QuitRequested() returns true. But if any BWindow refuses to quit, that window and all surviving windows are saved, and this QuitRequested() returns false.

Augment this function as you will, but be sure to call the BApplication version in your implementation.


ReadyToRun()

virtual void ReadyToRun(void)

Hook function that's called when the app receives a B_READY_TO_RUN message. The message is sent automatically during the Run() function, and is sent after the initial B_REFS_RECEIVED and B_ARGV_RECEIVED messages (if any) have been handled. This is the only application message that every running app is guaranteed to receive.

What you do with ReadyToRun() is up to you—if your app hasn't put up a window by the time this function is called, you'll probably want to do it here. The default version of ReadyToRun() is empty.


RefsReceived()

virtual void RefsReceived(BMessage *message)

Hook function that's called when the app receives a B_REFS_RECEIVED message. The message is sent when the user drops a file (or files) on your app's icon, or double clicks a file that's handled by your app. The message can arrive either at launch time, or while your app is already running—use IsLaunching() to tell which.

message contains a single field named "refs" that contains one or more entry_ref (B_REF_TYPE) items—one for each file that was dropped or double-clicked. Do with them what you will; the default implementation is empty. Typically, you would use the refs to create BEntry or BFile objects.


ResolveSpecifier()  see BHandler::ResolveSpecifier()


Run() , Quit()

virtual thread_id Run(void)
virtual void Quit(void)

These functions, inherited from BLooper, are different enough from their parent versions to warrant description.

Run() doesn't spawn a new thread—it runs the message loop in the thread that it's called from, and doesn't return until the message loop stops.

Quit() doesn't kill the looper thread—it tells the thread to finish processing the message queue (disallowing new messages) at which point Run() will be able to return. After so instructing the thread, Quit() returns—it doesn't wait for the message queue to empty.

Also, Quit() doesn't delete the BApplication object. It's up to you to delete it after Run() returns. (However, Quit() does delete the object if it's called before the message loop starts—i.e. before Run() is called.)


SetCursor() , HideCursor() , ShowCursor() , ObscureCursor() , IsCursorHidden()

void SetCursor(const void *cursor)
void SetCursor(const BCursor *cursor, bool sync = true)
void HideCursor(void)
void ShowCursor(void)
void ObscureCursor(void)
bool IsCursorHidden(void) const

SetCursor() sets the cursor image that's used when this is the active application. You can pass one of the Be-defined cursor constants (B_HAND_CURSOR and B_I_BEAM_CURSOR) or create your own cursor image. The cursor data format is described below.

You can also call SetCursor() passing a BCursor object; specifying sync as true forces the Application Server to immediately resynchronize, thereby ensuring that the cursor change takes place immediately. The default BCursors are B_CURSOR_SYSTEM_DEFAULT for the hand cursor and B_CURSOR_I_BEAM for the I-beam text editing cursor.

HideCursor() removes the cursor from the screen.

ShowCursor() restores it.

ObscureCursor() hides the cursor until the user moves the mouse.

IsCursorHidden() returns true if the cursor is hidden (but not obscured), and false if not.

The cursor data format is described in the "Cursor Data Format" section under BCursor.


ShowCursor()  see SetCursor()


WindowAt() , CountWindows()

BWindow *WindowAt(int32 index) const
int32 CountWindows(void) const

WindowAt() returns the index'th BWindow object in the application's window list. If index is out of range, the function returns NULL.

CountWindows() returns the number of windows in the window list.

The windows list includes all windows explicitly created by the app—whether they're normal, floating, or modal, and whether or not they're actually displayed—but excludes private windows created by Be classes.

The order of windows in the list has no signficance.

Locking the BApplication object doesn't lock the window list. If you need coordinated access to the list, you'll have to provide your own locking mechanism that protects these functions and all BWindow construction and deletion.


Global Variables


be_app

BApplication *be_app;

be_app is the global variable that represents your BApplication object. You can refer to be_app anywhere you need a reference to the BApplication object that you created. If you want to call a function that's declared by your BApplication subclass, you have to cast be_app to your subclass:

((MyApp *)be_app)->MyAppFunction();


be_app_messenger

BMessenger *be_app_messenger;

be_app_messenger is a global BMessenger that targets your be_app object. It's created in the BApplication constructor.


Archived Fields

Field Type code Meaning
"mime_sig" B_STRING_TYPE Application signature.


Scripting Suites and Properties

Suite: "suite/vnd.Be-application"

"Name"

Command Specifier Meaning
B_GET_PROPERTY B_DIRECT_SPECIFIER Gets the name of the application's main thread.


"Window"

Command Specifiers Meaning
B_COUNT_PROPERTIES B_DIRECT_SPECIFIER Returns CountWindows().
Not applicable. B_NAME_SPECIFIER,
B_INDEX_SPECIFIER,
B_REVERSE_INDEX_SPECIFIER
The message is forwarded to the specified BWindow.


The Be Book The Application Kit The Application Kit Index

The Be Book,
...in lovely HTML...
for BeOS Release 5.

Copyright © 2000 Be, Inc. All rights reserved..