摘要:自從發了5篇關於消息的文章,有的網友來信希望我講一些比較實用的消息機制用法,這裏我想就用戶的自定義消息做一個全面的論述,希望能夠解除你心頭的困惑。
一、普通的自定義消息方法。
根據我在前面的幾篇文章中提到的消息值的範圍,我向大家都很清楚用戶自定義消息的範圍,不過,雖然說用會自定義消息從WM_USER開始,但是由於我們的工程裏面一般還有很多其他的控件,他們也要佔用一部分WM_USER消息範圍,所以我們必須爲他們留出一部分範圍,這裏,我們保留100個消息,一般情況下,這可以滿足我們的要求。
(1)定義消息的值。在我們要發生消息的地方(例如CMyView.cpp的開始部分)進行如下定義#define WM_MSG_1 (WM_USER+100)
接下來的工作其實很簡單,我們在前面說了,消息正常工作有3個部分必須協調:消息聲明、消息映射、消息體。我們就一次進行手工加入。
(2)首先在AFX_MSG塊中加入消息聲明:在CMyView.h中,找到如下部分,並加入消息聲明:
protected:
// {{AFX_MSG(CMyView)
......
afx_msg LRESULT OnMyMsg(WPARAM wParam,LPARAM lParam);
file://}}AFX_MSG
(3)在MESSAGE_MAP塊中添加ON_MESSAGE宏指令:
BEGIN_MESSAGE_MAP(CMyView, CView)
file://{{AFX_MSG_MAP(CMyView)
.....
ON_MESSAGE(WM_MSG_1, OnMyMsg)
file://}}AFX_MSG_MAP
END_MESSAGE_MAP()
(4)添加消息函數體:
LPESULT CMyView::OnMyMsg(WPARAM wParam, LPARAM lParam)
{
AfxMessageBox("消息已經收到!");
return 0;
}
消息至此就已經定義完畢,接下來我們就可以激活消息了,就可以用我們前面所說的PostMessage/SendMessage,一切OK!
二、自定義消息塊
消息塊就以一個Range,主要是用來一次處理多個消息,不過對消息有一個要求:消息的值必須是連續的。這樣做的好處就是:簡化類,可以通過一個函數來完成一組消息的處理工作。
通常,消息塊有4個:ON_CONTROL_RANGE、ON_NOTIFY_RANGE、ON_COMMAND_RANGE和ON_UPDATE_COMMAND_UI_RANGE,他們的使用方法差不多,我就找個比較常用的來談談吧:ON_COMMAND_RANGE和ON_UPDATE_COMMAND_UI_RANGE
步驟如下:
1. 使用命令範圍宏
ON_COMMAND_RANGE宏接收所有ID在某一範圍之內的命令消息(WM_COMMAND消息)。使用這個宏可以在一個函數中處理多條命令。
1) 在類的. h 文件的{{ }}之後定義命令處理函數,以便不受Cl0assWizard的干擾。
protected:
file://{{AFX_MSG(CTestView)
file://}}AFX_MSG
afx_msg void OnTestCommandRange(UINT nID);
DECLARE_MESSAGE_MAP()
2) 同樣在{{ }}之後,加入ON_COMMAND_RANGE宏到類的消息映像。頭兩個參數定義了要處理的命令ID的範圍。這些ID有序列大小,且最後一個ID比第一個大。最後一個參數是在第一步中定義的消息處理函數的名稱。
BEGIN_MESSAGE_MAP(CTestView,CView)
file://{{AFX_MSG_MAP(CTestView)
file://}}AFX_MSG_MAP
ON_COMMAND_RANGE(ID_TEST_1,ID_TEST_4,OnTestCommandRange)
END_MESSAGE_MAP()
3) 用下面的語句添加消息處理函數。參數nID是要處理命令的ID。
void CTestView::OnTestCommandRange(UINT nID)
{
switch (nID)
{
case ID_TEST_1: break ;
case ID_TEST_2: break ;
case ID_TEST_3: break ;
case ID_TEST_4: break ;
}
}
2. 使用用戶界面命令範圍宏
ON_UPDATE_COMMAND_UI_RANGE宏截取一定範圍內的消息中更新用戶界面的請求。使用這個宏,可以啓用所有的菜單命令或者處理一組工具欄按鈕。
1) 在類的.h 文件映像的{{ }}之後定義用戶界面命令處理函數,以便不受ClassWizard 的干擾。
protected:
file://{{AFX_MSG(CTestView)
file://}}AFX_MSG
afx_msg void OnUpdateTestCommandRange(CCmdUI* pCCmdUI);
2) 同樣,在{{ }}之後,加入ON_UPDATE_COMMAND_UI_RANGE宏到用戶類的命令映像中。頭兩個參數定義了要處理的消息I D 的範圍。這些ID有序列大小,最後一個ID值比第一個大。最後一個參數是第一步中定義的用戶界面命令處理函數的名字。
BEGIN_MESSAGE_MAP(CTestView,CView)
file://{{AFX_MSG_MAP(CTestView)
file://}}AFX_MSG_MAP
ON_UPDATE_COMMAND_UI_RANGE(ID_TEST_1,ID_TEST_4,OnUpdateTestCommandRange)
END_MESSAGE_MAP()
3) 處理界面命令消息的語句如下:
void CTestView::OnUpdateTestCommandRange(CCmdUI *pCmdUI)
{
switch (pCmdUI->m_nID)
{
case ID_TEST_1: break ;
case ID_TEST_2: pCmdUI->SetRadio();break ;
case ID_TEST_3: break ;
case ID_TEST_4: break ;
}
}
更多分享請關注:軟信網-編程-http://www.iis365.net.cn