Keep up with the times, with VS2010, create an MFC application HelloWorld.
Directory structure:
All files are divided into 6 parts: solution-related files, project-related files, application header files and source files, resource files, precompiled header files, and compilation links to deliver files.
1. Solution-related Documents
Solution-related files include the. sdf file, the. sln file, the. suo file, and the Ipch folder under the solution folder.
The. sdf file and the IPCH directory typically occupy a larger space, a few 10 trillion or even hundreds of megabytes, related to smart hints, error hints, code recovery, and team local repositories. If you feel you don't need to, you can set them up without generating them by clicking the menu bar tools->options, pop Up the Options dialog, select the text editor->c/c++->advanced in the left panel, The first item in the list on the right disable database is changed from false to true, and the last time you close VS2010 and then delete the. sdf file and the IPCH directory will not be created again. However, there will be a lot of inconvenience when this option is turned off, such as the smart tip when writing a program.
The. sln file and the. suo file are the MFC auto-generated solution files that contain the project information in the current solution and the settings for the storage solution.
2. Engineering Related Documents
Project-related files include. vcxproj files and. vcxproj.filters files under the project folder.
The. vcxproj file is an MFC-generated engineering file that contains information about the current project's settings and the files that the project contains.. vcxproj.filters files store the project's virtual directory information, which is the directory structure information in the solution browser.
3. Application header files and source files
Depending on the type of application (single document, multi-document, or dialog-based program), the Application Wizard automatically generates some header and source files that are the body of the project and are used to implement the main frame, document, view, and so on. Below is a brief description of each file:
HelloWorld.h: The primary header file for the application. It mainly contains the declaration of the Chelloworldapp class derived from the CWinAppEx class, and the declaration of the Global object Theapp of the Chelloworldapp class.
HelloWorld.cpp: The main source file for the application. It mainly contains the implementation of Chelloworldapp class, the definition of global object Theapp of Chelloworldapp class, etc.
MainFrm.h and MainFrm.cpp: These two files derive CMainFrame classes from the CFrameWndEx class for creating the main frame, menu bar, toolbars, and status bar.
HelloWorldDoc.h and HelloWorldDoc.cpp: These two files derive the document class Chelloworlddoc from the CDocument class, including some member functions for initializing documents, serializing (saving and loading) documents, and debugging.
HelloWorldView.h and HelloWorldView.cpp: They derive from the CView Class A view class known as Chelloworldview, which is used to display and print document data, including some drawings and member functions for debugging.
ClassView.h and ClassView.cpp: derived from the CDockablePane class Cclassview class for implementing class View on the left panel of the application interface.
FileView.h and FileView.cpp: derived from the CDockablePane class Cfileview class for implementing file View on the left panel of the application interface.
OutputWnd.h and OutputWnd.cpp: derived from the CDockablePane class, the Coutputwnd class is used to implement the side panel output under the application interface.
PropertiesWnd.h and PropertiesWnd.cpp: derived from the CDockablePane class Cpropertieswnd class for implementing the Application interface right panel properties.
ViewTree.h and ViewTree.cpp: The Cviewtree class is derived from the CTreeCtrl class for implementing a tree view that appears in ClassView, FileView, and so on.
4. Resource Files
Generally we use the MFC Build Window program will have dialog boxes, icons, menus and other resources, the Application Wizard will generate resource-related files: Res directory, helloworld.rc file and Resource.h file.
Res directory: The Res directory under the project folder contains icon files such as application default icons, toolbar use icons, and so on.
HELLOWORLD.RC: Contains the default menu definition, String table, and accelerator key table, specifying the default About dialog box and application default icon file.
Resource.h: Contains ID definitions for various resources.
5. Precompiled Header File
Almost all MFC programs contain files such as AFXWIN.h, and if compiled once each time, the compilation speed will be greatly slowed down. So the commonly used MFC header files are placed in the StdAfx.h file, and then by Stdafx.cpp contains stdafx.h files, the compiler compiles the stdafx.cpp only once, and generates compiled precompiled header helloworld.pch, greatly improving the efficiency of the compilation.
6. Compile the link to the file
If it is compiled in debug mode, the Debug subfolder is generated under both the solution folder and the project folder, and the release subfolder is generated if the release method is compiled.
The Debug or Release subfolder under the project folder contains the intermediate files that are generated when the link is compiled, and the debug or Release subfolder under the solution folder primarily contains the executable file for the application.
C + + is typically the main function, and the entry function for Windows applications is the WinMain function, and the MFC program starts with the WinMain function. Window Flow: Enter WinMain function, initialize wndclassex, call registerclassex Function Registration window class, call ShowWindow and UpdateWindow function display and update window Enter the message loop. About message loops Simply put, a Windows application is message-driven, a system or user sends a message when the application does something or completes a task, enters the program's message queue, and then the message loop takes the message out of the message queue and hands it to the corresponding window process. The window procedure function of this program is the Mywndproc function, which completes an operation or task when the window procedure function finishes processing the message.
MFC applications
The following is a running process for an MFC application that is parsed through the code in the MFC library:
First, define the global object Theapp:chelloworldapp Theapp in HelloWorld.cpp. After calling the constructors for CWinApp and Chelloworldapp, enter the WinMain function (located in Appmodul.cpp).
extern "C" int WINAPI _twinmain (hinstance hinstance, hinstance hprevinstance, _in_ LPTSTR lpcmdline, int nCmdShow) #pragma warning (suppress:4985) { //call shared/exported WinMain return Afxwinmain ( HINSTANCE, hPrevInstance, lpCmdLine, nCmdShow);
In TCHAR.h, there is this definition: #define _tWinMain WinMain, so the _twinmain here is the WinMain function. It calls the Afxwinmain function (located in WinMain.cpp).
int AFXAPI Afxwinmain (hinstance hinstance, hinstance hprevinstance,lptstr lpcmdline, int ncmdshow) { ............. Abbreviated //APP global initializations (rare) if (papp! = NULL &&!papp->initapplication ()) Goto Initfailure; if (!pthread->initinstance ()) { ... The //Run function is located in THRDCORE.cpp, and this function enters the message loop Nreturncode = Pthread->run (); .............. Slightly return nreturncode;
The code for the above InitInstance function is as follows:
BOOL ctestapp::initinstance () {....... Slightly csingledoctemplate* pdoctemplate; Pdoctemplate = new CSingleDocTemplate ( idr_mainframe, runtime_class (Ctestdoc), runtime_class ( CMainFrame), //main SDI frame window runtime_class (Ctestview)); if (!pdoctemplate) return FALSE; AddDocTemplate (pdoctemplate); Parse command line to standard shell commands, DDE, File open ccommandlineinfo cmdinfo; ParseCommandLine (cmdinfo); ProcessShellCommand is located in AppUI2.cpp, register and create the window if (! ProcessShellCommand (cmdinfo)) return FALSE; M_pmainwnd->showwindow (sw_show); M_pmainwnd->updatewindow (); return TRUE; }
The ProcessShellCommand function in InitInstance called CMainFrame's LoadFrame function to register and create the window, and after the ProcessShellCommand function was executed, M_ was called. The pMainWnd ShowWindow and UpdateWindow functions display and update the frame window. Is this similar to the SDK program above?
Next is the message loop, which calls the Pthread run function (located in THRDCORE.cpp) in the Afxwinmain function above, which contains the message loop in run. The code for the run function is as follows:
int Cwinthread::run () {....... Slightly//Phase2:pump messages while available do {//pump Messa GE, but quit on Wm_quit if (! PumpMessage ()) return ExitInstance (); Reset "No idle" state after pumping "normal" message if (Isidlemessage (&m_msgcur)) {bidle = TRUE; Lidlecount = 0; }} while (::P eekmessage (&m_msgcur, NULL, NULL, NULL, pm_noremove)); .............. slightly} BOOL CWinThread::P umpmessage () {return afxinternalpumpmessage (); } BOOL AFXAPI Afxinternalpumpmessage () {_afx_thread_state *pstate = AfxGetThreadState (); if (!::getmessage (& (Pstate->m_msgcur), NULL, NULL, NULL)) { ............. A little bit} ....... Slightly if (pstate->m_msgcur.message! = Wm_kickidle &&! Afxpretranslatemessage (& (Pstate->m_msgcur))) {:: TranslateMessage (& (Pstate->m_msgcur )); ::D ispatchmessage (& (Pstate->m_msgcur)); } return TRUE; }
We see PumpMessage in the GetMessage, TranslateMessage, DispatchMessage, and so on to establish a message loop and post messages.
The window procedure function Afxwinproc in the following form:
LRESULT CALLBACK AfxWndProc (HWND hwnd,uint nmsg,wparam WPARAM, LPARAM LPARAM) { ... Cwnd*pwnd=cwnd::fromhandlepermanent (hWnd); Returnafxcallwndproc (Pwnd,hwnd,nmsg,wparam,lparam); }
The process of running an MFC application is also a process of initializing, registering and creating the window, then displaying, updating, and finally entering the message loop, which is handled by the window procedure function.
Windows applications are message-driven. In MFC software development, the interface operation or the communication between the threads will often use the message, through the processing of the message to achieve the corresponding operation. The typical process is that the user operates the window, and then a message is generated that is sent to the window to handle the message processing function, responding to the user's actions.
What is a message
window messages generally consist of three parts: 1. An unsigned integer, which is a message value, (2) A parameter of the type of wparam that accompanies the message, and (3) a parameter of the LPARAM type that accompanies the message. In fact, we generally say that the message is a narrow sense of the message value, that is, an unsigned integer, often defined as a macro.
What is the message mapping mechanism
MFC uses a message-mapping mechanism to process messages, and in the application framework, it behaves as a message-map table corresponding to message-processing function one by one, as well as code for declaring and implementing a message-handling function. When a window receives a message, it looks in the message map for the message handler function that corresponds to the message, which is then handled by the message handler function accordingly. SDK programming needs to be in the window process to determine the message value of the corresponding processing, in contrast to MFC's message mapping mechanism to facilitate the use of more.
Windows message Classification
Let's start with the classification of Windows messages. Windows messages are divided into system messages and user-defined messages. There are three types of Windows system messages:
1. Standard Windows messages. Messages that begin with WM_ except WM_COMMAND are standard messages. For example, Wm_create, Wm_close.
2. Command message. The message name is WM_COMMAND, which is accompanied by an identifier ID to differentiate the message from which menu, toolbar button, or accelerator key is coming from.
3. Notification message. The notification message is typically sent to the parent window by a child window such as a list box, and the message name is WM_COMMAND, which comes with a control notification code to differentiate the control.
All derived classes of CWnd can receive standard Windows messages, notification messages, and command messages. Command messages can also be received by the document class, and so on.
User-defined message is actually a user-defined macro as a message, the value of this macro should be greater than or equal to Wm_user, then this macro can be used as a system message, the window class can define its handler function.
Message map Table
In addition to some directly derived classes of classes or CObject that do not have base classes, other classes can automatically generate message map tables. The following explanations are based on the cmainframe of the preceding routines HelloWorld. The message map table is as follows:
Begin_message_map (CMainFrame, CFrameWndEx) on_wm_create () on_command (id_view_customize, &cmainframe: : onviewcustomize) on_registered_message (Afx_wm_createtoolbar, &cmainframe::ontoolbarcreatenew) ON_ Command_range (id_view_applook_win_2000, id_view_applook_windows_7, &cmainframe::onapplicationlook) ON_ Update_command_ui_range (id_view_applook_win_2000, id_view_applook_windows_7, &cmainframe::o Nupdateapplicationlook) on_wm_settingchange () End_message_map ()
The content between Begin_messag_map and End_message_map becomes the message map entry entry. Message map In addition to adding a message map table to the CMainFrame implementation file, a macro call is added to the class definition file MainFrm.h:
Declare_message_map ()
Typically this macro call is written at the end of the class definition.
Add a message handler function
How do I add a message handler function? There are three steps to adding either automatically or manually:
1. Add the function declaration of the message handler function to the class definition, and note that the afx_msg starts with a. For example, the function declaration of the WM_CREATE message handler function in MainFrm.h: afx_msg int OnCreate (lpcreatestruct lpcreatestruct);.
2. Add the message map entry entry for the message in the class's message map table. For example, the message map entry entry for wm_create: On_wm_create ().
3. Add a function implementation of the message handler function in the class implementation. For example, the implementation of the message handler function in MainFrm.cpp wm_create:
int CMainFrame::OnCreate (lpcreatestruct lpcreatestruct)
{
......
}
With the above three steps, messages such as wm_create can be processed by the message handler function in the window class.
Message handler functions for various Windows messages
The message handler functions for standard Windows messages are similar to wm_create messages.
The message map entry form for the command message is as follows: On_command (Id_view_customize, &cmainframe::onviewcustomize), message id_view_customize, The message handler function is onviewcustomize.
If you want to process some command messages in bulk using a handler, you can like On_command_range in the CMainFrame message map table (id_view_applook_win_2000, Id_view_applook_windows_ 7, &cmainframe::onapplicationlook) Add the message-map entry entry so that the value is id_view_applook_win_2000 to Id_view_applook_windows_ command messages, such as menu items between 7, are handled by CMainFrame's Onapplicationlook function. The function prototype is afx_msg void Onapplicationlook (UINT id), and the parameter ID is the ID of the menu item, such as the user action.
WM_NOTIFY notification messages are often sent to the parent window when manipulating controls such as a list box. The wparam parameter of the WM_NOTIFY message points to a struct that is the Id,lparam parameter of the control that sent the notification message, either the NMHDR struct or the other struct that the first element is a NMHDR struct variable. The NMHDR structure is defined as follows (for understanding only):
Typedef STURCT tagnmhdr{
HWND Hwndfrom;
UINT Idfrom;
UINT Code;
} NMHDR;
Hwndfrom is the handle to the notification message control, idfrom the control id,code the notification code for the notification message to be processed, such as Nm_click.
The message map entry form for the notification message is as follows:
On_notify (WNOTIFYCODE,ID,MEMBERFXN)
wNotifyCode is the notification code for the notification message to be processed, for example: Nm_click. ID is the ID of the control ID. Memberfxn the handler function for this message.
The prototype of the handler function for the notification message is:
afx_msg void Memberfxn (NMHDR * pnotifystruct, LRESULT * result);
If you need to use a user-defined message, first define the message macro, such as: #define WM_UPDATE_WND (wm_user+1), and then add the message map entry entry to the message map table: On_message (Wm_update_wnd, & Cmainframe::onupdatewnd), and then add the function declaration of the message handler function in MainFrm.h: afx_msg LRESULT onupdatewnd (WPARAM WPARAM, LPARAM LPARAM); Finally, this function is implemented in MainFrm.cpp.
The directory structure and message Flow of MFC (i)