WPARAM和LPARAM的含义
lParam 和 wParam 是宏定义,一般在消息函数中带这两个类型的参数,通常用来存储窗口消息的参数。
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
wParam 通常用来存储小段信息,如,标志
lParam 通常用于存储消息所需的对象
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
typedef unsigned int UINT;
typedef long LONG;
typedef UINT WPARAM;
typedef LONG LPARAM;
lParam 和 wParam 是 Win16 系统遗留下来的产物,在 Win16 API 中 WndProc 有两个参数,一个 WORD 类型的 16 位整型变量,另一个是 LONG 类型的 32 位整型变量。根据匈牙利命名法(Hungarian notation),16 位的变量就被命名为 wParam,而 32 位的变量就被命名为 lParam。
到了 Win32 API 中,原来的 16 位变量也被扩展为 32 位,因此 lParam 和 wParam 的大小完全相同。在 Win32 API 的早期,为了保证和 Win16 API 的代码兼容,MS 定义了 MPARAM 和 LPARAM 两个宏。保留 w 前缀的原因一方面是由于 WPARAM 宏也以 W 开头,另一方面是希望提醒程序员注意到可移植性。到了现在,Win16 早已退出历史舞台,但是这个前缀仍然约定俗成的沿用了下来。
the history of WPARAM, LPARAM
Once upon a time, Windows was 16-bit. Each message could carry with it two pieces of data, called WPARAM and LPARAM. The first one was a 16-bit value (“word”), so it was called W. The second one was a 32-bit value (“long”), so it was called L.
You used the W parameter to pass things like handles and integers. You used the L parameter to pass pointers.
When Windows was converted to 32-bit, the WPARAM parameter grew to a 32-bit value as well. So even though the “W” stands for “word”, it isn’t a word any more. (And in 64-bit Windows, both parameters are 64-bit values!)
It is helpful to understand the origin of the terms. If you look at the design of window messages, you will see that if the message takes a pointer, the pointer is usually passed in the LPARAM, whereas if the message takes a handle or an integer, then it is passed in the WPARAM. (And if a message takes both, the integer goes in the WPARAM and the pointer goes in the LPARAM.)
“在Win 3.x中,WPARAM是16位的,而LPARAM是32位的,两者有明显的区别。因为地址通常是32位的,所以LPARAM 被用来传递地址,这个习惯在Win32 API中仍然能够看到。在Win32 API中,WPARAM和LPARAM都是32位,所以没有什么本质的区 别。Windows的消息必须参考帮助文件才能知道具体的含义。如果是你定义的消息,愿意怎么使这两个参数都行。但是习惯上,我们愿意使用LPARAM传 递地址,而WPARAM传递其他参数。”
在 MSDN 网站中关于 Windows Data Types 中有如下定义:
LPARAM: A message parameter. This type is declared in WinDef.h as follows: typedef LONG_PTR LPARAM;
WPARAM: A message parameter. This type is declared in WinDef.h as follows: typedef UINT_PTR WPARAM;
LPARAM is a typedef for LONG_PTR which is a long (signed 32-bit) on win32 and __int64 (signed 64-bit) on x86_64.
WPARAM is a typedef for UINT_PTR which is an unsigned int (unsigned 32-bit) on win32 and unsigned __int64 (unsigned 64-bit) on x86_64
(x86_64 is how Microsoft now refer to amd64)
In c#, you should use IntPtr for LPARAM and UIntPtr for WPARAM.
在 C# 与 C++ 的互操作中,可以使用 IntPtr 来声明 LPARAM 类型变量,使用 UIntPtr 来声明 WPARAM 类型的变量。
当 WPARAM, LPARAM 和 LRESULT 在 32 位和 64 位 Windows 系统中传递的时候会发生什么?
如果是从 64 位 Windows 系统到 32 位系统,那么只有一个选择:截断 truncation。
如果是从 32 位到 64 位,那么对 WPARAM 采用补零扩展(zero-extended),对 LPARAM 和 LRESULT 采用符号扩展 (sign-extended)。
扩展方式不同的原因主要是因为 WPARAM 被定义为 “字 (WORD)” 也就是 “UINT_PTR”,而 LPARAM 和 LRESULT 被定义为 “LONG”,也就是 “LONG_PTR”。
What happens to WPARAM, LPARAM, and LRESULT when the travel between 32-bit and 64-bit windows?
The integral types WPARAM, LPARAM, and LRESULT are 32 bits wide on 32-bit systems and 64 bits on 64-bit systems. What happens when a 32-bit process sends a message to a 64-bit window or vice versa ?
There’s really only one choice when converting a 64-bit value to a 32-bit value: Truncation. When a 64-bit process sends a message to a 32-bit window, the 64-bit WPARAM and LPARAM values are truncated to 32 bits. Similarly, when a 64-bit window returns an LRESULT back to a 32-bit sender, the value is truncate.
But converting a 32-bit value to a 64-bit value includes a choice: Do you zero-extend or sign-extend?
The answer is obvious if you remember the history of WPARAM, LPARAM, and LRESULT or if you just look at the header file.
The WPARAM is zero-extend, while LPARAM and LRESULT are sign-extended.
If you remember that WPARAM used to be a WORD and LPARAM and LRESULT used to be LONG, then this follows from the fact that WORD is an unsigned type (therefore zero-extended) and LONG is a signed type (therefore sign-extend).
Even if you didn’t know that, you could look it up in the header file.
typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
typedef LONG_PTR LRESULT;
UINT_PTR is an unsigned type (therefore zero-extended) and LONG_PTR is a signed type (therefore sign-extended).
具体的消息表示
WM_PAINT消息,LOWORD(lParam)是客户区的宽,HIWORD(lParam)是客户区的高
滚动条WM_VSCROLL或WM_HSCROLL消息,LOWORD(wParam)指出了鼠标对滚动条的操作。比如上、下、左、右、翻页、移动等。
击键消息,有WM_SYSKEYDOWN、WM_SYSKEYUP、WM_KEYUP、WM_KEYDOWN,其中wParam是虚拟键代码,lParam是包含属于击键的其他信息。lParam消息参数分为6个域,有重复计数、环境代码、键的先前状态等。4. 字符消息WM_CHAR、WM_DEADCHAR、WM_SYSCHAR、WM_SYSDEADCHAR,lParam消息参数跟击键消息的lParam 消息参数内容相同,wParam参数是ANSI或Unicode字符代码
客户区鼠标消息WM_LBUTTONDOWN、WM_LBUTTONUP、WM_RBUTTONDOWN、WM_RBUTTONUP、 WM_MBUTTONDOWN、WM_MBUTTONUP,lParam参数的低位是鼠标的客户区x坐标,高位是客户区y坐标。wParam参数是指示鼠标键及Shift和Ctrl键的状态。wParam&MK_SHIFT或MK_CTRL,如果返回TRUE就意味着有按下Shift或Ctrl 键。
非客户区消息,wParam参数指明移动或者单击鼠标键的非客户区位置,以HT开头,lParam参数低位指出了鼠标所在屏幕坐标的x坐标,高位指出了鼠标所在屏幕坐标的y坐标。
鼠标轮滚动消息,WM_MOUSEWHEEL消息,lParam将获得鼠标的屏幕位置(坐标),wParam参数的低位表明鼠标键和Shift与Ctrl 键的状态。wParam高位有一个“delta”值,该值可正可负,指出了滚轮导致屏幕滚动几行,120表示向上3行。
计时器消息WM_TIMER,wParam参数等于计时器的ID值,lParam为0
按钮子窗口的WM_COMMAND消息,wParam参数的低位是子窗口ID,高位是通知码, lParam参数是接收消息的子窗口的句柄。
焦点消息,对于正在失去焦点的窗口,会收到WM_KILLFOCUS消息,其wParam参数是即将接收输入焦点的窗口的句柄。对于即将获取焦点的窗口,会收到WM_SETFOCUS消息,其wParam参数是正在失去焦点的窗口的句柄。11. 编辑控制的WM_COMMAND消息,wParam参数的低位是子窗口ID,高位是通知码, lParam参数是子窗口句柄。12. 列表框的WM_COMMAND消息,wParam参数的低位是子窗口ID,高位是通知码, lParam参数是子窗口句柄。13. 菜单消息1,WM_INITMENU,wParam是主菜单句柄,lParam是0.
菜单消息2,WM_MENUSELECT,菜单跟踪消息,指针移到菜单的某一些,就会发送这个消息给窗口过程,其wParam参数的低位是选中项菜单的 ID或者弹出式菜单的句柄,高位是选择标识,lParam参数是包含选中项的菜单句柄。
菜单消息3,WM_INITMENUPOPUP,准备显示一个弹出式菜单时产生的消息,wParam参数是弹出式菜单的句柄,lParam的低位是弹出式菜单的索引,如果该菜单是系统菜单,那么高位是1,否则为0.
菜单消息4,WM_COMMAND,选中菜单后产生,wParam低位是击中菜单的ID,高位是0,lParam参数也是0
菜单消息5,WM_SYSCOMMAND,表示用户从系统菜单中选择一个启用的菜单项,其wParam参数是菜单的ID, lParam为0.如果该消息是由按鼠标产生的,那么lParam参数是鼠标的屏幕坐标。
加速键消息,WM_COMMAND消息,wParam低位是加速键ID,高位是1, lParam是0.
19.控制项着色消息,WM_CTLCOLORBTN消息,wParam是按钮的设备描述表句柄,lParam是按钮的窗口句柄。
WPARAM和LPARAM的含义的更多相关文章
- LRESULT与wParam和lParam的问题
在微软vc提供的头文件中有定义在winnt.h中typedef long LONG;在windef.h中typedef LONG LRESULT; 所以LRESULT就是long,也就是长整形之所以取 ...
- SendMessage和PostMessage区别以及WPARAM 和 LPARAM区别
WPARAM 和 LPARAM wParam和lParam 这两个是Win16系统遗留下来的产物,在Win16API中WndProc有两个参数:一个是WORD类型的16位整型变量:另一个是LONG类型 ...
- wParam与lParam的区别
wParam与lParam的区别 lParam 和 wParam 是宏定义,一般在消息函数中带这两个类型的参数,通常用来存储窗口消息的参数. LRESULT CALLBACK WindowProc(H ...
- wParam和lParam两个参数到底是什么意思?
在Windows的消息函数中,有两个非常熟悉的参数:wParam,lParam. 这两个参数的字面意义对于现在的程序来说已经不重要了,因为它是16位系统的产物,为了保持程序的可移植性,就将它保存了下来 ...
- SendMessage()、WPARAM、LPARAM函数使用例子(转)
http://chujiaba.blog.163.com/blog/static/18991813720106209350592/ 2010-07-20 21:35:00| 分类: C | 标 ...
- 利用自定义消息处理函数的WPARAM或LPARAM参数传递指针
有自定义消息: #define WM_TEST WM_USER+121 消息处理函数: afx_msg void OnTest(WPARAM wParam,LPARAM lParam); 该消息是一个 ...
- 自定义消息中如果需要定义WPARAM和LPARAM,该怎么使用和分配?
写Windows程序不可避免要使用自定义的消息,也就是从WM_USER开始定义的消息.在定义一个消息后,往往我们还要定义针对该消息的WPARAM甚至是LPARAM.WPARAM和LPARAM是什么,可 ...
- 【转】各种消息下wParam及lParam值的含义
转载自:http://bbs.fishc.com/forum.php?mod=viewthread&tid=52668#lastpost 01.WM_PAINT消息 LOWORD(lParam ...
- WM_PAINT在微软官方定义中,wParam和lParam都没有使用,所以就被Delphi给重定义了这个消息,还增加了DC(Delphi可任意改写消息的结构)
LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); Parameters wParam ...
随机推荐
- 释放Windows C盘空间 -- 虚拟内存和休眠文件
本文由Suzzz原创,发布于 http://www.cnblogs.com/Suzzz/p/4111718.html ,转载请保留此声明. 项目组有一Windows工作站, 由于需要使用Kinect最 ...
- mysql 查找表的auto_increment和修改
1.查看最大的AUTO_INCREMENT SELECT AUTO_INCREMENT from information_schema.tables where table_schema='cont ...
- 蓝桥杯 历届试题 PREV-32 分糖果
历届试题 分糖果 时间限制:1.0s 内存限制:256.0MB 问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一半给左手边 ...
- HUD2102(基础bfs)
A计划 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- iperf 网络测速
1.介绍 1) # ipref -g //这个最直观 2)Iperf 是一个网络性能测试工具.Iperf可以测试最大TCP和UDP带宽性能.Iperf具有多种参数和UDP特性,可以根据需要调整. ...
- Day2-Python基础2---字典操作
一.字典操作 字典一种key - value 的数据类型,使用就像我们上学用的字典,通过笔划.字母来查对应页的详细内容. 语法: 1.基本语法 >>> info = { 'stu11 ...
- boost::ASIO的同步方式和异步方式
http://blog.csdn.net/zhuky/article/details/5364574 http://blog.csdn.net/zhuky/article/details/536468 ...
- java中Swing编程再度练习篇
总结: 注意理解frame的层级关系 package com.da; //添加背景图片 //我只实现了插入图片.但并没有实现是背景图片 import javax.swing.JFrame; impor ...
- Oracle Sql中输入特殊字符 转义字符
1.单引号,出现在单引号对中的'号必须成对出现,每对代表一个', 例如select '''' from dual; 结果:' 前后两个'代表正常字符串,中间两个''代表一个',此语句输出结果只有一个'
- 推荐一款GIF录制工具
LICEcap 是一款屏幕录制工具,支持导出 GIF 动画图片格式,轻量级.使用简单,录制过程中可以随意改变录屏范围 下载 http://www.cockos.com/licecap/