Analysis of MFC's execution process

Source: Internet
Author: User
Tags class definition getmessage message queue

An analysis of the execution details of MFC program

The MFC program is also a Windows program, so it should also have a winmain. But it's not visible in the program. In fact, before the program enters the point. A second (and only one) global object (Theapp). This is called the Application object, and when the operating system loads and activates the program, the global object gets configured and its constructors run first. Earlier than WinMain.

A CWinApp instead of WinMain

The derived object of CWinApp is called Application object, and it is conceivable that CWinApp itself represents a program ontology. The so-called program ontology is a data or action related to the program itself and not to the form. The CWinApp class definition is as follows:

class CWINAPP: public CWinThread

{

//startup args

HINSTANCE m_hinstance;

HINSTANCE m_hprevinstance;

LPTSTR m_lpCmdLine;

int m_ncmdshow;

runing args

cwnd* m_pMainWnd;

cwnd* m_pActiveWnd;

LPCTSTR M_pszappname;

LPCTSTR M_pszregistrykey;

Public:

LPCTSTR M_pszexename; //executable name

LPCTSTR m_pszHelpFilePath; //default based on module path

LPCTSTR M_pszprofilename; //default based on app name

Public:

Virtual BOOL initapplication ();

//overrides for Implementation

Virtual BOOL InitInstance ();

Virtual int ExitInstance ();

Virtual int Run ();

Virtual BOOL OnIdle (LONG lCount);

};

The WinMain of the SDK program in the traditional sense is now completed by the three functions of CWinApp:

Virtual BOOL initapplication ();

Virtual BOOL InitInstance ();

Virtual int Run ();

So where does the WndProc function go? CFrameWnd is primarily used to master a form, and you can almost say that it is used in place of the form function in the SDK program.

By building a so-called message map Mechanism, MFC sends the message itself to the "specific function corresponding to the message".

For a message map implementation mechanism, see another blog post.

Analysis of the process of two program execution

What you see, the left half of the MFC program code. The right half is the program code we wrote ourselves.

When the program starts running, the Theapp global object is generated, and the constructor runs. CWinApp constructors such as the following

Cwinapp::cwinapp (LPCSTR lpszappname)

{

M_pszappname = Lpszappname;

//initialize CWinThread State

afx_module_thread_state* pthreadstate = Afxgetmodulethreadstate ();

Pthreadstate->m_pcurrentwinthread = this;

M_hthread =:: GetCurrentThread ();

M_nthreadid =:: GetCurrentThreadID ();

//initialize CWinApp State

afx_module_state* pModuleState = Afxgetmodulestate ();

Pmodulestate->m_pcurrentwinapp = this;

//in non-running state until WinMain

M_hinstance = NULL;

m_pszHelpFilePath = NULL;

........

}

The member variables in the CWinApp will be given the configuration and initial value due to the birth of the Theapp global object. Theapp configuration is complete, WinMain debut. We did not write the WinMain program code, which MFC was already ready and added directly to the application code by the linker:

extern "C" int WINAPI

_tWinMain (hinstance hinstance, hinstance hprevinstance, LPTSTR lpcmdline, int ncmdshow)

{

Return Afxwinmain (HINSTANCE, hPrevInstance, lpCmdLine, nCmdShow);

}

int AFXAPI Afxwinmain (hinstance 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;

}

Of AfxGetApp is a global function that defines the domain AFXWIN1.INL:

_afxwin_inline cwinapp* AFXAPI AfxGetApp ()

{return afxcurrentwinapp;}

#define AFXCURRENTWINAPP afxgetmodulestate ()->m_pcurrentwinapp

According to the operation in Cwinapp::cwinapp () described previously, it is possible to know that AfxGetApp is actually acquiring CMyWinApp object pointers. So, afxwinmain in this operation:

cwinapp* papp = AfxGetApp ();

Papp->initapplication ();

Papp->initinstance ();

Nreturncode = papp->run;

In fact, it is equivalent to calling:

Cmywinapp::initapplication ();

Cmywinapp::initinstance ();

Cmywinapp::run ();

Thus causing the call:

Cwinapp::initapplication ();

Cmywinapp::initinstance ();//Rewrite the method of the parent class, calling the subclass's

CWinApp::Run ();

Afxwininit--afx Internal initialization operation

AfxWinInit is the first operation following the CWinApp constructor. Here is a summary of its operations

BOOL AFXAPI afxwininit (hinstance hinstance, hinstance hprevinstance, LPTSTR lpcmdline, int ncmdshow)

{

ASSERT (hprevinstance = = NULL);

Set resource handles

afx_module_state* pState = Afxgetmodulestate ();

Pstate->m_hcurrentinstancehandle = hinstance;

Pstate->m_hcurrentresourcehandle = hinstance;

Fill in the initial state for the application

cwinapp* papp = AfxGetApp ();

if (papp! = NULL)

{

Windows Spcific Initialization

Papp->m_hinstance = hinstance;

Papp->m_hprevinstance = hprevinstance;

Papp->m_lpcmdline = lpCmdLine;

Papp->m_ncmdshow = nCmdShow;

Papp->setcurrenthandles ();

}

Initialize thread specific data

if (!afxcontexisdll)

{

Afxinitthread ();

}

return TURE;

}

Cwinapp::initapplication.

BOOL cwinapp::initapplication ()

{

if (Cdocmanager::p staticdocmanager! = NULL)

{

if (M_pdocmanager = = NULL)

{

M_pdocmanager = Cdocmanager::p staticdocmanager;

}

Cdocmanager::p staticdocmanager = NULL;

}

if (M_pdocmanager! = NULL)

{

M_pdocmanager->adddoctemplate (NULL);

}

Else

{

Cdocmanager::bstaticinit = FALSE;

}

return TRUE;

}

These are the things that MFC does for internal management.

Cmywinapp::initinstance

Watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqv/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity /center ">

Following initapplication. Calling InitInstance is called cmywinapp::initinstance ();

That is, call our rewritten InitInstance function.

CFrameWnd::Create Generate main form (and first register form Class)

Watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqv/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity /center ">

Cmywinapp::initinstance starts with a new Cmyframewnd object, ready to be used as a C + + object for the main box form.

Calls the constructor of the Cmyframewnd class to call the CREATE function, which produces a form. During the call to the CREATE function, create invokes the Createex,createex function implementation such as the following:

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;

PreCreateWindow (CS);

Afxhookwindowcreate (this);

HWND hwnd =:: CreateWindow (...);

........

}

You might be familiar with SDK programming here. The form class, in fact, when the form class is called in the CREATE function, the null representation of the form class parameters will produce a standard outer box form with the MFC built-in form class.

form display and update

Watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqv/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity /center ">

After the Cmyframewnd::cmyframewnd is over. The form has been born, and the process is back to cmywinapp::initinstance. The ShowWindow function is called so that the form is displayed and the UpdateWindow function is called to send a WM_PAINT message to the Hello program.

We are very concerned about how this WM_PAINT message is sent to the hands of form functions. And where is the form function?

MFC programs are also like SDK programs. Have a getmessage/dispatchmesage loop?

CWinApp::Run

The program executes to this, and the next execution Papp->run () is equivalent to calling Cmywinapp::run ();

The run function is a virtual function of CWinApp, and we have not rewritten it. So the above operation is equivalent to calling CWinApp::Run (); It calls the PumpMessage () function by reading the Run function to implement the code. In this function, the message loop function is really handled.

Three finishing

1. The birth of the program:

Application object generated, memory is then configured, the initial value is also set up. Afxwinmain

Run AfxWinInit, which has a call to Afxinitthread, to increase the message queue to as much as 96.

Afxwinmain run initapplication.

This is a virtual function of CWinApp, and we don't usually rewrite it.

Afxwinmain run InitInstance.

This is the virtual function of CWinApp, and we must rewrite it.

Cmywinapp::initinstance new has a Cmyframewnd object.

The Cmyframewnd constructor calls create to produce the main form.

Go back to InitInstance and continue running ShowWindow. Display the form.

Run UpdateWindow. Then issued WM_PAINT.

Back to Afxwinmain. Run and enter the message loop.

2. The program starts executing:

The program obtains the WM_PAINT message (by CWinApp::Run in:: GetMessage loop).

WM_PAINT via::D ispatchmessage sent to form function CWnd::D Efwindowproc

In

CWnd::D Efwindowproc passes the message through the message map table.

When a matching item is found in the delivery process, the corresponding function in the project is called. This function is established by the application using macros between Begin_message_map and End_message_map.

Standard message handlers also have standard naming. For example, WM_PAINT must be handled by OnPaint.

3. Program of Death

The user clicks "File/close" and then emits Wm_clos.

Cmyframewnd does not have a wm_close handler set up. The default handler is then given.

The default handler for Wm_close is called::D Estroywindow, and

and issued Wm_destroy.

CWinApp::Run will end its internal message loop after receiving wm_quit. and then call

ExitInstance, this is a virtual function of CWinApp.

Finally go back to Afxwinmain, run Afxwinterm, end the program.

Analysis of MFC's execution process

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.