`
mengdejun
  • 浏览: 410376 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

自己写的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;
}

 

KC网络电话,中国最优秀的网络电话

分享到:
评论

相关推荐

    Thunk技术

    在实际开发中,Thunk技术不仅限于解决32位和64位兼容性问题,还可以应用于其他场景。例如,在跨线程通信或者异步编程中,Thunk可以作为回调函数的代理,将调用上下文转换为适合异步处理的形式。此外,现代编程语言如...

    thunk-redis, 基于 thunk/promise的redis客户端,支持所有redis特性.zip

    thunk-redis, 基于 thunk/promise的redis客户端,支持所有redis特性 thunk基于 thunk/promise的redis客户端,支持所有redis特性。 插件实现:thunk RateLimiter 最快的抽象速率限制器。定时队列分布式计时作业队列,...

    thunk技术实现窗口类的封装.rtf

    thunk技术实现窗口类的封装.rtf

    最快的基于thunk,promise的redis客户端,支持所有redis功能 .zip

    最快的基于thunk/promise的redis客户端,支持所有redis功能。thunk-redis最快的基于thunk/promise的redis客户端,支持所有redis功能。 砰实现方式thunk-ratelimiter最快的抽象速率限制器。timed-queue分布式定时作业...

    利用thunk技术改写窗口类回调函数为窗口对象成员函数

    为了解决这个问题,我们可以利用Thunk技术将窗口类的回调函数改写为窗口对象的成员函数,从而更好地封装和管理代码。 首先,让我们理解什么是Thunk。在Windows API中,Thunk是一种用于不同地址空间或不同代码段之间...

    thunk_x64.zip_thunk _x64Thunk

    x64实现Thunk的新思路,兼容x86,目前能使用的第一份x64下的thunk代码。

    MinGW对Thunk的实现

    在MinGW中,Thunk是一个关键的概念,它是用于在不同调用约定之间转换的代码段,特别是在32位Windows程序中,处理stdcall和cdecl调用约定的转换。 Thunk通常被用于动态库(DLL)中,以便在不同地址空间和调用约定...

    redux-thunk 例子

    在React开发中,Redux是一个非常流行的 state management 库,它帮助我们管理应用的状态。而Redux Thunk 是一个 Redux 的中间件,专门用于处理异步操作,使得在Redux中执行复杂的逻辑变得简单。在这个"redux-thunk ...

    Thunk 代码

    Thunk,你懂的,这么简单,就没写示例了。

    Thunk经典资料全集

    Thunk经典资料全集,收集几乎所有的Thunk资料。

    Thunk v0.4 by intret

    Thunk v0.4 by intret 是一个C++实现的Thunk技术实例,它提供了一个简单的类,并包含使用示例,帮助开发者理解和应用Thunk技术。 首先,我们要理解什么是Thunk。在Windows编程中,Thunk通常被用来解决32位和64位...

    GenericThunk_source_toy63r_Vc_

    《通用Thunk技术在C语言中的应用——以"toy63r Vc"为例》 Thunk技术,源于汇编语言的概念,通常用于不同编程环境或体系结构间的接口转换。在C语言中,由于其不支持成员函数的this指针,使得在处理对象方法时面临...

    前端项目-redux-thunk.zip

    在前端开发领域,Redux是一个非常流行的状态管理库,它帮助开发者集中管理应用中的全局状态,使得复杂的单页面应用(SPA)能够保持数据流的一致性和可预测性。本项目"前端项目-redux-thunk.zip"专注于介绍如何在...

    vCO:另一个基于 thunk 的 CO 版本

    **vCO: 另一个基于 Thunk 的 CO 版本** 在JavaScript的世界中,异步编程是不可或缺的一部分,尤其是在处理I/O操作时。传统的回调函数模式由于其“回调地狱”问题,导致代码可读性和可维护性降低。为了解决这个问题...

    管理系统系列--基于antd、redux-observable、redux-thunk、react-router响应.zip

    【标题】"管理系统系列--基于antd、redux-observable、redux-thunk、react-router响应" 提供了一个关于构建管理系统的框架,这个系统利用了现代前端技术栈中的几个关键组件。在这个项目中,开发者采用了一些最流行的...

    基于React18、React-Router V6、Redux Vite2、Ant-Design 开源的一套后台管理框架

    Hooks Admin 是一个全面的后台管理框架,它充分利用了React18、React-Router V6、Redux、React Hooks、TypeScript以及Vite2等现代前端技术,同时采用了流行的Ant Design UI库,为开发者提供了高效且易用的开发环境。...

    KWinGUI 1.0 界面库,thunk封装!

    总的来说,KWinGUI 1.0界面库是一个致力于简化跨平台GUI开发的工具,其thunk封装技术是实现这一目标的关键,它帮助开发者克服不同平台间API的不一致性,提高代码的可移植性和维护性。对于那些想要为KDE环境或其他...

    Redux异步解决方案之Redux-Thunk原理及源码解析.docx

    在现代前端开发中,尤其是在使用Redux进行状态管理时,经常会遇到需要处理异步操作的情况。这些操作可能包括发送网络请求、设置定时器等。然而,Redux的核心设计原则是行动(Action)必须是同步的并且返回一个纯对象...

    redux-thunk-3.0.0-beta.0.zip

    Redux 的 Thunk 中间件。它允许编写带有内部逻辑的函数,这些函数可以与 Redux 存储的 dispatch 和 getState 方法交互。

Global site tag (gtag.js) - Google Analytics