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) { TRACE0("Error: Trying to use SubclassWindow with incorrect CWnd\n"); TRACE0("\tderived class.\n"); TRACE3("\thWnd = $%04X (nIDC=$%04X) is not a %hs.\n", (UINT)hWnd, _AfxGetDlgCtrlID(hWnd), GetRuntimeClass()->m_lpszClassName); ASSERT(FALSE); // undo the subclassing if continuing after assert ::SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)oldWndProc); } #endif return TRUE; }
/** * ウィンドウを動的サブクラス化し、CWnd オブジェクトに結び付けるためにこのメンバー関数を呼び出します * @param[in] hWnd ウィンドウ ハンドル * @retval TRUE 成功 * @retval FALSE 失敗 */ BOOL CWndProc::SubclassWindow(HWND hWnd) { if (!Attach(hWnd)) { return FALSE; } PreSubclassWindow(); WNDPROC newWndProc = &CWndProc::WndProc; WNDPROC oldWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWndProc))); if ((m_pfnSuper == NULL) && (oldWndProc != newWndProc)) { m_pfnSuper = oldWndProc; } return TRUE; }
void CSubclassWnd::Subclass(HWND hWnd) { ASSERT(hWnd); // Do you really want to subclass a window that has a NULL handle? ASSERT(!m_bIsSubclassed); ASSERT(m_hWnd == NULL); m_hWnd = hWnd; m_hWndAfter = hWnd; // Store address of the original window procedure m_oldWndProc = (WNDPROC)GetWindowLongPtr(m_hWnd, GWLP_WNDPROC); ASSERT(m_oldWndProc != SubclassWndProc); PreSubclassWindow(); // And set the new one m_oldWndProc = (WNDPROC)(::LONG_PTR)SetWindowLongPtr(m_hWnd,GWLP_WNDPROC,(LONG)(::LONG_PTR)SubclassWndProc); CEventLock lock(CSubclassWnd::m_CS); CSubclassWnd::m_SubclassWndMap[m_hWnd] = this; m_bIsSubclassed = true; }