由於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函數出錯