[Technical learning] talking about the implementation of super-class technology in MFC.

Source: Internet
Author: User

Blog from panr // keywords:
// Object programming, superclass, subclasses, and superclassing
// MFC, cwnd: subclasswindow
// General controls and cmnctrl
//
// Subject:
// Through the analysis of the cwnd: subclasswindow function, we will discuss the implementation of the super class technology in MFC.
//
//
// Background
// I saw a post from mahongxi (roast chicken wings) (color touch) on csdn in-12
// Introduces the concept of form superclassization in MFC. The following is a summary of my personal reply.
//
// Log
// Modify the layout of panr at, and post it to the csdn document center.
// Modify: panr 2002-12-15 errata
// Original: panr
//
// About "document center"
// In that post, we can see that njtu_shiyl (yujing) mentioned the document center,
// I keep wondering where the document center is?
// When I review the post later, I came here with Brother wings.
// So this article is my first time.
// I guess I found the right place...
//
//

I. Overview of superclass
In MFC, the form instance provides the following two capabilities after a form handle is superclass:
1. When we call the member function for the form instance, the corresponding form of the corresponding form handle will be changed directly.
2. messages sent by the system to the corresponding form handle will first pass through the message ing of the form instance

Here is an example:
For example, I wrote a class named csuperedit (the parent class is cedit). In this class, I declared void onchar (uint nchar, uint nrepcnt, uint nflags ); the on_wm_char row is added to the message loop.
Now I just need to declare csuperedit m_edit in the dialog box cprog1dlg; then, in the cprog1dlg: oninitdialog, add the followingCodeTo achieve "superclassization ":
Hwnd hwndcontrol =: getdlgitem (pparent-> m_hwnd, idc_edit1 );
M_edit.subclasswindow (hwndcontrol );

After the supercategory processing:
When we call m_edit.setwindowtext ("<enter a, B, c> ");, the corresponding text on the idc_edit1 form is changed to "<enter A, B, and C>"
When you press the keyboard in the idc_edit1 form, the system will call the csuperedit: onchar function (instead of the original cedit: onchar function) That I wrote myself)

Ii. Overview of superclass
All the secrets are in cwnd: subclasswindow. Let's check what it actually does. The following is the function body (in the wincore. cpp file ):
Bool cwnd: subclasswindow (hwnd)
{
If (! Attach (hwnd ))
Return false;

// Allow any other subclassing to occur
Presubclasswindow ();

// Now hook into the afx wndproc
Wndproc * lplpfn = getsuperwndprocaddr ();
Wndproc oldwndproc = (wndproc): setwindowlong (hwnd, gwl_wndproc, (DWORD) afxgetafxwndproc ());
Assert (oldwndproc! = (Wndproc) afxgetafxwndproc ());
Return true;
}

Presubclasswindow is a non-functional function, so we only need to study two functions to understand the approximate functions of cwnd: subclasswindow cwnd: attach and: afxgetafxwndproc.
In the two, cwnd: attach corresponds to function 1, that is, "When we call a member function on the form instance, the corresponding form of the corresponding form handle will be directly changed"
: The afxgetafxwndproc function corresponds to function 2, that is, "messages sent to the corresponding form handle first pass through the message ing of the form instance"

 

Iii. Implementation of function 1
The function body of cwnd: attach is as follows (in the wincore. cpp file ):
Bool cwnd: attach (hwnd hwndnew)
{
If (hwndnew = NULL)
Return false;

Chandlemap * pmap = afxmaphwnd (true); // create map if not exist

Assert (pmap! = NULL );
Pmap-> setpermanent (m_hwnd = hwndnew, this );
Return true;
}
The most important thing is m_hwnd = hwndnew (anyone who has been familiar with Windows APIs knows that all form operation functions in Windows use the form handle as a call parameter ), obviously, as long as I save the form handle, I can specify a form in the system and perform operations on the form.
Yes, the idea is that simple. Now we can see that cwnd (don't forget that csuperedit is inherited from cwnd, and cwnd here is actually csuperedit) saves the idc_edit1 handle in the member variable m_hwnd in the attach function, then function 1 is implemented.

As for the chandlemap: setpermanent function, it is used to extend the use period of the handle, and it has nothing to do with "superclass". We will not discuss it here. For details about its implementation, refer to the winhand_.h file.

 

IV. Implementation of function 2
4.1: gwl_wndproc attribute of the form handle
In the previous discussion, I mentioned that function 2 is related to: afxgetafxwndproc. The implementation of this function is like this (also in the wincore. cpp file ):
Wndproc afxapi afxgetafxwndproc ()
{
# Ifdef _ afxdll
Return afxgetmodulestate ()-> m_pfnafxwndproc;
# Else
Return & afxwndproc;
# Endif
}

This refers to the afxgetmodulestate ()-> m_pfnafxwndproc if it is called in the DLL; otherwise, the address of the afxwndproc function is returned. Therefore, in a general executable file, what cwnd: subclasswindow does for function 2 can be simplified to one line: setwindowlong (hwnd, gwl_wndproc, (DWORD) & afxwndproc );

This function is used to set the gwl_wndproc attribute of the form handle hwnd to the address of afxwndproc. The problem that needs to be solved now is: what is the gwl_wndproc attribute of the form handle? In fact, I don't need to say that everyone can guess (because we are discussing the form message, and I have been saying afxwndproc is a function ), it specifies the form message processing function.
This attribute is more accurately described as follows: For all messages sent to the form, the Windows operating system uses this message as the parameter to call the function specified by the gwl_wndproc attribute of the form handle.

4.2: passed to the MFC Environment
(In this section, refer to "25,000 li changzheng" in the chapter "message ing and Command Transmission" in "deep dive into MFC ")
Function 2 can be expressed as: How does the afxwndproc function find the message ing I wrote for The csuperedit class? Or starting from the function body
Lresult callback afxwndproc (hwnd, uint nmsg, wparam, lparam)
{
// Special message which identifies the window as using afxwndproc
If (nmsg = wm_queryafxwndproc)
Return 1;

// All other messages route through message map
Cwnd * pwnd = cwnd: fromhandlepermanent (hwnd );
Return afxcallwndproc (pwnd, hwnd, nmsg, wparam, lparam );
}

As listed above: afxwndproc has only four rows. Obviously, it only wraps the: afxcallwndproc function. It just wraps the hwnd parameter into pwnd, and then converts it to: afxcallwndproc.
: Afxcallwndproc this function is actually doing something, but one of them has a direct relationship with message passing:
Lresult afxapi afxcallwndproc (cwnd * pwnd, hwnd, uint nmsg,
Wparam = 0, lparam = 0)
{
...

// Delegate to object's windowproc
Lresult = pwnd-> windowproc (nmsg, wparam, lparam );

...
Return lresult;
}

Now we can see that through the following two functions: afxwndproc/: afxcallwndproc, messages in the operating system are transmitted to the MFC environment.
Further discussions can focus on lresult cwnd: windowproc (uint message, wparam, lparam );

 

4.3: Conclusion
We can see the transfer: In order to implement different function calls, oop itself provides many methods such as inheritance and virtual functions. MFC is a language for objects.

Now csuperedit is inherited from cedit, and cedit is inherited from cwnd.ProgramCalling csuperedit: onchar is not technically difficult. For example, you can write a virtual function virtual void cwnd: onchar (uint nchar, uint nrepcnt, uint nflags) that responds to keyboard messages in cwnd :: calling onchar in windowproc
So as long as I reload the csuperedit: onchar function, the program will naturally call the function I wrote.

Microsoft has made some optimizations to reduce the volume of program files. It does not use virtual modifiers to modify all functions, instead, the "Response Message and corresponding response function" is registered in a message_map (called message ing.
In the afxmsg_.h file, the on_wm_char macro is defined as {wm_char, 0, 0 ,... & onchar}, which is used to add the onchar function of wm_char and the current class (now csuperedit) to the Message ing registration form.
Now that you have a registration form such as "message ing", you can call csuperedit: onchar to make cwnd receive the wm_char message.AlgorithmAnd code, it is estimated that you and I can implement it within two hours, and I will not be here. For the relevant code in MFC, please refer to the book "in a simple way"

 

========================================================== ====================================

Reference: http://msdn.microsoft.com/en-us/library/ms649784.aspx

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.