自己写的vc开发框架,基于thunk技术

QWindow.h
#pragma once
#define QWIN_DECLARE_MESSAGE_MAP() BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#define QWIN_BEGIN_MESSAGE_MAP(cls) BOOL cls::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
#define QWIN_END_MESSAGE_MAP() return FALSE;}
#define QWIN_MESSAGE_MAP(id,fun) if(uMsg==id){return fun(hWnd,uMsg,wParam,lParam);}
#define QWIN_CHAIN_MESSAGE_MAP(id,cls) if(uMsg==id){return cls::ProcessWindowMessage(hWnd,uMsg,wParam,lParam);}
#define QWIN_DECLARE_EMPTY_MSG_MAP() BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){return FALSE;}
#define QWIN_COMMAND_CODE_MAP(code,fun) if(uMsg == WM_COMMAND && code == HIWORD(wParam)){return fun(hWnd,uMsg,wParam,lParam);}
#define QWIN_COMMAND_ID_MAP(id,fun) if(uMsg == WM_COMMAND && id == LOWORD(wParam)){return fun(hWnd,uMsg,wParam,lParam);}
#define QWIN_COMMAND_MAP(id,code,fun) if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)){return fun(hWnd,uMsg,wParam,lParam);}
#define QWIN_DECLARE_WND_CLASS(WndClassName) \
	public:\
	static WNDCLASSEX& GetWndClassInfo() \
{ \
	static WNDCLASSEX wc = \
{ \
	sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, (WNDPROC)CQWindow::StartWindowProc, \
	0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName, NULL \
}; \
	return wc; \
}

#define QWIN_DECLARE_WND_SUPER_CLASS(cls,ClassName,WndClassName)				\
	public:																		\
	WNDPROC cls##ComponentProc;										    \
	public:																		\
	static WNDCLASSEX& GetWndClassInfoEx(cls* c)							\
{																	\
	static WNDCLASSEX wc={0};										\
	::GetClassInfoEx(_WinModule.GetInstance(),WndClassName,&wc);		\
	c->cls##ComponentProc=wc.lpfnWndProc;							\
	wc.lpfnWndProc = (WNDPROC)CQWindow::StartWindowProc;			\
	wc.lpszClassName =ClassName;									\
	wc.cbSize=sizeof(WNDCLASSEX);									\
	return wc;														\
}
#define QWIN_REFLECTION_WND_SUPER_CLASS(cls) else{::CallWindowProc(cls##ComponentProc,hWnd,uMsg,wParam,lParam);return FALSE;}

#pragma pack(push,1)
struct _WndProcThunk
{
	DWORD   m_mov;          // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
	DWORD   m_this;
	BYTE    m_jmp;          // jmp WndProc
	DWORD   m_relproc;      // relative jmp
};
#pragma pack(pop)
class WndProcThunk
{
public:
	_WndProcThunk thunk;
	void Init(WNDPROC proc, void* pThis)
	{
		thunk.m_mov = 0x042444C7;  //C7 44 24 04
		thunk.m_this = (DWORD)pThis;
		thunk.m_jmp = 0xe9;
		thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
		::FlushInstructionCache(GetCurrentProcess(), &thunk, sizeof(thunk));
	}
	WNDPROC GetWndProc()
	{
		return (WNDPROC)&(thunk);
	}
	
};
struct IMessageMap
{
	virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)=0;
};
class CQWindow;
class CQWinModule;
extern CQWinModule _WinModule;
class CQWinModule
{
private:
	HINSTANCE m_hInst;
	CQWindow *m_pWindow;
	DWORD m_dwThreadID;
public:
	CQWinModule(){m_dwThreadID=::GetCurrentThreadId();}
	~CQWinModule(){Term();}
	void Init(HINSTANCE hInstance){m_hInst=hInstance;}
	void Term(){m_hInst=NULL;}
	void SetInstance(HINSTANCE hInstance){Init(hInstance);}
	void AddCreateWndData(CQWindow* pWindow){m_pWindow=pWindow;}
	HINSTANCE GetInstance(){return m_hInst;}
	CQWindow* GetCurrentWindow(){return m_pWindow;}

};
class CQWindow:public IMessageMap
{
public:
	CQWindow(void);
	~CQWindow(void);
public:
	static LRESULT CALLBACK StandardWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
	{
		CQWindow* pThis=(CQWindow*)hWnd;
		if(uMsg==WM_NCDESTROY)
			::PostQuitMessage(0);
		if(!pThis->ProcessWindowMessage(pThis->m_hWnd,uMsg,wParam,lParam))
			return ::DefWindowProc(pThis->m_hWnd,uMsg,wParam,lParam);
		else
			return 0;
	}
	static LRESULT CALLBACK StartWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
	{
		CQWindow* pThis=_WinModule.GetCurrentWindow();
		pThis->m_hWnd=hWnd;
		pThis->thunk.Init(StandardWindowProc,pThis);
		WNDPROC proc=pThis->thunk.GetWndProc();
		::SetWindowLong(hWnd,GWL_WNDPROC,(LONG)proc);
		return proc(hWnd,uMsg,wParam,lParam);
	}
public:
	BOOL UpdateWindow(void);
	BOOL ShowWindow(int cCmd);
	virtual LRESULT SendMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
	virtual LRESULT PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
	virtual BOOL Create(LPCTSTR szClassName, LPCTSTR szTitle, HINSTANCE hInstance, HWND hWndParent = 0, 
		DWORD dwStyle = WS_OVERLAPPEDWINDOW, DWORD dwExStyle = 0, HMENU hMenu = 0,
		int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int nWidth = CW_USEDEFAULT, int nHeight = CW_USEDEFAULT);
	virtual BOOL ProcessWindowMessage(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
public:
	HWND m_hWnd;
	WndProcThunk thunk;
};
template<class TC>class CQWindowImpl :public CQWindow
{
public:
	WNDPROC tx;
public:
	CQWindowImpl(void){}
public:
	~CQWindowImpl(void){}
public:
	int RegCls()
	{
		tx=CQWindow::StartWindowProc;
		m_cls=TC::GetWndClassInfo();
		PerRegistercls(&m_cls);
		return RegisterClassEx(&m_cls);
	}
	int RegSuperCls()
	{
		m_cls=TC::GetWndClassInfoEx((TC*)this);
		PerRegistercls(&m_cls);
		return RegisterClassEx(&m_cls);
	}
	virtual int PerRegistercls(WNDCLASSEX* cls){return 0;}
public:
	WNDCLASSEX m_cls;
	WNDPROC m_OldlpfnWndProc;
};

 

QWindow.cpp
#include "StdAfx.h"
#include "QWindow.h"
CQWinModule _WinModule;
CQWindow::CQWindow(void)
{
}
CQWindow::~CQWindow(void)
{
}
BOOL CQWindow::Create(LPCTSTR szClassName, LPCTSTR szTitle, HINSTANCE hInstance, HWND hWndParent /* = 0 */, DWORD dwStyle /* = WS_OVERLAPPEDWINDOW */, DWORD dwExStyle /* = 0 */, HMENU hMenu /* = 0 */, int x /* = CW_USEDEFAULT */, int y /* = CW_USEDEFAULT */, int nWidth /* = CW_USEDEFAULT */, int nHeight /* = CW_USEDEFAULT */)
{
	_WinModule.AddCreateWndData(this);
	m_hWnd =::CreateWindowEx(dwExStyle, szClassName, szTitle, dwStyle, x, y, 
		nWidth, nHeight, hWndParent, hMenu, hInstance,NULL);
	return m_hWnd != NULL;
}
BOOL CQWindow::UpdateWindow(void)
{
	return ::UpdateWindow(m_hWnd);
}
BOOL CQWindow::ShowWindow(int cCmd)
{
	return ::ShowWindow(m_hWnd,cCmd);
}
LRESULT CQWindow::SendMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	return ::SendMessage(m_hWnd,uMsg,wParam,lParam);
}
LRESULT CQWindow::PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	return ::PostMessage(m_hWnd,uMsg,wParam,lParam);
}
BOOL CQWindow::ProcessWindowMessage(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	return FALSE;
}

 

你可能感兴趣的:(框架,vc++)