These two functions are two very important virtual functions of the basic class cwnd of MFC, which is always annoying.
Class cwnd: Public c0000target
{
Public:
Virtual bool precreatewindow (createstruct & CS );
Virtual void presubclasswindow ();
Bool subclasswindow (hwnd );
};
The virtual functions in the parent class can be re-implemented by the quilt class to achieve polymorphism. Generally, the base class has a default implementation.
Msdn defines these two functions.
Precreatewindow:
Called by the framework before the creation of the Windows window
Attached to this cwnd object.
This object is called by the framework before the window is created and attach to the cwnd object referred to by this pointer)
Presubclasswindow:
This member function is called by the framework to allow other necessary
Subclassing to occur before the window is subclassed.
The window is called by the Framework before being subclassed to allow other necessary subclassing requests)
Although I already have a translation, let me explain the attach of cwnd and the subclass of the window! To understand attach, we must know the difference between a C ++ cwnd object and a window handle (window): A window handle is a Windows system-level concept, it represents a specific window handle. You can operate on this handle to modify the behavior of window properties. SDK Programming
.
Cwnd is the c ++ encapsulation of Windows by MFC class. Attach is to establish an association between the cwnd object and the window handle. In this way, you can use the interface of the cwnd object to modify the actual window
Attributes and behaviors.
Well, precreatewindow is called by framework before the window is created, and the function name also describes this. Pre should be the abbreviation of previous, and presubclasswindow should be called by framework before the subclass window. You may not know when to rewrite the function. The author of Luo luochao, please use code to speak! Before the source code, there is no secret ). Let's take a look at the implementation of these three functions in MFC!
Bool cwnd: createex (DWORD dwexstyle, lpctstr lpszclassname,
Lpctstr lpszwindowname, DWORD dwstyle,
Int X, int y, int nwidth, int nheight,
Hwnd hwndparent, hmenu nidorhmenu, 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 =: createjavaswex (CS. dwexstyle, CS. lpszclass,
CS. lpszname, CS. style, CS. X, CS. Y, CS. CX, CS. Cy,
CS. hwndparent, CS. hmenu, CS. hinstance, CS. lpcreateparams );
Return true;
}
// For child windows
Bool cwnd: precreatewindow (createstruct & CS)
{
If (CS. lpszclass = NULL)
{
// Make sure the default window class is registered
Verify (afxdeferregisterclass (afx_wnd_reg ));
// No wndclass provided-use child window default
Assert (CS. Style & ws_child );
CS. lpszclass = _ afxwnd;
}
Return true;
}
Cwnd: createex first sets CS (createstruct), and calls the cwnd: precreatewindow function before calling the true window creation function: createjavaswex, the parameter CS is passed in as a reference. The cwnd precreatewindow function only assigns values to CS. lpszclass. After all, no window class is specified in the parameters of the window creation function cwnd: createex, this is indispensable (see <windows programming> Chapter 3 ). Therefore, to modify the CS member variables such as the window size, style, and window class to which the window belongs, rewrite the precreatewindow function.
// From vs install pathvc98mfcsrcwincore. cpp
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 ());
If (* lplpfn = NULL)
* Lplpfn = oldwndproc; // The first control of that type created
# Ifdef _ debug
Else if (* lplpfn! = Oldwndproc)
{
: Setwindowlong (hwnd, gwl_wndproc, (DWORD) oldwndproc );
}
# Endif
Return true;
}
Void cwnd: presubclasswindow ()
{
// No Default Processing
}
Cwnd: subclasswindow first calls the attach (hwnd) function to associate the cwnd object with the window indicated by hwnd. Then, presubclasswindow is called before: setwindowlong is used to modify the window (subclass. Cwnd: presubclasswindow is nothing.
In the implementation of cwnd, in addition to cwnd: subclasswindow, presubclasswindow is called. The code of the createex function listed above calls an afxhookwindowcreate function. See the following code:
// From vs install pathvc98mfcsrcwincore. cpp
Bool cwnd: createex ()
{
// Allow modification of several common create parameters
If (! Precreatewindow (CS ))
{
Postncdestroy ();
Return false;
}
Afxhookwindowcreate (this );
Hwnd =: createjavaswex (CS. dwexstyle, CS. lpszclass,
CS. lpszname, CS. style, CS. X, CS. Y, CS. CX, CS. Cy,
CS. hwndparent, CS. hmenu, CS. hinstance, CS. lpcreateparams );
Return true;
}
Next, check the afxhookwindowcreate code:
// From vs install pathvc98mfcsrcwincore. cpp
Void afxapi afxhookwindowcreate (cwnd * pwnd)
{
If (pthreadstate-> m_hhookoldcbtfilter = NULL)
{
Pthreadstate-> m_hhookoldcbtfilter =: setwindowshookex (wh_cbt,
_ Afxcbtfilterhook, null,: getcurrentthreadid ());
If (pthreadstate-> m_hhookoldcbtfilter = NULL)
Afxthrowmemoryexception ();
}
}
The main function: setwindowshookex is used to set a hook function _ afxcbtfilterhook. Every time windows generates a window (there are many other similar functions, for more information, see <simple introduction to MFC> Chapter 9th, page 1). The hook function you set will be called.
After this setting, return to the cwnd: createex function and execute: createmediawex to create a window. When the window is generated, the hook function _ afxcbtfilterhook is called. In _ afxcbtfilterhook, The presubclasswindow function is called for the second time. See the following code:
// From vs install pathvc98mfcsrcwincore. cpp
/**///////////////////////////////////// /////////////////////////////////////////
// Window Creation hooks
Lresult callback
_ Afxcbtfilterhook (INT code, wparam, lparam)
{
// Connect the hwnd to pwndinit
Pwndinit-> attach (hwnd );
// Allow other subclassing to occur first
Pwndinit-> presubclasswindow ();
{
// Subclass the window with standard afxwndproc
Oldwndproc = (wndproc) setwindowlong (hwnd, gwl_wndproc, (DWORD) afxwndproc );
Assert (oldwndproc! = NULL );
* Poldwndproc = oldwndproc;
}
}
The presubclasswindow is also called before the setwindowlong function is called to implement the window subclass.