This chapter introduces the document/view architecture of MFC, explains the data structure of implementing the structure, and then writes a console application to simulate the initialization of MFC, clarify the sequence of MFC initialization, and then explain how to create a most basic MFC application.
MFC's most important structural document/view structure
MFC provides a framework for constructing Windows applications that not only establishes a standard structure for an application, generates a series of startup files, but also provides a standard graphical user interface such as menus, toolbars, status bars, etc. for developers to complement the program. Developers just need to complete the code for the pending app. One of the most important frameworks is the document application framework for the document/view architecture.
In the document/view structure, the program's data is stored in the document class (as a data member of the document Class), and the document class is an abstract representation of the data. The data display is responsible for the view, the view is the client area of the program window, the frame window is the frame of the client area, the program data is displayed in the window, and the user interacts with the program through the view.
Documents, views, and frames are interrelated, coordinated, and each other contains pointers to each other. Document, view, and frame relationships, as shown in:
MFC document/View structure-related classes
In General, an application that takes a document/view structure should consist of at least the following objects: An Application object (an object derived from the CWinApp class), a Frame window object (an object derived from the CFrameWnd class), a Document object (an object derived from a CDocument class), A View object (an object derived from the CView class). In addition, you must have a document template class (CDocTemplate) that is responsible for managing documents and views. The protagonist is the CDocument class (document Class) and the CView Class (view Class), which is the origin of the document/view architecture. The functions of each category are described as follows:
1.CWinApp
The CwinApp (Application Class) provides an interface for users to communicate with Windows applications. After instantiating the object, the object automatically contacts itself with the widnows system, receives the message sent by Windows, and gives it to the appropriate object in the program, eliminating many of the programmer's work, making it easy to develop the Windows sequence.
There is an important member function in this class: InitInstance (), in a Windows environment, you can run multiple instances of the same program, and the function InitInstance () does some initialization work when a new instance is generated. There is also a function initapplication (), which differs from the former as "every program is called only Once" and InitInstance () is "every routine called once".
2.CFrameWnd
The CFrameWnd (frame window class) is the application's frame window. The so-called frame window refers to the main window of the entire application including menus, toolbars, the status bar, and the window client area, equivalent to the main window mentioned in the simple application framework. In the MFC program, generally do not need to operate the CFrameWnd class frequently, more is the window class to operate, to achieve the purpose of editing the data in the program.
3.CView
The CView (view Class) is derived from the Cwnd class, which manages the window client area in the document/view structure, which is called a view in the document/view structure. The view class is dedicated to displaying the data of the application, there is an important function OnDraw () in the view class, and the OnDraw () function is a function for displaying the application data, which is typically overridden in a derived class. In the document/view structure, the overridden OnDraw () function first clears the client area window and then draws the client's desired content on the window, that is, the OnDraw () function will centrally manage all the data display work.
4.CDocument
CDocument (document Class) While the view class is responsible for the display of application data, the data for the application is generally not managed directly by the view class, but as a data member of the document class (CDocument), centrally managed by the document class, and the document class is directly associated with the disk. Save the data in the document class, or remove the saved data from the disk. The view class uses the OnDraw () function to present the data, but the application's data is stored in the document class, and the return value of the function getdocument () of the view class is a pointer to the document class, which provides access to the public data members in the document class. The data of the document class to be saved or taken to disk for data transfer, you can use the CFile class combined with the CFileDialog class implementation. In the document/view structure, the data Access task can be accomplished easily through the serialization function Serialize () in the document class. In the document/view structure, the data transfer process is as follows:
5.CDocTemplate
the role of the CDocTemplate (document template Class) is to connect the document class in the document/view structure, the relationship between the view class and the frame window class, the document class, the relationship between the view class and the frame window class, which is established in the document template class. The document template class also loads resources such as menus and the ID used with the menu resource. Specifically, the document template class CDocTemplate is established in the InitInstance () function of the CWinApp derived class, and the document template class is used to connect resources, frame windows, documents, and views.
class Hierarchy
Inherit the class diagram, the parent class on the left, and the derived class on the right. The classes in the solid box are only CObject in "Afx.h" and the rest are in "afxwin.h", and all the dashed boxes are derived classes that are defined by the user themselves.
simulating MFC initialization using a console program
Note: Use the console Application (WIN32 console application) emulation instead of the MFC program! In addition to the need to copy code, I at the bottom of the article in appendix I gave the code download link and use method.
Assuming that a new console application is called "My", it is natural to write a derived class of the above five important classes, where cdoctemplate is used to manage other classes of objects that can be used directly, and is not discussed here (its derived classes are declared in "AFXWIN.h"). A four header file is created and a derived class of other classes is declared.
My.hclass cmyapp:public Cwinapp{public:cmyapp (); virtual BOOL InitInstance (); Overwrite};
Mydoc.hclass cmydoc:public Cdocument{public:cmydoc ();};
Myframe.hclass cmyframe:public cframewnd{public:cmyframe ();};
Myview.hclass cmyview:public Cview{public:cmyview ();};
This is all the header files that the customer needs to create, and when you use the IDE to create an MFC program, he will automatically create the header file for you. Also note the following 3 header files, which are real in the MFC class library and have the same name. "Afx.h" declares the CObject base class, "AFXWIN.h" declares the base class for most of the classes used in MFC, and "stdafx.h" is designed to reduce the number of duplicate compilation settings used to build a precompiled header file. PCH and a pre-defined type file, StdAfx. Obj. Because MFC architecture is very large, contains many header files, if it is more time-consuming to compile, so we put the commonly used MFC header files in stdafx.h, such as AFXWIN.h, Afxext.h, Afxdisp.h, Afxcmn.h, and then let Stdafx.cpp contains this stdafx.h file. This way, because the compiler can identify which files have been compiled, Stdafx.cpp compiles only once and generates so-called precompiled header files.
Stdfx.h#include "AFXWIN.h"//Other necessary header files//#include <......>//#include <......>//#include <......>/ /link necessary libraries//#pragma comment (...) #pragma comment (...) #pragma comment (...)
//afxwin.h# pragma once#include "afx.h"//ccmdtarget class declaration class Ccmdtarget:public cobject{public:ccmdtarget ();};/ /cdocument class Cdocument:public ccmdtarget{public:cdocument ();};/ The/cwnd class declares class Cwnd:public Ccmdtarget{public:cwnd (); virtual BOOL Create (); BOOL CreateEx (); virtual BOOL PreCreateWindow ();};/ /cframewnd class Cframewnd:public Cwnd{public:cframewnd ();};/ /cview class Cview:public Cwnd{public:cview ();};/ /cwinthread class Cwinthread:public ccmdtarget{public:cwnd* m_pMainWnd; CWinThread (); virtual BOOL InitInstance (); virtual int Run ();};/ /cwinapp class declarations Class Cwinapp:public Cwinthread{public:cwinapp (); virtual bool InitApplication (); virtual bool InitInstance (); Overwrite virtual int Run (); Overwrite};
Description of the time, the CWnd class has created the virtual function of the window, Create,createex (the former extension version), PreCreateWindow. It is therefore necessary to overwrite these functions when actually writing their derived classes. There are important initapplication () functions in CWinApp and InitInstance () and Run () that inherit from CWinThread, which are typically overwritten by their derived classes. It is worth mentioning that CWinThread has a data member cwnd* m_pMainWnd, which is a pointer to the frame window object.
afx.h//demo required, MFC does not actually contain <iostream> #include <iostream>using namespace std;//actually the following are written in <windef.h >, MFC is usually programmed to automatically include the header file, which is convenient for the demonstration to write this typedef int BOOL; #define TRUE 1;//cobect class declares Class Cobject{public:cobject ();};
The ancestor class CObject was declared in "Afx.h".
OK, so far, all the header files have been created, and the next step is to write their corresponding. cpp files. In the presentation, we add an output to the constructors of all classes to facilitate runtime viewing.
The first is the implementation of four customer classes:
Mydoc.cpp#include "stdafx.h" #include "MyDoc.h" Cmydoc::cmydoc () {cout<< "Cmydoc Constructor." <<endl;}
Myframe.cpp#include "stdafx.h" #include "MyFrame.h"//cmyframe class method Definition Cmyframe::cmyframe () {cout<< "Cmyframe Constructor. " <<endl;}
//MyView.cpp #include "stdafx.h" #include "MyView.h"//cmyview class method Definition Cmyview::cmyview () {cout<< "CMyView Constructor." <<endl;}
My.cpp#include "stdafx.h" #include "My.h" #include "MyFrame.h" #include "MyDoc.h" #include "MyView.h"// The CMyWinApp class method defines Cmyapp::cmyapp () {cout<< "CMyApp Constructor." <<endl;} BOOL cmyapp::initinstance () //Cover {cout<< "Cmyapp::initinstance ()." <<endl;//The following comments are the contents of the MFC source code, using Rtti to instantiate the Cmydoc,//cmyframe, CMyView, and use the CDocTemplate class to connect the document template that manages the/*//registration application. Document Template//will use the connection between the composition document, frame window and view csingledoctemplate* pdoctemplate;pdoctemplate = new CSingleDocTemplate (Idr_mainframe, Runtime_class (Cmydoc), Runtime_class (cmyframe), //main SDI frame window runtime_class (CMyView)); if (!pdoctemplate) return FALSE; AddDocTemplate (pdoctemplate); */this->m_pmainwnd = new Cmyframe (); return TRUE;} Global variable CMyApp theapp;int main () {theapp.initapplication (); Theapp.initinstance (); Theapp.run (); return 0;}
explain several points, InitInstance () in the comment is the source code in MFC, I posted here is to let everyone understand that MFC is at this time instanced Cmydoc, Cmyframe and CMyView, as for what Runtime_class is, The next few chapters are detailed in the blog.
Why is MFC not WinMain ()?
Watch out! The most important thing comes! "My.cpp" has a very critical global object CMyApp Theapp, which is the key to the entire MFC initialization. Since the construction of global objects in C + + will be earlier than the program entry point (DOS environment is main,windows to WinMain), the CMyApp constructor is first executed to complete a series of initializations. Notice that there is a main () function in the demo program, but the MFC program does not (the Window program main function is actually WinMain ()), then where does it go? MFC encapsulates WinMain () and automatically calls the WinMain () function after the instantiation of the CMyApp Theapp and obtains a pointer to the Theapp object to manipulate it, making the user appear to be theapp the entry point of the program.
Then there is the remaining in MFC. cpp Files:
Stdfx.cpp#include "StdAfx.h"
Afx.cpp#include "Afx.h"//cobject class declaration Cobject::cobject () {cout<< "CObject Constructor." <<endl;}
Afxwin.cpp#include "AFXWIN.h"//import "CMyApp.h" here in order to use the THEAPP global variable to use the modified version of AfxGetApp () #include "My.h" extern CMyApp The Theapp;//ccmdtarget class method defines Ccmdtarget::ccmdtarget () {cout<< "CCmdTarget Constructor." <<endl;} The CDocument class method defines cdocument::cdocument () {cout<< "CDocument Constructor." <<endl;} The CWnd class method defines Cwnd::cwnd () {cout<< "CWnd Constructor." <<endl;} BOOL cwnd::create () {cout<< "CWnd::Create ()." <<endl;return TRUE;} BOOL Cwnd::createex () {cout<< "Cwnd::createex ()." <<endl;return TRUE;} BOOL CWnd::P recreatewindow () {cout<< "CWnd::P Recreatewindow ()." <<endl;return TRUE;} The CFrameWnd class method defines Cframewnd::cframewnd () {cout<< "CFrameWnd Constructor." <<endl;} The CView class method defines Cview::cview () {cout<< "CView Constructor." <<endl;} The CWinThread class method defines Cwinthread::cwinthread () {cout<< "CWinThread Constructor." <<endl;} BOOL cwinthread::initinstance () {cout<< "cwinthread::initinstance ()." <<endl;return TRUE;} int Cwinthread::run () {cout<< "Cwinthread::run ()." <<endl;return 1;} The CWinApp class method defines Cwinapp::cwinapp () {cout<< "CWinApp Constructor." <<endl;} BOOL cwinapp::initinstance () {cout<< "CWinApp::InitInstance ()." <<endl;return TRUE;} BOOL cwinapp::initapplication () {cout<< "cwinapp::initapplication ()." <<endl;return TRUE;} int CWinApp::Run () {cout<< "CWinApp::Run ()." <<endl;return 1;}
It is important to note that the InitInstance () virtual function is declared in CWinThread, and initapplication () is declared in CWinApp.
Call me! Done! Run the result as follows, you can look at the results of MFC initialization process:
Operation Result:CObject Constructor.
CCmdTarget Constructor.
CWinThread Constructor.
CWINAPP Constructor.
CMyApp Constructor.
Cwinapp::initapplication ().
Cmyapp::initinstance ().
CObject Constructor.
CCmdTarget Constructor.
CWnd Constructor.
CFrameWnd Constructor.
Cmyframe Constructor.
CWinApp::Run ().
briefly summarize the MFC initialization process:
first initialize the global object Theapp, complete the initialization in Theapp's InitInstance () function, including the frame window class, the view class, the document class (and the document template Class), and then use the message mechanism to communicate the objects of these classes, it is important to note the inheritance hierarchy of these classes.
Create an MFC project
The next step is to create a real MFC program and compare it to the above simulated MFC, and create the method at the bottom of the article in Appendix two. So how do you see "AFXWIN.h" and "Afx.h"? For example, you can simply double-click "My.cpp" to move the mouse to the right-click on the CMyApp and go to the definition to easily jump to the appropriate location. Should now be able to have a general positioning of this heap of files.
Appendix I: Creating MyMFC with existing code
code Download Link: http://download.csdn.net/detail/raito__/9552324
file--New->visual C + +->WIN32->WIN32 Console Application Modify name MyMFC
Click Next, select [Empty Project], and click OK.
Open your project directory (if you don't know where, click the file--and the nearest file to see it), go to Mymfc, and then go to MYMFC and copy all the code to the current location. (The code has a download link at the bottom of the article)
In the Solution Explorer interface, add an existing item, such as the right-click Header file, to find the location of the code copy, and add all the header files into the project. (Press and hold the CTRL key to select multiple) the source files are also manipulated.
Double-click My.cpp Compilation (CTRL+F7) to run (CTRL+F5).
Appendix II: Creating an MFC Projectfile, new->visual C + +->MFC->MFC application, change name to: OK
Select • Single Document • Use MFC in a static library
Click [Next] until the [generated class] interface, click CMainFrame to modify the class name/file name to MyFrame (for form unification)
Click Finish
Note: You need to open Stdafx.cpp in Solution Explorer to compile (CTRL+F7), then open My.cpp to compile, to run (CTRL+F5), otherwise it will be an error. (because the content in stdafx.h needs to be imported first) The result of the run is as follows (the unrelated window has been closed).
Watch out! If the program error: [Cannot open include files: "MainFrm.h": No such file or directory] because the VS modified file name is a bit small problem, very simple, double-click the error, [#include "MainFrm.h"] modified to [# Include "MyFrame.h"] recompile.
MFC six mechanisms (1) Initialization of MFC programs