MFC control self-painting (vi)

Source: Internet
Author: User


The difference between WindowProc and DefWindowProc


1.
WindowProc is the window handler you defined for your window.
DefWindowProc is the default window handling function provided by the Windows platform
If some messages you do not need to do special processing, call DefWindowProc to deal with it, do not need you to go to those Windows "standard action"

2.
According to 1, obviously, you can only define WindowProc and not define DefWindowProc

Look at MFC's CWnd source code is at a glance
LRESULT Cwnd::windowproc (UINT message, WPARAM WPARAM, LPARAM LPARAM)
{
Onwndmsg does most of the work, except for DefWindowProc call
LRESULT LRESULT = 0;
if (! ONWNDMSG (Message, WParam, LParam, &lresult))//If the message needs to be handled by itself,
The Windows system does not have to be processed by default after processing
LResult = DefWindowProc (message, WParam, LParam); You don't have to deal with it, just give it to Windows.

return lResult;
}


The difference between PreCreateWindow, Presubclasswindow and SubclassWindow in CWnd

MFC (VC6.0) of CWnd and its subclasses have the following three functions://From VS Install PathVC98MFCIncludeAFXWIN.H
Class Cwnd:public CCmdTarget
{
...
Public
...
Virtual BOOL PreCreateWindow (createstruct& CS);
virtual void Presubclasswindow ();
BOOL SubclassWindow (HWND hwnd);
...
};


It is very difficult to distinguish between what they are doing, and under what circumstances to rewrite which function.

Want to know the rewrite function. Let me tell you first which cannot rewrite, that is SubclassWindow. Scott Meyers's masterpiece <<effective C++>> 's 36th is this: differentiate between inheritance of interface and inheritance of implementation. You will soon know that the non-virtual function in the parent class is designed to be overridden by the quilt class. According to the virtual keyword, we ruled out the SubclassWindow, also know that PreCreateWindow and Presubclasswindow is designed to be rewritten. The next question is when it's time to write. To know when to write, you must know when the function is called, and the purpose of executing the function that you want to achieve. Let's take a look at the explanations for these three functions, MSDN:

PreCreateWindow:

Called by the framework before the creation of the Windows window
Attached to this CWnd object.
(translated: Called by the framework before the window is created and attach to the CWnd object referred to by the This pointer)

Presubclasswindow:

This member function was called by the framework of the-allow other necessary
Subclassing to occur before the Windows is subclassed.
(translated: Called by the framework before window is subclassed to allow other necessary
subclassing occurrence)

Although I already have the translation, but let me give a simple explanation to the attach of CWnd and the subclass of the window. To understand attach, we have to know the difference between a C + + CWnd object and a window: window is the real windows, and CWnd is the C + + encapsulation of MFC with the class for Windows. Attach, is to attach the window to the CWnd object operation. After the attach (attach) is complete, the CWnd object is contacted with the window. The subclass of a window refers to the action of modifying the window procedure, not the derived subclass in the object-oriented class.

Well, PreCreateWindow is called by the framework before the window is created, and the function name illustrates this, and the pre should be an abbreviation for previous, Presubclasswindow called by the framework before the subclass window. This is not to say, you may still not know when to rewrite which function. Ro-ro The author, or use the code to speak. Before the source code, there is no secret (the Czech language).      Let's take a look at the three functions in MFC that are implemented in this way. From VS Install PathVC98MFCSRCWINCORE.CPP
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 hwnd =:: CreateWindowEx (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::P Recreatewindow (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 Set CS (createstruct) before calling the real window creation function: CreateWindowEx, called CWnd::P the Recreatewindow function, and passed the argument CS in the way of reference. The PreCreateWindow function of CWnd is only assigned to Cs.lpszclass. After all, the window creation function Cwnd::createex a number of parameters, and no one specifies the window class to create the window, and this is indispensable (refer to <<windows programming >> Chapter III).      So when you need to modify the size of the window, style, the window belongs to the window class and other CS member variables, to overwrite the PreCreateWindow function. From VS Install PathVC98MFCSRCWINCORE.CPP
BOOL Cwnd::subclasswindow (HWND hwnd)
{
if (! Attach (HWND))
return FALSE;

Subclassing to occur
Presubclasswindow ();

Now hooks 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::P Resubclasswindow ()
{
No default processing
}

Cwnd::subclasswindow first calls the function attach (HWND) to associate the CWnd object with the window that the HWND refers to. The Presubclasswindow is then called before using:: SetWindowLong to modify the window procedure (subclass). CWnd::P Resubclasswindow did nothing.

In the implementation of CWnd, in addition to Cwnd::subclasswindow will call Presubclasswindow, there is another place. The above-listed function CreateEx code, which calls a 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 hwnd =:: CreateWindowEx (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;
}

    
then look at 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 ();
     }
     , .....
    }

Its main role:: SetWindowsHookEx function is used to set a hook function (hook function) _afxcbtfilterhook, whenever Windows produces a window (there are many other similar, please refer to << mfc> > 9th, 563 pages), the hook function you set is called.

After this setting is complete, go back to the Cwnd::createex function, execute:: CreateWindowEx to create a window, when the window is generated, will invoke the above set of hook function _afxcbtfilterhook. And it is in _afxcbtfilterhook that the function Presubclasswindow is called the second time. See code below://from VS Install PathVC98MFCSRCWINCORE.CPP
/////////////////////////////////////////////////////////////////////////////
Window Creation Hooks

LRESULT CALLBACK
_afxcbtfilterhook (int code, WPARAM WPARAM, LPARAM LPARAM)
{
...
...
Connect the HWND to Pwndinit ...
Pwndinit->attach (HWND);
Allow and subclassing to occur first
Pwndinit->presubclasswindow ();
...
{
        &n

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.