Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Visual C++ 2005 (2006) [eng]-1

.pdf
Скачиваний:
108
Добавлен:
16.08.2013
Размер:
18.66 Mб
Скачать

Working with Menus and Toolbars

void CSketcherDoc::OnUpdateColorBlue(CCmdUI* pCmdUI)

{

// Set menu item Checked if the current color is blue

pCmdUI->SetCheck(m_Color==BLUE);

}

void CSketcherDoc::OnUpdateColorGreen(CCmdUI* pCmdUI)

{

// Set menu item Checked if the current color is green

pCmdUI->SetCheck(m_Color==GREEN);

}

void CSketcherDoc::OnUpdateColorRed(CCmdUI* pCmdUI)

{

// Set menu item Checked if the current color is red

pCmdUI->SetCheck(m_Color==RED);

}

A typical Element menu item update handler is coded as:

void CSketcherDoc::OnUpdateElementLine(CCmdUI* pCmdUI)

{

// Set Checked if the current element is a circle

pCmdUI->SetCheck(m_Element==LINE);

}

You can now code all the other update handlers in a similar manner:

void CSketcherDoc::OnUpdateElementCurve(CCmdUI* pCmdUI)

{

// Set Checked if the current element is a curve

pCmdUI->SetCheck(m_Element==CURVE);

}

void CSketcherDoc::OnUpdateElementCircle(CCmdUI *pCmdUI)

{

// Set Checked if the current element is a circle

pCmdUI->SetCheck(m_Element==CIRCLE);

}

void CSketcherDoc::OnUpdateElementRectangle(CCmdUI* pCmdUI)

{

// Set Checked if the current element is a rectangle

pCmdUI->SetCheck(m_Element==RECTANGLE);

}

After you get the idea, it’s easy, isn’t it?

Exercising the Update Handlers

When you’ve added the code for all the update handlers, you can build and execute the Sketcher application again. Now, when you change a color or an element type selection, this is reflected in the menu, as shown in Figure 13-11.

699

Chapter 13

Figure 13-11

You have completed all the code that you need for the menu items. Make sure that you have saved everything before embarking on the next stage. These days, toolbars are a must in any Windows program of consequence, so the next step is to take a look at how you can add toolbar buttons to support our new menus.

Adding Toolbar Buttons

Select the Resource View and extend the toolbar resource. You’ll see that it has the same ID as the main menu, IDR_MAINFRAME. If you double-click this ID, the Editor window appears as shown in Figure 13-12.

Figure 13-12

700

Working with Menus and Toolbars

A toolbar button is a 16x15 array of pixels that contains a pictorial representation of the function it operates. You can see in Figure 13-12 that the resource editor provides an enlarged view of a toolbar button so that you can see and manipulate individual pixels. If you click the new button at the right end of the row as indicated, you’ll be able to draw this button. Before starting the editing, drag the new button about half a button width to the right. It separates from its neighbor on the left to start a new block.

You should keep the toolbar button blocks in the same sequence as the items on the menu bar, so you’ll create the element type selection buttons first. You’ll be using the following editing buttons provided by the resource editor that appear in the toolbar for the Visual C++ 2005 application window.

Pencil for drawing individual pixels

Eraser for erasing individual pixels

Fill an area with the current color

Zoom the view of the button

Draw a rectangle

Draw an ellipse

Draw a curve

If it is not already visible, you can display the window for selecting a color by right-clicking a toolbar button and selecting Show Colors Window from the pop-up. Make sure that the black color is selected and use the pencil tool to draw a diagonal line in the enlarged image of the new toolbar button. In fact, if you want it a bit bigger, you can use the Magnification Tool editing button to enlarge it up to eight times its actual size. If you make a mistake, you can change to the Erase Tool editing button, but you need to make sure that the color selected corresponds to the background color for the button you are editing. You can also erase individual pixels by clicking them using the right mouse button, but again you need to be sure that the background color is set correctly when you do this. To set the background color, just click the appropriate color using the right mouse button. After you’re happy with what you’ve drawn, the next step is to edit the toolbar button properties.

Editing Toolbar Button Properties

Double-click your new button in the toolbar to bring up its properties window, as shown in Figure 13-13.

The properties box shows a default ID for the button, but you want to associate the button with the menu item Element > Line that we’ve already defined, so click ID and then click the down arrow to display alternative values. You can then select ID_ELEMENT_LINE from the drop-down box. If you click on Prompt you’ll find that this also causes the same prompt to appear in the status bar because the prompt is recorded along with the ID. You can close the Properties window to complete the button definition.

You can now move on to designing the other three element buttons. You can use the rectangle editing button to draw a rectangle and the ellipse button to draw a circle. You can draw a curve using the pencil to set individual pixels, or use the curve button. You need to associate each button with the ID corresponding to the equivalent menu item that you defined earlier.

701

Chapter 13

Figure 13-13

Now add the buttons for the colors. You should also drag the first button for selecting a color to the right so that it starts a new group of buttons. You could keep the color buttons very simple and just color the whole button with the color it selects. You can do this by selecting the appropriate foreground color, then selecting the “fill” editing button and clicking on the enlarged button image. Again you need to use ID_COLOR_BLACK, ID_COLOR_RED, and so on, as IDs for the buttons. The toolbar editing window should look like the one shown in Figure 13-14.

Figure 13-14

That’s all you need for the moment, so save the resource file and give Sketcher another spin.

702

Working with Menus and Toolbars

Exercising the Toolbar Buttons

Build the application once again and execute it. You should see the application window shown in Figure 13-15.

Figure 13-15

There are some amazing things happening here. The toolbar buttons that you added already reflect the default settings that you defined for the new menu items. If you let the cursor linger over one of the new buttons, the prompt for the button appears in the status bar. The new buttons work as a complete substitute for the menu items and any new selection made, using either the menu or the toolbar, is reflected by showing the toolbar button depressed, as well as the check against the menu item.

If you close the document view window, Sketcher1, you’ll see that our toolbar buttons are automatically grayed and disabled. If you open a new document window, they are automatically enabled once again. You can also try dragging the toolbar with the cursor. You can move it to either side of the application window, or have it free-floating. You can also enable or disable it through the View > Toolbar menu option. You got all this without writing a single additional line of code!

Adding Tooltips

There’s one further tweak that you can add to your toolbar buttons that is remarkably easy: adding tooltips. A tooltip is a small box that appears adjacent to the toolbar button when you let the cursor linger on the button. The tooltip contains a text string that is an additional clue as to the purpose of the toolbar button.

To add tooltips, select the Resource View tab and, after expanding the resource list, click the String Table folder and double-click the resource. This contains the IDs and prompt strings associated with menu items and toolbar buttons. You should see the IDs for the menus that you added earlier together with the prompt text for each under the caption heading. To add a tooltip, you just need to add \n (the newline character), followed by the tooltip text to the end of the caption text. For the prompt text you have already entered you can double-click text to enable editing of it and then add \n to the end of the prompt text in the caption

703

Chapter 13

column, so you could change the existing caption for the ID_ELEMENT_LINE ID from Line to Line\ nSets line drawing mode, for example. Thus the caption text has two parts separated by \n, the first part being the prompt that appears in the status bar and the second is the tooltip text.

Add \n followed by a tooltip to the caption text for each of the IDs for the menu items in the Element and Color menus — not forgetting to start each tooltip text with \n. That’s all you have to do. After saving the String Table resource, you can now rebuild the application and execute it. Placing the cursor over one of the new toolbar buttons causes the tooltip to be displayed after a second or two.

Summar y

In this chapter, you learned how MFC connects a message with a class member function to process it, and you wrote your first message handlers. Much of the work in writing a Windows program is writing message handlers, so it’s important to have a good grasp of what happens in the process. When we get to consider other message handlers, you’ll see that the process for adding them is just the same.

You have also extended the standard menu and the toolbar in the MFC Application wizard-generated program, which provides a good base for the application code that we add in the next chapter. Although there’s no functionality under the covers yet, the menu and toolbar operation looks very professional, courtesy of the Appwizard-generated framework and the Event Handler wizard.

The important points that you’ve seen in this chapter are:

MFC defines the message handlers for a class in a message map that appears in the .cpp file for the class.

Command messages that arise from menus and toolbars can be handled in any class that’s derived from CCmdTarget. These include the application class, the frame and child frame window classes, the document class, and the view class.

Messages other than command messages can only be handled in a class derived from CWnd. This includes frame window and view classes, but not application or document classes.

MFC has a predefined sequence for searching the classes in your program to find a message handler for a command message.

You should always use the Event Handler wizard to add message handlers to your program.

The physical appearances of menus and toolbars are defined in resource files, which are edited by the built-in resource editor.

Items in a menu that can result in command messages are identified by a symbolic constant with the prefix ID. These IDs are used to associate a handler with the message from the menu item.

To associate a toolbar button with a particular menu item, you give it the same ID as that of the menu item.

To add a tooltip for a toolbar button corresponding to a menu item, you add the tooltip text to the entry for the ID for the menu item in the caption column in the String Table resource. The tooltip text is separated from the menu prompt text by \n.

704

Working with Menus and Toolbars

In the next chapter, you’ll add the code necessary to draw elements in a view, and use the menus and toolbar buttons that you created here to select what to draw and in which color. This is where the Sketcher program begins to live up to its name.

Exercises

You can download the source code for the examples in the book and the solutions to the following exercises from http://www.wrox.com.

1.Add a menu item Ellipse to the Element pop-up.

2.Implement the command and command update handlers for it in the document class.

3.Add a toolbar button corresponding to the Ellipse menu item and add a tooltip for the button.

4.Modify the command update handlers for the color menu items so that the currently selected item is displayed in uppercase, and the others are displayed in lowercase.

705

14

Drawing in a Window

In this chapter, you will add some meat to the Sketcher application. You’ll focus on understanding how you get graphical output displayed in the application window. By the end of this chapter, you’ll be able to draw all but one of the elements for which you have added menu items. I’ll leave the problem of how to store them in a document until the next chapter. In this chapter, you will learn about:

What coordinate systems Windows provides for drawing in a window

Device context and why it is necessary

How and when your program draws in a window

How to define handlers for mouse messages

How to define your own shape classes

How to program the mouse to draw your shapes in a window

How to get your program to capture the mouse

Basics of Drawing in a Window

Before I go into drawing using MFC, it will be useful to get a better idea of what is happening under the covers of the Windows operating system when you are drawing in a window. Similar to any other operation under Windows, writing to a window on your display screen is achieved through using Windows API functions. There’s slightly more to it than that though; the way Windows works complicates the situation somewhat.

For a start, you can’t just write to a window and forget it. There are many events that require that your application to redraw the window — such as if the user resizes the window that you’re drawing in, for instance or if part of your window that was previously hidden is exposed by the user moving another window.

Chapter 14

Fortunately, you don’t need to worry about the details of such occurrences, because Windows actually manages all these events for you; however, it does mean that you can only write permanent data to a window when your application receives a specific Windows message requesting that you do so. It also means that you need to be able to reconstruct everything that you’ve drawn in the window at any time.

When all, or part, of a window needs to be redrawn, Windows sends a WM_PAINT message to your application. This is intercepted by MFC that passes the message to a function member of one of your classes. I’ll explain how you handle this a little later in this chapter.

The Window Client Area

A window doesn’t have a fixed position onscreen, or even a fixed visible area, because a window can be dragged around using the mouse and resized by dragging its borders. How, then, do you know where to draw onscreen?

Fortunately, you don’t. Because Windows provides you with a consistent way of drawing in a window, you don’t have to worry about where it is onscreen; otherwise, drawing in a window would be inordinately complicated. Windows does this by maintaining a coordinate system for the client area of a window that is local to the window. It always uses the upper-left corner of the client area as its reference point. All points within the client area are defined relative to this point, as shown in Figure 14-1.

This is the reference point for this window’s client areas.

This location of point is defined by the distances x and y.

y

x

Figure 14-1

The horizontal and vertical distances of a point from the upper-left corner of the client area will always be the same, regardless of where the window is onscreen or how big it is. Of course, Windows needs to keep track of where the window is, and when you draw something at a point in the client area, it needs to figure out where that actually is onscreen.

708