// From VS Install PathVC98MFCIncludeAFXWIN.H class CWnd : public CCmdTarget ...{ ... public: ... virtual BOOL PreCreateWindow(CREATESTRUCT& cs); virtualvoid PreSubclassWindow(); BOOL SubclassWindow(HWND hWnd); ... };
让人很不容易区分,不知道它们究竟干了些什么,在什么情况下要改写哪个函数?
想知道改写函数?让我先告诉你哪个不能改写,那就是SubclassWindow。Scott Meyers的杰作<<Effective C++>>的第36条是这样的:Differentiate between inheritance of interface and inheritance of implementation. 看了后你马上就知道,父类中的非虚拟函数是设计成不被子类改写的。根据有无virtual关键字,我们在排除了SubclassWindow后,也就知道PreCreateWindow和PreSubClassWindow是被设计成可改写的。接着的问题便是该在什么时候该写了。要知道什么时候该写,必须知道函数是在什么时候被调用,还有执行函数的想要达到的目的。我们先看看对这三个函数,MSDN给的解释:
PreCreateWindow:
Called by the framework before the creation of the Windows window attached to this CWnd object. (译:在窗口被创建并attach到this指针所指的CWnd对象之前,被framework调用)
PreSubclassWindow:
This member function is called by the framework to allow other necessary subclassing to occur before the window is subclassed. (译:在window被subclassed之前被framework调用,用来允许其它必要的 subclassing发生)
// From VS Install PathVC98MFCSRCWINCORE.CPP BOOL CWnd::SubclassWindow(HWND 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 elseif (*lplpfn != oldWndProc) ...{ ... ::SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)oldWndProc); } #endif return TRUE; } void CWnd::PreSubclassWindow() ...{ // no default processing }