自定义WM_NOTIFY消息
习惯了用自定义用户消息进行各种状态的通知,特别是子窗口与父窗口之间的交互。但ON_MESSAGE没有控件ID的限制,如果有多个子窗口发送同一个消息给父窗口时,父窗口就不知道哪个窗口发的(当然可以用参数进行约定)。
如何解决这个问题?

有几种思路:1.重写ON_MESSAGE宏,增加ID的限制;2.模拟按钮单击消息;3.自定义WM_NOTIFY消息。基于这些思路都不能修改MFC底层的代码。

用调试的方式查看MFC的实现代码,发现重写ON_MESSAGE宏不能实现,具有ID判断的只在WM_NOTIFY和WM_COMMAND两个消息中,两个消息最终都会进入 CCmdTarget::OnCmdMsg函数进行ID判断。在比较之下,决定使用WM_NOTIFY消息。

下面分析下WM_NOTIFY消息的路由过程。

分析 CWnd::OnWndMsg函数,在MFC中窗口消息在这边派送的。关于WM_NOTIFY消息的代码如下:
LRESULT lResult = 0;
...
// special case for notifies
if (message == WM_NOTIFY)
{
NMHDR* pNMHDR = (NMHDR*)lParam;
if (pNMHDR->hwndFrom != NULL && OnNotify(wParam, lParam, &lResult))
goto LReturnTrue;
return FALSE;
}

OnNotify的定义如下:
BOOL CWnd::OnNotify(WPARAM, LPARAM lParam, LRESULT* pResult)
可以发现这边忽略了WPARAM的作用,lParam的参数实际指向NMHDR* pNMHDR信息。
在OnNotify中进过必要的处理后进入OnCmdMsg函数,在这个函数中会找相应的消息映射,并进行ID对应。如果找到会进入_AfxDispatchCmdMsg函数调用对应的消息函数。

分析到这,我们比较关心的是NMHDR结构体的定义
typedef struct tagNMHDR
{
    HWND      hwndFrom;
    UINT_PTR  idFrom;
    UINT      code;         // NM_ code
}   NMHDR;

通过分析代码发现:
hwndFrom:必须有,声明消息来自哪个窗口。
idFrom:可有可无,声明窗口ID
code:具体的子消息,即通知类型。非常关键。

分析到此,我们实现下自定义notify.

1.定义通知类型:
#define WM_GRID_SELECT_CHANGE(WM_USER + 1)

2.增加消息映射函数,并实现:
afx_msg void OnNotifyGridChanged(NMHDR *pNMHDR, LRESULT *pResult);

3.增加映射对应关系:
ON_NOTIFY(WM_GRID_SELECT_CHANGE, GRIDCTRL_ID, &CContradictionRuleView::OnNotifyGridChanged)

4.在子窗口中发送WM_NOTIFY消息
if (this->GetParent())
{
NMHDR nmhdr;
nmhdr.hwndFrom= this->m_hWnd;
nmhdr.idFrom = 0;//m_id;
nmhdr.code = WM_GRID_SELECT_CHANGE;  // 用户自定义消息

//发送notify消息
this->GetParent()->SendMessage(WM_NOTIFY, (WPARAM)nmhdr.idFrom,(LPARAM)&nmhdr);
}

OK到此实现了自定义的notify消息。希望对你有所帮助,如果有什么疑问请联系wjh_2010@163.com。
版权所有,如需转载请声明出处和作者(wjh_2010@163.com)


自定义WM_NOTIFY消息的更多相关文章

  1. Laravel 5.5 FormRequest 自定义错误消息 postman调试时X-Requested-With设为XMLHttpRequest

    Laravel 5.5 FormRequest 自定义错误消息 使用FormRequest进行表单验证,就不用让验证逻辑和控制器里面的逻辑都混在一起.但在使用的时候呢,发现json错误返回的数据,与我 ...

  2. openfire自定义发送消息

    加入以下类: 这个是xml格式的,解析时可以将xml转成map,参数可自由定义 import org.jivesoftware.smack.packet.PacketExtension; /** * ...

  3. WM_NOTIFY消息流程实例分析

    我们以CListCtrl控件为例来分析WM_NOTIFY消息. CListCtrl控件在Report样式下会包含CHeaderCtrl标头控件,即CHeaderCtrl标头控件为CListCtrl控件 ...

  4. FMX有两种消息处理的实现方式,一种是用TMessageManager来实现自定义的消息,另外一种象TEdit中的实现,直接声明消息方法(firemonkey messaging)

    看FMX代码,发现有两种消息处理的实现方式,一种是用TMessageManager来实现自定义的消息,另外一种象TEdit中的实现,直接声明消息方法.   早前,看过文章说TMessageManage ...

  5. SpringMVC自定义配置消息转换器踩坑总结

    问题描述 最近在开发时候碰到一个问题,springmvc页面向后台传数据的时候,通常我是这样处理的,在前台把数据打成一个json,在后台接口中使用@requestbody定义一个对象来接收,但是这次数 ...

  6. 【Java TCP/IP Socket】构建和解析自定义协议消息(含代码)

    在传输消息时,用Java内置的方法和工具确实很用,如:对象序列化,RMI远程调用等.但有时候,针对要传输的特定类型的数据,实现自己的方法可能更简单.容易或有效.下面给出一个实现了自定义构建和解析协议消 ...

  7. 基于jquery的自定义显示消息数量

    根据需求简单的实现一个小功能控件,暂时不支持扩展 $("xxxxxxx").iconCountPlugin(options, start, isOffset) {//三个参数,自定 ...

  8. 自定义HTTP消息拦截

    /// <summary> /// HTTP消息拦截器 /// </summary> public class RequestHandler : DelegatingHandl ...

  9. SpringCloud微服务实战——搭建企业级开发框架(十六):集成Sentinel高可用流量管理框架【自定义返回消息】

    Sentinel限流之后,默认的响应消息为Blocked by Sentinel (flow limiting),对于系统整体功能提示来说并不统一,参考我们前面设置的统一响应及异常处理方式,返回相同的 ...

随机推荐

  1. win 7 下Maven环境的搭建

    Apache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具. Maven是什么? 比较正式的定义:Maven是一个项目管理工具,它包含了: 一个项目对象模型 (Project O ...

  2. “内部类” 大总结(Java)

    (本文整理自很久以前收集的资料(我只是做了排版修改),作者小明,链接地址没有找到,总之感谢,小明) (后面也对"静态内部类"专门做了补充) 内部类的位置: 内部类可以作用在方法里以 ...

  3. Trie树也称字典树

    Trie树 Trie树也称字典树,因为其效率很高,所以在在字符串查找.前缀匹配等中应用很广泛,其高效率是以空间为代价的. 一.Trie树的原理 利用串构建一个字典树,这个字典树保存了串的公共前缀信息, ...

  4. qt信号signal和槽slot机制

    内容: 一.概述 二.信号 三.槽 四.信号与槽的关联 五.元对象工具 六.程序样例 七.应注意的问题 信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工 ...

  5. (转载)OC学习篇之---Foundation框架中的NSDirctionary类以及NSMutableDirctionary类

    昨天学习了Foundation框架中NSArray类和NSMutableArray类,今天来看一下Foundation框架中的NSDirctionary类,NSMutableDirctionary类, ...

  6. python oop __slots__方法

    动态语言python 可以在程序运行的情况下给class加上功能.具体为 #引入一个 from types import MethodType #方法 #然后 s.set_age = MethodTy ...

  7. 前端复习-01-dom操作包括ie和现代浏览器处理相关

    一.事件流事件流描述的是从页面中接受事件的顺序.IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流1.事件冒泡事件冒泡,即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然 ...

  8. feof使用注意

    [feof使用注意] 以下是错误的用法,發生狀況->多讀一次?: FILE* pf; while(!feof(pf)){ //fread 讀取 //資料處理 } feof是發生在fread使用" ...

  9. 关于设置MX记录

    简介:正确设置MX(Mail Exchanger)邮件交换记录是企业电子邮件服务稳定运行的基本条件,我们经常发现很多企业电子邮箱管理员因为设置了不符合规范的MX记录,导致重要的外部邮件退回或者丢失. ...

  10. effective c++ (二)

    条款04:确定对象使用前已先被初始化 1.由于 c part of c++而且初始化可能导致运行期成本,那么就不保证发生初始化:例如arry是c part of c++的部分从而不能保证初始化,而ST ...