為什么要有消息映射,它的使用是怎樣的?
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 閱讀(551)
評論(0) 編輯 收藏 引用 所屬分類:
MFC