由于MFC中无法通过类向导来自定义消息,所以需要手动添加,主要过程如下:
本文基于vs2008下通过线程实现数据实时更新的对话框运用程序
1. 定义消息(Resource.h文件中):
由于很多新控件也会用到WM_USER消息,所以定义WM_USER+100或更高,避免冲突
#define WM_UPDATEDATA (WM_USER + 100)
2015-3-18 更新
1. 定义消息( stdafx.h文件中):
由于很多新控件也会用到WM_USER消息,所以定义WM_USER+100或更高,避免冲突,消息定义到stdafx.h文件中,Resource.h文件由系统维护,经常出现自定义的消息丢失。
#define WM_UPDATEDATA (WM_USER + 100)
2. 声明消息响应函数:
放在消息映射部分,即DECLARE_MESSAGE_MAP()之前
// 实现 protected: HICON m_hIcon; // 生成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg LRESULT OnUpdateData(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP()
3. 实现消息响应函数:
由于在vs2008中未定义ON_MESSAGE_VOID,所以定义的消息响应函数必须有返回值,即LRESULT;而消息参数是WPARAM wParam和LPARAM lParam
LRESULT CEditTestDlg::OnUpdateData(WPARAM wParam, LPARAM lParam) { UpdateData(wParam); return 0; }
4. 将消息映射到消息处理函数:
放在AFX_MSG_MAP之前,把WM_UPDATEDATA消息映射到消息响应函数OnUpdateData
BEGIN_MESSAGE_MAP(CEditTestDlg, CDialog) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_MESSAGE(WM_UPDATEDATA, OnUpdateData) //}}AFX_MSG_MAP ON_BN_CLICKED(IDC_BUTTON1, &CEditTestDlg::OnBnClickedButton1) END_MESSAGE_MAP()
5. 发送自定义消息:
以下函数是在一个新的线程中调用的,PostMessage,SendMessage,SendMessageTimeout均可用,推荐使用SendMessageTimeout函数
static UINT SendMsgThread(LPVOID lpParam) { CEditTestDlg *dlg = (CEditTestDlg*) lpParam; int i = 0; while (i < 100) { Sleep(20); i += 1; dlg->m_value2.Format(_T("%d"), i); //PostMessage(dlg->m_hWnd,WM_UPDATEDATA,FALSE,NULL); //SendMessage(dlg->m_hWnd,WM_UPDATEDATA,FALSE,NULL); SendMessageTimeout(dlg->m_hWnd, WM_UPDATEDATA, FALSE,NULL, SMTO_BLOCK, 1000, NULL); } return 0; }
如果用户需要一个定义整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage定义消息:
在Resource.h中将代码
#define WM_UPDATEDATA (WM_USER + 100)
修改为
static UINT WM_UPDATEDATA=RegisterWindowMessage(_T("User"));
并使用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。
注:如果仍然使用ON_MESSAGE宏指令,compile可以通过,但是无法响应消息。
相关内容可查看:线程调用UpdateData函数出错