diff options
Diffstat (limited to 'win32/common/atlwinhk.h')
-rw-r--r-- | win32/common/atlwinhk.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/win32/common/atlwinhk.h b/win32/common/atlwinhk.h new file mode 100644 index 0000000..4dddf82 --- /dev/null +++ b/win32/common/atlwinhk.h @@ -0,0 +1,151 @@ +/* + * AUTHOR + * N. Nielsen + * + * VERSION + * 2.2.0b + * + * LICENSE + * This software is in the public domain. + * + * The software is provided "as is", without warranty of any kind, + * express or implied, including but not limited to the warranties + * of merchantability, fitness for a particular purpose, and + * noninfringement. In no event shall the author(s) be liable for any + * claim, damages, or other liability, whether in an action of + * contract, tort, or otherwise, arising from, out of, or in connection + * with the software or the use or other dealings in the software. + * + * SUPPORT + * Send bug reports to: <nielsen@memberwebs.com> + */ + +#ifndef __ATLWINHK_H__ +#define __ATLWINHK_H__ + +///////////////////////////////////////////////////////////////////////// +// Hooks an CWindowImpl to windows that the API or other code creates +// By Stef: 06/10/99 + + +// Use this macro in the class definition and pass class name +// as first param +#define DECLARE_HOOK_AND_SUBCLASS(Class) \ + HHOOK m_hHookCur; \ + static LRESULT CALLBACK HookCreateProc(int nCode, \ + WPARAM wParam, \ + LPARAM lParam) \ + { \ + Class* pThis = (Class*) _Module.ExtractCreateWndData(); \ + \ + if (nCode != HCBT_CREATEWND) \ + { \ + /*Add it back again*/ \ + _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis); \ + /*wait for HCBT_CREATEWND just pass others on...*/ \ + return CallNextHookEx(pThis->m_hHookCur, nCode, wParam, lParam); \ + } \ + \ + pThis->SubclassWindow((HWND)wParam); \ + \ + UnhookWindowsHookEx(pThis->m_hHookCur); \ + HHOOK hHookCur = pThis->m_hHookCur; \ + pThis->m_hHookCur = NULL; \ + \ + return CallNextHookEx(hHookCur, nCode, wParam, lParam); \ + } + +// Use this *immediately* before the code that creates the window +// It will subclass the first window that's created by that thread +// so add immediately before. +#define HOOK_AND_SUBCLASS_NEXT() \ + ((m_hHookCur = SetWindowsHookEx(WH_CBT, HookCreateProc, NULL, ::GetCurrentThreadId())) == NULL) + +const LPCTSTR kDialogClass = (LPCTSTR)0x00008002; + +template<class _Class> +class CHookWindow +{ +public: + CHookWindow() + { + m_hHookCur = NULL; + m_szHookClass = NULL; + m_szHookName = NULL; + } + + bool SubclassNext(LPCTSTR szClass = NULL, LPCTSTR szName = NULL) + { + _Class* pThis = (_Class*)this; + _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis); + + m_hHookCur = SetWindowsHookEx(WH_CBT, HookCreateProc, NULL, ::GetCurrentThreadId()); + + if(m_hHookCur) + { + m_szHookClass = szClass; + m_szHookName = szName; + } + + return m_hHookCur == NULL; + } + + static LRESULT CALLBACK HookCreateProc(int nCode, WPARAM wParam, LPARAM lParam) + { + _Class* pThis = (_Class*) _Module.ExtractCreateWndData(); + HHOOK hHookCur = pThis->m_hHookCur; + + bool bSkip = false; + + if(nCode != HCBT_CREATEWND) + { + bSkip = true; + } + else + { + CBT_CREATEWND* pCreate = (CBT_CREATEWND*)lParam; + + if(pThis->m_szHookClass) + { + // If it's not a pointer (for at least two bytes) + if(IsBadReadPtr(pCreate->lpcs->lpszClass, 2) || IsBadReadPtr(pThis->m_szHookClass, 2)) + // Then just compare values + bSkip = pCreate->lpcs->lpszClass != pThis->m_szHookClass; + + else + // Otherwise compare strings + bSkip = _tcsicmp(pCreate->lpcs->lpszClass, pThis->m_szHookClass) != 0; + } + + if(pThis->m_szHookName) + { + if(IsBadReadPtr(pCreate->lpcs->lpszName, _tcslen(pThis->m_szHookName)) || + _tcsicmp(pCreate->lpcs->lpszName, pThis->m_szHookName)) + bSkip = true; + } + } + + if(bSkip) + { + /*Add it back again*/ + _Module.AddCreateWndData(&(pThis->m_thunk.cd), pThis); + } + else + { + pThis->SubclassWindow((HWND)wParam); + + UnhookWindowsHookEx(pThis->m_hHookCur); + pThis->m_hHookCur = NULL; + } + + return CallNextHookEx(hHookCur, nCode, wParam, lParam); + } + +protected: + HHOOK m_hHookCur; + LPCTSTR m_szHookName; + LPCTSTR m_szHookClass; +}; + + +#endif //__ATLWINHK_H__ |