/***************************************************************************** * * (C) COPYRIGHT MICROSOFT CORPORATION, 2000 * * TITLE: w32utils.inl * * VERSION: 1.0 * * AUTHOR: LazarI * * DATE: 23-Dec-2000 * * DESCRIPTION: Win32 templates & utilities (Impl.) * *****************************************************************************/ //////////////////////////////////////////////// // // class CSimpleWndSubclass // // class implementing simple window subclassing // (Windows specific classes) // template inline BOOL CSimpleWndSubclass::IsAttached() const { return (NULL != m_hwnd); } template BOOL CSimpleWndSubclass::Attach(HWND hwnd) { if( hwnd ) { // make sure we are not attached and nobody is using // GWLP_USERDATA for something else already. ASSERT(NULL == m_hwnd); ASSERT(NULL == m_wndDefProc); ASSERT(NULL == GetWindowLongPtr(hwnd, GWLP_USERDATA)); // attach to this window m_hwnd = hwnd; m_wndDefProc = reinterpret_cast(GetWindowLongPtr(m_hwnd, GWLP_WNDPROC)); // thunk the window proc SetWindowLongPtr(m_hwnd, GWLP_USERDATA, reinterpret_cast(this)); SetWindowLongPtr(m_hwnd, GWLP_WNDPROC, reinterpret_cast(_ThunkWndProc)); return TRUE; } return FALSE; } template BOOL CSimpleWndSubclass::Detach() { if( m_hwnd ) { // unthunk the window proc SetWindowLongPtr(m_hwnd, GWLP_WNDPROC, reinterpret_cast(m_wndDefProc)); SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0); // clear out our data m_wndDefProc = NULL; m_hwnd = NULL; return TRUE; } return FALSE; } template LRESULT CALLBACK CSimpleWndSubclass::_ThunkWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // get the pThis ptr from GWLP_USERDATA CSimpleWndSubclass *pThis = reinterpret_cast*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); // must be attached ASSERT(pThis->IsAttached()); // static cast pThis to inheritorClass inheritorClass *pTarget = static_cast(pThis); // messsage processing is here if( WM_NCDESTROY == uMsg ) { // this window is about to go away - detach. LRESULT lResult = pTarget->WindowProc(hwnd, uMsg, wParam, lParam); pThis->Detach(); return lResult; } else { // invoke the inheritorClass WindowProc (should be defined) return pTarget->WindowProc(hwnd, uMsg, wParam, lParam); } } template inline LRESULT CSimpleWndSubclass::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hwnd, uMsg, wParam, lParam); } template inline LRESULT CSimpleWndSubclass::DefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if( m_wndDefProc ) { return CallWindowProc(m_wndDefProc, hwnd, uMsg, wParam, lParam); } return ::DefWindowProc(hwnd, uMsg, wParam, lParam); } template inline LRESULT CSimpleWndSubclass::DefDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if( m_wndDefProc ) { return CallWindowProc(m_wndDefProc, hwnd, uMsg, wParam, lParam); } return ::DefDlgProc(hwnd, uMsg, wParam, lParam); }