Subclass.h
上传用户:weijiexitu
上传日期:2007-01-18
资源大小:54k
文件大小:6k
源码类别:

菜单

开发平台:

WINDOWS

  1. ////////////////////////////////////////////////////////////////
  2. // 1997 Microsoft Sytems Journal
  3. // If this code works, it was written by Paul DiLascia.
  4. // If not, I don't know who wrote it.
  5. //
  6. #ifndef _SUBCLASSW_H
  7. #define _SUBCLASSW_H
  8. //////////////////
  9. // Generic class to hook messages on behalf of a CWnd.
  10. // Once hooked, all messages go to CSubclassWnd::WindowProc before going
  11. // to the window. Specific subclasses can trap messages and do something.
  12. //
  13. // To use:
  14. //
  15. // * Derive a class from CSubclassWnd.
  16. //
  17. // * Override CSubclassWnd::WindowProc to handle messages. Make sure you call
  18. //   CSubclassWnd::WindowProc if you don't handle the message, or your
  19. //   window will never get messages. If you write seperate message handlers,
  20. //   you can call Default() to pass the message to the window.
  21. //
  22. // * Instantiate your derived class somewhere and call HookWindow(pWnd)
  23. //   to hook your window, AFTER it has been created.
  24. //   To unhook, call HookWindow(NULL).
  25. //
  26. // This is a very important class, crucial to many of the widgets Window
  27. // widgets implemented in PixieLib. To see how it works, look at the HOOK
  28. // sample program.
  29. //
  30. #ifndef GET_X_LPARAM
  31. #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
  32. #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
  33. #endif
  34. class CSubclassWnd;
  35. class ISubclassCallback
  36. {
  37. public:
  38. virtual void PostNcDestroy(HWND hWnd) = 0;
  39. };
  40. class CSubclassWnd
  41. {
  42. friend class CSubclassWndMap;
  43. friend class CSubclasser;
  44. public:
  45. CSubclassWnd();
  46. ~CSubclassWnd();
  47. virtual BOOL HookWindow(HWND hRealWnd, CSubclasser* pSubclasser = NULL);
  48. virtual BOOL IsValid() const { return IsValidHook(); }
  49. inline HWND GetHwnd() const { return m_hWndHooked; }
  50. inline CWnd* GetCWnd() const { return CWnd::FromHandle(m_hWndHooked); }
  51. static void SetCallback(ISubclassCallback* pCallback) { s_pCallback = pCallback; }
  52. protected:
  53. HWND m_hWndHooked; // the window hooked
  54. WNDPROC m_pOldWndProc; // ..and original window proc
  55. CSubclassWnd* m_pNext; // next in chain of hooks for this window
  56. CSubclasser* m_pSubclasser;
  57. static ISubclassCallback* s_pCallback;
  58. protected:
  59. // this is called only when m_hWndHooked is detached as a result
  60. // of receiving WM_NCDESTROY else HookWindow(NULL) was called
  61. virtual void PreDetachWindow() { }
  62. virtual void PostDetachWindow() { }
  63. // Subclass a window. Hook(NULL) to unhook (automatic on WM_NCDESTROY)
  64. virtual BOOL IsHooked() const { return m_hWndHooked != NULL; }
  65. virtual BOOL IsValidHook() const { return ::IsWindow(m_hWndHooked); }
  66. inline DWORD GetExStyle() const { return ::GetWindowLong(m_hWndHooked, GWL_EXSTYLE); }
  67. inline DWORD GetStyle() const { return ::GetWindowLong(m_hWndHooked, GWL_STYLE); }
  68. inline HWND GetParent() const { return ::GetParent(m_hWndHooked); }
  69. inline void GetClientRect(LPRECT pRect) const { ::GetClientRect(m_hWndHooked, pRect); }
  70. inline void GetWindowRect(LPRECT pRect) const { ::GetWindowRect(m_hWndHooked, pRect); }
  71. inline void Invalidate(BOOL bErase = TRUE) const { ::InvalidateRect(m_hWndHooked, NULL, bErase); }
  72. inline BOOL IsWindowEnabled() const { return ::IsWindowEnabled(m_hWndHooked); }
  73. inline BOOL IsWindowVisible() const { return ::IsWindowVisible(m_hWndHooked); }
  74. void ClientToWindow(LPRECT pRect);
  75. void ScreenToClient(LPRECT pRect);
  76. void ClientToScreen(LPRECT pRect);
  77. void SetRedraw(BOOL bRedraw = TRUE) { ::SendMessage(m_hWndHooked, WM_SETREDRAW, bRedraw, 0); }
  78. virtual void Redraw() const { Invalidate(); }
  79. virtual BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) const;
  80. virtual BOOL SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) const;
  81. static LRESULT CALLBACK HookWndProc(HWND, UINT, WPARAM, LPARAM);
  82. static CMapPtrToPtr& GetValidMap(); // map containing every CSubclassWnd
  83. static BOOL IsValid(const CSubclassWnd* pScWnd);
  84. virtual LRESULT WindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp);
  85. LRESULT Default(); // call this at the end of handler fns if you are happy with the defaults
  86. };
  87. class CSubclasser
  88. {
  89. friend class CSubclassWnd;
  90. friend class CSubclassWndMap;
  91. protected:
  92. CSubclasser() {}
  93. virtual LRESULT ScWindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp)
  94. {
  95. ASSERT(hRealWnd == m_subclass.GetHwnd()); 
  96. return m_subclass.WindowProc(hRealWnd, msg, wp, lp); 
  97. }
  98. virtual CSubclasser* GetTopSubclasser() { return this; }
  99. // this is called only when m_subclass.m_hWndHooked is detached as a result
  100. // of receiving WM_NCDESTROY else m_subclass.HookWindow(NULL) was called
  101. virtual void ScPreDetachWindow() { }
  102. virtual void ScPostDetachWindow() { }
  103. // Subclass a window. Hook(NULL) to unhook (automatic on WM_NCDESTROY)
  104. inline operator HWND() const { return m_subclass.GetHwnd(); }
  105. inline BOOL ScHookWindow(HWND hWnd) { return m_subclass.HookWindow(hWnd, GetTopSubclasser()); }
  106. inline BOOL ScIsHooked() { return m_subclass.IsHooked(); }
  107. inline BOOL ScIsValidHook() { return m_subclass.IsValidHook(); }
  108. inline CWnd* ScGetCWnd() { return m_subclass.GetCWnd(); }
  109. inline HWND ScGetHwnd() { return m_subclass.GetHwnd(); }
  110. inline BOOL ScPostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  111. { return m_subclass.PostMessage(message, wParam, lParam); }
  112. BOOL ScSendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
  113. { return m_subclass.SendMessage(message, wParam, lParam); }
  114. protected:
  115. CSubclassWnd m_subclass;
  116. protected:
  117. LRESULT ScDefault(HWND hRealWnd) 
  118. ASSERT(hRealWnd == m_subclass.GetHwnd()); 
  119. return m_subclass.Default(); 
  120. } // in time we will have mutiple subclassed wnds
  121. };
  122. #endif // _SUBCLASSW_H