WM_NOTIFY消息
来源:互联网 发布:吉他读谱软件 编辑:程序博客网 时间:2024/05/16 17:30
转自:http://blog.sina.com.cn/s/blog_6e9095270100n4ec.html
WM_NOTIFY消息
(2006-07-11 09:47:43)标签:
杂谈
分类: MSN搬家 当自定义控件中发生了特殊的事件需要通知父窗口时,可以向父窗口发送消息,最简单的方法就是直接向父窗口直接发送自定义消息:
this->GetParent()->SendMessage(WM_USR1, wParam, lParam);
这种方法简单虽然简单,但是不太干净。因为这样做的前提是要保证WM_USR1消息ID在父窗口的范围内保持唯一,否则父窗口就可能会混淆该消息的来源。而一个窗口中的控件会有很多,并不能保证所有控件的所有消息ID都是唯一的。这就会留下了隐患。
其实有一种更好的,也是标准的解决方案,那就是利用WM_NOTIFY消息向父窗口发送通知。
顾名思义,WM_NOTIFY是专门用于控件向父窗口发送消息的。这个消息与其它的消息不同,用户可以自行定义通知的内容,但传递消息的方式是统一的,程序的处理非常规范、简洁。以下是一点点总结和心得:
【如何发送WM_NOTIFY消息】
发送的方法如下所示:
this->GetParent()->SendMessage(WM_NOTIFY, (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
从上面可以看出无论是发送什么通知,其格式都是统一的:首先利用NMHDR结构体进行包装,然后再作为WM_NOTIFY消息发送出去。而NMHDR结构,既可以使用系统提供的默认结构,也可以根据需要自行进行扩充。
【NMHDR结构体的扩充】
如果仅仅是向父窗口发送一个“通知”,那么使用默认的NMHDR结构体就已经足够了;但若需要同时传递一些附加的信息,就需要对NMHDR结构体进行扩充了。使用WM_NOTIFY发送通知的魅力就在于,用户可以根据自己的需要扩充任何附加信息进去。下面就是自定义的NMHDR结构体:
typedef struct tagMyNMHDR {
注意,这个结构体内包含了NMHDR结构体。这里利用到了C/C++的一个著名的特性:C/C++语言不做内存越界检查。因此,对于自定义的结构体,只要把NMHDR放在第一个元素的地方,就可以安全地把该结构体转型为NMHDR。这样就可以很方便地在WM_NOTIFY消息中发送自定义的附加信息了。
【父窗口如何进行消息影射】
消息发送出去后,父窗口(也就是消息接受方)如何接受这个消息呢?首先是要做消息映射:
ON_NOTIFY(WM_USR1, CTRLID, memberfun1)
afx_msg void memberfun2(UINT id, NMHDR *nmhdr, LRESULT *result);
到此为止,WM_NOTIFY消息从生成、发送,到接受的过程就完成了。再回过头来看看生成NMHDR结构的地方,是否会发现什么问题呢?是的,那就是:
NMHDR结构体的内存应该什么时机进行分配,什么时机进行释放呢?
在上例中,NMHDR结构体是建立在栈上的,在方法执行完毕后,NMHDR所占用的内存将自动被释放,不用担心内存泄露的问题。但是也因此引发一个新问题:如果以异步的形式(PostMessage)发送消息会有什么结果呢?可想而知,在接受方处理消息的时候,发送方很有可能已经结束处理,NMHDR结构也已被自然释放掉了。因此接受方所收到的NMHDR指针已经变成了“野指针”!从而必然引发内存崩溃!危险!
那么,如果把NMHDR建立在堆上,又会如何呢?这样做虽然可以避免了上述野指针的问题,但是已经分配给NMHDR结构体的内存,由谁来释放呢?什么时机释放呢?发送方固然已经无力对其进行释放,由接收方进行释放也是很麻烦的。因为有时会存在消息反射和消息传递的情况,对接收方来说很难判断自己是否是消息处理链的最后一个环节。这使问题复杂化了,同时也违背了“谁分配谁释放”的内存处理原则,稍不留神就会引发内存泄露。
结论:最好不要在堆上建立NMHDR结构体,也不要用PostMessage方法异步发送WM_NOTIFY消息。
0 0
- WM_NOTIFY消息
- WM_NOTIFY消息
- WM_NOTIFY消息
- WM_NOTIFY消息
- WM_NOTIFY消息
- WM_NOTIFY消息
- WM_NOTIFY消息
- WM_COMMAND,WM_NOTIFY等消息
- WM_COMMAND,WM_NOTIFY等消息
- 如何发送WM_NOTIFY消息
- 自定义WM_NOTIFY消息
- WM_COMMAND,WM_NOTIFY等消息
- WM_Notify与消息反射
- WM_NOTIFY消息的讲解
- 控件的WM_NOTIFY消息映射
- TN061:ON_NOTIFY及WM_NOTIFY消息
- WM_NOTIFY消息流程实例分析
- 全面解读WM_NOTIFY & 消息反射
- 浅谈HTTP routing
- Linux 编译的四个阶段
- 通往阿里之路
- Minimum Depth of Binary Tree
- android数据库
- WM_NOTIFY消息
- wget: unable to resolve host address的解决方法
- java设计模式示例
- Android开发小问题集
- JS 常用函数 去空格、去重复元素 jquery去空格 1410231
- ubuntu安装ftp服务器
- Azure网站上的PHP — 架构
- Populating Next Right Pointers in Each Node II
- JQuery replace字符串替换