书籍:《Visual C++ 2017从入门到精通》的3.8.5 查找/替换对话框的使用
环境:visual studio 2022
内容:[例 3.14] 查找/替换对话框的使用
说明:以上内容大部分来自腾讯元宝。
在MFC中注册自定义消息需要遵循系统规范,确保消息的唯一性和正确性。以下是详细步骤及原理说明:
一、消息注册流程
1. 定义消息名称
消息名称需唯一,通常以项目前缀命名(如MYAPP_SHOW):
// 在公共头文件(如stdafx.h)中定义
#define WM_MY_CUSTOM_MESSAGE _T("MyApp_CustomMessage")
2. 注册消息
通过 RegisterWindowMessage 函数动态生成唯一消息ID:
// 在类初始化函数(如OnInitDialog)中注册
UINT m_nCustomMsg = RegisterWindowMessage(WM_MY_CUSTOM_MESSAGE);
if (m_nCustomMsg == 0) {
AfxMessageBox(_T("消息注册失败!"));
return FALSE;
}
返回值:成功时返回 0xC000~0xFFFF 之间的唯一ID,失败返回0。作用域:消息ID在注册它的进程中有效,跨进程需使用相同名称重新注册。
二、消息映射与处理
1. 声明消息处理函数
在类头文件中声明处理函数:
// MyDialog.h
class CMyDialog : public CDialogEx {
DECLARE_MESSAGE_MAP()
public:
afx_msg LRESULT OnCustomMessage(WPARAM wParam, LPARAM lParam);
};
2. 添加消息映射
在类实现文件的消息映射中绑定消息:
// MyDialog.cpp
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
ON_REGISTERED_MESSAGE(m_nCustomMsg, &CMyDialog::OnCustomMessage)
END_MESSAGE_MAP()
关键宏:ON_REGISTERED_MESSAGE 用于动态注册消息,ON_MESSAGE 用于预定义消息(如WM_USER+1)。
3. 实现消息处理函数
LRESULT CMyDialog::OnCustomMessage(WPARAM wParam, LPARAM lParam) {
CString strData = (LPCTSTR)lParam; // 假设传递字符串
AfxMessageBox(strData);
return 0;
}
三、发送消息
1. 同一进程内发送
通过窗口句柄直接发送:
// 发送端
CWnd* pWnd = FindWindow(NULL, _T("目标窗口标题"));
if (pWnd) {
::SendMessage(pWnd->m_hWnd, m_nCustomMsg, 0, (LPARAM)_T("Hello World"));
}
2. 跨进程发送
需确保目标进程已注册同名消息:
// 跨进程示例(需包含目标进程句柄)
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess) {
::SendMessage(hProcess, m_nCustomMsg, 0, (LPARAM)_T("跨进程消息"));
CloseHandle(hProcess);
}
四、注意事项
消息唯一性
使用 RegisterWindowMessage 保证系统唯一性,避免与其他消息冲突。跨进程通信时,需确保所有进程使用相同的消息名称。
线程安全
消息注册和发送需在主线程中完成,避免多线程竞争。
内存管理
若通过 lParam 传递指针,需确保接收方在消息处理前不释放内存。
调试技巧
使用 OutputDebugString 输出消息ID和内容,辅助调试。
五、完整示例
1. 注册与声明
// stdafx.h
#define WM_DATA_READY _T("DataReady")
// MyDialog.h
class CMyDialog : public CDialogEx {
DECLARE_MESSAGE_MAP()
public:
afx_msg LRESULT OnDataReady(WPARAM wParam, LPARAM lParam);
};
2. 注册与映射
// MyDialog.cpp
UINT CMyDialog::m_nDataMsg;
BOOL CMyDialog::OnInitDialog() {
CDialogEx::OnInitDialog();
m_nDataMsg = RegisterWindowMessage(WM_DATA_READY);
return TRUE;
}
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
ON_REGISTERED_MESSAGE(m_nDataMsg, &CMyDialog::OnDataReady)
END_MESSAGE_MAP()
LRESULT CMyDialog::OnDataReady(WPARAM wParam, LPARAM lParam) {
// 处理数据
return 0;
}
3. 发送消息
// 发送端代码
CMyDialog dlg;
dlg.DoModal();
::SendMessage(dlg.m_hWnd, dlg.m_nDataMsg, 0, (LPARAM)_T("数据已加载"));
六、扩展应用
自定义消息队列
通过 PostThreadMessage 将消息投递到指定线程的消息队列。
消息加密
对 wParam 和 lParam 进行加密传输,提升安全性。
多消息绑定
在消息映射中绑定多个处理函数:
ON_REGISTERED_MESSAGE(m_nMsg1, &CMyClass::OnMsg1)
ON_REGISTERED_MESSAGE(m_nMsg2, &CMyClass::OnMsg2)
通过以上步骤,可高效实现MFC消息的注册、发送与处理。若需跨模块通信,建议结合DLL注入或COM机制增强兼容性。
Copyright © 2022 日本世界杯_林高远世界杯 - edenyn.com All Rights Reserved.