The execution sequence of the MFC Program

Source: Internet
Author: User

Many people who have just learned MFC will be confused by MFC. In the past, the main () function in the traditional C language disappeared, and the winmain () function in the window sdk api disappeared. How did the program compiled with MFC start to run? Does MFC comply with the most basic C ++ standards? What is the order in which MFC code runs? Which of the following statements is used to run so many files and functions? Which one is run first? Which one is called? So many "which one" has _^ )? What exactly is so complicated here? When I started learning, I was confused and couldn't understand anything. But in order to learn other things first, I swallowed up and read it, first, I learned some usage of cdialog and cview, and developed a very simple program.
A few days ago, when I was surfing the Internet, I saw many people watching the video tutorial sun Xin VC ++ lecture. It seems that everyone was doing well, so I went to a place to download it. We can see the running mechanism of MFC today, which shows the running sequence of MFC. Sun uses an instance, breakpoint, and continuous debugging and running in the video. (The truth is better than words !!!) It tells us how MFC starts running. Next, I will sort out the materials I have learned from my tutorials and some of my predecessors on the Internet:

Key points: MFC Running Mechanism execution sequence function usage and Call Sequence

Sun repeatedly stated in the video that the program of MFC is exactly the same as that of C language.

By grasping this point, it is easier to understand the running mechanism of the MFC program.

The main function in C is equivalent to the winmain function in MFC.

If you are interested, you can use the breakpoint settings of VC to track the functions described below to understand the execution sequence.

1. C language execution steps

In C, the steps are as follows:

1. Examples of global variable memory allocation are as follows:

# Include <iostream. h>

Int A = 88;

Main (){

Cout <A <Endl;

}

If we set a breakpoint before Main, we will find that a already exists before entering main. That is to say, a global variable like a has been created and initialized before entering the main function.

2. Enter the main function.

Ii. MFC program running steps (mainly initialization)

Open an MFC Appwizard (exe) project and track its execution steps. The following sequence is displayed:

1) global variable definition in cxxapp (the global variable defined before the winmain () function)

Cxxapp theapp;

2) Call the cxxapp Constructor (of course, to create a class, it will first call its own constructor. At this time, winmain () is not running yet. Is it strange? It is similar to the variable A in the above example .)

Cxxapp: cxxapp (){}

3) enter the winmain function (_ twinmain is a macro and the value is winmain) (this function is not written by ourselves and is hidden in a relatively hidden file, D: /program files/Microsoft Visual Studio/vc98/mfc/src/winmain. in CPP .)

_ Twinmain () {}( if you view its definition, # DEFINE _ twinmain winmain, the two are actually the same)

4) Complete initialization: including window class registration, window generation, display, and update

Pthread-> initinstance () (because initinstance is a virtual function, this call is the initinstance () function of the derived class, that is, the function you can see in theapp)

For the MFC program, mainframe, view, toolbar, controlbar, etc. are all windows, so the following window registration and creation, display, and so on need to be called multiple times, each corresponding to a window

(1) Registration window class

Afxenddeferregisterclass () (equivalent to the registerclass () function in the SDK)

(2) create a window

Cmainframe: precreatewindow () // It is an opportunity for us to modify window attributes.

Cframewnd: Create ()

(3) message loop

Pumpmessage ()

Supplement 1:

In MFC, more steps are required to define global variables because (window) class definition is involved.

If global variables involve class definitions (similar to the type definition in C), follow these steps (taking the window class of MFC as an example, this is often used in the SDK, functions written using APIs should be known)

1) Design a window class

2) Registration window class

3) create a window

4) display and update window

5) message loop

Supplement 2: This course involves the source file location of the MFC function.

Root directory

Find the location where you install MFC under vc98, for example, D:/program files/Microsoft Visual Studio/vc98/mfc on my computer. The following provides the relative path. Find the SRC folder under the MFC folder under the installation directory, and the source code under the SRC is the MFC source code.

1. Search for the winmain population:

Path: MFC | SRC | appmodul. cpp:
_ Twinmain (hinstance, hinstance hprevinstance,
Lptstr lpcmdline, int ncmdshow)
{
// Call shared/exported winmain
Return afxwinmain (hinstance, hprevinstance, lpcmdline, ncmdshow );
}
Note: (# DEFINE _ twinmain winmain)

2. for global objects or global variables, memory and initial values have been allocated to global objects or global variables when the program runs the winmain function. (Understand the key to running the constructor cteapp first: cteapp () and then running winmain)
So: cteapp theapp;-> cteapp: cteapp () {}-> _ twinmain (){}
Note: Each MFC program has only one class (Application class) derived from the winapp class, and only one example object from the application class, indicating the application itself. In a Win32 program, the application is represented by the winmain entry function (represented by an example number of an application ). In an MFC-based application, an application object is generated to uniquely represent an application.

3. By calling the constructor of the base class cwinapp during the construction of the Application object, the initialization of the program including Runtime is completed in the constructor of the cwinapp.
Cwinapp constructor: MFC | SRC | appcore. cpp
Cwinapp: cwinapp (lpctstr lpszappname ){...} // The parameter is included, while the cteapp constructor does not explicitly transmit the parameter to the parent class. Do you have the following default parameters for cwinapp:
(In the cwinapp class definition, cwinapp (lpctstr lpszappname = NULL );)
Note: In the cwinapp () function:
Pthreadstate-> m_pcurrentwinthread = this;
Pmodulestate-> m_pcurrentwinapp = This
(This points to the cteapp object of the derived class, that is, theapp)
Debugging: cteapp theapp; (-> cteapp: cteapp ()-> cwinapp: cwinapp () (first call the base class initialization function)-> cteapp: cteapp () -> _ twinmain () {}( the red arrow indicates the sequence of running in sequence)

4. The _ twinmain function calls the afxwinmain () function to complete its functions. (Afx * prefix indicates that this is an application framework function and a global function. The application framework is a framework model that aids in generating applications and organically integrates some classes, we can design our own applications based on these class functions ).
Afxwinmain () function path: MFC | SRC | winmain. cpp:
In the afxwinmain () function:
Cwinapp * PAPP = afxgetapp ();
Note: PAPP stores pointer to the winapp derived class Object (theapp.
// _ Afxwin_inline cwinapp * afxapi afxgetapp ()
// {Return afxcurrentwinapp ;}

Call pthread-> initinstance ()
Note: pthread also points to theapp. Because the virtual bool initapplication () in the base class is defined as a virtual function, when pthread-> initinstance () is called, The initinstance () of the cteapp derived class is called () function.

Nreturncode = pthread-> Run ();
Note: pthread-> Run () completes the message loop.

5. Registration window class: afxenddeferregisterclass ();
File where the afxenddeferregisterclass () function is located: MFC | SRC | appcore. cpp
Bool afxapi afxenddeferregisterclass (long ftoregister ){...}
(Design window class: In MFC, we have designed several default window classes. Based on the selection of different applications, we call the afxenddeferregisterclass () function to register the selected window class.
Debugging: cwinapp ();-> cteapp theapp; (-> cteapp: cteapp ()-> cwinapp: cwinapp ()-> cteapp: cteapp () -> _ twinmain () {}// enter the program
-> Afxwinmain ();-> PAPP-> initapplication ();-> pthread-> initinstance () // parent class initinstance virtual function;-> cteapp: initinstance () // subclass implementation function;-> afxenddeferregisterclass (long ftoregister) // register the selected window class (for document management, register in advance and register in precreatewindow normally) // enter the creation window stage (subsequent debugging is not performed)

6. precreatewindow (): // mainly registers window classes. This function allows the program to modify window parameters multiple times, and this function is also called repeatedly.
Bool cmainframe: precreatewindow (createstruct & CS)
{
If (! Cframewnd: precreatewindow (CS ))
Return false;
Return true;
}
Note:
Cframewnd: precreatewindow () function file: MFC | SRC | winfrm. cpp
Bool cframewnd: precreatewindow (createstruct & CS)
{
If (CS. lpszclass = NULL)
{
Verify (afxdeferregisterclass (afx_wndframeorview_reg ));
// Determine whether the afx_wndframeorview_reg model window class is registered. If not, register it.
CS. lpszclass = _ afxwndframeorview; // color_window background
// Assign the registered window class name to CS. lpszclass
}

If (CS. Style & fws_addtotitle) & afxdata. bwin4)
CS. Style | = fws_prefixtitle;

If (afxdata. bwin4)
CS. dwexstyle | = ws_ex_clientedge;

Return true;
}

Where:
Virtual bool precreatewindow (createstruct & CS); // precreatewindow () is a virtual function. If a subclass has a precreatewindow, The precreatewindow is called. This is a feature of virtual functions.
# Define verify (f) assert (f)
# Define afxdeferregisterclass (fclass) afxenddeferregisterclass (fclass)
Deprecision afx_wndframeorview_reg 0x00008
Const tchar _ afxwndframeorview [] = afx_wndframeorview; // In the wincore. cpp file, it is defined as a global array.
// # Define afx_wndframeorview afx_wndclass ("frameorview ")

7. Create window:
Create () function path: MFC | SRC | winfrm. cpp:
Cframewnd: Create (...){
...
Createex (...); // inherited from the parent class, call cwnd: createex ().
...
}

Cwnd: createex () function path: MFC | SRC | wincore. cpp
Bool cwnd: createex (...){
...
If (! Precreatewindow (CS) // virtual function, if the subclass has a subclass called.
{
Postncdestroy ();
Return false;
}
...
Hwnd =: createjavaswex (CS. dwexstyle, CS. lpszclass,
CS. lpszname, CS. style, CS. X, CS. Y, CS. CX, CS. Cy,
CS. hwndparent, CS. hmenu, CS. hinstance, CS. lpcreateparams );

...
}
Note: the correspondence between the create‑wex () function and the createstruct struct parameter enables us to modify the appearance of the desired window by modifying the CS struct member in precreatewindow (CS) before creating the window. Precreatewindow (CS) // is a virtual function, if the subclass has a subclass called.
Hwnd createmediawex (
DWORD dwexstyle,
Maid,
Lptstr lpwindowname,
DWORD dwstyle,
Int X,
Int y,
Int nwidth,
Int nheight,
Hwnd hwndparent,
Hmenu,
Hinstance,
Lpvoid lpparam
);
Typedef struct tagcreatestruct {// CS
Lpvoid lpcreateparams;
Hinstance;
Hmenu;
Hwnd hwndparent;
Int Cy;
Int CX;
Int y;
Int X;
Long style;
Lpctstr lpszname;
Lpctstr lpszclass;
DWORD dwexstyle;
} Createstruct;

8. Display and update window:
Cteapp class, in teapp. cpp
M_pmainwnd-> showwindow (sw_show); // display window. m_pmainwnd points to the frame window.
M_pmainwnd-> updatewindow (); // update window
Description: Call Sequence
Class cteapp: Public cwinapp {...}
Class cwinapp: Public cwinthread {...}
Class cwinthread: Public c0000target
{
...
Public:
Cwnd * m_pmainwnd;
...
...
}

9. Message loop:
Int afxapi afxwinmain ()
{...
// Perform specific initializations
If (! Pthread-> initinstance ()){...}
// Complete window initialization, complete window registration, and complete window creation, display, and update.
Nreturncode = pthread-> Run ();
// Inherit the basic class run () method and call cwinthread: Run () to complete the message loop
...
}
//////////////////////////////////////// ////////////////////////
Cwinthread: Run () method path: MFC | SRC | thrdcore. cpp
Int cwinthread: Run ()
{...
// Phase2: pump messages while available
Do // message loop
{
// Pump message, but quit on wm_quit
If (! Pumpmessage () // retrieves and processes the message
Return exitinstance ();
...
} While (: peekmessage (& m_msgcur, null, pm_noremove ));
...
}
Note:
Bool peekmessage (,) Function Description
The peekmessage function checks a thread message queue for a message and places the message (if any) in the specified structure.
If a message is available, the return value is nonzero.
If no messages are available, the return value is zero.

//////////////////////////////////////// /////////////////////
Bool cwinthread: pumpmessage ()
{
...
If (! : Getmessage (& m_msgcur, null) // retrieve the message
{...}
...
// Process this message
If (m_msgcur.message! = Wm_kickidle &&! Pretranslatemessage (& m_msgcur ))
{
: Translatemessage (& m_msgcur); // converts messages (such as keyboard messages ).
: Dispatchmessage (& m_msgcur); // callback function for dispatching messages to the window (in fact, the dispatched messages are mapped to messages and processed by the message response function .)
}
Return true;
}

9. Document and view structure:
The View window can be considered as a subwindow of the cmainfram class window.
The document class is a document class.
The DOC-VIEW structure separates the data itself from its display.
Document class: data storage and loading
View class: Display and modify data

10. Integration of document, view, and framework classes:
In the cteapp class cteapp: initinstance () function, the document class, View class, and framework class are organically organized together through the document template.
...
Csingledoctemplate * pdoctemplate;
Pdoctemplate = new csingledoctemplate (
Idr_mainframe,
Runtime_class (ctedoc ),
Runtime_class (cmainframe), // main SDI frame window
Runtime_class (cteview ));
Adddoctemplate (pdoctemplate); // Add to template
...

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/arthur9984/archive/2008/04/22/2315477.aspx

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.