Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 80 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
80
Dung lượng
760,94 KB
Nội dung
Creating Single Document Interface Applications 221 10 LISTING 10.18. THE MODIFIED OnNewDocument FUNCTION. 1: BOOL CDay10Doc::OnNewDocument() 2: { 3: if (!CDocument::OnNewDocument()) 4: return FALSE; 5: 6: // TODO: add reinitialization code here 7: // (SDI documents will reuse this document) 8: 9: /////////////////////// 10: // MY CODE STARTS HERE 11: /////////////////////// 12: 13: // Initialize the color to black 14: m_nColor = ID_COLOR_BLACK - ID_COLOR_BLACK; 15: 16: /////////////////////// 17: // MY CODE ENDS HERE 18: /////////////////////// 19: 20: return TRUE; 21: } 7. Scroll down to the AddLine function, and modify it as in Listing 10.19. LISTING 10.19. THE MODIFIED AddLine FUNCTION. 1: CLine * CDay10Doc::AddLine(CPoint ptFrom, CPoint ptTo) 2: { 3: // Create a new CLine object 4: CLine *pLine = new CLine(ptFrom, ptTo, m_crColors[m_nColor]); 5: try 6: { 7: // Add the new line to the object array 8: m_oaLines.Add(pLine); 9: // Mark the document as dirty 10: SetModifiedFlag(); 11: } 12: // Did we run into a memory exception? 13: catch (CMemoryException* perr) 14: { 15: // Display a message for the user, giving him or her the 16: // bad news 17: AfxMessageBox(“Out of memory”, MB_ICONSTOP | MB_OK); 18: // Did we create a line object? 19: if (pLine) continues 014 31240-9 CH10 4/27/00 12:19 PM Page 221 LISTING 10.19. CONTINUED 20: { 21: // Delete it 22: delete pLine; 23: pLine = NULL; 24: } 25: // Delete the exception object 26: perr->Delete(); 27: } 28: return pLine; 29: } 8. Add a new member function to the CDay10Doc class. Specify the function type as UINT, the declaration as GetColor, and the access as public. 9. Edit the GetColor function, adding the code in Listing 10.20. LISTING 10.20. THE GetColor FUNCTION. 1: UINT CDay10Doc::GetColor() 2: { 3: // Return the current color 4: return ID_COLOR_BLACK + m_nColor; 5: } In the OnNewDocument and the GetColor functions, the color is added and subtracted from ID_COLOR_BLACK. This is the lowest numbered color menu ID when you add the menu entries. These calculations maintain the variable as a number between 0 and 7, but when working with the menus, they allow comparison with the actual menu IDs. Modifying the Menu Now comes the fun part. You need to add a new pull-down menu to the main menu. You need to add menu entries for all the colors in the color table. You need to add message handlers for all the color menu entries. Finally, you need to add event handlers to check the menu entry that is the current color. To do all of this, follow these steps: 1. Select the Resource View tab in the workspace pane. Expand the tree so that you can see the contents of the Menu folder. Double-click the menu resource. 2. Grab the blank top-level menu (at the right end of the menu bar) and drag it to the left, dropping it in front of the View menu entry. 3. Open the properties for the blank menu entry. Specify the caption as &Color. Close the properties dialog. 222 Day 10 014 31240-9 CH10 4/27/00 12:19 PM Page 222 Creating Single Document Interface Applications 223 10 4. Add submenu entries below the Color top-level menu. Specify the submenus in order, setting their properties as specified in Table 10.2. You should wind up with a menu looking like Figure 10.7. TABLE 10.2. MENU PROPERTY SETTINGS. Object Property Setting Menu Entry ID ID_COLOR_BLACK Caption &Black Menu Entry ID ID_COLOR_BLUE Caption B&lue Menu Entry ID ID_COLOR_GREEN Caption &Green Menu Entry ID ID_COLOR_CYAN Caption &Cyan Menu Entry ID ID_COLOR_RED Caption &Red Menu Entry ID ID_COLOR_MAGENTA Caption &Magenta Menu Entry ID ID_COLOR_YELLOW Caption &Yellow Menu Entry ID ID_COLOR_WHITE Caption &White 5. Open the Class Wizard. Select the CDay10Doc in the Class Name combo box. 6. Add functions for both the COMMAND and UPDATE_COMMAND_UI event messages for all the color menu entries. 7. After the final menu entry function has been added, click Edit Code. 8. Edit the Black menu functions as in Listing 10.21. FIGURE 10.7. The Color menu as designed. 014 31240-9 CH10 4/27/00 12:19 PM Page 223 LISTING 10.21. THE BLACK MENU FUNCTIONS. 1: void CDay10Doc::OnColorBlack() 2: { 3: // TODO: Add your command handler code here 4: 5: /////////////////////// 6: // MY CODE STARTS HERE 7: /////////////////////// 8: 9: // Set the current color to black 10: m_nColor = ID_COLOR_BLACK - ID_COLOR_BLACK; 11: 12: /////////////////////// 13: // MY CODE ENDS HERE 14: /////////////////////// 15: } 16: 17: void CDay10Doc::OnUpdateColorBlack(CCmdUI* pCmdUI) 18: { 19: // TODO: Add your command update UI handler code here 20: 21: /////////////////////// 22: // MY CODE STARTS HERE 23: /////////////////////// 24: 25: // Determine if the Black menu entry should be checked 26: pCmdUI->SetCheck(GetColor() == ID_COLOR_BLACK ? 1 : 0); 27: 28: /////////////////////// 29: // MY CODE ENDS HERE 30: /////////////////////// 31: } 9. Edit the Blue menu functions as in Listing 10.22. Edit the remaining menu func- tions in the same way, substituting their menu IDs for ID_COLOR_BLUE. LISTING 10.22. THE BLUE MENU FUNCTIONS. 1: void CDay10Doc::OnColorBlue() 2: { 3: // TODO: Add your command handler code here 4: 5: /////////////////////// 6: // MY CODE STARTS HERE 7: /////////////////////// 8: 9: // Set the current color to blue 224 Day 10 014 31240-9 CH10 4/27/00 12:19 PM Page 224 Creating Single Document Interface Applications 225 10 10: m_nColor = ID_COLOR_BLUE - ID_COLOR_BLACK; 11: 12: /////////////////////// 13: // MY CODE ENDS HERE 14: /////////////////////// 15: } 16: 17: void CDay10Doc::OnUpdateColorBlue(CCmdUI* pCmdUI) 18: { 19: // TODO: Add your command update UI handler code here 20: 21: /////////////////////// 22: // MY CODE STARTS HERE 23: /////////////////////// 24: 25: // Determine if the Blue menu entry should be checked 26: pCmdUI->SetCheck(GetColor() == ID_COLOR_BLUE ? 1 : 0); 27: 28: /////////////////////// 29: // MY CODE ENDS HERE 30: /////////////////////// 31: } In the first of the two menu functions, the COMMAND function, the current color variable is set to the new color. If you add the menu entries in the correct order, their ID numbers are sequential, starting with ID_COLOR_BLACK. Subtracting ID_COLOR_BLACK from the menu ID should always result in the correct position in the color table for the selected color. For example, the Black color is position 0 in the color table. ID_COLOR_BLACK − ID_COLOR_BLACK = 0. Blue is position 1 in the color table. Because ID_COLOR_BLUE should be one greater than ID_COLOR_BLACK, ID_COLOR_BLUE — ID_COLOR_BLACK = 1. The second function, the UPDATE_COMMAND_UI function, may need a little explaining. The UPDATE_COMMAND_UI event is called for each menu entry just before it is displayed. You can use this event message function to check or uncheck the menu entry, based on whether it is the current color. You can also use this event to enable or disable menu entries or make other modifications as necessary. The code in this function pCmdUI->SetCheck(GetColor() == ID_COLOR_BLUE ? 1 : 0); does several things. First, the pCmdUI object that is passed in as the only argument is a pointer to a menu object. The SetCheck function can check or uncheck the menu entry, depending on whether the argument passed is 1 or 0 (1 checks, 0 unchecks). The argu- ment portion for the SetCheck function is a flow-control construct that can be somewhat 014 31240-9 CH10 4/27/00 12:19 PM Page 225 confusing if you haven’t spent a large amount of time programming in C/C++. The first half GetColor() == ID_COLOR_BLUE is a simple boolean conditional statement. It results in a true or false result. The portion following this conditional statement ? 1 : 0 is basically an if else statement in shorthand. If the conditional statement is true, then the value is 1, and if the statement is false, the value is 0. This is a fancy way of placing an if else flow control within the argument to another function. If you compile and run your application, you should be able to change the color that you are drawing with. When you pull down the color menu, you should see the current draw- ing color checked on the menu, as in Figure 10.8. Summary Whew! What a day! You learned quite a bit today because this was a packed chapter. You initially learned about the SDI style application and about a couple of standard applications that you have probably used that are SDI applications. You next learned about the Document/View architecture that Visual C++ uses for SDI applications. You learned to create a simple class of your own for use in your drawing application. You created a drawing application that can maintain the images drawn using it. You learned how you can save and restore documents in the Document/View architecture. You also learned about the CObArray object array class and how you can use it to create a dynamic object array for storing various classes. Finally, you learned how you can check and uncheck menu entries in MFC applications. 226 Day 10 FIGURE 10.8. Specifying the current color on the menu. 014 31240-9 CH10 4/27/00 12:19 PM Page 226 Creating Single Document Interface Applications 227 10 Q&A Q Is there any way that you can reduce the number of COMMAND and UPDATE_ COMMAND_UI functions for the menus? A Yes, you can send all the color COMMAND events to the same function. From there, you can examine the nID value (which is passed as an argument) and compare it to the menu IDs to determine which menu is calling the function. As a result, you can write the COMMAND function for the color menus as follows: void CDay10Doc::OnColorCommand(UINT nID) { // TODO: Add your command handler code here /////////////////////// // MY CODE STARTS HERE /////////////////////// // Set the current color to blue m_nColor = nID - ID_COLOR_BLACK; /////////////////////// // MY CODE ENDS HERE /////////////////////// } For the UPDATE_COMMAND_UI functions, you can do the same thing, only slightly differently. In this case, you can examine the pCmdUI->m_nID value to determine which menu the function is being called for. This makes the UPDATE_COMMAND_UI function look like the following: void CDay10Doc::OnUpdateColor(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here /////////////////////// // MY CODE STARTS HERE /////////////////////// // Determine if the Blue menu entry should be checked pCmdUI->SetCheck(GetColor() == pCmdUI->m_nID ? 1 : 0); /////////////////////// // MY CODE ENDS HERE /////////////////////// } 014 31240-9 CH10 4/27/00 12:19 PM Page 227 Q What’s the difference between SDI and MDI applications? A Although SDI applications can perform only one task, MDI (Multiple Document Interface) applications can have multiple documents open at the same time. Plus, in an MDI application, not all document types need be the same. You’ll learn more about MDI applications tomorrow. Workshop The Workshop provides quiz questions to help you solidify your understanding of the material covered and exercises to provide you with experience in using what you’ve learned. The answers to the quiz questions and exercises are provided in Appendix B, “Answers.” Quiz 1. What does SDI stand for? 2. What functionality is in the view class? 3. What function is called to redraw the document if the window has been hidden behind another window? 4. Where do you place code to clear out the current document before starting a new document? 5. What is the purpose of the document class? Exercise Add another pull-down menu to control the width of the pen used for drawing. Give it the following settings: Menu Entry Width Setting Very Thin 1 Thin 8 Medium 16 Thick 24 Very Thick 32 228 Day 10 In the pen constructor, the second argument is the width. Tip 014 31240-9 CH10 4/27/00 12:19 PM Page 228 DAY 11 WEEK 2 Creating Multiple Document Interface Applications Today, you will learn how to build Multiple Document Interface (MDI) appli- cations using Visual C++. You will be able to build applications that allow users to work on multiple documents at one time, switching between the win- dows of the application to do their work. In this chapter, you will learn • The difference between SDI and MDI applications. • How to create an MDI application. • How to send multiple menu entries to a single event-handling function. • How to add a context menu to a Document/View style application. What Is an MDI Application? As far as coding an MDI application with Visual C++, there’s little difference between creating an SDI and an MDI application. However, when you get 015 31240-9 CH11 4/27/00 12:28 PM Page 229 deeper into the two application styles, you’ll find quite a few differences. Although an SDI application allows the user to work on only one document at a time, it also normally limits the user to working on a specific type of document. MDI applications not only enable the user to work on multiple documents at the same time, but also MDI applica- tions can allow the user to work on multiple types of documents. An MDI application uses a window-in-a-window style, where there is a frame window around one or more child windows. This is a common application style with many popu- lar software packages, including Word and Excel. Architecturally, an MDI application is similar to an SDI application. In fact, with a sim- ple MDI application, the only difference is the addition of a second frame class to the other classes that the AppWizard creates, as shown in Figure 11.1. As you can see, the Document/View architecture is still very much the approach you use for developing MDI applications as well as SDI applications. When you create an MDI application, you will create just one more class than you created with an SDI application. The classes are • The CWinApp derived class • The CMDIFrameWnd derived class • The CMDIChildWnd derived class • The CDocument derived class • The CView derived class Document object (CDocument) Messages passed to the frame window and view object Two-way flow of information between the document and the view objects Application object (CWinApp) Main Frame window (CMainFrame) Child Frame window View object (CView) (CChildView) 230 Day 11 FIGURE 11.1. The MDI Document/ View architecture. 015 31240-9 CH11 4/27/00 12:28 PM Page 230 [...]... // Find the Black button on the toolbar 32: iTBCtlID = m_wndColorBar.CommandToIndex(ID_COLOR_BLACK); 33: if (iTBCtlID >= 0) 34: { 0 16 31 240 -9 CH12 4/ 27/00 12:30 PM Page 249 Adding Toolbars and Status Bars 35: 36: 37: 38: 39: 40 : 41 : 42 : 43 : 44 : 45 : 46 : 47 : 48 : 49 : 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60 : 61 : 62 : 63 : 64 : 65 : 66 : 67 : 68 : 69 : 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: } 249 ... the event function? 4 What event message should you use to display a pop-up menu? 015 31 240 -9 CH11 4/ 27/00 12:29 PM Page 241 Creating Multiple Document Interface Applications 241 Exercise Add the pull-down and context menus for the width, using the same pen widths as yesterday 11 015 31 240 -9 CH11 4/ 27/00 12:29 PM Page 242 0 16 31 240 -9 CH12 4/ 27/00 12:29 PM Page 243 WEEK 2 DAY 12 Adding Toolbars and Status... 12 0 16 31 240 -9 CH12 4/ 27/00 12:30 PM 2 46 Page 2 46 Day 12 FIGURE 12.1 The toolbar designer Creating a New Toolbar To insert a new toolbar, right-click on the Toolbar folder and select Insert Toolbar from the pop-up menu This creates an empty toolbar with a single blank button As you start drawing an icon on each of the blank buttons in the toolbar, another blank button is added on the end For use in your... are in common practice with most Windows applications today If you want to design and use your own toolbars and status bars in your applications, you might think that Visual C++ provides plenty of support for your efforts and even makes 0 16 31 240 -9 CH12 4/ 27/00 12:30 PM Page 245 Adding Toolbars and Status Bars 245 it easy to implement After all, Microsoft’s own application developers have been in the... EDIT what you see in these blocks of generated ➥code ! 15: //}}AFX_MSG 16: DECLARE_MESSAGE_MAP() 17: private: 18: UINT m_nColor; 19: CObArray m_oaLines; 20: }; 4 Open the Day11Doc.cpp source-code file 5 Search for the line BEGIN_MESSAGE_MAP and add the lines in Listing 11.2 just after it It’s important that this code be between the BEGIN_MESSAGE_MAP line and the //{{AFX_MSG_MAP line If these commands... frame 0 16 31 240 -9 CH12 4/ 27/00 244 12:29 PM Page 244 Day 12 q How to show and hide your toolbar with a menu entry q How to place a combo box on your toolbar q How to display descriptions of your toolbar entries in the status bar q How to add your own status bar elements Toolbars, Status Bars, and Menus One of the driving intentions behind the development of Graphical User Interfaces (GUI) such as Windows... frame window CBRS_FLOAT_MULTI Allows multiple toolbars to be floated in a single miniframe window 0 The toolbar will not be able to dock with the frame 12 0 16 31 240 -9 CH12 4/ 27/00 12:30 PM Page 2 54 2 54 Day 12 The final function that you added was a frame window function, DockControlBar, which is passed the address of the toolbar variable This function physically docks the toolbar to the frame window... declarations in Listing 11.1 before the line that you searched for (The string that you searched for is the beginning marker for the Class Wizard maintained message map Anything you place between it and the end marker, //}}AFX_MSG, is likely to be removed or corrupted by the Class Wizard.) LISTING 11.1 THE EVENT-HANDLER DECLARATIONS IN Day11Doc.h 1: #ifdef _DEBUG 2: virtual void AssertValid() const; continues... making a small gap between the buttons on either side Docking the Toolbar The last thing that you do in the code that you add to the OnCreate function in the CMainFrame class is the following: // Enable docking for the Color Toolbar m_wndColorBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); // (AppWizard generated line) // Dock the Color Toolbar DockControlBar(&m_wndColorBar); In the... 31 240 -9 CH11 4/ 27/00 12:28 PM Page 233 Creating Multiple Document Interface Applications 233 Adding Menu Handling Functionality Now that you’ve got all the functionality in your application, you would probably like to add the color menu so you can use all those available colors in your drawings When you expand the Resource View tree and look in the Menu folder, you’ll find not one, but two menus defined . it as in Listing 10.19. LISTING 10.19. THE MODIFIED AddLine FUNCTION. 1: CLine * CDay10Doc::AddLine(CPoint ptFrom, CPoint ptTo) 2: { 3: // Create a new CLine object 4: CLine *pLine = new CLine(ptFrom,. (pLine) continues 0 14 31 240 -9 CH10 4/ 27/00 12:19 PM Page 221 LISTING 10.19. CONTINUED 20: { 21: // Delete it 22: delete pLine; 23: pLine = NULL; 24: } 25: // Delete the exception object 26: perr->Delete(); 27:. here 4: 5: /////////////////////// 6: // MY CODE STARTS HERE 7: /////////////////////// 8: 9: // Set the current color to blue 2 24 Day 10 0 14 31 240 -9 CH10 4/ 27/00 12:19 PM Page 2 24 Creating Single