The initiation and death sequence of the MFC Program)

Source: Internet
Author: User
MFC Program Startup and death sequence)

Initiation and death sequence of the MFC Program

 

1. Create the Application Object theapp
The program first produces one (and only one) Application
The object theapp is also a cwinapp object. When a global object is generated, the constructor is executed. Because cmywinapp constructor is not defined, the constructor of the cwinapp class is executed. This function is defined in the appcore. cpp 75th line. You can search for it by yourself. Therefore, the member variables in cwinapp will get the configuration and initial values because of the birth of theapp global object.
2. winmain debut
When programming with SDK, the entry point of the program is the winmain function, and we do not see the winmain function in the MFC program !~
It turns out that she was hidden in the MFC Code . After theapp configuration is complete, winmain comes on stage, slow! Looking at the program, the Code is not connected to the winmain function! I don't know about this. MFC is already ready and directly added to the application code by the linker. It turns out that she is in appmodul. in CPP, we think that after theapp configuration is complete, the program will be transferred to appmodul. CPP is coming. So what is the execution? Let's take a look at the code extracted from appmodul. cpp:
Extern C int winapi
_ Twinmain (hinstance, hinstance hprevinstance, lptstr
Lpcmdline, int ncmdshow)
{
// Call shared/exported winmain
Return afxwinmain (hinstance, hprevinstance, lpcmdline, ncmdshow );
}
_ Twinmain function "_ t" is a macro prepared to support Unicode.

_ The return value of the twinmain function is the return value of the afxwinmain function. The afxwinmain function is defined in the winmain. cpp 21st line. After a little sorting, you can see what this "program entry point" mainly does:
Int afxapi afxwinmain (hinstance, hinstance hprevinstance,
Lptstr lpcmdline, int ncmdshow)
{
Int nreturncode =-1;
Cwinapp * PAPP = afxgetapp ();
Afxwininit (hinstance, hprevinstance, lpcmdline, ncmdshow );
PAPP-> initapplication ();
PAPP-> initinstance ()
Nreturncode = PAPP-> Run ();
Afxwinterm ();
Return nreturncode;
}
The afxgetapp () function is used to obtain the cmywinapp Object Pointer. Therefore, the above functions are equivalent to the following calls:
Cmywinapp: initapplication ();
Cmywinapp: initinstance ()
Cmywinapp: Run ();
Therefore, the following code is called:
Cwinapp: initapplication (); // because cmywinapp has not changed initapplication
Cmywinapp: initinstance () // because cmywinapp has changed initinstance
Cwinapp: Run (); // because the cmywinapp has not rewritten run
A friend who has used the SDK to write a program may now smile.
3. afxwininit-afx internal Initialization
Afxwininit is the first operation after the cwinapp constructor. It mainly performs afx internal initialization operations. This function is defined in appinit. cpp row 24th.

4. Run cwinapp: initapplication.
The operation after afxwininit is PAPP-> initapplication. We know that PAPP points to the cmywinapp object. When you call:
PAPP-> initapplication ();
Equivalent to calling:
Cmywinapp: initapplication ();

However, you need to know that cmywinapp inherits from cwinapp, and initapplication is a virtual function of cwinapp. We have not rewritten it (in most cases, we do not need to rewrite it), so the above operation is equivalent to calling:
Cwinapp: initapplication ();

This function is defined in appcore. cpp row 125th. You can find it by yourself! I won't move it out, and the operations in it are all done by MFC for internal management (in fact, I can't understand it, I know this is the case ).
5. Run cwinapp: initinstance.
After the initapplication function, afxwinmain calls PAPP-> initinstance. When the program calls:
PAPP-> initinstance ();
Equivalent to calling:
Cmywinapp: initinstance ();

However, you must know that cmywinapp inherits from cwinapp, and initinstance is a virtual function of cwinapp. Since we have changed it, the above operation is to call the initinstance function of our (cmywinapp.
6. cframewnd: Create generates the main window (and registers the window class first)

Now we have come to cwinapp: initinstance. This function first creates a cmyframewnd object to generate the main window. Before creating a cmyframewnd pair, you must first execute the constructor cmyframewnd: cmyframewnd (). This function uses the create function to generate a window:
Cmyframewnd: cmyframewnd ()
{
Create (null, hello MFC, ws_overlappedwindow, rectdefault,
Null, mainmenu );
}

Here, create is a member function of cframewnd, which will generate a window. All the friends who have used the SDK programming know that to create the main window, you must first register a window class and specify window attributes, but which window class is used here? The first parameter of the create function (for details about other parameters, refer to msdn or in-depth introduction to MFC). What does it mean to set the window class to null? It means to generate a standard out-of-box window using the built-in air class of MFC. However, our programs generally do not register any window classes! Oh, before the create function generates a window, it will trigger the registration operation of the window class.

Let's dig out what the create function has done first. The create function is defined in winfrm. THE 538th rows of CPP (here I won't copy the code, you can open it by yourself). The function calls the createex function in line 562, because createex is a member function of cwnd, cframewnd is followed by cwnd, so cwnd: createex will be called. This function is defined in wincore. cpp row 665th. The following code is used:
Bool cwnd: createex (DWORD dwexstyle, lpctstr lpszclassname,
Lpctstr lpszwindowname, DWORD dwstyle,
Int X, int y, int nwidth, int nheight,
Hwnd hwndparent, hmenu nidorhmenu, lpvoid lpparam)
{
// Allow modification of several common create parameters
Createstruct Cs;
CS. dwexstyle = dwexstyle;
CS. lpszclass = lpszclassname;
CS. lpszname = lpszwindowname;
CS. Style = dwstyle;
CS. x = X;
CS. Y = y;
CS. Cx = nwidth;
CS. Cy = nheight;
CS. hwndparent = hwndparent;
CS. hmenu = nidorhmenu;
CS. hinstance = AfxGetInstanceHandle ();
CS. lpcreateparams = lpparam;
If you have used SDK programming, you may feel a little bit about the above Code. The precreatewindows called in the function is a virtual function, which is defined in cwnd and cframewnd. The cframewnd: precreatewindow should be called here because this pointer refers to the object. This function is defined in winfrm. cpp line 521st. The following code is used:
bool cframewnd: precreatewindow (createstruct & CS)
{< br> If (CS. lpszclass = NULL)
{< br> verify (afxdeferregisterclass (afx_wndframeorview_reg);
CS. lpszclass = _ afxwndframeorview; // color_window background
}< br>...
}< br> Afxdeferregisterclass is a macro defined in afximpl. h. This macro is shown below:
# Define afxdeferregisterclass (fclass)
Afxenddeferregisterclass (fclass)
Note: The macro here is different from the "let alone MFC". The above code is extracted from Visual C ++ 6.0.

Afxenddeferregisterclass is defined in wincore. cpp row 3,619th. This function is very complex and mainly involves registering five window classes (Wow! How can I use five window classes? I still don't know). The precreatewindow member functions of different classes are called at the moment before the window is generated and ready to register the window class. If the specified window class is null, the system default class is used. The precreatewindow member functions of cwnd and Its Derived classes show the window classes used by the framework for different functions.
7. window display and update

After cmyframewnd: cmyframewnd is completed, the window has been generated; the program flow is returned to cmywinapp: initinstance, so the showwindow function is called to display the window and the updatewindow function is called to send the wm_paint message. In the SDK program, messages are processed by window functions. Where are window functions and how are they delivered to window functions? Let's start with cwinapp: Run.
8. Execute cwinapp: Run -- the source of live water of program life

After executing the cmywinapp: initinstance function, the program goes to the PAPP-> run of the afxwinmain function. Now we know that this will execute the cwinapp: Run function, this function is defined in appcore. line 2 of CPP. The following is the program code:
Int cwinapp: Run ()
{
If (m_pmainwnd = NULL & afxolegetuserctrl ())
{
// Not launched/embedding or/automation, but has no main
Window!
Trace0 (warning: m_pmainwnd is null in cwinapp: Run-quitting
Application. \ n );
Afxpostquitmessage (0 );
}
Return cwinthread: Run ();
}

If (precreatewindow (CS ))
{
Postncdestroy ();
Return false;
}
Afxhookwindowcreate (this );
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 );
...
}

 

The function calls the cwinthread: Run function. This function is defined in line 456th of thrdcore. cpp. I will not copy it here. The function calls the pumpmessage function in Row 3. This function is defined in Row 3 of thrdcore. cpp. The Code is as follows:
Bool cwinthread: pumpmessage ()
{
If (! : Getmessage (& m_msgcur, null ))
{
Return false;
}
// Process this message
If (m_msgcur.message! = Wm_kickidle &&! Pretranslatemessage (& m_msgcur ))
{
: Translatemessage (& m_msgcur );
: Dispatchmessage (& m_msgcur );
}
Return true;
}

The main operation of this function is to send the message from: dispatchmessage to the window function (cwnd: defwindowproc), but the program generally does not provide any window function, but in afxenddeferregisterclass, before registering the five window classes, you have specified the window function:
Wndcls. lpfnwndproc = defwindowproc;

Although the window function is specified as the defwindowproc member function (cwnd: defwindowproc), the message is actually not sent to this place, but a global function named afxwndproc.
9. Connect messages and processing functions-message map mechanism
At this point, the main window has been generated, waiting for various messages, and then calling the corresponding processing function. However, how can messages and processing functions be connected together? MFC uses message
The map mechanism (Message ing mechanism) provides two sets of macros for the "very convenient interface" used by applications. The principle of the two sets of macros is not clear yet and cannot be explained here, the main usage is: first give the processing function in conjunction with declare_message_map () in the class declaration, such:
Class cmyframewnd: Public cframewnd
{
Public:
Cmyframewnd ();
Afx_msg void onpaint (); // For wm_paint
Afx_msg void onabout (); // For wm_command (idm_about)
Declare_message_map ()
}

Then, use the bebin_message_map () and end_message_map () Macros in any location of the corresponding. cpp file (of course not in the function) to add the corresponding messages, such:
Begin_message_map (cmyframewnd, cframewnd)
On_command (idm_about, onabout)
On_wm_paint ()
End_message_map ()

Why does a message automatically flow to the specified function after such a macro? The answer lies in the structure design of message map.

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.