// ---------------------------------------------------------------------------- // hook a window // ---------------------------------------------------------------------------- bool CSkin::Hook(CWnd *pWnd) { // unsubclass any other window if (Hooked()) UnHook(); // this will be our new subclassed window m_hWnd = (HWND)*pWnd; // -------------------------------------------------- // change window style (get rid of the caption bar) // -------------------------------------------------- LONG_PTR dwStyle = GetWindowLongPtr(m_hWnd, GWL_STYLE); m_dOldStyle = dwStyle; dwStyle &= ~(WS_CAPTION|WS_SIZEBOX); SetWindowLongPtr(m_hWnd, GWL_STYLE, dwStyle); RECT r; pWnd->GetWindowRect(&r); m_oldRect = r; pWnd->MoveWindow(r.left, r.top, m_iWidth, m_iHeight, FALSE); pWnd->SetMenu(NULL); if(m_rgnSkin != NULL) // set the skin region to the window pWnd->SetWindowRgn(m_rgnSkin, true); // subclass the window procedure m_OldWndProc = (WNDPROC)SetWindowLongPtr( m_hWnd, GWLP_WNDPROC, (LONG_PTR)SkinWndProc ); // store a pointer to our class instance inside the window procedure. if (!SetProp(m_hWnd, "skin", (void*)this)) { // if we fail to do so, we just can't activate the skin. UnHook(); return false; } // update flag m_bHooked = ( m_OldWndProc ? true : false ); for(int i = 0; i < m_nButtons; i++) { RECT r; m_buttons[i].GetRect(r); m_buttons[i].CreateButton("", WS_VISIBLE, r, pWnd, 0); } // force window repainting RedrawWindow(NULL,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN); // successful return if we're hooked. return m_bHooked; }
// ---------------------------------------------------------------------------- // toggle skin on/off - must be Hooked() before attempting to enable skin. // ---------------------------------------------------------------------------- bool CSkin::Enable(bool bEnable) { // refuse to enable if there is no window subclassed yet. if (!Hooked()) return false; // toggle m_bEnabled = bEnable; // force window repainting InvalidateRect(m_hWnd, NULL, TRUE); return true; }
void VMTHook::UnhookMethod( size_t index ) { assert( index<_vcount ); if ( Hooked() ) { void* dest = &_vftable[index]; DWORD dwOld; if ( VirtualProtect( dest, sizeof(void*), PAGE_EXECUTE_READWRITE, &dwOld ) ) { _vftable[index] = _backup[index]; VirtualProtect( dest, sizeof(void*), dwOld, &dwOld ); } } else _backup[index] = _vftable[index]; }
// ---------------------------------------------------------------------------- // unhook the window // ---------------------------------------------------------------------------- bool CSkin::UnHook() { // just to be safe we'll check this WNDPROC OurWnd; // cannot unsubclass if there is no window subclassed // returns true anyways. if (!Hooked()) return true; if(m_rgnSkin != NULL) // remove the skin region from the window SetWindowRgn(m_hWnd, NULL, true); // unsubclass the window procedure OurWnd = (WNDPROC)SetWindowLongPtr( m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_OldWndProc ); // remove the pointer to our class instance, but if we fail we don't care. RemoveProp(m_hWnd, "skin"); // update flag - if we can't get our window procedure address again, // we failed to unhook the window. m_bHooked = ( OurWnd ? false : true ); SetWindowLongPtr(m_hWnd, GWL_STYLE, m_dOldStyle); RECT r; GetWindowRect(m_hWnd, &r); MoveWindow(m_hWnd, r.left, r.top, m_oldRect.right - m_oldRect.left, m_oldRect.bottom - m_oldRect.top, FALSE); // force window repainting RedrawWindow(NULL,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN); // successful return if we're unhooked. return !m_bHooked; }