WM_COMMAND 和 WM_NOTIFY 的区别
当我们按下一个菜单选项,或者一个控件需要通知父窗口一个事件发生(如鼠标单击、双击等),或者快捷键被按下时,Windows将会发送一个 WM_COMMAND 消息给父窗口。那么 WM_COMMAND 消息参数是什么呢?
| WM_COMMAND 消息来源 | WPARAM 高位 | WPARAM 低位 | LPARAM |
|---|---|---|---|
| 菜单 | 0 | 菜单 ID | 0 |
| 快捷键 | 1 | 快捷键对应菜单 ID | 0 |
| 控件 | 响应 Code(如BN_CLICKED) | 控件 ID | 控件句柄 |
OK,一切运行的很好,通过 WPARAM 高位置1或0区分菜单、快捷键、或者控件事件Code,通过 WPARAM 低位可以知道发出WM_COMMAND消息的菜单项或控件ID,通过LPARAM知道控件句柄。
然而,有一天,当选中一个 ListControl 控件中的某一行时,人们忽然发现父窗口需要知道被选中该行的索引,这下为难了,对于控件来看,整个WM_COMMAND消息的WPARAM、LPARAM 都被塞的满满的。怎么办呢?这儿有一种解决办法:新增一个消息,就叫WM_LIST_CONTROL_CLICKED吧,如下:
| 消息类型 | WPARAM 高位 | WPARAM 低位 | LPARAM |
|---|---|---|---|
| WM_LIST_CONTROL_CLICKED | 被选中行的索引 | ListControl 控件的 ID | ListControl 控件的句柄 |
呃,看起来的确解决了问题,我们把事件 Code 通过消息 ID 体现了出来,然后把被选中行的索引塞进了WPARAM的高位,看起来非常完美!然而又有一天,人们发现对ListView,父窗口需要知道单击该控件时选中的行号和列号,以便处理,照猫画虎,我们又加了一个WM_LIST_VIEW_CLICKED。接着人们发现其他一些控件都需要这样的改进,如果这样增加消息的话,岂不是没完没了了?!!
于是,WM_NOTIFY消息横空出世:
| 消息类型 | WPARAM | LPARAM |
|---|---|---|
| WM_NOTIFY | 发生 WM_NOTIFY 消息的控件 ID | NMHDR 指针 |
现在,我们将所有附加信息都存放在 NMHDR(Notify Message Handler)的一个结构体中,该结构体指针通过 LPARAM 通知到父窗口。NMHDR如下:
- typedef struct tagNMHDR
- {
- HWND hwndFrom; // 控件句柄.
- UINT_PTR idFrom; // 控件 ID.
- UINT code; // NM_ code.
- } NMHDR;
这只是一个一般的结构,如果我们需要知道 ListView选中的行和列,那么需要:
- typedef struct tagNMLISTVIEW
- {
- NMHDR hdr; // NMHDR.
- int iItem; // 行号.
- int iSubItem; // 列号.
- UINT uNewState;
- UINT uOldState;
- UINT uChanged;
- POINT ptAction;
- LPARAM lParam;
- } NMLISTVIEW, *LPNMLISTVIEW;
像其他的控件,都会对应这样一个结构体,它们的第一个字段一定是 NMHDR。但一些微软标准控件并不会发送WM_NOTIFY 消息,这些控件有:Edit、ComboBox、ListBox、Button、ScrollBar、Static等。所以在使用过程中请注意用法,最好的做法是参考MSDN。
WM_COMMAND 和 WM_NOTIFY 的区别的更多相关文章
- WM_COMMAND和WM_NOTIFY区别[转]
对这几个消息的理解要先了解一下Window消息的背景. 在Windows3.1里,控件会将mouse, keybord等等的消息通知它的父窗口, 使用的消息就只有WM_COM ...
- WM_COMMAND消息
原文地址:https://blog.csdn.net/whm243149796/article/details/78966065 当用户点击菜单.按钮.下拉列表框等控件时候,会触发WM_COMMAND ...
- windows消息机制详解(转载)
消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了.例如,单击鼠标.改变窗口尺寸.按下键盘上的一个键都会使Windows发送一个消息给应用程序.消息本身是作为一个记录传递给应用程序的 ...
- Windows消息编程(写的不错,有前因后果)
本文主要包括以下内容: 1.简单理解Windows的消息2.通过一个简单的Win32程序理解Windows消息3.通过几个Win32程序实例进一步深入理解Windows消息4.队列消息和非队列消息5. ...
- [用UpdateLayeredWindow实现任意异形窗口]
前面提到,我们可以用SetWindowRgn或SetLayeredWindowAttributes实现不规则以及半透明的效果 对于SetWindowRgn,它通过一个Rgn来设置区域,这个Rgn一般可 ...
- ATL7窗口类详细剖析
前言: ATL是微软继MFC之后提供的一套C++模板类库,小巧.精妙.效率极高.它的主要作用是为我们编写COM/DOM/COM+程序提供了丰富的支持.但是ATL只能写COM么?我以前只是MFC程序员的 ...
- 深度解析VC中的消息(转发)
http://blog.csdn.net/chenlycly/article/details/7586067 这篇转发的文章总结的比较好,但是没有告诉我为什么ON_MESSAGE的返回值必须是LRES ...
- ATL的GUI程序设计(4)
第四章 对话框和控件 对于Win32 GUI的程序设计来说,其实大部分的情况下我们都不需要自己进行窗口类的设计,而是可以使用Win32中与用户交互的标准方式--对话框(Dialog Box).我们可以 ...
- 如何给对话框中的控件发送消息呢?Windows消息分类
以博文CTabCtrl中介绍的那样,给Tab添加子对话框来显示Tab内容.那么如果这个子对话框中含有个CTreeCtrl控件,有个Button控件,我想要模拟给这两个控件发送消息,该怎么办呢?直接把给 ...
随机推荐
- hibernate 实体对象的三种状态以及转换关系。
最新的Hibernate文档中为Hibernate对象定义了四种状态(原来是三种状态,面试的时候基本上问的也是三种状态),分别是:瞬时态(new, or transient).持久态(managed, ...
- 谷歌SEO老域名注册完全攻略
老域名有优势,不管在百度和谷歌都是一样的. 我们查看搜索结果就能发现,谷歌里面很多排前十的网站都是N年前的,一零年以后的算是比较新的,很多产品网站域名是零几年,甚至很多排名更好的域名是九几年的. 谷歌 ...
- 有谁知道什么工具测试IOS手机上APP的性能软件啊?
有谁知道什么工具测试IOS手机上APP的性能软件啊?
- flume-ng源码阅读memory-channel(原创)
org.apache.flume.channel.MemoryChannel类是Flume-NG的memory-channel. private LinkedBlockingDeque<Even ...
- java 实现图片拼接
1.想要实现多个图片的纵向和横向拼接.实现代码如下 2.补充发现横向拼接的一个bug 宽度没有增加(已修复) 百度地址:工具jar下载 链接:https://pan.baidu.com/s/1uZCN ...
- ZC_02_获取Constructor
1. package reflectionZ; import java.lang.reflect.Constructor; import java.lang.reflect.Type; public ...
- Django Celery Redis 异步执行任务demo实例
一.windows中安装redis 安装过程见 <在windows x64上部署使用Redis> 二.环境准备 requirements.txt Django==1.10.5 celery ...
- python 超时异常处理
异常处理具体见:[循序渐进学Python]9.异常处理 环境平台:Python2.7.9 + Win8.1 本篇记录一下自己写爬虫的遇到的问题,程序中批量获取图片地址,然后批量保存.由于没有设置网址打 ...
- Flask ajax 动态html 的javascript 事件失效
$('.db_edit').click(function(){ $(".editdbproduct").val($(this).parent().parent().find('.e ...
- mysql-debug: Thread stack overrun
bug info 报错信息: java.sql.SQLException: Thread stack overrun: 5456 bytes used of a 131072 byte stack, ...