DumontEXE 0.0.1
Subclass.h
00001 ////////////////////////////////////////////////////////////////
00002 // 1997 Microsoft Sytems Journal
00003 // If this code works, it was written by Paul DiLascia.
00004 // If not, I don't know who wrote it.
00005 //
00006 #ifndef SUBCLASSW_H
00007 #define SUBCLASSW_H
00008 
00009 //////////////////
00010 // Generic class to hook messages on behalf of a CWnd.
00011 // Once hooked, all messages go to CSubclassWnd::WindowProc before going
00012 // to the window. Specific subclasses can trap messages and do something.
00013 //
00014 // To use:
00015 //
00016 // * Derive a class from CSubclassWnd.
00017 //
00018 // * Override CSubclassWnd::WindowProc to handle messages. Make sure you call
00019 //   CSubclassWnd::WindowProc if you don't handle the message, or your
00020 //   window will never get messages. If you write separate message handlers,
00021 //   you can call Default() to pass the message to the window.
00022 //
00023 // * Instantiate your derived class somewhere and call HookWindow(pWnd)
00024 //   to hook your window, AFTER it has been created.
00025 //    To unhook, call HookWindow(NULL).
00026 //
00027 // This is a very important class, crucial to many of the widgets Window
00028 // widgets implemented in PixieLib. To see how it works, look at the HOOK
00029 // sample program.
00030 //
00031 
00032 #ifndef GET_X_LPARAM
00033   #define GET_X_LPARAM(lp)  ((int)(short)LOWORD(lp))
00034   #define GET_Y_LPARAM(lp)  ((int)(short)HIWORD(lp))
00035 #endif
00036 
00037 class CSubclassWnd;
00038 
00039 class ISubclassCallback
00040 {
00041 public:
00042   virtual void PostNcDestroy(HWND hWnd) = 0;
00043 };
00044 
00045 class CSubclassWnd
00046 {
00047   friend class CSubclassWndMap;
00048   friend class CSubclasser;
00049 
00050 public:
00051   CSubclassWnd();
00052   ~CSubclassWnd();
00053 
00054   virtual BOOL HookWindow(HWND hRealWnd, CSubclasser* pSubclasser = NULL);
00055   virtual BOOL IsValid() const { return IsValidHook(); }
00056 
00057   inline HWND  GetHwnd() const { return m_hWndHooked; }
00058   inline CWnd* GetCWnd() const { return CWnd::FromHandle(m_hWndHooked); }
00059 
00060   static void SetCallback(ISubclassCallback* pCallback) { s_pCallback = pCallback; }
00061 
00062 protected:
00063   HWND           m_hWndHooked;   // the window hooked
00064   WNDPROC        m_pOldWndProc;  // ..and original window proc
00065   CSubclassWnd * m_pNext;        // next in chain of hooks for this window
00066   CSubclasser  * m_pSubclasser;
00067 
00068   static ISubclassCallback* s_pCallback;
00069 
00070 protected:
00071   // this is called only when m_hWndHooked is detached as a result
00072   // of receiving WM_NCDESTROY else HookWindow(NULL) was called
00073   virtual void PreDetachWindow() { }
00074   virtual void PostDetachWindow() { }
00075 
00076   // Subclass a window. Hook(NULL) to unhook (automatic on WM_NCDESTROY)
00077   virtual BOOL IsHooked() const { return m_hWndHooked != NULL; }
00078   virtual BOOL IsValidHook() const { return ::IsWindow(m_hWndHooked); }
00079 
00080   inline DWORD GetExStyle()                   const { return ::GetWindowLong(m_hWndHooked, GWL_EXSTYLE); }
00081   inline DWORD GetStyle()                     const { return ::GetWindowLong(m_hWndHooked, GWL_STYLE); }
00082   inline HWND  GetParent()                    const { return ::GetParent(m_hWndHooked); }
00083   inline void  GetClientRect(LPRECT pRect)    const { ::GetClientRect(m_hWndHooked, pRect); }
00084   inline void  GetWindowRect(LPRECT pRect)    const { ::GetWindowRect(m_hWndHooked, pRect); }
00085   inline void  Invalidate(BOOL bErase = TRUE) const { ::InvalidateRect(m_hWndHooked, NULL, bErase); }
00086   inline BOOL  IsWindowEnabled()              const { return ::IsWindowEnabled(m_hWndHooked); }
00087   inline BOOL  IsWindowVisible()              const { return ::IsWindowVisible(m_hWndHooked); }
00088          void  ClientToWindow(LPRECT pRect);
00089          void  ScreenToClient(LPRECT pRect);
00090          void  ClientToScreen(LPRECT pRect);
00091 
00092   void SetRedraw(BOOL bRedraw = TRUE) { ::SendMessage(m_hWndHooked, WM_SETREDRAW, bRedraw, 0); }
00093   virtual void Redraw() const { Invalidate(); }
00094 
00095   virtual BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) const;
00096   virtual BOOL SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0) const;
00097 
00098   static LRESULT CALLBACK HookWndProc(HWND, UINT, WPARAM, LPARAM);
00099 
00100   static CMapPtrToPtr& GetValidMap(); // map containing every CSubclassWnd
00101   static BOOL IsValid(const CSubclassWnd* pScWnd);
00102 
00103   virtual LRESULT WindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp);
00104   LRESULT Default(); // call this at the end of handler fns if you are happy with the defaults
00105 
00106 };
00107 
00108 class CSubclasser
00109 {
00110   friend class CSubclassWnd;
00111   friend class CSubclassWndMap;
00112 
00113 protected:
00114   CSubclasser() {}
00115 
00116   virtual LRESULT ScWindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp)
00117   {
00118     ASSERT(hRealWnd == m_subclass.GetHwnd()); 
00119     return m_subclass.WindowProc(hRealWnd, msg, wp, lp); 
00120   }
00121 
00122   virtual CSubclasser* GetTopSubclasser() { return this; }
00123 
00124   // this is called only when m_subclass.m_hWndHooked is detached as a result
00125   // of receiving WM_NCDESTROY else m_subclass.HookWindow(NULL) was called
00126   virtual void ScPreDetachWindow() { }
00127   virtual void ScPostDetachWindow() { }
00128 
00129   // Subclass a window. Hook(NULL) to unhook (automatic on WM_NCDESTROY)
00130   inline operator HWND() const { return m_subclass.GetHwnd(); }
00131   inline BOOL ScHookWindow(HWND hWnd) { return m_subclass.HookWindow(hWnd, GetTopSubclasser()); }
00132   inline BOOL ScIsHooked() { return m_subclass.IsHooked(); }
00133   inline BOOL ScIsValidHook() { return m_subclass.IsValidHook(); }
00134   inline CWnd* ScGetCWnd() { return m_subclass.GetCWnd(); }
00135   inline HWND ScGetHwnd() { return m_subclass.GetHwnd(); }
00136 
00137   inline BOOL ScPostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
00138     { return m_subclass.PostMessage(message, wParam, lParam); }
00139 
00140   BOOL ScSendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
00141     { return m_subclass.SendMessage(message, wParam, lParam); }
00142 
00143 protected:
00144   CSubclassWnd m_subclass;
00145 
00146 protected:
00147   LRESULT ScDefault(HWND hRealWnd) 
00148   { 
00149     ASSERT(hRealWnd == m_subclass.GetHwnd()); 
00150     return m_subclass.Default(); 
00151   } // in time we will have mutiple subclassed wnds
00152 };
00153 
00154 #endif // SUBCLASSW_H
00155 
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties




~ ~ ~ ~ ~ ~
Source Code without Comments is like a Cranberry Garland
without the berries. Comment your Code!
 
Commence Database User Support Group Forum
http://newsgroup.showoff-db.org/
~ ~ ~ ~ ~ ~
Author: Mark Petryk
Lorimark Solutions, LLC
mark@lorimarksolutions.com