自定义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. ChromePHP - Chrome浏览器下的PHP debug工具

    一款 Chrome 下用来配合调试 PHP 的工具,看官方介绍应该和 FirePHP 有异曲同工的.喜欢用Chrome 的PHPer 可以尝试一下. 官方网站:http://www.chromephp ...

  2. ansible官方文档翻译之变量

    Ansible变量 在使用ansible变量的时候,主要是因为各个系统的不同,从而需要使用不同的变量来进行设置,例如在设置一些配置文件的时候,有大部分内容是相同的,但是一部分内容是和主机的ip地址或者 ...

  3. Swift相关图书推荐

    Swift与Cocoa框架开发 作      者 [澳] 曼宁(Jonathon Manning),巴特菲尔德-艾迪生(Paris Buttfield 出 版 社 人民邮电出版社 出版时间 2015- ...

  4. cannot restore segment prot after reloc: Permission denied

    编辑/etc/selinux/config,找到这段:# This file controls the state of SELinux on the system. # SELINUX= can t ...

  5. 轻松学习Linux之如何创建可执行脚本

    本文出自 "李晨光原创技术博客" 博客,谢绝转载!

  6. phonegap 新窗口 inappbrowser插件

    在Phonegap 开发过程中,需要调用外部网页,又要跳出白名单安全限制,可以使用 inappbrowser插件. http://plugins.cordova.io/#/package/org.ap ...

  7. c语言分析函数调用关系图(call graph)的几种方法

    一.基于 Doxygen或 lxr 的API形式的文档系统. 二.基于CodeViz, CodeViz是<Understanding The Linux Virtual Memory Manag ...

  8. css font-face自定义字体

    font-face:自定义字体 1.找到一个字体文件 2.放入新建的的font的文件夹内: 3.在样式里面以下内容 注释:aa是字体名 <style> @font-face{     fo ...

  9. Hadoop学习笔记(1)

    Hadoop是什么?先问一下百度吧: [百度百科]一个分布式系统基础架构,由Apache基金会所开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. H ...

  10. Linux下的crontab定时执行任务命令详解

    在LINUX中,周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron].cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间.cron的配置文件称为“cr ...