优化Win32Class,将不常用的代码移到.h文件中,将常用的代码移到.cpp文件中去。

其中使用MY_MESSAGE_DECLARE和MY_MESSAGE_MAP这2个宏将原本在Win32Class.h文件中的声明消息响应函数和定义消息响应函数数组的代码也移到了Win32Class.cpp文件中。这样,.h文件中都是一些结构性和固定模式的不需要经常改动的内容了,而.cpp文件中的内容就全是需要经常改动、和应用相关的内容,如要再添加新的消息及其响应代码,只需要照葫芦画瓢即可,真正实现了将主要精力放在业务上而不是程序的框架上的目标。

其实,上面2个宏的实现思想就是MFC消息映射的核心思想,通过实现我们自己的类库的过程,将原本复杂晦涩、难于理解的MFC消息映射的概念轻松的揭示给了大家。这为我们后面学习MFC打下了良好的基础。

头文件Win32Class.h的内容如下:

// Win32Lib.h: interface for the CMyWnd class.
//
#if !defined(AFX_WIN32LIB_H__510E6511_F3DB_4E80_B512__INCLUDED_)
#define AFX_WIN32LIB_H__510E6511_F3DB_4E80_B512__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//返回元素的个数
#define dim(x)(sizeof(x) / sizeof(x[0]))

//定义函数指针
typedef LRESULT(*FXN)(HWND, UINT, WPARAM, LPARAM);

//消息映射结构
struct tagMESSAGEMAP
{
	UINT Code;	//消息
	FXN Fxn;	//响应函数
};

class CMyWnd
{
public:
	HINSTANCE m_hInstance;
	HWND m_hWnd;

public:
	BOOL Create();
	BOOL ShowWindow();
	BOOL UpdateWindow();
	CMyWnd();
	virtual ~CMyWnd(){};

	//主窗口回调函数
	static LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);

	//声明消息响应函数
	MY_MESSAGE_DECLARE
};

//消息映射数组
MY_MESSAGE_MAP

class CMyApp  
{
public:
	CMyWnd* m_pMainWnd;
	BOOL InitInstance();
	BOOL Run();
	CMyApp();
	virtual ~CMyApp(){};
};

//入口函数
int WINAPI WinMain(
	HINSTANCE hInstance,		// handle to current instance
	HINSTANCE hPrevInstance,	// handle to previous instance
	LPSTR lpCmdLine,			// command line
	int nCmdShow)				// show state
{
	return 0;
}

//
// CMyWnd Class
//
CMyWnd::CMyWnd()
{
	m_hWnd = NULL;
	m_hInstance = NULL;
}

BOOL CMyWnd::Create()
{
	WNDCLASS wndcls;
	wndcls.cbClsExtra = 0;
	wndcls.cbWndExtra = 0;
	wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndcls.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);
	wndcls.hInstance = m_hInstance;
	wndcls.lpfnWndProc = WinProc;
	wndcls.lpszClassName = "ItJob2010";
	wndcls.lpszMenuName = NULL;
	wndcls.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&wndcls);

	m_hWnd = ::CreateWindow(wndcls.lpszClassName, "培训中心", 
		WS_OVERLAPPEDWINDOW, 
		0, 0, 600, 400, NULL, NULL, m_hInstance, NULL);

	::SetTimer(m_hWnd, 123, 1000, NULL);

	if (m_hWnd == NULL)
		return FALSE;
	else
		return TRUE;
}

BOOL CMyWnd::ShowWindow()
{
	return ::ShowWindow(m_hWnd, SW_SHOWNORMAL);
}

BOOL CMyWnd::UpdateWindow()
{
	return ::UpdateWindow(m_hWnd);
}

//主窗口回调函数
LRESULT CALLBACK CMyWnd::WinProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	// 如果当前消息是我们关心的、定义在数组中的消息,则处理之
	for (int i = 0; i < dim(MessageMaps); i++)
	{
		if (wMsg == MessageMaps[i].Code)
		{
			FXN iFxn = MessageMaps[i].Fxn;
			LRESULT lResult = iFxn(hWnd, wMsg, wParam, lParam);
			if (lResult == 0)
				return 0;
		}
	}

	// 否则,将消息交给系统去处理
	return DefWindowProc(hWnd, wMsg, wParam, lParam);
}

//
// CMyApp Class
//
CMyApp::CMyApp()
{
	m_pMainWnd = NULL;

	if (InitInstance())
		Run();
}

BOOL CMyApp::Run()
{
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return TRUE;
}

BOOL CMyApp::InitInstance()
{
	m_pMainWnd = new CMyWnd();
	m_pMainWnd->Create();
	m_pMainWnd->ShowWindow();
	return m_pMainWnd->UpdateWindow();
}

#endif // !defined(AFX_WIN32LIB_H__510E6511_F3DB_4E80_B512__INCLUDED_)


实现文件Win32Class.cpp的内容如下:

#include <windows.h>
#include <stdio.h>

//声明消息响应函数
#define MY_MESSAGE_DECLARE									\
static LRESULT OnChar(HWND, UINT, WPARAM, LPARAM);			\
static LRESULT OnLButtonDown(HWND, UINT, WPARAM, LPARAM);	\
static LRESULT OnPaint(HWND, UINT, WPARAM, LPARAM);			\
static LRESULT OnDestroy(HWND, UINT, WPARAM, LPARAM);			\
static LRESULT OnTimer(HWND, UINT, WPARAM, LPARAM);			\

//消息映射数组
#define MY_MESSAGE_MAP										\
tagMESSAGEMAP MessageMaps[] = {								\
	WM_CHAR,			CMyWnd::OnChar,							\
	WM_LBUTTONDOWN,		CMyWnd::OnLButtonDown,			\
	WM_PAINT,			CMyWnd::OnPaint,						\
	WM_DESTROY,			CMyWnd::OnDestroy,					\
	WM_TIMER,			CMyWnd::OnTimer,						\
};																\

#include "Win32Class.h"

CMyApp theApp;

//消息响应函数: 字符按下
LRESULT CMyWnd::OnChar(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	char szChar[20];
	sprintf(szChar, "char is %c", (char)wParam);
	MessageBox(hWnd, szChar, "OnChar", 0);
	return 0;
}

//消息响应函数: 鼠标左键按下
LRESULT CMyWnd::OnLButtonDown(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	hdc = GetDC(hWnd);
	TextOut(hdc, 0, 50, "计算机编程语言培训", strlen("计算机编程语言培训"));
	ReleaseDC(hWnd, hdc);
	return 0;
}

//消息响应函数:重绘窗口
LRESULT CMyWnd::OnPaint(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	//画一个圆
	RECT rc;
	GetClientRect(hWnd, &rc);

	int iR = min(rc.right - rc.left, rc.bottom - rc.top) / 2;
	iR = iR * 4 / 5;
	POINT pt;
	pt.x = (rc.right + rc.left) / 2;
	pt.y = (rc.bottom + rc.top) / 2;

	HDC hdc;
	PAINTSTRUCT ps;
	hdc = BeginPaint(hWnd, &ps);

	::Ellipse(hdc, pt.x - iR, pt.y - iR, pt.x + iR, pt.y + iR);
	MoveToEx(hdc, pt.x, pt.y,(LPPOINT)NULL);
	LineTo(hdc, pt.x + iR, pt.y);

	//显示时间
	static char stime[] = "23:59:59";
	SYSTEMTIME tm;
	::GetLocalTime(&tm);
	sprintf(stime, "%.2d:%.2d:%.2d", tm.wHour, tm.wMinute, tm.wSecond);
	::TextOut(hdc, 10, 10,(LPCSTR)stime, strlen(stime));

	EndPaint(hWnd, &ps);

	return 0;
}

//消息响应函数: 销毁窗口
LRESULT CMyWnd::OnDestroy(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	PostQuitMessage(0);
	return 0;
}

//消息响应函数: 定时器
LRESULT CMyWnd::OnTimer(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	RECT rc;
	::GetClientRect(hWnd, &rc);
	::InvalidateRect(hWnd, &rc, TRUE);
	return 0;
}

点击更多 C++视频教程
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值