其中使用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++视频教程