Analysis of MFC's running process

Source: Internet
Author: User

Analysis of the running details of MFC program

The MFC program is also a Windows program, so it should also have a winmain, but it is not visible in the program. In fact, before the program entry point, there is a (and only one) global object (Theapp), this is called Application object, when the operating system loads and activates the program, the global object is configured, its constructors are executed first, earlier than WinMain.

A CWinApp replaces WinMain

The derived object of CWinApp is known as Application object, and it is conceivable that CWinApp itself represents a program ontology. The so-called program ontology is related to the program itself but not the data or actions related to the window. The CWinApp class is defined 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 work done by the WinMain of the SDK program in the traditional sense is now done by the three functions of CWinApp:

Virtual BOOL initapplication ();

Virtual BOOL InitInstance ();

Virtual int Run ();

So where does the WndProc function go? CFrameWnd is mainly used to master a window, you can almost say it is used to replace the role of the window function in the SDK program. By building a so-called message map mechanism, MFC automatically sends messages to "specific functions corresponding to messages". For a message map implementation mechanism, see another blog post.

Analysis of running process of two programs

, the left half of the MFC program code, the right half is written by our own program code.

When the program starts executing, the Theapp global object is generated, and the constructor executes. The CWinApp constructor is as follows

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 configured with the initial value due to the birth of the Theapp global object. Theapp configuration Completed, 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;

}

Where 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 action in Cwinapp::cwinapp () described earlier, you know that AfxGetApp is actually getting the CMyWinApp object pointer. So, Afxwinmain in the following:

cwinapp* papp = AfxGetApp ();

Papp->initapplication ();

Papp->initinstance ();

Nreturncode = papp->run;

is actually 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

After initapplication, call InitInstance is called cmywinapp::initinstance ();

That is, call our rewritten InitInstance function.

CFrameWnd::Create Generate main window (and Register window class first)

Cmywinapp::initinstance starts with a new Cmyframewnd object, ready to be used as a C + + object for the main frame window. Calls the constructor of the Cmyframewnd class to call the CREATE function, which produces a window. In the process of calling the CREATE function, create calls the Createex,createex function implementation as follows:

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 (...);

........

}

To be familiar with the programming of the SDK will ask the window class, in fact, the window class in the CREATE function call when the window class parameter null represents the MFC built-in window class to produce a standard frame window.

window display and update

After the Cmyframewnd::cmyframewnd is finished, the window has been born, the program flow is back to cmywinapp::initinstance, and the ShowWindow function is called to display the window. and call the UpdateWindow function to make the Hello program send out the WM_PAINT message.

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

MFC program is also like the SDK program, there is a getmessage/dispatchmesage loop?

CWinApp::Run

The program runs 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 do not overwrite it, so this is equivalent to calling CWinApp::Run (); By studying the Run function, it calls the PumpMessage () function, in which the message loop function is actually processed.

Three finishing

1. The birth of the program:

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

Executes AfxWinInit, which has a call to Afxinitthread, which increases the message queue to as much as 96.

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

Afxwinmain executes 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 window.

Go back to InitInstance to continue execution of ShowWindow, display window.

Execute the UpdateWindow, then issue WM_PAINT.

Go back to Afxwinmain, execute run, and enter the message loop.

2. The program starts running:

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

WM_PAINT via::D ispatchmessage sent to Window 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 is bound to be handled by OnPaint.

3. Program of Death

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

Cmyframewnd does not set the Wm_close handler, so it is handed to the default handler.

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, execute afxwinterm, end the program.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Analysis of MFC's running 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.