123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- #include "StdAfx.h"
- #include "Subclass.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- class CSubclassWndMap : private CMapPtrToPtr {
- public:
- CSubclassWndMap();
- ~CSubclassWndMap();
- static CSubclassWndMap& GetHookMap();
- void Add(HWND hwnd, CSubclassWnd* pSubclassWnd);
- void Remove(CSubclassWnd* pSubclassWnd);
- void RemoveAll(HWND hwnd);
- CSubclassWnd* Lookup(HWND hwnd);
- };
- #define theHookMap (CSubclassWndMap::GetHookMap())
- IMPLEMENT_DYNAMIC(CSubclassWnd, CWnd);
- CSubclassWnd::CSubclassWnd()
- {
- m_pNext = NULL;
- m_pOldWndProc = NULL;
- m_hWnd = NULL;
- }
- CSubclassWnd::~CSubclassWnd()
- {
- if (m_hWnd)
- HookWindow((HWND)NULL);
- }
- BOOL CSubclassWnd::HookWindow(HWND hwnd)
- {
- ASSERT_VALID(this);
- if (hwnd) {
-
- ASSERT(m_hWnd==NULL);
- ASSERT(::IsWindow(hwnd));
- theHookMap.Add(hwnd, this);
- } else if (m_hWnd) {
-
- theHookMap.Remove(this);
- m_pOldWndProc = NULL;
- }
- m_hWnd = hwnd;
- return TRUE;
- }
- LRESULT CSubclassWnd::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
- {
- ASSERT(m_pOldWndProc);
- return m_pNext ? m_pNext->WindowProc(msg, wp, lp) :
- ::CallWindowProc(m_pOldWndProc, m_hWnd, msg, wp, lp);
- }
- LRESULT CSubclassWnd::Default()
- {
-
- MSG& curMsg = AfxGetThreadState()->m_lastSentMsg;
-
-
- return CSubclassWnd::WindowProc(curMsg.message, curMsg.wParam, curMsg.lParam);
- }
- #ifdef _DEBUG
- void CSubclassWnd::AssertValid() const
- {
- CObject::AssertValid();
- ASSERT(m_hWnd==NULL || ::IsWindow(m_hWnd));
- if (m_hWnd) {
- for (CSubclassWnd* p = theHookMap.Lookup(m_hWnd); p; p=p->m_pNext) {
- if (p==this)
- break;
- }
- ASSERT(p);
- }
- }
- void CSubclassWnd::Dump(CDumpContext& dc) const
- {
- CObject::Dump(dc);
- }
- #endif
- LRESULT CALLBACK
- HookWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
- {
- #ifdef _USRDLL
-
- AFX_MANAGE_STATE(AfxGetStaticModuleState());
- #endif
-
-
-
-
- MSG& curMsg = AfxGetThreadState()->m_lastSentMsg;
- MSG oldMsg = curMsg;
- curMsg.hwnd = hwnd;
- curMsg.message = msg;
- curMsg.wParam = wp;
- curMsg.lParam = lp;
-
- CSubclassWnd* pSubclassWnd = theHookMap.Lookup(hwnd);
- ASSERT(pSubclassWnd);
- LRESULT lr;
- if (msg==WM_NCDESTROY) {
-
-
-
- WNDPROC wndproc = pSubclassWnd->m_pOldWndProc;
- theHookMap.RemoveAll(hwnd);
- lr = ::CallWindowProc(wndproc, hwnd, msg, wp, lp);
- } else {
-
- lr = pSubclassWnd->WindowProc(msg, wp, lp);
- }
- curMsg = oldMsg;
- return lr;
- }
- CSubclassWndMap::CSubclassWndMap()
- {
- }
- CSubclassWndMap::~CSubclassWndMap()
- {
- }
- CSubclassWndMap& CSubclassWndMap::GetHookMap()
- {
-
-
-
-
- static CSubclassWndMap theMap;
- return theMap;
- }
- void CSubclassWndMap::Add(HWND hwnd, CSubclassWnd* pSubclassWnd)
- {
- ASSERT(hwnd && ::IsWindow(hwnd));
-
- pSubclassWnd->m_pNext = Lookup(hwnd);
- SetAt(hwnd, pSubclassWnd);
-
- if (pSubclassWnd->m_pNext==NULL) {
-
- pSubclassWnd->m_pOldWndProc =
- (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (DWORD)HookWndProc);
- } else {
-
- pSubclassWnd->m_pOldWndProc = pSubclassWnd->m_pNext->m_pOldWndProc;
- }
- ASSERT(pSubclassWnd->m_pOldWndProc);
- }
- void CSubclassWndMap::Remove(CSubclassWnd* pUnHook)
- {
- HWND hwnd = pUnHook->m_hWnd;
- ASSERT(hwnd && ::IsWindow(hwnd));
- CSubclassWnd* pHook = Lookup(hwnd);
- ASSERT(pHook);
- if (pHook==pUnHook) {
-
- if (pHook->m_pNext)
- SetAt(hwnd, pHook->m_pNext);
- else {
-
- RemoveKey(hwnd);
- SetWindowLong(hwnd, GWL_WNDPROC, (DWORD)pHook->m_pOldWndProc);
- }
- } else {
-
- while (pHook->m_pNext!=pUnHook)
- pHook = pHook->m_pNext;
- ASSERT(pHook && pHook->m_pNext==pUnHook);
- pHook->m_pNext = pUnHook->m_pNext;
- }
- }
- void CSubclassWndMap::RemoveAll(HWND hwnd)
- {
- CSubclassWnd* pSubclassWnd;
- while ((pSubclassWnd = Lookup(hwnd))!=NULL)
- pSubclassWnd->HookWindow((HWND)NULL);
- }
- CSubclassWnd* CSubclassWndMap::Lookup(HWND hwnd)
- {
- CSubclassWnd* pFound = NULL;
- if (!CMapPtrToPtr::Lookup(hwnd, (void*&)pFound))
- return NULL;
- ASSERT_KINDOF(CSubclassWnd, pFound);
- return pFound;
- }
|