Summary : This article briefly introduces the VC ++ 6.0 MFC programming method and the MFC application framework.
Keywords: VC ++ 6.0; MFC;ProgramFramework
1. MFC Overview
The MFC application framework is based on the framework. The application established in this framework mode is totally different from the previous Win32 SDK Programming Method in the program structure. Since its launch in early 1990s, MFC has been trying to encapsulate Windows API functions into various logical classes in the class library. This encapsulation of MFC is not simply grouping and packaging API functions, but more attempts to implement all system policies through classes. As more and more system functions are added, the size of MFC is also expanding. Currently, there are more than 200 classes, covers the basic content of common windows, document/visual frameworks, Ole, databases, Internet, and distributed functions. Such a solid program development foundation makes it easier for programmers to develop Windows programs.
MFC provides a wide range of classes with different functions to meet the widest possible needs. The vast majority of MFC classes are derived directly or indirectly from the cobject class. The cobject class provides three important features for Its Derived classes: serialization) support for running-time information and diagnostic debugging. Durability outputs or inputs the persistent data in a class object to an external storage medium, such as a disk file, as a stream; runtime class information (rtci) you can obtain the class name of an object and other information about the object at runtime. Rtci is also an important tool in C ++ except for the run-time type information (rtti) mechanism. Diagnosis and debugging support is an integral part of the cobject class, you can perform a validity check when implementing a cobject derived class and output the status information to the debugging window.
Not all functions provided by MFC are class member functions, and MFC also provides a series of global functions prefixed with afx. Class member functions can only be used in the context of the class object to which they belong, but these afx functions can be used directly anywhere at any time. The following table lists several important afx functions:
Function Name |
Function Description |
Afxabout |
Terminate an application unconditionally. It is usually used when an error cannot be replied. |
Afxbeginthread |
Create a new thread and start execution |
Afxendthread |
Terminate the thread currently being executed |
Afxmessagebox |
Display a Windows message window |
Afxgetapp |
Returns a pointer to an application object. |
Afxgetappname |
Return Application name |
Afxgetmainwnd |
Returns a pointer to the application's main window. |
AfxGetInstanceHandle |
Returns a handle that identifies the current application instance. |
Afxregisterwndclass |
Register a user-defined window class for an MFC Application |
2. MFC encapsulation of API functions
If you have experienced SDK development, you will be deeply touched by the cumbersome programming methods and a large number of Win32 API function calls. API functions of all different functions are put together in the form of global functions. because the number of API functions is large, it is difficult to learn or use them. In contrast, the MFC class library built on the basis of API functions can greatly simplify programming by classifying and encapsulating relevant API functions, only a small amount of work is required for Windows applications written in the MFC class to complete the same task.
Many API functions are encapsulated by MFC into more than 200 classes based on different functions. These classes basically cover most of the functions that may be used for Windows programming. Because there are too many encapsulated MFC classes, we cannot describe them one by one. Next we will give a brief introduction to the encapsulation of API functions using the important cobject and cwnd classes.
The cobject class is one of the most important and basic classes in MFC. It does not support multiple inheritance. The derived class can only have one cobject base class. The cobject class is located at the top of the class hierarchy, and most of the MFC classes are derived from the cobject class. The cobject class includes several basic functions required by all MFC classes: persistence support, runtime class information support, and diagnostic debugging support. The persistence support function is provided by the member functions isserializable () and serialize. The former is used to check whether objects support serialization. If a class can be serialized, The declare_serial macro must be included in the declaration and the implement_serial macro must be included in the implementation. The serialize () function can write objects to an archive file or read objects from an archive file. The member function getruntimeclass () can get a pointer to the cruntimeclass Class Object. Through this pointer, you can get the runtime class information of the object. The cobject class provides the member functions assertvalid () and dump () in diagnostic debugging support. The former can check the validity of the object's memory status, the latter is responsible for dumping the object content to a cdumpcontext object and providing diagnostic services and some useful debugging information.
In MFC, The cwnd class provides the basic functions of all window classes and is a very important class. about 1/3 of the MFC classes are based on this class. This class encapsulates the APIs used to create and manipulate window classes, and uses the message ing mechanism to hide the inconvenient window processing functions used in SDK programming, it is more convenient for message distribution and processing.
The most important encapsulation of the cwnd class is the encapsulation of the API function createwindow (), which is encapsulated as the member function create () of the cwnd class (). From the MFC source file wincore. cpp provided by VC, we can clearly see that the cwnd class encapsulates the createwindow () function. The following describes the implementation of the relevant sections:
Bool cwnd: Create (lpctstr lpszclassname, lpctstr lpszwindowname, DWORD dwstyle, const rect & rect, cwnd * pparentwnd, uint NID, ccreatecontext * pcontext) { // Can't use for desktop or pop-up windows (use createex instead) Assert (pparentwnd! = NULL ); Assert (dwstyle & ws_popup) = 0 ); Return createex (0, lpszclassname, lpszwindowname, dwstyle | ws_child, rect. left, rect. top, rect. right-rect. left, rect. bottom-rect. top, pparentwnd-> getsafehwnd (), (hmenu) NID, (lpvoid) pcontext ); } |
It can be seen that the main work is completed in the createex () member function, and this function is the encapsulation of the API function create‑wex. EncapsulatedCodeConstruct and fill in a createstruct structure that is very similar to the wndclass structure before calling createjavaswex (), and call precreatewindow ().
Bool cwnd: createex (DWORD dwexstyle, maid, DWORD dwstyle, int X, int y, int nwidth, int nheight, hwnd hwndparent, hmenu handle, 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 (! Precreatewindow (CS )) { Postncdestroy (); Return false; } Afxhookwindowcreate (this ); Hwnd =: createmediawex (CS. dwexstyle, CS. lpszclass, CS. lpszname, CS. style, CS. x, CS. y, CS. CX, CS. cy, CS. hwndparent, CS. hmenu, CS. hinstance, CS. lpcreateparams ); # Ifdef _ debug If (hwnd = NULL) { Trace1 ("Warning: window creation failed: getlasterror returns 0x % 8.8x \ n", getlasterror ()); } # Endif If (! Afxunhookwindowcreate ()) Postncdestroy (); // cleanup if createmediawex fails too soon If (hwnd = NULL) Return false; Assert (hwnd = m_hwnd); // shold have been set in send MSG hook Return true; } |
It seems that the encapsulated Window Creation function is much more complicated than the original API function, but this does not mean that the encapsulation of MFC will lead to low programming efficiency, on the contrary, as cwnd appears in the form of a base class in most cases, you can add code to the derived class to complete () to create a window of the derived class.
3. MFC ApplicationProgramFramework
The MFC application framework can be seen as a superset of the basic MFC class libraries. The class libraries are a collection of classes that can be used in any program, the application framework defines the structure of the program. The following is a simple example of using the MFC application framework. Through this routine, you can clearly understand the general structure of the MFC application framework.
// sample01.h file // application class class csample01app: Public cwinapp {< br> public: virtual bool initinstance (); }; // framework window class class csample01frame: Public cframewnd {< br> public: csample01frame (); protected: afx_msg void onpaint (); declare_message_map () }; // sample01.cpp file # include # include "sample01.h" // Application Object csample01app theapp; // Initialize the application instance bool csample01app: initinstance () {< br> m_pmainwnd = new csample01frame (); m_pmainwnd-> showwindow (m_ncmdshow ); m_pmainwnd-> updatewindow (); return true; }< br> // message ing begin_message_map (csample01frame, cframewnd) on_wm_paint () end_message_map () // constructor csample01frame: csample01frame () {< br> Create (null, "MFC Application Framework Program"); }< br> // wm_paint message response function void CS Ample01frame: onpaint () {< br> cpaintdc DC (this); DC. textout (100,100, "Hello world! "); } |
Create a Win32 Application Project sample01, just like writing a sample00 Program (see "CD \ \ sample01 \"), and add the header file sample01.h and the source file sample01.cpp to the project respectively, and write the above Code into the corresponding file. To ensure smooth compilation, you also need to modify the compilation command and use the "Alt + F7" shortcut key to call out the "Project Settings" dialog box, add the option "_ afxdll" at the end of the "Preprocessor definitions" column, separated by commas. Next, you need to add the command line "/MD" at the end of the "Project Options" column and separate them with spaces. Compile and run the program. It can be seen that the effect is the same as that of the sample00 program written in the SDK method. However, the code implementation is more structured and the compilation process is simpler.
Next, analyze the above application framework code. First, let's talk about csample01app, a derived class of the cwinapp class, at the core of the MFC application. The cwinapp class provides message loops and key virtual functions that can obtain messages and distribute them to the application window, by overloading these virtual functions, developers can expand some of the inherent behavior of the application. After the header file afxwin. H is included, you can use some MFC classes including cwinapp in the program. An MFC application has only one application object and must be declared globally. Therefore, this object has been resident in the memory since the program started running.
Because the program using the MFC application framework is still a Windows Application in essence, it is necessary to have a winmain () function as the windows application entry in the program. The reason why the winmain () function is not seen in the previous sample code is that the function has been hidden into the application framework by means of encapsulation. In addition to winmain (), the run () function of the cwinapp class member function is also implicitly executed. This function is also very important. It is responsible for putting messages into the message loop of the application window, run () is called by the winmain () function. When the winmain () function finds the application object, it immediately calls the virtual function initinstance () of the cwinapp class (). Because the basic cwinapp class does not know what kind of main framework window is required, the initinstance () function must be overloaded in the derived class of cwinapp. The initinstance () function is called when the application has started running but the window has not been created. If the window is not created by initinstance (), the application cannot own the window, this means that applications that lack the initinstance () function will not be able to receive and process messages, which is meaningless for Windows applications. It can be seen that deriving from the cwinapp class and reloading the initinstance () function is a necessary condition for compiling the MFC Application Framework Program.
In addition to the application class, the csample01frame class derived from cframewnd also describes the main framework window of the application. Call the cframewnd member function create () of the base class in the constructor. Windows is responsible for creating the actual window structure and linking it to the C ++ object by the application framework.
In this example, most of the functions of the program are actually completed in the basic classes such as cwinapp and cframewnd of MFC. During programming, you only need to write a small amount of functional code in the derived class, c ++ allows you to borrow a large amount of code from the base class in this way without having to copy the code. The application framework is responsible for providing the structure framework of the program. On this basis, developers can add the corresponding implementation code to complete a complete application conveniently. The application framework not only defines the structure of the application, but also contains more C ++ base classes.
4. Summary
the sdk api programming method, the MFC programming method, and the ATL programming method described later in this series of lectures are several commonly used programming methods in VC ++ programming, among them, MFC has become the most commonly used Programming Method by most program developers with its powerful functions and flexible programming methods. This article starts from the basic issues and discusses in detail the MFC and its framework programs, so that readers can have a basic understanding of the MFC programming.