Teach Yourself Visual C++ 6 in 21 Days phần 3 doc

80 289 0
Teach Yourself Visual C++ 6 in 21 Days phần 3 doc

Đ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

009 31240-9 CH07 4/27/00 11:49 AM Page 141 Working with Text and Fonts 141 FIGURE 7.4 Displaying the selected font with the font name Add a check box to display the font sample in italics, as in Figure 7.5 FIGURE 7.5 Displaying the selected font in italics 009 31240-9 CH07 4/27/00 11:49 AM Page 142 010 31240-9 Rev 4/27/00 11:50 AM Page 143 WEEK 1 In Review Well, you’ve made it through the first week By this point, you’ve gotten a good taste for what’s possible when building applications with Visual C++ Now it’s time to look back over what’s been covered and what you should have learned up to this point What you might want to at this point, to cement your understanding of how you can use these elements in your own applications, is to try designing and building a couple of simple applications of your own You can use a variety of controls and add some additional dialogs, just so you can make sure that you understand and are comfortable with these topics In fact, you might want to try out all the topics that I’ve covered up to this point in small applications of your own design That’s the true test of your understanding of how the concepts work You might also want to dive into the MFC documentation to learn a little about some of the more advanced functionality that I haven’t covered to see if you can figure out how you can use and incorporate it into your applications One of the most important things that you should understand at this point is how you can use controls and dialog windows in your applications to get and display information to the user This is an important part of any Windows application because just about every application interacts with the user in some way You should be able to place any of the standard controls on a dialog in your application and be able to incorporate them into your application without any problem Likewise, you should be comfortable with using the standard message box and dialog windows provided to your application by the Windows operating system You should also be 010 31240-9 Rev 144 4/27/00 11:50 AM Page 144 Week able to create and incorporate your own custom dialog windows into any application you might want to build If you don’t feel comfortable with any of these topics, you might want to go back and review Day to get a better understanding of how you can use controls and Day to understand how you can incorporate standard and custom dialog windows into your applications Another key skill that you will be using in the majority of your applications is the ability to build and incorporate menus into your applications You need to have a firm understanding of how to design a good menu, how to make sure that there are no conflicting mnemonics, and how you can attach application functionality to the menu selections At this point, you should be able to create your own customized menus, with entries for each of the various functions that your application performs, and integrate it with your application with no problems If you aren’t 100% comfortable with this topic, you might want to go back and study Day a little more You will find that there are various situations in which you need to have some means of triggering actions on a regular basis or in which you need to keep track of how long some process has been running For both of these situations, as well as numerous others, you’ll often find yourself turning to the use of timers in your application If you are even slightly foggy on how you can integrate timers into your applications, you will definitely want to go back and review Day Understanding how you can use text and fonts in your applications will allow you to build more flexibility into the appearance of your applications—to give your users the ability to customize the appearance as they want You will be able to examine the available fonts on the computer on which your application is running and, if a font that you want to use in your application isn’t available, choose another font that is close to use instead If you still have any questions on how the font infrastructure in Windows works and how you can use it in your applications, you’ll want to go back and review Day once more Depending on the nature of your application, being able to capture and track mouse and keyboard actions by the user can be very important If you are building a drawing application, this is crucial information If you are building an application that needs to include drag-and-drop capabilities, this is important once again There are any number of situations in which you’ll want to include this functionality into your applications By this point, you should understand how you can capture the various mouse events and determine which mouse buttons are involved in the event You should also be able to capture keyboard events in situations where the keyboard input isn’t captured by any controls that are on the window If you don’t feel like you have a complete grasp of this, you should take another look at Day 010 31240-9 Rev 4/27/00 11:50 AM Page 145 In Review Finally, you should be familiar with the Visual C++ development environment, the Developer Studio You should have a good understanding of what each area of the environment is for and how you can use the various tools and utilities in building your applications You should be comfortable with using the workspace pane to navigate around your application project, locating and bringing into the various editors and designers any part of your application You should be comfortable with locating and redesigning the icon that will be displayed to represent your application and with finding any member functions or variables in any of your application’s classes By now you should be getting fairly comfortable working with Visual C++ If you feel like you understand all the topics that I’ve covered so far, you are ready to continue forward, learning more about the various things that you can do, and functionality that you can build, using Visual C++ as your programming tool With that said, it’s on to the second week… 145 010 31240-9 Rev 4/27/00 11:50 AM Page 146 011 31240-9 AAG Wk2 4/27/00 11:53 AM Page 147 WEEK At a Glance In the second week, you’ll dive into several more involved topics These topics are still very much core to building Windows applications You’ll find yourself using what you learn in this week, along with what you learned during the first week, in just about all the applications that you build with Visual C++ To start the week, on Day 8, you’ll learn how to draw graphics in a Windows application You’ll learn how to draw simple lines, rectangles, and ellipses What’s more important—you’ll learn about the device context and how you can use it to draw your graphics without worrying about the graphics hardware your users might or might not have in their computers On Day 9, you’ll learn how easy it is to incorporate ActiveX controls into your applications You’ll see how Visual C++ builds custom C++ classes around the controls that you add to your project, enabling you to interact with an added control just as if it were another C++ object On Day 10, you’ll learn how to build a basic Single Document Interface (SDI) application You’ll learn about the Document/View architecture that is used with Visual C++ for building this style of application, and you’ll learn how you can use it to build your own applications On Day 11, you’ll learn how you can apply what you learned about building SDI applications to building Multiple Document Interface (MDI) applications You’ll see how you can use the same Document/View architecture to create MDI applications, some of the most common style of Windows applications available today 10 11 12 13 14 011 31240-9 AAG Wk2 148 4/27/00 11:53 AM Page 148 Week On Day 12, you’ll learn how you can create and modify your own toolbars and status bars You’ll learn how you can attach toolbar buttons to menus in your application and how you can add additional toolbars You’ll also learn how you can place your own informational elements on the status bar at the bottom of most Windows applications and how you can keep the status bar updated with the status of your application On Day 13, you’ll see how you can use the structure provided for you by the Document/View architecture to save and restore the data created in your application You’ll learn how flexible this facility is and how you can store different data types in the same file, restoring them to your application just as they were when you first saved them Finally, rounding out the week on Day 14, you’ll learn how easy it is to build a database application with an ODBC database You’ll learn how to query a set of records from the database and how to allow the user to edit and modify them, saving the changes back to the database When you finish this week, you’ll be well prepared for tackling most basic application development tasks with Visual C++ You might want to take a short break at that point to experiment a bit—trying to build various types of applications, pushing your skills, and learning what your limits are (and aren’t)—before jumping into the final week of more advanced topics 012 31240-9 CH08 4/27/00 11:54 AM Page 149 WEEK DAY Adding Flash— Incorporating Graphics, Drawing, and Bitmaps You’ve probably noticed that a large number of applications use graphics and display images This adds a certain level of flash and polish to the application With some applications, graphics are an integral part of their functionality Having a good understanding of what’s involved in adding these capabilities to your applications is a key part of programming for the Windows platform You’ve already learned how you can draw lines and how you can string a series of these lines together to make a continuous drawing Today, you’re going to go beyond that capacity and learn how you can add more advanced graphics capabilities to your applications Today, you will learn • How Windows uses a device context to translate drawing instructions into graphics output • How you can determine the level of control you have over the graphics output through different mapping modes 012 31240-9 CH08 4/27/00 11:54 AM Page 150 150 Day • How Windows uses pens and brushes to draw different portions of the graphics image • How you can load and display bitmaps dynamically Understanding the Graphics Device Interface The Windows operating system provides you with a couple of levels of abstraction for creating and using graphics in your applications During the days of DOS programming, you needed to exercise a great deal of control over the graphics hardware to draw any kind of images in an application This control required an extensive knowledge and understanding of the various types of graphics cards that users might have in their computers, along with their options for monitors and resolutions There were a few graphics libraries that you could buy for your applications, but overall, it was fairly strenuous programming to add this capability to your applications With Windows, Microsoft has made the job much easier First, Microsoft provides you with a virtual graphics device for all of your Windows applications This virtual device doesn’t change with the hardware but remains the same for all possible graphics hardware that the user might have This consistency provides you with the ability to create whatever kind of graphics you want in your applications because you know that the task of converting them to something that the hardware understands isn’t your problem Device Contexts Before you can create any graphics, you must have the device context in which the graphics will be displayed The device context contains information about the system, the application, and the window in which you are drawing any graphics The operating system uses the device context to learn in which context a graphic is being drawn, how much of the area is visible, and where on the screen it is currently located When you draw graphics, you always draw them in the context of an application window At any time, this window may be full view, minimized, partly hidden, or completely hidden This status is not your concern because you draw your graphics on the window using its device context Windows keeps track of each device context and uses it to determine how much and what part of the graphics you draw to actually display for the user In essence, the device context you use to display your graphics is the visual context of the window in which you draw them The device context uses two resources to perform most of its drawing and graphics functions These two resources are pens and brushes Much like their real-world counterparts, pens and brushes perform similar yet different tasks The device context uses pens to 014 31240-9 CH10 4/27/00 12:19 PM Page 206 206 Day 10 Adding Lines The first functionality that you need to add to the document class is the ability to add new lines This should be a simple process of getting the from and to points, creating a new line object, and then adding it to the object array To implement this function, add a new member function to the CDay10Doc class, specifying the type as CLine* and the declaration as AddLine(CPoint ptFrom, CPoint ptTo) with public access Edit the function, adding the code in Listing 10.3 LISTING 10.3 THE CDay10Doc AddLine FUNCTION 1: CLine * CDay10Doc::AddLine(CPoint ptFrom, CPoint ptTo) 2: { 3: // Create a new CLine object 4: CLine *pLine = new CLine(ptFrom, ptTo); 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) 20: { 21: // Delete it 22: delete pLine; 23: pLine = NULL; 24: } 25: // Delete the exception object 26: perr->Delete(); 27: } 28: return pLine; 29: } At first, this function is understandable You create a new CLine instance, passing the from and to points as constructor arguments Right after that, however, you have something interesting, the following flow control construct: 1: try 2: { 3: 014 31240-9 CH10 4/27/00 12:19 PM Page 207 Creating Single Document Interface Applications 4: 5: 6: 7: 8: 9: 10: 11: 12: 207 } catch ( ) { } What is this? This construct is an example of structured exception handling Some code could fail because of a factor beyond your control, such as running out of memory or disk space, you can place a try section around the code that might have a problem The try section should always be followed by one or more catch sections If a problem occurs during the code in the try section, the program immediately jumps to the catch sections Each catch section specifies what type of exception it handles (in the case of the AddLine function, it specifically handles memory exceptions only), and if there is a matching catch section for the type of problem that did occur, that section of code is executed to give the application a chance to recover from the problem If there is no catch section for the type of problem that did occur, your program jumps to a default exception handler, which will most likely shut down your application For more information on structured exception handling, see Appendix A, “C++ Review.” Within the try section, you add the new CLine instance to the array of line objects Next, you call the SetModifiedFlag function, which marks the document as “dirty” (unsaved) so that if you close the application or open another file without saving the current drawing first, the application prompts you to save the current drawing (with the familiar Yes, No, Cancel message box) In the catch section, you inform the user that the system is out of memory and then clean up by deleting the CLine object and the exception object Finally, at the end of the function, you return the CLine object to the calling routine This enables the view object to let the line object draw itself Getting the Line Count The next item you will add to the document class is a function to return the number of lines in the document This functionality is necessary because the view object needs to loop through the array of lines, asking each line object to draw itself The view object will need to be able to determine the total number of lines in the document and retrieve any specific line from the document Returning the number of lines in the document is a simple matter of returning the number of lines in the object array, so you can just return the return value from the GetSize 10 014 31240-9 CH10 4/27/00 12:19 PM Page 208 208 Day 10 method of the CObArray class To implement this function, add a new member function to the CDay10Doc class, specifying the type as int and the declaration as GetLineCount with public access Edit the function, adding the code in Listing 10.4 LISTING 10.4 THE CDay10Doc GetLineCount FUNCTION 1: int CDay10Doc::GetLineCount() 2: { 3: // Return the array count 4: return m_oaLines.GetSize(); 5: } Retrieving a Specific Line Finally, you need to add a function to return a specific line from the document This is a simple matter of returning the object at the specified position in the object array To implement this function, add a new member function to the CDay10Doc class, specifying the type as CLine* and the declaration as GetLine(int nIndex) with public access Edit the function, adding the code in Listing 10.5 LISTING 10.5 THE CDay10Doc GetLine FUNCTION 1: CLine * CDay10Doc::GetLine(int nIndex) 2: { 3: // Return a pointer to the line object 4: // at the specified point in the object array 5: return (CLine*)m_oaLines[nIndex]; 6: } Note Notice that the object being returned had to be cast as a pointer to a CLine object Because the CObArray class is an array of CObjects, every element that is returned by the array is a CObject instance, not a CLine object instance Showing the User Now that you have built the capability into the document class to hold the drawing, you need to add the functionality to the view object to read the user’s drawing input and to draw the image The mouse events to capture the user input are almost identical to those you created a week ago The second part of the functionality that you need to implement 014 31240-9 CH10 4/27/00 12:19 PM Page 209 Creating Single Document Interface Applications 209 is drawing the image You will make an addition to a function that already exists in the view object class Before adding these functions, you need to add a member variable to the CDay10View class to maintain the previous mouse point, just as you did a week ago Add a member variable to the CDay10View class through the workspace pane, specifying the type as CPoint, the name as m_ptPrevPos, and the access as private Adding the Mouse Events To add the mouse events to capture the user’s drawing efforts, open the Class Wizard and add functions to the CDay10View class for the WM_LBUTTONDOWN, WM_LBUTTONUP, and WM_MOUSEMOVE event messages Edit the functions as in Listing 10.6 LISTING 10.6 THE CDay10View 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 10 MOUSE FUNCTIONS void CDay10View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default /////////////////////// // MY CODE STARTS HERE /////////////////////// // Capture the mouse, so no other application can // grab it if the mouse leaves the window area SetCapture(); // Save the point m_ptPrevPos = point; /////////////////////// // MY CODE ENDS HERE /////////////////////// CView::OnLButtonDown(nFlags, point); } void CDay10View::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default /////////////////////// // MY CODE STARTS HERE /////////////////////// // Have we captured the mouse? continues 014 31240-9 CH10 4/27/00 12:19 PM Page 210 210 Day 10 LISTING 10.6 31: 32: 33: 34: 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: CONTINUED if (GetCapture() == this) // If so, release it so other applications can // have it ReleaseCapture(); /////////////////////// // MY CODE ENDS HERE /////////////////////// CView::OnLButtonUp(nFlags, point); } void CDay10View::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default /////////////////////// // MY CODE STARTS HERE /////////////////////// // Check to see if the left mouse button is down if ((nFlags & MK_LBUTTON) == MK_LBUTTON) { // Have we captured the mouse? if (GetCapture() == this) { // Get the Device Context CClientDC dc(this); // Add the line to the document CLine *pLine = GetDocument()->AddLine(m_ptPrevPos, point); // Draw the current stretch of line pLine->Draw(&dc); // Save the current point as the previous point m_ptPrevPos = point; } } /////////////////////// // MY CODE ENDS HERE /////////////////////// CView::OnMouseMove(nFlags, point); } 014 31240-9 CH10 4/27/00 12:19 PM Page 211 Creating Single Document Interface Applications 211 In the OnLButtonDown function, the first thing you is call the SetCapture function This function “captures” the mouse, preventing any other applications from receiving any mouse events, even if the mouse leaves the window space of this application This enables the user to drag the mouse outside the application window while drawing and then drag the mouse back into the application window, without stopping the drawing All mouse messages are delivered to this application until the mouse is released in the OnLButtonUp function, using the ReleaseCapture function In the meantime, by placing the GetCapture function in an if statement and comparing its return value to this, you can determine whether your application has captured the mouse If you capture the mouse, you want to execute the rest of the code in those functions; otherwise, you don’t In the OnMouseMove function, after you create your device context, you several things in a single line of code The line CLine *pLine = GetDocument()->AddLine(m_ptPrevPos, point); creates a new pointer to a CLine class instance Next, it calls the GetDocument function, which returns a pointer to the document object This pointer is used to call the document class’s AddLine function, passing the previous and current points as arguments The return value from the AddLine function is used to initialize the CLine object pointer The CLine pointer can now be used to call the line object’s Draw function Note A pointer is the address of an object It is used to pass an object more efficiently around a program Passing a pointer to an object, instead of the object itself, is like telling someone that the remote control is “on the couch between the second and third cushion, beside the loose pocket change” instead of handing the remote to the person Actually, in programming terms, handing the remote to the person requires making an exact copy of the remote and handing the copy to the other person It is obviously more efficient to tell the person where to find the remote than to manufacture an exact copy of the remote The notation -> denotes that the object’s functions or properties are accessed through a pointer, as opposed to directly through the object itself with the period (.) notation Drawing the Painting In the view class, the function OnDraw is called whenever the image presented to the user needs to be redrawn Maybe another window was in front of the application window, the window was just restored from being minimized, or a new document was just loaded from a file Why the view needs to be redrawn doesn’t matter All you need to worry 10 014 31240-9 CH10 4/27/00 12:19 PM Page 212 212 Day 10 about as the application developer is adding the code to the OnDraw function to render the document that your application is designed to create Locate the OnDraw function in the CDay10View class and add the code in Listing 10.7 LISTING 10.7 THE CDay10View OnDraw FUNCTION 1: void CDay10View::OnDraw(CDC* pDC) 2: { 3: CDay10Doc* pDoc = GetDocument(); 4: ASSERT_VALID(pDoc); 5: 6: // TODO: add draw code for native data here 7: 8: /////////////////////// 9: // MY CODE STARTS HERE 10: /////////////////////// 11: 12: // Get the number of lines in the document 13: int liCount = pDoc->GetLineCount(); 14: 15: // Are there any lines in the document? 16: if (liCount) 17: { 18: int liPos; 19: CLine *lptLine; 20: 21: // Loop through the lines in the document 22: for (liPos = 0; liPos < liCount; liPos++) 23: { 24: // Get the from and to point for each line 25: lptLine = pDoc->GetLine(liPos); 26: // Draw the line 27: lptLine->Draw(pDC); 28: } 29: } 30: 31: /////////////////////// 32: // MY CODE ENDS HERE 33: /////////////////////// 34: } In this function, the first thing you did was find out how many lines are in the document to be drawn If there aren’t any lines, then there is nothing to If there are lines in the document, you loop through the lines using a for loop, getting each line object from the document and then calling the line object’s Draw function 014 31240-9 CH10 4/27/00 12:19 PM Page 213 Creating Single Document Interface Applications 213 Before you can compile and run your application, you’ll need to include the header file for the Cline class in the source code file for the document and view classes To add this to your application, edit both of these files (Day10Doc.cpp and Day10View.cpp), adding the Line.h file to the includes, as shown in Listing 10.8 LISTING 10.8 THE CDay10Doc includes 1: 2: 3: 4: 5: #include #include #include #include #include “stdafx.h” “Day10.h” “MainFrm.h” “Line.h” “Day10Doc.h” At this point, you should be able to compile and run your application, drawing figures in it as shown in Figure 10.4 If you minimize the window and then restore it, or if you place another application window in front of your application window, your drawing should still be there when your application window is visible again (unlike the application you built a week ago) FIGURE 10.4 Drawing with your application Saving and Loading the Drawing Now that you can create drawings that don’t disappear the moment you look away, it’d be nice if you could make them even more persistent If you play with the menus on your application, it appears that the Open, Save, and Save As menu entries on the File menu activate, but they don’t seem to anything The printing menu entries all work, but the entries for saving and loading a drawing don’t Not even the New menu entry works! Well, you can something to fix this situation 10 014 31240-9 CH10 214 4/27/00 12:19 PM Page 214 Day 10 Deleting the Current Drawing If you examine the CDay10Doc class, you’ll see the OnNewDocument function that you can edit to clear out the current drawing Wrong! This function is intended for initializing any class settings for starting work on a new drawing and not for clearing out an existing drawing Instead, you need to open the Class Wizard and add a function on the DeleteContents event message This event message is intended for clearing the current contents of the document class Edit this new function, adding the code in Listing 10.9 LISTING 10.9 THE CDay10Doc DeleteContents FUNCTION 1: void CDay10Doc::DeleteContents() 2: { 3: // TODO: Add your specialized code here and/or call the base class 4: 5: /////////////////////// 6: // MY CODE STARTS HERE 7: /////////////////////// 8: 9: // Get the number of lines in the object array 10: int liCount = m_oaLines.GetSize(); 11: int liPos; 12: 13: // Are there any objects in the array? 14: if (liCount) 15: { 16: // Loop through the array, deleting each object 17: for (liPos = 0; liPos < liCount; liPos++) 18: delete m_oaLines[liPos]; 19: // Reset the array 20: m_oaLines.RemoveAll(); 21: } 22: 23: /////////////////////// 24: // MY CODE ENDS HERE 25: /////////////////////// 26: 27: CDocument::DeleteContents(); 28: } This function loops through the object array, deleting each line object in the array Once all the lines are deleted, the array is reset by calling its RemoveAll method If you compile and run your application, you’ll find that you can select File | New, and if you decide not to save your current drawing, your window is wiped clean 014 31240-9 CH10 4/27/00 12:19 PM Page 215 Creating Single Document Interface Applications 215 Saving and Restoring the Drawing Adding the functionality to save and restore your drawings is pretty easy to implement, but it might not be so easy to understand That’s okay; you’ll spend an entire day on understanding saving and restoring files, also known as serialization, in three days In the meantime, find the Serialize function in the CDay10Doc class The function should look something like 1: void CDay10Doc::Serialize(CArchive& ar) 2: { 3: if (ar.IsStoring()) 4: { 5: // TODO: add storing code here 6: } 7: else 8: { 9: // TODO: add loading code here 10: } 11: } Remove all the contents of this function, and edit the function so that it looks like Listing 10.10 LISTING 10.10 THE CDay10Doc Serialize FUNCTION 1: void CDay10Doc::Serialize(CArchive& ar) 2: { 3: /////////////////////// 4: // MY CODE STARTS HERE 5: /////////////////////// 6: 7: // Pass the serialization on to the object array 8: m_oaLines.Serialize(ar); 9: 10: /////////////////////// 11: // MY CODE ENDS HERE 12: /////////////////////// 13: } This function takes advantage of the functionality of the CObArray class This object array will pass down its array of objects, calling the Serialize function on each of the objects This means that you need to add a Serialize function to the CLine class Specify it as a void function type with the declaration of Serialize(CArchive& ar) Edit the function, adding the code in Listing 10.11 10 014 31240-9 CH10 4/27/00 12:19 PM Page 216 216 Day 10 LISTING 10.11 THE CLine Serialize FUNCTION 1: void CLine::Serialize(CArchive &ar) 2: { 3: CObject::Serialize(ar); 4: 5: if (ar.IsStoring()) 6: ar m_ptFrom >> m_ptTo; 9: } This function follows basically the same flow that the original Serialize function would have followed in the CDay10Doc class It uses the I/O stream functionality of C++ to save and restore its contents At this point, if you compile and run your application, you expect the save and open functions to work Unfortunately, they don’t (yet) If you run your application and try to save a drawing, a message box will tell you that the application was unable to save the file, as in Figure 10.5 FIGURE 10.5 Unable to save drawings The reason that you are unable to save your drawing is that Visual C++ must be told that a class should be serializable To this, you add one line to the CLine class header file and one line to the CLine source code file Open the CLine header file (Line.h), and add the DECLARE_SERIAL line in Listing 10.12 just after the first line of the class definition LISTING 10.12 THE Line.h EDIT FOR SERIALIZATION 1: class CLine : public CObject 2: { 3: DECLARE_SERIAL (CLine) 4: public: 5: CLine(CPoint ptFrom, CPoint ptTo, UINT nWidth, COLORREF crColor); Next, open the CLine source code file, and add the IMPLEMENT_SERIAL line in Listing 10.13 just before the class constructor functions 014 31240-9 CH10 4/27/00 12:19 PM Page 217 Creating Single Document Interface Applications LISTING 10.13 THE Line.cpp 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 217 EDIT FOR SERIALIZATION // Line.cpp: implementation of the CLine class // ////////////////////////////////////////////////////////////////////// #include “stdafx.h” #include “Day10.h” #include “Line.h” #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]= FILE ; #define new DEBUG_NEW #endif IMPLEMENT_SERIAL (CLine, CObject, 1) ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CLine::CLine() { } Now if you compile and run your application, you should be able to draw your own selfportrait and save it for posterity, as shown in Figure 10.6 FIGURE 10.6 My self-portrait 10 014 31240-9 CH10 4/27/00 12:19 PM Page 218 218 Day 10 Interacting with the Menu Now that you have a working drawing program, it would be nice if the user could choose the color with which she wants to draw Adding this functionality requires making changes in the CLine class to associate the color with the line and to CDay10Doc to maintain the currently selected color Finally, you need to add a pull-down menu to select the desired color Adding Color to the CLine Class The changes to the CLine class are fairly straightforward The first thing that you need to is to add another member variable to the CLine class to hold the color of each line Next, you need to modify the class constructor to add color to the list of attributes to be passed in Third, you need to modify the Draw function to use the specified color Finally, you need to modify the Serialize function to save and restore the color information along with the point information To all these things, follow these steps: Select the CLine class in the Class View tab of the workspace pane Right-click the mouse and select Add Member Variable from the pop-up menu Specify the variable type as COLORREF, the name as m_crColor, and the access as private Click OK to add the variable Right-click the CLine constructor in the Class View tree Select Go to Declaration from the pop-up menu Add COLORREF crColor as a third argument to the constructor declaration Right-click the CLine constructor in the Class View tree Select Go to Definition from the pop-up menu Modify the constructor to add the third argument and to set the m_crColor member to the new argument, as in Listing 10.14 LISTING 10.14 THE MODIFIED CLine CONSTRUCTOR 1: CLine::CLine(CPoint ptFrom, CPoint ptTo, COLORREF crColor) 2: { 3: //Initialize the from and to points 4: m_ptFrom = ptFrom; 5: m_ptTo = ptTo; 6: m_crColor = crColor; 7: } Scroll down to the Draw function and modify it as in Listing 10.15 014 31240-9 CH10 4/27/00 12:19 PM Page 219 Creating Single Document Interface Applications LISTING 10.15 THE MODIFIED 219 Draw FUNCTION 1: void CLine::Draw(CDC * pDC) 2: { 3: // Create a pen 4: CPen lpen (PS_SOLID, 1, m_crColor); 5: 6: // Set the new pen as the drawing object 7: CPen* pOldPen = pDC->SelectObject(&lpen); 8: // Draw the line 9: pDC->MoveTo(m_ptFrom); 10: pDC->LineTo(m_ptTo); 11: // Reset the previous pen 12: pDC->SelectObject(pOldPen); 13: } Scroll down to the Serialize function and modify it as in Listing 10.16 LISTING 10.16 THE MODIFIED Serialize FUNCTION 1: void CLine::Serialize(CArchive &ar) 2: { 3: CObject::Serialize(ar); 4: 5: if (ar.IsStoring()) 6: ar > m_ptTo >> (DWORD) m_crColor; 9: } The only part of any of these steps that should be a surprise is that you are capturing the return value from the SelectObject function when you are specifying the pen to use in drawing the lines You didn’t this last week The return value from the SelectObject function is the pen that was in use before you changed it This way, you can use the previous pen to restore it to the device context when you are done drawing Adding Color to the Document The changes that you need to make to the CDay10Doc class are just slightly more extensive than those made to the CLine class You need to add a member variable to hold the current color and a color table to convert color IDs into RGB values You need to initialize the current color variable in the OnNewDocument function Then, you need to modify the AddLine function to add the current color to the CLine constructor Finally, you add a function to return the current color That’s all that you need to for now until you start 10 014 31240-9 CH10 4/27/00 12:19 PM Page 220 220 Day 10 adding menu message handlers for setting the current color To these things, follow these steps: Select the CDay10Doc class in the Class View tab on the workspace pane Rightclick the mouse and choose Add Member Variable from the pop-up menu Specify the variable type as UINT, the name as m_nColor, and the access as private Click OK to add the variable Repeat step Specify the variable type as “static const m_crColors[8], and the access as public COLORREF,” the name as Open the CDay10Doc source code (Day10Doc.cpp) and add the population of the m_crColors color table as in Listing 10.17 LISTING 10.17 THE 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: COLOR TABLE SPECIFICATION //}}AFX_MSG_MAP END_MESSAGE_MAP() const COLORREF CDay10Doc::m_crColors[8] = { RGB( 0, 0, 0), // Black RGB( 0, 0, 255), // Blue RGB( 0, 255, 0), // Green RGB( 0, 255, 255), // Cyan RGB( 255, 0, 0), // Red RGB( 255, 0, 255), // Magenta RGB( 255, 255, 0), // Yellow RGB( 255, 255, 255) // White }; ////////////////////////////////////////////////////////////////////// // CDay10Doc construction/destruction CDay10Doc::CDay10Doc() } Scroll down to the OnNewDocument function and edit it as in Listing 10.18 ... 012 31 240-9 CH08 4/27/00 11:54 AM 166 Page 166 Day LISTING 8.5 25: 26: 27: 28: 29: 30 : 31 : 32 : 33 : 34 : 35 : 36 : 37 : 38 : 39 : 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:... Application 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: 83: 84: 85: 86: 87: 88:... lines starting at line 21 in Listing 8.8 to the OnPaint function LISTING 8.8 THE MODIFIED OnPaint FUNCTION 1: void CPaintDlg::OnPaint() 2: { 3: CPaintDC dc(this); // device context for painting

Ngày đăng: 13/08/2014, 18:20

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan