The Nature of MFC

Source: Internet
Author: User

First, Introduction

In the previous topic, purely manual completion of a Windows application, however, in actual development, most of us use the existing class library to develop Windows applications. MFC (Microsoft Foundation Class, Microsoft Basic Class Library) is a Microsoft to simplify the development of programmers and the Windows API into the C + + class, the use of these classes, programmers can effectively complete the Windows platform under the development of applications. It will be analyzed in detail in this topic.

Second, use the wizard to create an MFC program

class libraries to help effectively develop Windows applications in addition to MFC, there are other open source libraries, such as QT, but QT is not developed by Microsoft, in order to better analyze MFC, let us use visual MFC Templates and Wizard tools in studio to create an MFC-based single document (SDI) application.

    1. Start Visual Studio 2010, click the File menu--New project--project, select the Visual C + + language in the Project window that appears, and then select the MFC application, and enter the name of the project as SDIMFC, as shown in.

  

2. After entering the project name click OK button, the MFC Application Wizard window will appear, click Next, Application type select: Single document as shown:

    

3. Click Next, the Third dialog box appears for the MFC Wizard, the composite document supports keeping the default selection, and then click Next in the dialog box that appears to complete the creation of a single-document MFC application. Next, press CTRL+F5 to run the MFC application, and then you'll see the MFC application interface we created, as shown in:

In the above program, we did not write any code, after running it generated a title bar, System menu, with a maximized, minimized box and a adjustable border of the application, all of this work is done by the MFC Wizard tools to help us, that the wizard tool for us to generate a lot of code, The following is a simple MFC program to analyze the next MFC framework.

Third, the MFC framework detailed analysis

Let's look at what code we generated with the MFC Wizard tool. You can see the class shown in VS by clicking on the Class View tab (if you don't see the Class View on the VS interface, which you can display through the view of the menu bar view, and so on).

As you can see, in MFC, the naming of classes begins with the letter "C", which is just a convention that allows developers to quickly identify whether the class belongs to a class in the MFC class library. As you can see from the picture, there are 15 classes in the previously created single document application, but here we only analyze 4 basic classes, because these 4 basic classes are included in every Windows application, and these 4 classes are: CMainFrame class, c+ project name (SDIMFC) +app class, c+ Project name +doc class (i.e. Csdimfcdoc Class) and Csdimfcview class (also the structure of c+ project name +view). The base classes of these 4 classes are all MFC classes, and the base Class View can be viewed by clicking on the icon in the VS Class View. For the class diagram hierarchy diagram in MFC, you can refer to Msdn:http://msdn.microsoft.com/zh-cn/library/ws8s10w4.aspx, (from MSDN), which is a good illustration of the hierarchy chart categories in MFC.

3.1 WinMain functions in MFC applications

A brief introduction to the structure of the MFC application we created earlier, let us delve into the implementation of the MFC application principle, in the previous topic, all Windows under the window application to follow a process: The program first into the WinMain function, and then design the window class, Registers the window class, creates the window, displays and updates the window, and finally enters the message loop, passing the message to the window procedure function for processing. Then in the MFC application, we use the VS Lookup tool in the MFC project to see the WinMain function but cannot find, and then see the CreateWindow function can not find, then is not the MFC application does not need to WinMain function, do not need to create a window? The answer to this question is definitely negative, because MFC applications are like Windows applications, so you must follow the previous topic, but the MFC-provided classes encapsulate these classes, all of which exist in the source code of MFC. Let's go find the entry for the program WinMain function.

Since the WinMain function exists with the MFC source code, naturally we need to know where the source of MFC, in the installation of Visual Studio, we have installed the source of MFC, the specific path is: vs installation path \VC\ATLMFC\SRC\MFC, If you install vs to D:\Program files (x86), the MFC source code path is in: D:\Program files (x86) \microsoft Visual Studio 10.0\vc\atlmfc\src\mfc. The following Windows Search tool to see the existence of the WinMain function in the C + + class, before the search, you need to set up under the Windows Search tool, by default, the Windows Search tool search for content in a location without an index, only search for file names, This needs to be set to search for the file name and content, as shown in the following settings (Win7 folder option under Select Tools):

After the setup is complete, enter WinMain in the search box and you will see a search result as shown:

The implementation of the WinMain function actually in the Appmodul.cpp file, with vs Open the CPP file, you will see the definition of the WinMain function:

extern "C" int winapi_twinmain (hinstance hinstance, hinstance hprevinstance,    _in_ LPTSTR lpcmdline, int ncmdshow) # pragma warning (suppress:4985) {    //call shared/exported WinMain    return Afxwinmain (hinstance, hPrevInstance, lpCmdLine, ncmdshow);}

The above code is _tWinMain function Ah, not I want the WinMain function, is it wrong? For this question, the answer is also negative, we did not find the wrong, here _tWinMain is a macro definition, press F12 can see it represents WinMain. The macro definition source code is as follows (exists in the Tchar.h header file):

/* Program */#define _TMAIN      main//macros define the # define _tWinMain   WinMain

To prove that we found the WinMain is exactly what we need to find the entry function, we can set a breakpoint in the Appmodul.cpp file _tWinMain function, and then press the F5 button to run the SDIMFC program, we found that The SDIMFC program stops at the breakpoint we just set, as shown here:

We have found the implementation of the WinMain function in MFC, but did not understand how the MFC program we created called the _tWinMain function in Appmodul.cpp, that is, how MFC classes in the program relate to the WinMain function? Let's take a look at the Csdimfcapp class (As for why you think of the class, because it's an app, so the guessing program goes into the class before entering the WinMain function), and double-clicking the class in Class View will see the definition of the class in VS, from the class definition. The Csdimfcapp class inherits from the CWinAppEx class, and the CWinAppEx class inherits from the CWinApp, in order to prove that the WinMain class was executed before the Csdimfcapp function, we set a breakpoint in the constructor of the Csdimfcapp class, Then press F5 to run the program, the Discovery program first stops at the constructor of the Csdimfcapp class, and then goes to the _tWinMain function (which is the breakpoint we set earlier). This raises another question-why does the program call Csdimfcapp's constructor first? Now that the constructor is called, an object of the class must be defined, and then we can find that in the Csdimfcapp class, a Csdimfcapp type of global object Theapp is defined, which exists in the SDIMFC.cpp file, with the following definition code:

The only one Csdimfcapp object Csdimfcapp Theapp; Initializes the object, which is initialized with the parameterless construct of the calling class, so the parameterless constructor of the class is called

Then we set a breakpoint at this global object and then press F5 to run the program, and you will find that the program executes in the order that the Theapp global object->csdimfcapp Constructor (the constructor of its parent class is called before calling the constructor of the derived class)->_ The Twinmain function. In an MFC program, the Theapp object is used to uniquely identify an instance of an application, with each MFC program having and only one Application object (this is the Theapp object).

3.2 Design and Registration window classes

Now that we have found the WinMain function in MFC, according to the previous topic, the next step is to find the code for the window class and the registration window class in the MFC application, in the previous topic, the window class and registration are defined in the WinMain function. Let's look at the WinMain function in MFC to help us encapsulate what, in the MFC WinMain function is simply to invoke the Afxwinmain function, let's look at the Afxwinmain specific code:

1//Afxwinmain function 2 int AFXAPI afxwinmain (hinstance hinstance, HInstance hprevinstance, 3 _in_ LPTSTR lpcmdline, int n Cmdshow) 4 {5 ASSERT (hprevinstance = = NULL); 6 7 int nreturncode = 1; 8 cwinthread* pThread = Afxgetthread ( ); 9 cwinapp* papp = AfxGetApp ();//AFX internal INITIALIZATION12 if (! AfxWinInit (HInstance, hPrevInstance, lpCmdLine, nCmdShow)) goto initfailure;14//APP global Initializati ONS (RARE) + if (papp! = NULL &&!papp->initapplication ()) + goto initfailure;18//Perform         Specific INITIALIZATIONS20 if (!pthread->initinstance ()) {if (Pthread->m_pmainwnd! = NULL) 23 {traceappmsg, 0, "warning:destroying non-null m_pmainwnd\n"); Pthread->m_pmai     Nwnd->destroywindow ();}27 Nreturncode = Pthread->exitinstance (); Goto initfailure;29 }
//the Pthread->run function is the completion of the message Loop taskNreturncode = Pthread->run (); initfailure:33 #ifdef _DEBUG34//Check for missing Afxlocktempmap CALLS3 5 if (afxgetmodulethreadstate ()->m_ntempmaplock! = 0) $ {PNS TRACE (traceappmsg, 0, "Warning:temp map lo CK Count Non-zero (%ld) \ n ", Afxgetmodulethreadstate ()->m_ntempmaplock);}40 afxlocktempmaps (); Afxunlocktempmaps ( -1); #endif43 afxwinterm (); return nreturncode;46}

The above code first calls the Afxgetthread function to get a pointer to the CWinThread type, and then calls the AfxGetApp function to get a pointer to the CWinApp type, and then continues to invoke the AfxWinInit function Afx ( Functions prefixed with AFX are initialized internally by the application framework function, application framework, and then Papp calls InitApplication function, which mainly completes the internal management of MFC, which is a virtual function. The implementation in CWinApp is (the function implementation code lookup is viewed in the way described earlier):

View Code

Then continue to call Pthread's InitInstance function, according to F12, the function is declared as virtual function, according to the polymorphism of the class, Here the InitInstance function called in the Afxwinmain function is the InitInstance function that calls the subclass Csdimfcapp, which defines the code as:

 1/csdimfcapp Initialize 2 BOOL csdimfcapp::initinstance () 3 {4///If an application manifest running on Windows XP specifies that you want to 5//use ComCtl32.dll Version 6 or later to enable visualization, 6//Requires Initcommoncontrolsex (). Otherwise, the window cannot be created. 7 Initcommoncontrolsex Initctrls; 8 initctrls.dwsize = sizeof (Initctrls); 9//Set it to include all 10//common control classes to be used in the application. One INITCTRLS.DWICC = icc_win95_classes;12 initcommoncontrolsex (&initctrls); Cwinappex::initinstance () ; 15 16 17//Initialize OLE library if (! AfxOleInit ()) {AfxMessageBox (idp_ole_init_failed); return false;22}23 Rolcontainer (); enabletaskbarinteraction (FALSE); 27 28//Use RichEdit control requires AFXINITRICHEDIT2 ()//Af XInitRichEdit2 (); 30 31//Standard initialization 32//If you do not use these features and you want to reduce the size of the 33//final executable, you should remove the following 34//unwanted specific initialization routines 35//Change to save Storage Settings registry key//TODO: The string should be modified appropriately, 37//For example, modified for company or organization name Setregistrykey (_t ("Application wizard generated local application")); loadstdprofiles  Ettings (4); Load standard INI file options (including MRU) InitContextMenuManager (); InitKeyboardManager (); InitTooltipManager (); Cmfctooltipin Fo ttparams;48 ttparams.m_bvislmanagertheme = true;49 Theapp.gettooltipmanager ()->settooltipparams (AFX_TOOLTIP_ type_all,50 Runtime_class (CMFCToolTipCtrl), &ttparams); 51 52//Register the application's document template.         Document template 53//will use the connection between the composition document, frame window and view csingledoctemplate* pdoctemplate;55 pdoctemplate = new CSingleDocTemplate (56         idr_mainframe,57 Runtime_class (Csdimfcdoc), Runtime_class (CMainFrame),//main SDI frame windows 59 Runtime_class (Csdimfcview)), if (!pdoctemplate), return false;62 adddoctemplate (pdoctemplate); 63 64 65//Analysis Standard shell command, DDE, open file Operation command line CCommandLineInfo cmdinfo;67 parsecommandline (Cmdinfo); 68 69 70 71// Dispatches the command specified on the command line. Returns FALSE if 72//starts the application with/RegServer,/register,/unregserver, or/unregister. if (! ProcessShellCommand (cmdinfo)) return false;75 76//Only one windowThe port has been initialized, so it is displayed and updated with M_pmainwnd->showwindow (sw_show); M_pmainwnd->updatewindow (); 79//Call Drag only if you have a suffix ACCEPTFILES80//In an SDI application, this should occur after ProcessShellCommand return true;82}

In the above code, 77 lines of code and 78 lines of code for the display and update of the window, m_pMainWnd for the window we created, press F12 to go to its definition as a pointer to the CWnd type, the CWnd class is MFC for our predefined standard window class, now we have found the MFC program in the window class, The next step is to find out how to register the Windows in MFC, in MFC, the registration of the window class is done by the Afxenddeferregisterclass function, It is defined in the Wincore.cpp file, the Afxenddeferregisterclass function is also through the AfxRegisterClass function (the function is defined in the Wincore.cpp file) to register the window class, because of the space problem, here does not stick its function of the definition of source code, You can view them in this machine.

3.3 Creating Windows

We have found the MFC design window and registration of the package, and then the MFC program is how to create a window, the function in MFC is done by the CreateEx function of the CWnd class, the function of the declaration in the AFXWIN.h file, the specific code is as follows:

Virtual BOOL CreateEx (DWORD dwExStyle, LPCTSTR lpszClassName,        LPCTSTR lpszWindowName, DWORD dwstyle,        int x, int y , int nwidth, int nheight,        HWND hwndparent, HMENU nidorhmenu, lpvoid lpparam = NULL);

Implementation code in the Wincore.cpp file, our program is created by the CMainFrame window, the CMainFrame class inherits from CFrameWndEx, the class inherits from the Cframewnd,cframewnd class's create function calls the CreateEx function, and The CREATE function of CFrameWnd is also called by the LoadFrame function of the CFrameWnd class. The CREATE function declaration for the CFrameWnd class is located in the AFXWIN.h file, where the implementation code is in the Winfrm.cpp file and the implementation code is as follows:

View Code3.4 Display window and update window

The contents of the InitInstance function in the Csdimfcapp class are the code for the window display and Update window, with the following code:

The only window is initialized, so it is displayed and updated M_pmainwnd->showwindow (sw_show); M_pmainwnd->updatewindow ();
3.5 Message Loops

The run function of the CWinThread class is the task of completing the message loop, which is called in the Afxwinmain function, which is defined in the Thrdcore.cpp file, and its definition code is as follows:

View Code3.6 Window Procedure Functions

In the Afxenddeferregisterclass function, there is one line in the code (red mark below):

BOOL AFXAPI Afxenddeferregisterclass (LONG ftoregister) {    //mask off all classes that is already registered    Afx_m odule_state* pModuleState = Afxgetmodulestate ();    Ftoregister &= ~pmodulestate->m_fregisteredclasses;    if (Ftoregister = = 0)        return TRUE;    LONG fregisteredclasses = 0;    Common initialization    wndclass wndcls;    memset (&wndcls, 0, sizeof (WNDCLASS));   Start with NULL defaults    //Set window procedure function, this refers to the timing of a default window procedure    wndcls.lpfnwndproc =  defwindowproc;< /c13>    wndcls.hinstance = AfxGetInstanceHandle ();    Wndcls.hcursor = Afxdata.hcurarrow;
.....
}

But in fact, MFC does not give all the messages to DefWindowProc this default window process, but instead of using a kind of message mapping mechanism to deal with various messages, MFC message mapping mechanism refers to the class Wizard can be added to the class message handler function, the specific operation is, In Class View, right-click a class and select the Class Wizard to switch to the Messages tab in the Pop-Up MFC Class Wizard form to add a handler for a message, which is the CMainFrame Execution Class Wizard:

The process is similar. NET to add event handlers through the events of a control in WinForm. (The event in WinForm corresponds to a message in MFC.)

At this point, we have analyzed the MFC program operating mechanism, we can find that its experience and the previous presentation is consistent, but MFC we do not need to implement these processes, which are encapsulated by the MFC framework to help us, thereby reducing the amount of developer's task, Put more time on the business logic of the implementation program. Let's go through the process of running the MFC program together:

    • Start the application first with the global Application object Theapp.
    • Calls the constructor of the global Application object, which invokes the constructor of the base class CWinApp, which completes some initialization of the application.
    • Enter into the WinMain function, the _tWinMain function, in which the Afxwinmain function is called, which gets a pointer to the subclass (the Csdimfcapp class in the program), which invokes the InitInstance virtual function, according to the polymorphic principle, The InitInstance function of subclass Csdimfcapp is actually called, and the InitInstance function of subclass Csdimfcapp completes some initialization work of the application, including the registration, creation, window display and update of the window class.
    • Enter the message loop. Although the default window procedure function is set in the registration function, the MFC application actually uses the message-mapping mechanism to process various messages, and when the Wm_quit message is received, the message loop exits and the program ends.
Iv. Document/View structure

The MFC program we created, in addition to the main frame window, has a window that is the View class window that corresponds to the CView class, and the frame window is a parent window of the View Class window, as shown in the relationship between them. The main frame window is the part of the entire application outline, and the View class window is just a blank place in the main frame window.

There is also a Csdimfcdoc class in the MFC program we created earlier, which derives from the CDocument class, which is CCmdTarget, and CCmdTarget is derived from the CObject class, thereby You can tell that the Csdimfcdoc class is not a window class, in fact it is a document class. MFC provides a document/view structure (Document/view), where the document refers to the CDocument class, and the view refers to the CView class. When Microsoft was designing MFC, considering that the data itself should be separated from its display (which is reflected in many Microsoft technologies, such as ASP. NET MVC), the idea was implemented using the document and view architecture. The storage and loading of data is done by the document class, and the display and modification of the data is done by the view class, thus separating the data management and display methods .

V. Summary

Here, the content of this topic is finished, this topic mainly analyzes the operation mechanism of MFC framework, so that MFC application also follow the WIN32 SDK program corresponding process, including Design window class, register window class, create window, display and update window, message loop and window processing function, Only these operations are encapsulated by MFC itself.

Transfer from http://www.cnblogs.com/zhili/p/MFCAnalyze.html

The Nature of MFC

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.