MFC running process analysis and MFC running process analysis

Source: Internet
Author: User

MFC running process analysis and MFC running process analysis

Detailed analysis of MFC program running

The MFC program is also a Windows program, so it should also have a WinMain, but it cannot be seen in the program. In fact, before the program enters the point, there is one (and only one) Global object (theApp), which is called the Application object. When the operating system loads and activates the program, the Global Object obtains the configuration, and its constructor executes the configuration first, which is earlier than WinMain.

Replacing WinMain with a CWinApp

The derived object of CWinApp is called application object. It can be imagined that CWinApp itself represents a program ontology. The program ontology is the data or action related to the program itself rather than 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 );

};

In the traditional sense, The WinMain of the SDK program is now completed by 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 grasp a window. You can say that it is used to replace the position of window functions in the SDK program. By built-in a so-called Message Map mechanism, MFC will automatically send messages to "specific functions corresponding to messages. For the Message Map implementation mechanism, see another blog.

Second program running process analysis

The left half is the MFC program code, and the right half is the program code we write ourselves.

When the program starts to execute, theApp is a global object generated and the constructor is executed. 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 CWinApp will get the configuration and initial values because theApp is a global object. After theApp configuration is complete, WinMain will appear. We have not compiled the WinMain program code. This is the code that has been prepared by MFC and is directly added 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;

}

AfxGetApp is a global function in the definition field AFXWIN1.INL:

_ AFXWIN_INLINE CWinApp * AFXAPI AfxGetApp ()

{Return afxCurrentWinApp ;}

# Define afxCurrentWinApp AfxGetModuleState ()-> m_pCurrentWinApp

According to the operation described previously in CWinApp: CWinApp (), we can see that AfxGetApp actually gets the CMyWinApp object pointer. Therefore, the following operations are performed in AfxWinMain:

CWinApp * pApp = AfxGetApp ();

PApp-> InitApplication ();

PApp-> InitInstance ();

NReturnCode = pApp-> Run;

 

Actually it is equivalent to calling:

CMyWinApp: InitApplication ();

CMyWinApp: InitInstance ();

CMyWinApp: Run ();

Therefore, the following code is called:

CWinApp: InitApplication ();

CMyWinApp: InitInstance (); // rewrite the method of the parent class and call

CWinApp: Run ();

 

AfxWinInit -- AFX internal initialization operation

AfxWinInit is the first operation after the CWinApp constructor. The following is its operation summary.

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: pStaticDocManager! = NULL)

{

If (m_pDocManager = NULL)

{

M_pDocManager = CDocManager: pStaticDocManager;

}

CDocManager: pStaticDocManager = NULL;

}

If (m_pDocManager! = NULL)

{

M_pDocManager-> AddDocTemplate (NULL );

}

Else

{

CDocManager: bStaticInit = FALSE;

}

Return TRUE;

}

These are all done by MFC for internal management.

CMyWinApp: InitInstance

After InitApplication, call InitInstance to call CMyWinApp: InitInstance ();

That is, we call the InitInstance function after rewriting.

CFrameWnd: Create generates the main window (and registers the window class first)

 

CMyWinApp: InitInstance creates a CMyFrameWnd object at the beginning and is ready to be used as the c ++ object in the main box window. The constructor of the CMyFrameWnd class is called, and the Create FUNCTION is called to generate a window. During the process of calling the Create FUNCTION, Create will call CreateEx. The CreateEx function is implemented 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 (.....);

........

 

}

If you are familiar with SDK programming, you may ask about the window class, in fact, when the Create FUNCTION is called, the NULL parameter passed by the window class indicates that a standard window will be generated using the built-in window class of MFC.

 

Window Display and update

 

After CMyFrameWnd: CMyFrameWnd is completed, the window has been generated; the program flow has returned to CmyWinApp: InitInstance, so the ShowWindow function is called to display the window, call the UpdateWindow function to send the WM_PAINT message to the hello program.

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

Does an MFC program have a GetMessage/DispatchMesage loop like an SDK program?

 

CWinApp: Run

When the program runs here, pApp-> Run () will be executed, which is equivalent to calling CMyWinApp: Run ();

The Run function is a virtual function of CWinApp, and we have not rewritten it. Therefore, the above operation is equivalent to calling CWinApp: Run (); by studying the Run function, the code will call PumpMessage () function. In this function, it is actually a message loop function.

 

3. Sorting

1. The birth of the program:

The Application object is generated, the memory is configured, and the initial value is also set. AfxWinMain

Run AfxWinInit. The latter calls AfxInitThread to increase the number of message queues to 96.

AfxWinMain executes InitApplication. This is a virtual function of CWinApp. We usually do not rewrite it.

AfxWinMain executes InitInstance. This is a virtual function of CWinApp. We must rewrite it.

CMyWinApp: InitInstance new A CMyFrameWnd object.

The CMyFrameWnd constructor calls Create to generate the main window.

Return to InitInstance and continue to execute ShowWindow. The window is displayed.

Run UpdateWindow, and WM_PAINT is sent.

Return to AfxWinMain and execute Run to enter the message loop.

2. The program starts running:

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

WM_PAINT sends the message via: DispatchMessage to the window function CWnd: DefWindowProc

.

CWnd: DefWindowProc transmits messages to the Message Map table ).

When a project is found to be consistent during the transfer, the corresponding function in the project is called. This function is set up by applications using macros between BEGIN_MESSAGE_MAP and END_MESSAGE_MAP.

Standard Message Processing programs also have standard names. For example, WM_PAINT must be processed by OnPaint.

3. Program death

The user clicks File/Close, and then WM_CLOS is sent.

CMyFrameWnd does not set the WM_CLOSE handler, so it is handed over to the default handler.

The default processing function for WM_CLOSE is called: DestroyWindow, and

WM_DESTROY.

CWinApp: Run ends its internal message loop after receiving WM_QUIT, and then calls

ExitInstance, a virtual function of CWinApp.

Return to AfxWinMain, execute AfxWinTerm, and end the program.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.