为什么要有消息映射,它的使用是怎样的?
MFC程序是不包括主要函数和时间循环。所有的事件处理都是作为CWinApp的一部分在后台处理的。而消息映射就是识别感兴趣的事件然后调用函数来响应这些事件。
一,首先是正常的程序
// button1.cpp
#include
#define IDB_BUTTON 100
// Declare the application class
class CButtonApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
// Create an instance of the application class
CButtonApp ButtonApp;
// Declare the main window class
class CButtonWindow : public CFrameWnd
{
CButton *button;
public:
CButtonWindow();
};
// The InitInstance function is called once
// when the application first executes
BOOL CButtonApp::InitInstance()
{
m_pMainWnd = new CButtonWindow();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
// The constructor for the window class
CButtonWindow::CButtonWindow()
{
CRect r;
// Create the window itself
Create(NULL,
"CButton Tests",
WS_OVERLAPPEDWINDOW,
CRect(0,0,200,200));
// Get the size of the client rectangle
GetClientRect(&r);
r.InflateRect(-20,-20);
// Create a button
button = new CButton();
button->Create("Push me",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
r,
this,
IDB_BUTTON);
}
当你运行代码时,会注意到按钮响应了用户事件。既它加亮了。除此之外它没有做任何事情,因为我们还没有教它怎样去做。我们需要编写消息映射来使按钮做一些感兴趣的事情。 |
二,建立消息映射
// button2.cpp
#include
#define IDB_BUTTON 100
// Declare the application class
class CButtonApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
// Create an instance of the application class
CButtonApp ButtonApp;
// Declare the main window class
class CButtonWindow : public CFrameWnd
{
CButton *button;
public:
CButtonWindow();
afx_msg void HandleButton(); //
DECLARE_MESSAGE_MAP()
};
// The message handler function
void CButtonWindow::HandleButton()
{
MessageBeep(-1);
}
// The message map
BEGIN_MESSAGE_MAP(CButtonWindow, CFrameWnd)
ON_BN_CLICKED(IDB_BUTTON, HandleButton)
END_MESSAGE_MAP()
/*用宏来建立消息映射。在代码中,你可以看见BEGIN_MESSAGE_MAP宏接收两各参数。第一个指定了使用消息映射的类的名称。第二个是基类。然后是ON_BN_CLICKED宏,接受两个参数控制的ID和该ID发送命令消息时所调用的函数。最后,消息映射用END_MESSAGE_MAP来结束。
当用户单击按钮时,它向其包含该按钮的父窗口发送了一个包含其ID的命令消息。那是按钮的缺省行为,这就是该代码工作的原因。按钮向其父窗口发送消息,是因为它是子窗口。父窗口截取该消息并用消息映射来确定所要调用的函数。MFC来安排,只要指定的消息一出现,相应的函数就会被调用。
ON_BN_CLICKED消息是CButton发送的唯一感兴趣的消息。它等同于CWnd中的ON_COMMAND消息,只是一个更简单方便的同义词而已。*/
// The InitInstance function is called once
// when the application first executes
BOOL CButtonApp::InitInstance()
{
m_pMainWnd = new CButtonWindow();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
// The constructor for the window class
CButtonWindow::CButtonWindow()
{
CRect r;
// Create the window itself
Create(NULL,
"CButton Tests",
WS_OVERLAPPEDWINDOW,
CRect(0,0,200,200));
// Get the size of the client rectangle
GetClientRect(&r);
r.InflateRect(-20,-20);
// Create a button
button = new CButton();
button->Create("Push me",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
r,
this,
IDB_BUTTON);
}
上边修改了两个地方,1增加了一个新的成员函数和一个新的表示消息映射的宏。HandleButton函数是正常的c++函数,它通过afx_msg标签确定为消息处理函数。该函数有一些特殊约束,比如它必须是void型并且不能接收任何参数。 DECLARE_MESSAGE_MAP宏建立了消息映射。函数和宏都必须是public型的。
对消息映射的理解:
消息映射智能用于MFC。使用消息映射的原因是解决虚拟函数的基本问题。 MFC文件中CWnd类,它包含200多个成员函数,所有成员函数当不使用消息映射都是虚拟的。MFC中大约有近30个类是以CWnd为基类的。这包括所有的可见控制如按钮、静态标签和列表。想象一下,mfc使用虚拟啊和你熟,并且你建立以应用程序包含20个控制.CWnd中200个虚拟函数中每个都需要自己的虚拟函数表,并且一个控制的每个例程都应有一组200个虚拟函数与之关联。则程序可能就有近4000个虚拟函数表在内存中,这对内存有限的及其来书是个大问题,因为其中的大部分是不用的。
消息映射复制了虚拟函数表的操作,但是它是基于需要的基础之上的。消息映射就是对系统说“当你看见一个特殊的消息时,请调用制定的函数”,只有这些函数实际上被重载到消息映射中,就节省二楼内存和cpu的负担。
posted on 2009-07-18 19:23
Bluesea 阅读(530)
评论(0) 编辑 收藏 引用 所属分类:
MFC