Click here to Skip to main content
15,886,110 members
Articles / Desktop Programming / MFC

VssReporter 2.1 - A Visual SourceSafe reporting tool for build administrators

Rate me:
Please Sign up or sign in to vote.
4.88/5 (100 votes)
25 Mar 200610 min read 623.5K   8.9K   162  
A support tool to allow those performing builds to independently determine exactly what source files have been changed and by whom
////////////////////////////////////////////////////////////////
// 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.
//
// heavily modified and extended by .dan.g. abstractspoon

#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;

class ISubclassCallback
{
public:
	virtual void PostNcDestroy(HWND hWnd) = 0;
};

class CSubclassWnd
{
	friend class CSubclassWndMap;
	friend class CSubclasser;

public:
	CSubclassWnd();
	virtual ~CSubclassWnd();

	virtual BOOL HookWindow(HWND hRealWnd, CSubclasser* pSubclasser = NULL);
	virtual BOOL IsValid() const { return IsValidHook(); }

	inline HWND GetHwnd() const { return m_hWndHooked; }
	inline CWnd* GetCWnd() const { return CWnd::FromHandle(m_hWndHooked); }

	static void SetCallback(ISubclassCallback* pCallback) { s_pCallback = pCallback; }

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;
	BOOL			m_bPreMFCSubclass;

	static ISubclassCallback* s_pCallback;

protected:
	// 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); }

	inline DWORD GetExStyle() const { return ::GetWindowLong(m_hWndHooked, GWL_EXSTYLE); }
	inline DWORD GetStyle() const { return ::GetWindowLong(m_hWndHooked, GWL_STYLE); }
	inline HWND GetParent() const { return ::GetParent(m_hWndHooked); }
	inline void GetClientRect(LPRECT pRect) const { ::GetClientRect(m_hWndHooked, pRect); }
	inline void GetWindowRect(LPRECT pRect) const { ::GetWindowRect(m_hWndHooked, pRect); }
	inline void Invalidate(BOOL bErase = TRUE) const { ::InvalidateRect(m_hWndHooked, NULL, bErase); }
	inline BOOL IsWindowEnabled() const { return ::IsWindowEnabled(m_hWndHooked); }
	inline BOOL IsWindowVisible() const { return ::IsWindowVisible(m_hWndHooked); }

	inline UINT GetDlgCtrlID() const { return ::GetDlgCtrlID(m_hWndHooked); }

	void ClientToWindow(LPRECT pRect) const;
	void ScreenToClient(LPRECT pRect) const;
	void ClientToScreen(LPRECT pRect) const;
	void ScreenToWindow(LPRECT pRect) const;
	void ClientToWindow(LPPOINT pPoint) const;
	void ScreenToClient(LPPOINT pPoint) const;
	void ClientToScreen(LPPOINT pPoint) const;
	void ScreenToWindow(LPPOINT pPoint) const;

	void SetRedraw(BOOL bRedraw = TRUE) { ::SendMessage(m_hWndHooked, WM_SETREDRAW, bRedraw, 0); }
	virtual void Redraw() const { Invalidate(); }

	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);

	virtual LRESULT WindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp);
	LRESULT Default(); // call this at the end of handler fns if you are happy with the defaults
	const MSG* GetCurrentMessage();
};

class CSubclasser
{
	friend class CSubclassWnd;
	friend class CSubclassWndMap;

protected:
	CSubclasser() {}

	virtual LRESULT ScWindowProc(HWND hRealWnd, UINT msg, WPARAM wp, LPARAM lp)
	{
		ASSERT(hRealWnd == m_subclass.GetHwnd()); 
		return m_subclass.WindowProc(hRealWnd, 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)
	inline operator HWND() const { return m_subclass.GetHwnd(); }
	inline BOOL ScHookWindow(HWND hWnd) { return m_subclass.HookWindow(hWnd, GetTopSubclasser()); }
	inline BOOL ScIsHooked() { return m_subclass.IsHooked(); }
	inline BOOL ScIsValidHook() { return m_subclass.IsValidHook(); }
	inline CWnd* ScGetCWnd() { return m_subclass.GetCWnd(); }
	inline HWND ScGetHwnd() { return m_subclass.GetHwnd(); }

	inline 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(HWND hRealWnd) 
	{ 
		UNREFERENCED_PARAMETER(hRealWnd);
		
		ASSERT(hRealWnd == m_subclass.GetHwnd()); 
		return m_subclass.Default(); 
	} // in time we will have mutiple subclassed wnds
};

#endif // _SUBCLASSW_H

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer Maptek
Australia Australia
.dan.g. is a naturalised Australian and has been developing commercial windows software since 1998.

Comments and Discussions