📄 subclass.h
字号:
////////////////////////////////////////////////////////////////
// 1997 Microsoft Sytems Journal
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
//
#ifndef _SUBCLASSW_H
#define _SUBCLASSW_H
//////////////////
// Generic class to hook messages on behalf of a CWnd.
// Once hooked, all messages go to CSubclassWnd::WindowProc before going
// to the window. Specific subclasses can trap messages and do something.
//
// To use:
//
// * Derive a class from CSubclassWnd.
//
// * Override CSubclassWnd::WindowProc to handle messages. Make sure you call
// CSubclassWnd::WindowProc if you don't handle the message, or your
// window will never get messages. If you write seperate message handlers,
// you can call Default() to pass the message to the window.
//
// * Instantiate your derived class somewhere and call HookWindow(pWnd)
// to hook your window, AFTER it has been created.
// To unhook, call HookWindow(NULL).
//
// This is a very important class, crucial to many of the widgets Window
// widgets implemented in PixieLib. To see how it works, look at the HOOK
// sample program.
//
#ifndef GET_X_LPARAM
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
#endif
class CSubclassWnd : public CObject
{
DECLARE_DYNAMIC(CSubclassWnd);
friend class CSubclassWndMap;
friend class CSubclasser;
public:
CSubclassWnd();
~CSubclassWnd();
virtual BOOL HookWindow(CWnd* pRealWnd, CSubclasser* pSubclasser = NULL);
virtual BOOL HookWindow(HWND hRealWnd, CSubclasser* pSubclasser = NULL);
LRESULT Default(); // call this at the end of handler fns
operator CWnd*() const;
operator HWND() const;
virtual BOOL IsValid() const { return IsValidHook(); }
virtual void Redraw() { Invalidate(); }
// Override this to handle messages in specific handlers
virtual LRESULT WindowProc(CWnd* pRealWnd, UINT msg, WPARAM wp, LPARAM lp);
protected:
HWND m_hWndHooked; // the window hooked
WNDPROC m_pOldWndProc; // ..and original window proc
CSubclassWnd* m_pNext; // next in chain of hooks for this window
CSubclasser* m_pSubclasser;
CWnd* m_pWndPermanent; // NULL if no CWnd attached
// this is called only when m_hWndHooked is detached as a result
// of receiving WM_NCDESTROY else HookWindow(NULL) was called
virtual void PreDetachWindow() { }
virtual void PostDetachWindow() { }
// Subclass a window. Hook(NULL) to unhook (automatic on WM_NCDESTROY)
virtual BOOL IsHooked() const { return m_hWndHooked != NULL; }
virtual BOOL IsValidHook() const { return ::IsWindow(m_hWndHooked); }
virtual CWnd* GetHookedWnd() const;
DWORD GetExStyle() const { return ::GetWindowLong(m_hWndHooked, GWL_EXSTYLE); }
DWORD GetStyle() const { return ::GetWindowLong(m_hWndHooked, GWL_STYLE); }
CWnd* GetParent() const { return CWnd::FromHandle(::GetParent(m_hWndHooked)); }
void GetClientRect(LPRECT pRect) const { ::GetClientRect(m_hWndHooked, pRect); }
void GetWindowRect(LPRECT pRect) const { ::GetWindowRect(m_hWndHooked, pRect); }
void Invalidate(BOOL bErase = TRUE) const { ::InvalidateRect(m_hWndHooked, NULL, bErase); }
BOOL IsWindowEnabled() const { return ::IsWindowEnabled(m_hWndHooked); }
BOOL IsWindowVisible() const { return ::IsWindowVisible(m_hWndHooked); }
void SetRedraw(BOOL bRedraw = TRUE) { ::SendMessage(m_hWndHooked, WM_SETREDRAW, bRedraw, 0); }
virtual BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) const;
virtual BOOL SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) const;
static LRESULT CALLBACK HookWndProc(HWND, UINT, WPARAM, LPARAM);
static CMapPtrToPtr& GetValidMap(); // map containing every CSubclassWnd
static BOOL IsValid(const CSubclassWnd* pScWnd);
};
class CSubclasser
{
public:
virtual LRESULT ScWindowProc(CWnd* pRealWnd, UINT msg, WPARAM wp, LPARAM lp)
{
ASSERT(pRealWnd == ScGetHookedWnd());
return m_subclass.WindowProc(pRealWnd, msg, wp, lp);
}
virtual CSubclasser* GetTopSubclasser() { return this; }
// this is called only when m_subclass.m_hWndHooked is detached as a result
// of receiving WM_NCDESTROY else m_subclass.HookWindow(NULL) was called
virtual void ScPreDetachWindow() { }
virtual void ScPostDetachWindow() { }
// Subclass a window. Hook(NULL) to unhook (automatic on WM_NCDESTROY)
BOOL ScHookWindow(CWnd* pRealWnd) { return m_subclass.HookWindow(pRealWnd, GetTopSubclasser()); }
BOOL ScIsHooked() { return m_subclass.IsHooked(); }
BOOL ScIsValidHook() { return m_subclass.IsValidHook(); }
CWnd* ScGetHookedWnd() { return m_subclass.GetHookedWnd(); }
BOOL ScPostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
{ return m_subclass.PostMessage(message, wParam, lParam); }
BOOL ScSendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
{ return m_subclass.SendMessage(message, wParam, lParam); }
protected:
CSubclassWnd m_subclass;
protected:
LRESULT ScDefault(CWnd* pRealWnd)
{
ASSERT(pRealWnd == ScGetHookedWnd());
return m_subclass.Default();
} // in time we will have mutiple subclassed wnds
};
#endif // _SUBCLASSW_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -