Thunk技术封装好的win32项目窗口类

转载请注明出处:http://blog.csdn.net/hhhhhhhhhhkkkkkkkkkk/article/details/39613887

由于windows API写窗口有点麻烦而单调,而普通的类成员函数不能用作回调函数,所以在这里发一个用Thunk技术封装好的窗口类,方便调试。里面有部分封装的事件接口,可以根据需要自行扩展。

class MainWindow
{
public:
	HWND m_hWnd;
private:
#pragma pack(push,1)
	struct THUNK
	{
		DWORD m_mov; // = 0x042444C7
		DWORD m_this; // = this
		BYTE m_jmp; // = 0xe9
		DWORD m_relproc; // = relative distance
	}*thunk;
#pragma pack(pop)
public:
	MainWindow() :m_hWnd(NULL){}
	~MainWindow()
	{
		VirtualFree(thunk, sizeof(THUNK), MEM_RELEASE);
	}
	bool Create()
	{
		WNDCLASSEX wcex;
		LPCTSTR lpszClassName = _T("ClassName");
		wcex.cbSize = sizeof(WNDCLASSEX);
		wcex.style = CS_HREDRAW | CS_VREDRAW;
		wcex.lpfnWndProc = MainWindow::TempWndProc;
		wcex.cbClsExtra = 0;
		wcex.cbWndExtra = 0;
		wcex.hInstance = GetModuleHandle(NULL);
		wcex.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SMALL));
		wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
		wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MY);
		wcex.lpszClassName = lpszClassName;
		wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
		RegisterClassEx(&wcex);
		thunk = (THUNK *)VirtualAlloc(NULL, sizeof(THUNK), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
		thunk->m_mov = 0x042444c7;
		thunk->m_jmp = 0xe9;
		//CreateWindow的最后一个参数为this指针
		CreateWindow(lpszClassName, NULL, WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, GetModuleHandle(NULL), this);
		if (m_hWnd == NULL)return false;
		ShowWindow(m_hWnd, SW_SHOW);
		UpdateWindow(m_hWnd);
		///
		MSG msg;
		HACCEL hAccelTable = LoadAccelerators(GetModuleHandle(NULL), MAKEINTRESOURCE(IDC_MY));
		while (GetMessage(&msg, NULL, 0, 0))
		{
			if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		return TRUE;
	}
protected:
	//辅助回调函数
	static LRESULT CALLBACK TempWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
	{
		if (message == WM_CREATE)//此处使用WM_NCCREATE消息也可以
		{
			//提取出对象指针
			MainWindow *w = NULL;
			w = (MainWindow*)((LPCREATESTRUCT)lParam)->lpCreateParams;
			w->m_hWnd = hWnd;
			WNDPROC pWndProc = (WNDPROC)w->thunk;
			w->thunk->m_this = (DWORD)w;

			//计算跳转位置
			w->thunk->m_relproc = (DWORD)&MainWindow::StaticWndProc - ((DWORD)w->thunk + sizeof(THUNK));

			SetWindowLong(hWnd, GWL_WNDPROC, (LONG)pWndProc);
			return pWndProc(hWnd, message, wParam, lParam);
		}
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
	{
		return ((MainWindow *)hWnd)->WndProc(message, wParam, lParam);
	}
protected:
	//主回调函数
	virtual LRESULT CALLBACK WndProc(UINT message, WPARAM wParam, LPARAM lParam)
	{
		HDC hdc;
		PAINTSTRUCT ps;
		RECT rect;
		switch (message)
		{
		case WM_CREATE:
			OnCreate();
			break;
		case WM_MOUSEMOVE:
			OnMouseMove(LOWORD(lParam), HIWORD(lParam));
			break;
		case WM_LBUTTONDOWN:
			OnLButtonDown(LOWORD(lParam), HIWORD(lParam));
			break;
		case WM_LBUTTONUP:
			OnLButtonUp(LOWORD(lParam), HIWORD(lParam));
			break;
		case WM_TIMER:
			OnTimer();
			break;
		case WM_PAINT:
			hdc = BeginPaint(m_hWnd, &ps);
			OnPaint(hdc);
			EndPaint(m_hWnd, &ps);
			break;
		case WM_SIZE:
			GetClientRect(m_hWnd, &rect);
			OnSize(rect);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(m_hWnd, message, wParam, lParam);
			break;
		}
		return TRUE;
	}
public:
	virtual void OnCreate()
	{

	}
	virtual void OnMouseMove(int mouseX, int mouseY)
	{

	}
	virtual void OnLButtonDown(int mouseX, int mouseY)
	{

	}
	virtual void OnLButtonUp(int mouseX, int mouseY)
	{

	}
	virtual void OnTimer()
	{

	}
	virtual void OnPaint(HDC&hdc)
	{

	}
	virtual void OnSize(RECT&rect)
	{

	}

};

调用方式:

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{

	MainWindow window;
	window.Create();
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用C++代码封装win32操作类, 与MFC相似,对于学习SDK与C++是巨好的参考 Tutorials Menu of tutorials Tutorial 1: The Simplest Window Tutorial 2: Using Classes and Inheritance Tutorial 3: Using Messages to Create a Scribble Window Tutorial 4: Repainting the Window Tutorial 5: Wrapping a Frame around our Scribble Window Tutorial 6: Customising Window Creation Tutorial 7: Customising the Toolbar Tutorial 8: Loading and Saving Files Tutorial 9: Printing Tutorial 10: Finishing Touches Tutorial 1: The Simplest Window The following code uses Win32++ to create a window. This is all the code you need (in combination with Win32++) to create and display a simple window. Note that in order to add the Win32++ code to our program, we use an #include statement as shown below. #include "../Win32++/Wincore.h" INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPTSTR, int) { //Start Win32++ CWinApp MyApp; //Create a CWnd object CWnd MyWindow; //Create (and display) the window MyWindow.Create(); //Run the application return MyApp.Run(); } This program has four key steps: Start Win32++. We do this here by creating a CWinApp object called MyApp. Create a CWnd object called MyWindow. Create a default window by calling the Create function. Start the message loop, by calling the Run function. If you compile and run this program, you'll find that the application doesn't end when the window is closed. This is behaviour is normal. An illustration of how to use messages to control the windows behaviour (including closing the application) will be left until tutorial 3.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值