如何在MFC应用程序中发送Windows通知?含指定样式通知实现问询
嘿,我来帮你理清在MFC应用里发送Windows通知的具体实现!其实Windows通知大多基于WM_NOTIFY消息,不同场景下的实现略有不同,我分几种常见情况给你拆解:
1. 向父窗口发送标准控件通知
很多MFC控件(比如CListCtrl、CTreeCtrl)的状态变化会通过WM_NOTIFY通知父窗口,但如果你需要手动模拟这类通知(比如测试控件逻辑),可以按以下步骤来:
比如模拟CListCtrl的LVN_ITEMCHANGED通知:
// 假设m_list是你的CListCtrl成员变量 NMLISTVIEW nmlv = {0}; // 填充基础NMHDR部分 nmlv.hdr.hwndFrom = m_list.m_hWnd; nmlv.hdr.idFrom = m_list.GetDlgCtrlID(); nmlv.hdr.code = LVN_ITEMCHANGED; // 设置具体的通知参数,比如选中第0项 nmlv.iItem = 0; nmlv.uNewState = LVIS_SELECTED; nmlv.uOldState = 0; // 发送给父窗口,用SendMessage同步发送(等待处理完成) GetParent()->SendMessage(WM_NOTIFY, (WPARAM)m_list.GetDlgCtrlID(), (LPARAM)&nmlv); // 也可以用PostMessage异步发送(不等待,直接放入消息队列) // GetParent()->PostMessage(WM_NOTIFY, (WPARAM)m_list.GetDlgCtrlID(), (LPARAM)&nmlv);
2. 自定义通知消息
如果需要实现自己的通知逻辑(比如自定义控件向父窗口传递状态),可以自定义通知码:
步骤1:定义自定义通知码
在头文件里声明(避免和系统码冲突,建议用WM_USER + 数值):
#define MY_CUSTOM_NOTIFY (WM_USER + 100)
步骤2:构造并发送通知
NMHDR nmhdr = {0}; nmhdr.hwndFrom = m_hWnd; // 当前发送通知的窗口句柄 nmhdr.idFrom = GetDlgCtrlID(); // 当前控件的ID nmhdr.code = MY_CUSTOM_NOTIFY; // 自定义的通知码 // 发送给父窗口 GetParent()->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nmhdr);
步骤3:父窗口处理自定义通知
在父窗口的消息映射里添加处理:
BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx) // ...其他消息映射 ON_NOTIFY(MY_CUSTOM_NOTIFY, IDC_MY_CONTROL, &CMyDialog::OnMyCustomNotify) END_MESSAGE_MAP()
然后实现处理函数:
void CMyDialog::OnMyCustomNotify(NMHDR* pNMHDR, LRESULT* pResult) { // 这里写你的自定义处理逻辑 AfxMessageBox(_T("收到自定义通知啦!")); // 记得设置pResult,通知系统已经处理完成 *pResult = 0; }
3. 发送通知给非父窗口
如果需要给其他任意窗口发送通知,只要拿到目标窗口的句柄即可:
// 比如通过窗口标题找到目标窗口 CWnd* pTargetWnd = FindWindow(NULL, _T("目标窗口的标题")); if (pTargetWnd != nullptr) { NMHDR nmhdr = {0}; nmhdr.hwndFrom = m_hWnd; nmhdr.idFrom = GetDlgCtrlID(); nmhdr.code = MY_CUSTOM_NOTIFY; pTargetWnd->SendMessage(WM_NOTIFY, (WPARAM)GetDlgCtrlID(), (LPARAM)&nmhdr); }
注意事项
- 所有通知都基于
NMHDR结构体,特定控件的通知会有扩展结构体(比如NMLISTVIEW、NMTREEVIEW),使用时要对应正确的结构体类型。 SendMessage是同步发送,会等待目标窗口处理完消息再返回;PostMessage是异步发送,消息放入队列后立刻返回,适合不需要等待结果的场景。
内容的提问来源于stack exchange,提问作者박찬용
相关产品推荐
相关产品推荐

