在自繪窗口的時候,子類化是MFC最經常使用的窗體技術之一。什麼是子類化?窗口子類化就是建立一個新的窗口函數代替原來的窗口函數。windows
Subclass(子類化)是MFC中最經常使用的窗體技術之一。子類化完成兩個工做:一是把窗體類對象attach到一個windows窗體實體中(即把一個窗體的hwnd賦給該類)。另外就是把該類對象的消息加入到消息路由中,使得該類能夠捕獲消息。
函數
而一般咱們會碰到DDX_Control、SubclassWindow、SubclassDlgItem等,不一樣的子類化方法。首先先看下面的代碼:spa
void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl) { if ((rControl.m_hWnd == NULL) && (rControl.GetControlUnknown() == NULL)) // not subclassed yet { ASSERT(!pDX->m_bSaveAndValidate); pDX->PrepareCtrl(nIDC); HWND hWndCtrl; pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl); if ((hWndCtrl != NULL) && !rControl.SubclassWindow(hWndCtrl)) { ASSERT(FALSE); // possibly trying to subclass twice? AfxThrowNotSupportedException(); } #ifndef _AFX_NO_OCC_SUPPORT else { if (hWndCtrl == NULL) { if (pDX->m_pDlgWnd->GetOleControlSite(nIDC) != NULL) { rControl.AttachControlSite(pDX->m_pDlgWnd, nIDC); } } else { // If the control has reparented itself (e.g., invisible control), // make sure that the CWnd gets properly wired to its control site. if (pDX->m_pDlgWnd->m_hWnd != ::GetParent(rControl.m_hWnd)) rControl.AttachControlSite(pDX->m_pDlgWnd); } } #endif //!_AFX_NO_OCC_SUPPORT } }
咱們發現 DDX_Control()函數中調用了SubclassWindow(),再看SubclassWindow()裏寫了什麼:code
// 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 else if (*lplpfn != oldWndProc) { ::SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)oldWndProc); } #endif return TRUE; }
而SubclassWindow又與SubclassDlgItem有什麼區別?前者用於一切具備HWND的窗體,後者只限定於對話框控件對象
用法:在OnInitDialog中調用SubclassDlgItem將派生類的控件對象與對話框中的基類控件相鏈接,則這個基類控件對象變成了派生控件對象
路由
總而言之,比較經常使用的就是DDX_Control。get