Reading Notes for exploring MFC (11)

Source: Internet
Author: User
Tags case statement

Chapter 2 life and death

 

This part should be an extension of some chapters in Chapter 1. It is no wonder that the first chapter was not detailed enough. Originally, Hou Jie put the big data in this chapter. When I saw the first chapter, I also found a document about the SDK program. It is estimated that it is easier to read this chapter.

 What function library is required?
1. Windows C Runtime function library (such as libc. Lib, msvcrt. Lib, and msvcrtd. Lib)
2. dll import function library (such as gdi32.lib, user32.lib, and kernel32.lib)
3. the MFC function library (afx function library), that is, the application framework body of the MFC, can be static
Links (such as mfc42.dll, mfc42d. dll) can also be dynamically linked (using the corresponding MFC import function library)
Instead, such as mfc42.lib, mfc42d. Lib)
The above work can be automatically completed by IDE.

 Header files required

For SDK programs, you only need to load windows. h;
If it is an MFC program, you also need some other header files:
Stdafx. h: Used as the precompiled header file, which only loads other MFC header files. Automatic Generation with VC
The program will be able to see this file. The following header files are added in this file.
Come in.
Afxwin. h: Each MFC program must load this header file (which appears in the header file above ).
Understand all the MFC classes. Afxwin. h contains afx. H, which is loaded into afxver _. H, and
Load windows. H, that is, the header file that must be loaded by the windows. h SDK function is
Afxwin. H is indirectly loaded.
Afxext. h: when using the toolbar, programs in the status bar must be loaded.
Afxdlgs. H: The program that uses the General dialog box must be loaded.
Afxcoll. h: All programs that use collections classes must be loaded.
Afxres. h: the RC file of MFC must be loaded. Standard resource IDs have default values, which are defined here
For example:
# Define id_file_new 0xe100
# Define id_file_open 0xe101
... ...
These menu items have text descriptions (appear in the status bar), and text descriptions are in the final framework program.
Add the instruction text to the RC file of the program.

Why do we need to pre-compile the header file (precompiled header )?
A program needs to be compiled frequently during the compilation process, but the standard header file of the Windows program is huge and the content remains unchanged. It will take a lot of time to re-compile every time, and it is not necessary. Pre-compilation can save the results of the first compilation of the header file, which can be obtained directly from the disk.

 Simplified MFC program structure

MFC encapsulates the winapi functions called in traditional Win32 programs into different classes, and even several basic functions in the SDK are encapsulated. This section describes the basic structure of the MFC program through a simple Win32 program.

The main body of an SDK program is in the winmain and wndproc functions, and the frameworks of these two parts remain unchanged in all programs. Therefore, MFC encapsulates these two functions with relatively fixed behaviors into two classes:

Winmain internal operations are encapsulated in cwinapp, and cwinapp represents the program body;
Wndproc internal operations are encapsulated in cframewnd, and cframewnd represents a window.

Of course, the winmain and wndproc operations in each program cannot be exactly the same. Therefore, we must derive our own classes based on the two classes above and rewrite some member functions.

Let's take a look at these two classes:

 Cwinapp -- replace winmain

An object derived from cwinapp is called an application object, which is the body of a program. A program body contains a lot of content, such as program-related data or actions unrelated to Windows, command line parameters, three initapplication and initinstance operations, that is, the cwinapp must have the above member variables and member functions.

All the functions to be done in the SDK are completed by three member functions in the cwinapp:
Virtual bool initapplication ();
Virtual bool initinstance ();
Virtual int run ();

These three parts are driven by a function similar to winmain.

 Cframewnd -- replace the position of wndproc

The traditional SDK program uses a swith-case statement to process messages received by the window. The MFC program has a new method. For example, in the hello program, cmyframewnd processes two messages, the statement is as follows:
Public:
Afx_msg void onpain ();
Afx_msg void onabout ();
Declare_message_map ()// This macro is used to associate messages with processing functions.
... ...

 Application Object -- exploiter

In each MFC program, there is only one application object. For example, in hello. CPP, the following declaration is provided:
Cmywinapp theapp;

When the program runs here, the constructor of cmywinapp is called. Because we have not defined this function, the constructor of its parent class is called to complete initialization and configuration work, for example, set some member variables of cwinapp to null and set m_pcurrentwinapp to this.

 Obscure winmain

After the global variable theapp is configured, it starts to enter the winmain function, but this function does not appear in our own code. In fact, this part of code is directly added to our application by the connector.

In a function named _ twinmain, The afxwinmain function is called. The afxwinmain function is defined in winmain. cpp. Its main tasks are:

Int afxwinmain (....) {
Cwinapp * PAPP = afxgetapp ();
Afxwininit (....); // The first operation after cwinapp Construction -- Initialization

PAPP-> initapplication (); //
PAPP-> initinstance (); // B
Nreturncode = PAPP-> Run (); // C

Afxwinterm ();
Return nreturncode;
}

Note the application of knowledge such as A, B, and C, inheritance, virtual, and object pointer.

The following describes several functions in afxwinmain:

 1. afxwininit -- afx internal initialization operation

 
Afxwininit is the first operation after the cwinapp constructor. The main steps are as follows:
1. Get the current global variable theapp address;
2. initialize the global variable (when the global variable is just constructed, it is basically initialized to null, and
Specific values are assigned here );

It is worth noting that in previous versions of VC, winmain calls afxwininit from the very beginning to register four window classes, and these four window classes are not completed in afxwininit.

 2. cwinapp: initapplication

PAPP-> initapplication. Although PAPP is a cwinapp class, it actually calls cmywinapp: initapplication. However, when cmywinapp inherits from cwinapp, you do not need to rewrite the initapplication function, therefore, cwinapp: initapplication () is still called ().

All operations in initapplication are performed for the internal management of MFC.

 3. cmywinapp: initinstance

PAPP-> initinstance (), the final call is cmywinapp: initinstance (). Because the function in cwinapp is an empty function, the application must rewrite the function, that is to say, we need to write this part of code (such as hello. CPP ).

Generally, initapplication and run in cwinapp do not need to be rewritten, but initinstance must be rewritten.

This section consists of the following steps: create a window, display a window, and update a window.

 3.1 cframewnd: Create generates the main window and registers the window class first.

Cmywinapp: initinstance initially new A cmyframewnd object, which triggers the corresponding constructor. Specifically, it calls the cframewnd member function create () to obtain a cmyframewnd object, used as the main window.

The create function has eight parameters, representing the wndclass window class, window title, window style, region, parent window, menu, and so on.

When executing the create function, you first need to load the menu and then call the createex () function. The parent class cwnd: createex () is actually called here ()

In wincore. cpp, cwnd: createex () is defined, mainly as follows:
1. Set Some attribute values;
2. precreatewindow (); this function is a virtual function, mainly used to complete the registration window class operations.
Macro expand, the specific window class will be registered according to the specific type of the window (such as the MDI window, SDI window, etc.)
Afxmdiframe42d, afxframeorview42, etc.), of course, the application framework will
The name is automatically converted to the afx: X: Y: Z: W format and becomes a unique class name. The names X, Y, Z, and W indicate the window wind respectively.
The hex value of the grid, the Hex Value of the window mouse, the Hex Value of the background color, and the Hex Value of the window icon.
3. Other operations (I do not know the specific situation, so I will not be able to understand it until I see it later)

 
 3.2 display and update of Windows

Bool cmywinapp: initinstance (){
M_pmainwnd = new cmyframewnd ();
M_pmainwnd-> showwindow (m_ncmdshow );
M_pmainwnd-> updatewindow ();
Return true;
}

 4. cwinapp: Run -- source of live water for program life

 
PAPP-> Run (); Because run is a virtual function, and you do not need to reload this function, cwinapp: Run () is called. In this function, it mainly calls cwinthread: Run ();

Cwinthread: Run differs from the previous SDK's message loop in that it processes idle time in addition to message loops:
For (;) {// This loop exits only when a wm_quit message is received.
Process idle time;
Process message loops;
}

The message loop is completed by pumpmessage (), which is continuously converted by translatemessage () and dispatchmessage () and sent separately.

After dispatchmessage, the message is sent to the corresponding window function. Of course, the window function is provided by MFC. When we register the window class, we have specified the window function:
Wndcls. lpfnwndproc = defwindowproc;

 Message ing mechanism

In message ing, MFC adopts the default rule, that is, if you see an on_wm_close macro, wm_close and onclose are associated accordingly. Therefore, you only need to declare the message processing function:
Class cmyframewnd :... {
Public:
Afx_msg void onpaint (); // declare the Message Processing Function
......
}

And define the corresponding macro, that is, add on_wm_paint between begin_message_map and end_message_map.

 MFC

The birth of a program
1. Before entering the afxwinmain function, a global application object is generated, and the memory is configured.
Value;
2. Execute afxwininit in afxwinmain, and the latter calls afxinitthread to send the message queue
Increase to 96 as much as possible
3. afxwinmain executes initapplication. This is a virtual function of cwinapp. We usually do not rewrite it;
4. afxwinmain executes initinstance. It is also a virtual function of cwinapp, but we must rewrite it;
5. cmywinapp: initinstance 'new' has a cmyframewnd object;
6. The cmyframewnd constructor calls create to generate the main window. The window class we specified in the create Parameter
Is null, so MFC registers a file named "afxframeorview42d" based on the window type and self-behavior.
Window class;
7. Return to initinstance and continue to execute showwindow. The window is displayed;
8. Execute upadtewindow and send wm_paint;
9. Return to afxwinmain and execute run to enter the message loop.

Program running
1. The program obtains the wm_paint message (obtained by the: getmessage loop in cwinapp: run;
2. wm_paint sends the message via: dispatchmessage to the window function cwnd: defwindowproc;
3. cwnd: defwindowproc transmits messages to the Message ing table;
4. When a project is found to be consistent during the transfer, the corresponding function is called. This function is used
The macro between begin_message_map and end_message_map is set up;
5. Standard Message Processing programs also have standard names. For example, wm_paint must be processed by onpaint.

Program death
1. When you click File/Close, wm_close is sent;
2. cmyframewnd usually does not set the program for processing the message, so it is handed over to the default handler;
3. The default function is to call: destroywindow for wm_close, and then send wm_destroy;
4. The default wm_destroy processing method is to call: postquitmessage, so wm_quit is sent;
5. cwinapp: Run receives wm_quit and regrets the completion of the internal message ,. Then, call exitinstance.
Is a virtual function of the cwinapp, which can be rewritten by the user;
6. Return to afxwinmain, execute afxwinterm, and end the program.

 Callback Function

Linedda () is used in Hello, which is a Windows API function:
Void winapi linedda (INT, Int,Lineddaproc, Lparam );
The preceding parameter specifies the vertical and horizontal coordinates of the start point. This function calculates the pixel coordinates of each screen passing through the corresponding line based on the bresenham algorithm, and calculates one, call the callback function specified by the fifth parameter. The callback function must be of the following type:
Typedef void (callback * lineddaproc) (INT, Int, lparam );
Linedda does not belong to any MFC class. Therefore, you must add the global operator (::):
Void cmyframewnd: onpaint (){
Cpaintdc DC (this );
Crect rect;
Getclientrect (rect );
DC. settextalign (ta_bottom | ta_center );
: Linedda (rect. Right/2,0, rect. Right/2, rect. Bottom/2,
(Lineddaproc) lineddacallback, (lparam) (lpvoid) & DC );
};

The lineddacallback is the callback function we have prepared. It must be declared in the class (according to the callback function type required by linedda) and declared as "static ", this is a hidden parameter that applies the C ++ compiler to common class member functions.

All the functions you designed and called by the Windows system are called callback functions. These functions have certain types to be used in combination with Windows calls.
On the one hand, some Windows API functions use the callback function as one of their parameters, such as the linedda function;
On the other hand, the callback function has the required type to facilitate the preceding API function call.

However, because C ++ adds a hidden this parameter to all member functions (including common callback functions) in the class, and the windows callback function does not require this parameter, when we use a function as the callback function, we must tell the compiler not to add the this parameter. You can:

1. Use the global function as the callback function (in C)
2. Use the static member function as the callback function. (More OO)

 Processing of idle time: onidle

Before processing the message loop, cwinthread also processes the idle time: when it finds that the current status is idle (system or program), it calls the onidle () function. This function is used to maintain the MFC itself.

If you want to process idle time in your own MFC program, you can rewrite the onidle function of the cwinapp derived class.

 Dialog and Control

When we click the "file/about" menu item, the Command Message wm_command (idm_about) is sent to the onabout function. We now generate a cdialog object in the onabout function, about:
Cdialog about ("aboutbox", this); // The former specifies the resource template (in the RC file)
// The latter specifies the owner of the about

Then run the dialog box:
About. domodal ();

 General dialog box
Open dialog box to obtain the file path:

Char szfilters [] = "text files (*. txt) | *. txt | all files (*. *) | *. * |"

Cfiledialog opendlg(
True, // The description dialog box is "Open" instead of "Save"
"TXT", // default Extension
"*. Txt", // default file name
Ofn_filemustexist | ofn_hidereadonly, // specifies the Object Attributes
Szfilters, // available File Types
This) // parent window

If (Opendlg. domodal () = idok){
Filename =Opendlg. getpathname ();
}

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.