⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subclass.h

📁 WMI接口测试Demo程序
💻 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 + -