1. Trang chủ
  2. » Công Nghệ Thông Tin

Beginning Visual C plus plus phần 7 pot

123 194 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Nội dung

Adding Message Handlers to Update the User Interface To set the check mark correctly for the new menus, you need to add the second kind of message handler, UPDATE_COMMAND_UI (signifying update command user interface), for each of the new menu items. This sort of message handler is specifically aimed at updating the menu item properties before the item is displayed. Go back to viewing the Sketcher.rc file in the Editor window. Right-click the Black item in the Color menu and select Add Event Handler from the pop-up menu. You can then select UPDATE_COMMAND_UI as the message type and CSketcherDoc as the class as shown in Figure 13-10. Figure 13-10 The name for an update function has been generated[md] OnUpdateColorBlack(). Because this seems a reasonable name for the function you want, click the Add and Edit button and have the Event Handler wizard generate it. As well as generating the skeleton function definition in SketcherDoc.cpp, its declara- tion is added to the class definition. An entry for it is also made in the message map that looks like this: ON_UPDATE_COMMAND_UI(ID_COLOR_BLACK, OnUpdateColorBlack) This uses the ON_UPDATE_COMMAND_UI() macro that identifies the function you have just generated as the handler to deal with update messages corresponding to the ID shown. You could now enter the code for the new handler but I’ll let you add command update handlers for each of the menu items for both the Color and Element menus first. Coding a Command Update Handler You can access the code for the OnUpdateColorBlack() handler in the CSketcherDoc class by select- ing the function in Class View. This is the skeleton code for the function: 697 Working with Menus and Toolbars 16_571974 ch13.qxp 1/20/06 11:26 PM Page 697 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com void CSketcherDoc::OnUpdateColorBlack(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here } The argument passed to the handler is a pointer to an object of the CCmdUI class type. This is an MFC class that is only used with update handlers, but it applies to toolbar buttons as well as menu items. The pointer points to an object that identifies the item that originated the update message so you use this to operate on the item to update how it appears before it is displayed. The CCmdUI class has five member functions that act on user interface items. The operations that each of these provides is as follows: Method Description ContinueRouting() Passes the message on to the next priority handler. Enable() Enables or disables the relevant interface item. SetCheck() Sets a check mark for the relevant interface item. SetRadio() Sets a button in a radio group on or off. SetText() Sets the text for the relevant interface item. We’ll use the third function, SetCheck(), as that seems to do what we want. The function is declared in the CCmdUI class as: virtual void SetCheck(int nCheck = 1); This function sets a menu item as checked if you pass 1 as the argument and set it unchecked if you pass 0 as the argument. The parameter has a default value of 1, so if you just want to set a check mark for a menu item regardless, you can call this function without specifying an argument. In our case, you want to set a menu item as checked if it corresponds with the current color. You can, therefore, write the update handler for OnUpdateColorBlack() as: void CSketcherDoc::OnUpdateColorBlack(CCmdUI* pCmdUI) { // Set menu item Checked if the current color is black pCmdUI->SetCheck(m_Color==BLACK); } The statement you have added calls the SetCheck() function for the Color > Black menu item, and the argument expression m_Color==BLACK results in 1 if m_Color is BLACK, or 0 otherwise. The effect, therefore, is to check the menu item only if the current color stored in m_Color is BLACK, which is pre- cisely what you want. The update handlers for all the menu items in a menu are always called before the menu is displayed so you can code the other handlers in the same way to ensure that only the item corresponding to the cur- rent color (or the current element) is checked: 698 Chapter 13 16_571974 ch13.qxp 1/20/06 11:26 PM Page 698 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 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 appli- cation 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 Working with Menus and Toolbars 16_571974 ch13.qxp 1/20/06 11:26 PM Page 699 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 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 pro- gram 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 Chapter 13 16_571974 ch13.qxp 1/20/06 11:26 PM Page 700 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com A toolbar button is a 16x15 array of pixels that contains a pictorial representation of the function it oper- ates. 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 corre- sponding to the equivalent menu item that you defined earlier. 701 Working with Menus and Toolbars 16_571974 ch13.qxp 1/20/06 11:26 PM Page 701 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 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 Chapter 13 16_571974 ch13.qxp 1/20/06 11:26 PM Page 702 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 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 substi- tute 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 Working with Menus and Toolbars 16_571974 ch13.qxp 1/20/06 11:26 PM Page 703 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 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 sav- ing 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. Summary 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 win- dow 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 Chapter 13 16_571974 ch13.qxp 1/20/06 11:26 PM Page 704 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 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 exer- cises 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 Working with Menus and Toolbars 16_571974 ch13.qxp 1/20/06 11:26 PM Page 705 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 16_571974 ch13.qxp 1/20/06 11:26 PM Page 706 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com [...]... CSketcherView::OnDraw(CDC* pDC) { CSketcherDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(!pDoc) return; pDC->Arc(50,50,150,150,100,50,150,100); // Draw the 1st (large) circle // Define the bounding rectangle for the 2nd (smaller) circle CRect* pRect = new CRect(250,50,300,100); CPoint Start( 275 ,100); // Arc start point CPoint End(250 ,75 ); // Arc end point pDC->Arc(pRect,Start, End); // Draw the second... be using objects of CClientDC because it is derived from CDC and contains all the members we will discuss at this point The advantage that CClientDC has over CDC is that it always contains a device context that represents only the client area of a window, and this is precisely what you want in most circumstances Displaying Graphics In a device context, you draw entities such as lines, circles, and text... rectangle for the 2nd circle CRect* pRect = new CRect(250,50,300,100); CPoint Start( 275 ,100); // Arc start point CPoint End(250 ,75 ); // Arc end point pDC->Arc(pRect,Start, End); // Draw the second circle delete pRect; pDC->SelectObject(pOldPen); // Restore the old pen } If you build and execute the Sketcher application with this version of the OnDraw() function, you get the same arcs drawn as before,... discussed virtual functions All you need to do to achieve this is to make sure that the classes defining specific elements share a common base class and that in this class you declare all the functions you want to be selected automatically at run time as virtual This indicates that the element classes could be organized could be as shown in Figure 14-13 CObject CElement CLine CRectangle CCircle CCurve... into actions on the particular physical output device being used A pointer to a device context is obtained by calling a Windows API function A device context provides you with a choice of coordinate systems called mapping modes, which is automatically converted to client coordinates You can also alter many of the parameters that affect the output to a device context by calling GDI functions; such parameters... you can select the old object back to restore it This is because the SelectObject() function you use to do this is overloaded for each of the kinds of object that can be selected There’s no version of SelectObject() that accepts a pointer to a CGdiObject as an argument, but there are versions that accept an argument of type CBrush*, CPen*, and pointers to other GDI objects The typical pattern of coding... do this All closed curves that you draw are filled with the current brush in the device context As mentioned earlier, you can define a brush as an instance of the class CBrush Take a look at some of the features of CPen and CBrush objects 71 7 Chapter 14 Creating a Pen The simplest way to create a pen object is first to declare an object of the CPen class: // Declare a pen object Simpo PDF CPen aPen;... drawn counterclockwise If you make (x4,y4) identical to (x3,y3), you’ll generate a complete, apparently closed curve In the second version of Arc(),the enclosing rectangle is defined by a RECT object, and a pointer to this object is passed as the first argument The function also accepts a pointer to an object of the class CRect, which has four public data members: left, top, right, and bottom These correspond... you can use the pointer Because you’ll put all the code to draw the document in this function, the Application wizard has included a declaration for the pointer pDoc and initialized it using the function GetDocument(), which returns the address of the document object related to the current view: CSketcherDoc* pDoc = GetDocument(); The GetDocument() function actually retrieves the pointer to the document... current position set by the MoveTo() function; the succeeding calls use the current position set by the previous LineTo() function call You can use this to draw any figure consisting of a sequence of lines, each connected to the previous line Of course, you are also free to use MoveTo() to change the current position at any time Drawing Circles You have a choice of several function members in the CDC . http://www.simpopdf.com void CSketcherDoc::OnUpdateColorBlue(CCmdUI* pCmdUI) { // Set menu item Checked if the current color is blue pCmdUI->SetCheck(m_Color==BLUE); } void CSketcherDoc::OnUpdateColorGreen(CCmdUI*. 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. 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

Ngày đăng: 12/08/2014, 10:21

TỪ KHÓA LIÊN QUAN