Mastering Visual C++ 6
by Michael J. Young ISBN: 0782122736
Sybex ?1998 (1397 pages)

¡@

The Program Classes and Files ¡@
¡@ The WinGreet program is known as a single document interface (or SDI) application, meaning that it displays only one document at a time. When AppWizard generates an SDI application, it derives four main classes: ¡@
  ¡@ The document class ¡@
  ¡@ The view class ¡@
  ¡@ The main frame window class ¡@
  ¡@ The application class ¡@
  Note ¡@ In Chapter 17 you¡¦ll learn about the main classes and source files that AppWizard generates for multiple document interface (MDI) applications. ¡@
¡@ The primary program tasks are divided among these four main classes, and AppWizard creates separate source files for each class. By default, it derives the names of both the classes and the class source files from the name of the project (though, as mentioned previously, you can specify alternative names when using AppWizard to generate the program). ¡@
¡@ The WinGreet document class is named CWinGreetDoc and is derived from the MFC class CDocument. The CWinGreetDoc header file is named WinGreetDoc.h and the implementation file is named WinGreetDoc.cpp (a general description of header and implementation files was given in the section ¡§Organizing the Source Files¡¨ in Chapter 4). The document class is responsible for storing the program data as well as for reading and writing this data to disk files. The WinGreet document class stores only a single message string and doesn¡¦t perform disk I/O. ¡@
¡@ The WinGreet view class is named CWinGreetView and is derived from the MFC class CView. The CWinGreetView header file is named WinGreetView.h, and the implementation file is named WinGreetView.cpp. The view class is responsible for displaying the program data (on the screen, printer, or other device) and for processing input from the user. This class manages the view window, which is used for displaying program data on the screen. The WinGreet view class merely displays the message string within the view window. ¡@
¡@ The WinGreet main frame window class is named CMainFrame and is derived from the MFC class CFrameWnd. The CMainFrame header file is named MainFrm.h, and the implementation file is named MainFrm.cpp. The main frame window class manages the main program window, which is a frame window that contains a window frame, a title bar, a menu bar, and a system menu. The frame window also contains Minimize, Maximize, and Close boxes, and sometimes other user interface elements such as a toolbar or a status bar (see Figure 9.10). Note that the view window¡Xmanaged by the view class¡Xoccupies the empty portion of the main frame window inside these interface elements (which is known as the client area of the main frame window). The view window has no visible elements except the text and graphics that the view class explicitly displays (such as the string ¡§Greetings!¡¨ displayed by WinGreet). The view window is a child of the main frame window, which means¡Xamong other things¡Xthat it¡¦s always displayed on top of and within the boundaries of the client area of the main frame window. ¡@
¡@ Finally, the application class is named CWinGreetApp and is derived from the MFC class CWinApp. The CWinGreetApp header file is named WinGreet.h, and the implementation file is named WinGreet.cpp. The application class manages the program as a whole; that is, it performs general tasks that don¡¦t fall within the province of any of the other three classes, such as initializing the program and performing the final program cleanup. Every MFC Windows program must create exactly one instance of a class derived from CWinApp. ¡@
¡@ The four main classes communicate with each other and exchange data by calling each other¡¦s public member functions and by sending messages (messages will be explained in Chapter 10). Table 9.1 summarizes the features of the four main classes in the WinGreet program. ¡@
¡@ Table 9.1: The Main Program Classes and Source Files ¡@
¡@
¡@
Class ¡@
Class Name ¡@
¡@
Derived From ¡@
¡@
Header File ¡@
¡@
Implementation File ¡@
¡@
Primary Responsibilities ¡@
¡@
¡@
¡@
Document ¡@
CWinGreet
Doc
¡@
¡@
CDocument ¡@
¡@
WinGreet
Doc.h
¡@
¡@
WinGreet
Doc.cpp
¡@
¡@
Storing program data; saving and loading program data from disk ¡@
¡@
View ¡@
CWinGreet
View
¡@
¡@
CView ¡@
¡@
WinGreet
View.h
¡@
¡@
WinGreet
View.cpp
¡@
¡@
Displaying program data; processing user input; managing view window ¡@
¡@
Main Frame Window ¡@
CMainFrame ¡@
¡@
CFrame
Wnd
¡@
¡@
Main
Frm.h
¡@
¡@
Main
Frm.cpp
¡@
¡@
Managing main program window ¡@
¡@
Application ¡@
CWin
GreetApp
¡@
¡@
CWin
App
¡@
¡@
Win
Greet.h
¡@
¡@
Win
Greet.cpp
¡@
¡@
General program tasks ¡@
¡@
¡@
¡@
¡@ AppWizard and the Developer Studio create several source and settings files in addition to the source files for the four main classes. The main additional files are briefly described in Table 9.2. (Besides these files, the Developer Studio creates the following files, which are used for storing various types of information: WinGreet.aps, WinGreet.ncb, WinGreet.opt, and WinGreet.plg.) Also, AppWizard generates a file named ReadMe.txt, which describes most of the files that it has generated for your program. Note that the set of files AppWizard creates depends on the program features you choose when generating the program; the specific files associated with various program features will be discussed when these features are introduced later in the book. ¡@
¡@ Table 9.2: Additional Source and Settings Files Generated by AppWizard and the Developer Studio ¡@
¡@
¡@
¡@ File ¡@
¡@ Purpose ¡@
¡@
¡@
¡@
Resource.h ¡@
Contains constant definitions for program resources. This file is maintained by the resource editors of the Developer Studio (you don¡¦t edit it directly), and it¡¦s included¡Xindirectly¡Xin all the main .cpp files and in the main resource-definition file (WinGreet.rc). ¡@
¡@
StdAfx.cpp and StdAfx.h ¡@
Used for generating precompiled headers. ¡@
¡@
WinGreet.clw ¡@
Stores information used by the ClassWizard tool (which is introduced in Chapter 10). ¡@
¡@
WinGreet.dsp ¡@
The WinGreet project file, which stores settings and other information for the project. ¡@
¡@
WinGreet.dsw ¡@
The WinGreet project workspace file, which stores information on the project workspace. As explained in Chapter 2, a project workspace manages one or more individual projects. To open the WinGreet project in the Developer Studio, you choose the File Ø Open¡K menu command and select the WinGreet.dsw file. ¡@
¡@
WinGreet.rc ¡@
The main resource-definition file for the program, which defines the accelerator keystroke table, the ¡§About¡¨ dialog box, the menu, the string table, and the program version information. This file is maintained by the resource editors of the Developer Studio (you shouldn¡¦t edit it directly), and it¡¦s processed by the Microsoft resource compiler (RC.EXE) when the program is built. ¡@
¡@
\res\WinGreet.ico ¡@
The main program icon file. Initially, this file stores the standard MFC icon; however, you can edit it using the graphics editor of the Developer Studio. This icon is displayed in the upper-left corner of the WinGreet window, on the Windows taskbar, and other places. WinGreet.rc contains an ICON statement that causes the resource compiler to include this icon in the program¡¦s resources. ¡@
¡@
\res\WinGreet
Doc.ico
¡@
The document icon file. The WinGreet program doesn¡¦t display this icon (document icons are displayed in MDI programs, as explained in Chapter 17). ¡@
¡@
\res\Win
Greet.rc2
¡@
This file is provided for manually defining program resources; that is, for defining them without using the interactive resource editors provided by the Developer Studio. Initially, it doesn¡¦t contain any definitions. If you want to define a resource manually, you can type its definition into this file. This file is included by the main resource file, WinGreet.rc, via an #include statement. ¡@
¡@
¡@
¡@
  Note ¡@ The AppWizard-generated files listed in Tables 9.1 and 9.2 are placed in the project folder you specified when you generated the program source files (WinGreet), and in the \res subfolder within the project folder. The files listed don¡¦t include the output files produced when you build the program (for example, the .obj, .res, and .exe files). As mentioned before, the output files are placed in the -Debug or -Release subfolder of the project folder. ¡@
¡@ The following listings, Listings 9.1 through 9.8, provide the complete text of the header and implementation files for the four main program classes. These listings contain the code that was generated by AppWizard, plus the manual code additions described in the exercise given previously in the chapter. The files you created in the exercise should match the files below (except for the lengths of a few lines that had to be broken to make the listings fit within the book margins). Also, a complete set of these files is included in the \WinGreet companion-CD folder (which you can copy to your hard disk, as explained in Chapter 1). ¡@
  Note ¡@ For the example programs, the book lists only the C++ files that define and implement the main classes, because these are the files that you generally work with when you develop a program (that is, these are the files that you¡¦re most likely to directly edit). The StdAfx C++ files (StdAfx.h and StdAfx.cpp) and the other source files listed in Table 9.2 are seldom viewed or directly edited, but rather are created and maintained by various development tools; they¡¦re therefore not printed in the book.

¡@

¡@

¡@

¡@

¡@

How the Program Works

The Flow of Program Control ¡@
¡@ The following is a list of some of the significant events that occur when you run the WinGreet program. These five events were selected from the many program actions that take place, because they best help you understand how the WinGreet program works and they illustrate the purpose of the different parts of the source code: ¡@
  1. ¡@ The CWinApp class constructor is called. ¡@
  2. ¡@ The program entry function, WinMain, receives control. ¡@
  3. ¡@ WinMain calls the program’s InitInstance function. ¡@
  4. ¡@ WinMain enters a loop for processing messages. ¡@
  5. ¡@ WinMain exits and the program terminates. ¡@
¡@ Figure 9.11 illustrates this sequence of events, and the following sections describe each event in detail.

¡@

¡@

¡@

1. The CWinApp Constructor Is Called ¡@
¡@ As mentioned previously, an MFC application must define exactly one instance of its application class. The file WinGreet.cpp defines an instance of the WinGreet application class, CWinGreetApp, in the following global definition: ¡@
¡@ ///////////////////////////////////////////////////////////////// ¡@
¡@ //////////// ¡@
¡@ // The one and only CWinGreetApp object ¡@
¡@ ¡@ ¡@
¡@ CWinGreetApp theApp; ¡@
¡@ Because the CWinGreetApp object is defined globally, the class constructor is called before the program entry function, WinMain, receives control. The CWinGreetApp constructor generated by AppWizard (also in WinGreet.cpp) does nothing: ¡@
¡@ /////////////////////////////////////////////////////////////////////////////// CWinGreetApp construction ¡@
¡@ ¡@ ¡@
¡@ CWinGreetApp::CWinGreetApp() ¡@
¡@ { ¡@
¡@    // TODO: add construction code here, ¡@
¡@    // Place all significant initialization in InitInstance ¡@
¡@ } ¡@
¡@ However, as you learned in Chapter 5, such a do-nothing constructor causes the compiler to invoke the default constructor of the base class, which is CWinApp. The CWinApp constructor (supplied by the MFC) performs the following two important tasks: ¡@
  ?/font> ¡@ It makes sure that the program declares only one application object (that is, only one object belonging to CWinApp or to a class derived from it). ¡@
  ?/font> ¡@ It saves the address of the program’s CWinGreetApp object in a global pointer declared by the MFC. It saves this address so that the MFC code can later call the WinGreetApp member functions. Calling these member functions will be described under step 3. ¡@
¡@ 2. WinMain Receives Control ¡@
¡@ After all global objects have been created, the program entry function, WinMain, receives control. This function is defined within the MFC code; it’s linked to the WinGreet program when the executable file is built. The WinMain function performs many tasks. The following steps describe the tasks that are the most important for understanding how the WinGreet program works. ¡@
¡@ 3. WinMain Calls InitInstance ¡@
¡@ Shortly after it receives control, WinMain calls the InitInstance member function of the CWinGreetApp class. It calls this function by using the object address that the CWinApp constructor saved in step 1. InitInstance serves to initialize the application, and it will be described later in the chapter. ¡@
  Note ¡@ The MFC saves the address of the CWinGreetApp object in a CWinApp pointer, which it uses to call InitInstance. Because InitInstance is a virtual function (see Chapter 5), the overriding version of InitInstance defined within the CWinGreetApp class receives control. CWinApp defines several other virtual functions that you can override. For example, you can override the ExitInstance function to perform final clean-up tasks immediately before your application terminates. For a description of all CWinApp overridable functions, see the following online help topic: Visual C++ Documentation, Reference, Microsoft Foundation Class Library and Templates, Microsoft Foundation Class Library, Class Library Reference, CWinApp, CWinApp Class Members. (In this topic, see the Overridables section.) ¡@
¡@ 4. WinMain Processes Messages ¡@
¡@ After completing its initialization tasks, WinMain enters a loop that calls the Windows system to obtain and dispatch all messages sent to objects within the WinGreet program (this loop is actually contained in a CWinApp member function named Run that’s called from WinMain). Messages are explained in Chapter 10. Control remains within this loop during the remaining time that the application runs. Under Windows 95 (and later) and Windows NT, however, preemptive multitasking allows other programs to run at the same time (see Chapter 22). ¡@
¡@ 5. WinMain Exits and the Program Terminates ¡@
¡@ When the user of the WinGreet program chooses the Exit command on the File menu or the Close command on the system menu, or clicks the Close box, the MFC code destroys the program window and calls the Win32 API function ::PostQuitMessage, which causes the message loop to exit. The WinMain function subsequently returns, causing the application to terminate. ¡@
¡@ The InitInstance Function ¡@
¡@ InitInstance is a member function of the application class, CWinGreetApp, and it’s defined in the source file WinGreet.cpp. The MFC calls this function from WinMain, and its job is to initialize the application. ¡@
¡@ At the time InitInstance is called, a more traditional Windows GUI application would simply create a main program window because of the view-document programming model used by the MFC. However, the AppWizard code does something a bit more complex. It creates a document template, which stores information about the program’s document class, its main frame window class, and its view class (don’t confuse the word template in this context with a C++ template as described in Chapter 7). The document template also stores the identifier of the program resources used in displaying and managing a document (the menu, icon, and so on). When the program first begins running and it creates a new document, it uses the document template to create an object of the document class for storing the document, an object of the view class for creating a view window to display the document, and an object of the main frame window class to provide a main program window for framing the view window. ¡@
¡@ A document template is a C++ object; for an SDI application such as WinGreet, it’s an instance of the CSingleDocTemplate MFC class. The following code in InitInstance creates the document template and stores it within the application object: ¡@
¡@ // Register the application’s document templates. Document ¡@
¡@ // templates serve as the connection between documents, frame ¡@
¡@ // windows, and views. ¡@
¡@ ¡@ ¡@
¡@ CSingleDocTemplate* pDocTemplate; ¡@
¡@ pDocTemplate = new CSingleDocTemplate( ¡@
¡@    IDR_MAINFRAME, ¡@
¡@    RUNTIME_CLASS(CWinGreetDoc), ¡@
¡@    RUNTIME_CLASS(CMainFrame),       // main SDI frame window ¡@
¡@    RUNTIME_CLASS(CWinGreetView)); ¡@
¡@ AddDocTemplate(pDocTemplate); ¡@
¡@ This code works as follows: ¡@
  ?/font> ¡@ It defines a pointer to a document template object, pDocTemplate. ¡@
  ?/font> ¡@ It uses the new operator to dynamically create a document template object (that is, an instance of the CSingleDocTemplate class), assigning the object’s address to pDocTemplate. ¡@
  ?/font> ¡@ It passes four parameters to the CSingleDocTemplate constructor. The first parameter is the identifier of the program resources used in displaying and managing a document (namely, the accelerator table, the icon, the menu, and a descriptive string). ¡@
  ?/font> ¡@ The next three parameters supply information on the document class, the main frame window class, and the view class. Information on each class is obtained by calling the MFC macro RUNTIME_CLASS (which supplies a pointer to a CRuntimeClass object). This information allows the program to dynamically create an object of each class when a new document is first created. ¡@
  ?/font> ¡@ The template object pointer is passed to the CWinApp member function AddDocTemplate, which stores the document template within the application object so that the template will be available when a document is opened. ¡@