[Contents] [Prev] [Next]

Step 10: Adding decorations

The only changes in Step 10 are in the InitMainWindow function. But these changes let you make your application more attractive and easier and more intuitive to use. In this step, you'll add a control bar with bitmap button gadgets and a status bar that displays the current menu choice. You can find the source for Step 10 in the files STEP10.CPP and STEP10.RC in the directory EXAMPLES\OWL\TUTORIAL.

There are four main changes in this step:

Changing the main window

Changing from a TFrameWindow to a TDecoratedFrame is quite easy. Because TDecoratedFrame is based on TFrameWindow, a decorated frame can be used just about anywhere that a regular frame window is used. In this case, just create a TDecoratedFrame and pass it as the parameter to the SetMainWindow function.

Even the constructors of the TFrameWindow and TDecoratedFrame are alike. The only difference is the fourth parameter, which wasn't being used anyway. The fourth parameter for TFrameWindow is a bool that tells the frame window whether it should shrink to the size of its client window.

The fourth parameter for TDecoratedFrame is also a bool. This parameter indicates whether the decorated frame should track menu selections. Menu tracking displays a text description of the currently selected menu choice or button in a message bar or status bar. If you specify true for this parameter, you must supply a message or status bar for the window. If you don't, your application will crash the first time it tries to send a message to the message or status bar.

If you're using a status bar, you must include the resources for it in your resource file. These resources are contained in the file STATUSBA.RC in the INCLUDE\OWL directory.

The only other difference is that the decorated frame requires some preparation, such as adding decorations like the control bar and status bar, before it can become the main window. So instead of constructing and setting the window in one step, you must construct the window, prepare it, then set it as the main window.

Creating the status bar

Status bars are created using the TStatusBar class. TStatusBar is based on the TMessageBar class, which is itself based on TGadgetWindow. Both message bars and status bars display text messages. But status bars have more options than message bars. For example, you can have multiple text gadgets, styled borders, and mode indicators (such as Insert or Overwrite mode) in a status bar.

The TStatusBar constructor takes five parameters, although you only use the first two. The rest of the parameters take on their default values:

Here is the status bar constructor:

TStatusBar* sb = new TStatusBar(frame, TGadget::Recessed);

Once the status bar is created, it is ready to be inserted into the decorated frame. This is described below.

Creating the control bar

Creating the control bar is more involved than creating the status bar. You first construct the actual TControlBar object. Then you create the gadgets that make up the controls on the bar and insert them into the control bar.

Constructing TControlBar

The TControlBar constructor takes four parameters, although you need to use only the first parameter here. The rest of the parameters take on their default values:

Here is the control bar constructor:

TControlBar *cb = new TControlBar(frame);

Building button gadgets

Button gadgets are used as control bar buttons. They associate a bitmap button with an event identifier. When the user presses a button gadget, it sends that event identifier. You can set this up so that pressing a button on the control is just like making a choice from a menu. In this section, you'll see how to set up buttons to replicate each of your current menu choices.

Button gadgets are created using the TButtonGadget class. The TButtonGadget constructor takes six parameters, of which you need to use only the first three:

Separator gadgets

There is another type of gadget commonly used when constructing control bars, called a separator gadget. Normally gadgets in a control bar are right next to each other. A separator gadget provides a little bit of space between two gadgets. This lets you separate gadgets into groups, place them in predetermined spots on the control bar, and so on.

Separator gadgets are contained in the TSeparatorGadget class. This is a simple class that takes a single int parameter. By default the value of this parameter is 6. This parameter indicates the number of pixels of space the separator gadget should take up.

Inserting gadgets into the control bar

Once your gadgets are constructed, you need to insert them into the control bar. The control bar can take gadgets because it is derived from the class TGadgetWindow. TGadgetWindow provides the basic functionality that lets you use gadgets in a window. TControlBar refines that functionality, producing a control bar.

You can insert gadgets into the control bar using the Insert function. This version of the Insert function is inherited by TControlBar from TGadgetWindow (later you'll use another version of this function contained in TDecoratedFrame). This function takes three parameters, although you need to use only the first parameter in the tutorial application:

In the tutorial application, constructing the gadgets and inserting them into the control bar is accomplished in a single step. Here is the code where the gadgets are inserted into the control bar:

cb->Insert(*new TButtonGadget(CM_FILENEW, CM_FILENEW,
cb->Insert(*new TButtonGadget(CM_FILEOPEN, CM_FILEOPEN,
cb->Insert(*new TButtonGadget(CM_FILESAVE, CM_FILESAVE,
cb->Insert(*new TButtonGadget(CM_FILESAVEAS, CM_FILESAVEAS,
cb->Insert(*new TSeparatorGadget);
cb->Insert(*new TButtonGadget(CM_PENSIZE, CM_PENSIZE,
cb->Insert(*new TSeparatorGadget);
cb->Insert(*new TButtonGadget(CM_ABOUT, CM_ABOUT,
Notice that the button gadgets replicate the menu commands you already have. This provides an easy way for the user to access frequently used menu commands. Of course, you aren't restricted to using gadgets in a control bar as substitutes or shortcuts for menu commands. Using the TType parameter, you can set up gadgets on a control bar to work like radio buttons (by using Exclusive with a group of gadgets), check boxes (using NonExclusive), and so on.

Inserting objects into a decorated frame

Now that you've constructed the decorations for your TDecoratedFrame window, all you need to do is insert the decorations into the window and make the window the main window.

Inserting decorations into a decorated frame is similar to inserting gadgets into a control bar. The TDecoratedFrame::Insert function takes two parameters:

Here is the code for inserting the decorations into the decorated frame:

// Insert the status bar and control bar into the frame
frame->Insert(*sb, TDecoratedFrame::Bottom);
frame->Insert(*cb, TDecoratedFrame::Top);

Once you've inserted the decorations into the frame, the last thing you have to do is set the main window to frame and set up the menu:

// Set the main window and its menu

Where to find more information

Here's a guide to where you can find more information on the topics introduced in this step:

[Contents] [Prev] [Next]