Thinking on VC Message Mappings
Author: Hao Qingxin
When learning VC , everyone inevitably uses message mappings. We all know that C is an object-oriented programming language, why do VC implements message mapping? First, we must understand how a Windows program containing messages works. Generally speaking, a Windows program containing messages should include at least two functions: int WinApi WinMain (Hinstance Hinstance, // Hinstance Hinstance Hinstance Hprevinstance, // Handle to Previous Instance LPSTR LPCMDLINE, // Command Line INT ncmdshow /// show state); second: long far pascal wndproc (hwnd hwnd, word message, word wparam, long lparam); we don't have to entangle the details of the program, just understand WndProc in the first function WinMain Function, some understanding is that WinMain tells the Windows system, listened, I know that you have to produce a lot of news, I have a WndProc function to handle the various messages you pass. Of course, the format of the message is the system specified.
Second, it is necessary to understand how C achieves polymorphism.
We know that the key to the achievement of polymorphism is the evening binding (or later binding), which is the compiler and does not specify an absolute address of the call function during compilation, but specifies the partial internal function. Move address.
In order to implement the above functions, the compiler makes us hands and feet.
1. In each class with virtual functions, the compiler is secretly placed a pointer called VpoInter.
2, when the system is run, create a VTABLE for each class, which contains the virtual function address.
3, Vpointer, point to VTABLE, by offset in VTABLE, to find the correct need to call the function address.
Then the encapsulation of the MFC on the Window API
When we use the MFC framework development program, especially when developing interface applications, you must use CWnd or derived a class of CWND. Based on object-oriented design principles, some general functions of CWnd, such as the window university change (OnSize), window movement (ONMOVE), it is best to declare a virtual function in CWND, and then overload them in inherited classes. However, in this way, each related derived class must have a VPointer and a set of recorded VTABLE, and the general function in CWnd is so many, and there is many CWnd derived classes, and it will inevitably lead to the system to run excessive resources. (Memory), this is obviously not suitable.
So how is the MFC implement?
The answer is to use a small virtual function as much as possible in the CWND base class, using message mapping mechanisms.
Everyone can look at the functions in the CWnd class, will find this.
CWnd :: OnMove
AFX_MSG Void Onmove (int X, int y);
The above function is not a virtual function.
How is the last problem message mapping implementation?
In one sentence, it is to utilize macros definition to implement a process-oriented message processing.
For example, there is a message mapping macro in the VC.
Begin_MESSAGE_MAP (CMAINFRAME, CFRAMEWND) / / {{AFX_MSG_MAP (CMAINFRAME)
ON_WM_CREATE () //}} AFX_MSG_MAP
ON_COMMAND (ID_FONT_DROPDOWN, DONOTHING)
END_MESSAGE_MAP ()
After compiling, the code is replaced with the following form (this is just a explanation, the actual situation is much more complicated):
// begin_Message_Map (CMAINFRAME, CFRAMEWND)
CMAINFRAME :: NewWndProc (...)
{
Switch (...)
{
// {{AFX_MSG_MAP (CMAINFRAME)
// ON_WM_CREATE ()
Case (WM_CREATE):
Oncreate (...);
Break;
//}} AFX_MSG_MAP
// ON_COMMAND (ID_FONT_DROPDOWN, DONOTHING)
Case (WM_COMMAND):
IF (HiWord (WP) == ID_FONT_DROPDOWN)
{
Donothing (...);
}
Break;
// end_message_map ()
}
}
In this way, VC eliminates the need for some virtual functions, saving memory space.
Reference:
Thingking In C , Bruce Eckel;
Www.vchelp.net
On the cold rock, only my alone --- Xiao Zhu