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).

具体的消息表示

  1. WM_PAINT消息,LOWORD(lParam)是客户区的宽,HIWORD(lParam)是客户区的高

  2. 滚动条WM_VSCROLL或WM_HSCROLL消息,LOWORD(wParam)指出了鼠标对滚动条的操作。比如上、下、左、右、翻页、移动等。

  3. 击键消息,有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字符代码

  4. 客户区鼠标消息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 键。

  5. 非客户区消息,wParam参数指明移动或者单击鼠标键的非客户区位置,以HT开头,lParam参数低位指出了鼠标所在屏幕坐标的x坐标,高位指出了鼠标所在屏幕坐标的y坐标。

  6. 鼠标轮滚动消息,WM_MOUSEWHEEL消息,lParam将获得鼠标的屏幕位置(坐标),wParam参数的低位表明鼠标键和Shift与Ctrl 键的状态。wParam高位有一个“delta”值,该值可正可负,指出了滚轮导致屏幕滚动几行,120表示向上3行。

  7. 计时器消息WM_TIMER,wParam参数等于计时器的ID值,lParam为0

  8. 按钮子窗口的WM_COMMAND消息,wParam参数的低位是子窗口ID,高位是通知码, lParam参数是接收消息的子窗口的句柄。

  9. 焦点消息,对于正在失去焦点的窗口,会收到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.

  10. 菜单消息2,WM_MENUSELECT,菜单跟踪消息,指针移到菜单的某一些,就会发送这个消息给窗口过程,其wParam参数的低位是选中项菜单的 ID或者弹出式菜单的句柄,高位是选择标识,lParam参数是包含选中项的菜单句柄。

  11. 菜单消息3,WM_INITMENUPOPUP,准备显示一个弹出式菜单时产生的消息,wParam参数是弹出式菜单的句柄,lParam的低位是弹出式菜单的索引,如果该菜单是系统菜单,那么高位是1,否则为0.

  12. 菜单消息4,WM_COMMAND,选中菜单后产生,wParam低位是击中菜单的ID,高位是0,lParam参数也是0

  13. 菜单消息5,WM_SYSCOMMAND,表示用户从系统菜单中选择一个启用的菜单项,其wParam参数是菜单的ID, lParam为0.如果该消息是由按鼠标产生的,那么lParam参数是鼠标的屏幕坐标。

  14. 加速键消息,WM_COMMAND消息,wParam低位是加速键ID,高位是1, lParam是0.

19.控制项着色消息,WM_CTLCOLORBTN消息,wParam是按钮的设备描述表句柄,lParam是按钮的窗口句柄。

WPARAM和LPARAM的含义的更多相关文章

  1. LRESULT与wParam和lParam的问题

    在微软vc提供的头文件中有定义在winnt.h中typedef long LONG;在windef.h中typedef LONG LRESULT; 所以LRESULT就是long,也就是长整形之所以取 ...

  2. SendMessage和PostMessage区别以及WPARAM 和 LPARAM区别

    WPARAM 和 LPARAM wParam和lParam 这两个是Win16系统遗留下来的产物,在Win16API中WndProc有两个参数:一个是WORD类型的16位整型变量:另一个是LONG类型 ...

  3. wParam与lParam的区别

    wParam与lParam的区别 lParam 和 wParam 是宏定义,一般在消息函数中带这两个类型的参数,通常用来存储窗口消息的参数. LRESULT CALLBACK WindowProc(H ...

  4. wParam和lParam两个参数到底是什么意思?

    在Windows的消息函数中,有两个非常熟悉的参数:wParam,lParam. 这两个参数的字面意义对于现在的程序来说已经不重要了,因为它是16位系统的产物,为了保持程序的可移植性,就将它保存了下来 ...

  5. SendMessage()、WPARAM、LPARAM函数使用例子(转)

      http://chujiaba.blog.163.com/blog/static/18991813720106209350592/ 2010-07-20 21:35:00|  分类: C |  标 ...

  6. 利用自定义消息处理函数的WPARAM或LPARAM参数传递指针

    有自定义消息: #define WM_TEST WM_USER+121 消息处理函数: afx_msg void OnTest(WPARAM wParam,LPARAM lParam); 该消息是一个 ...

  7. 自定义消息中如果需要定义WPARAM和LPARAM,该怎么使用和分配?

    写Windows程序不可避免要使用自定义的消息,也就是从WM_USER开始定义的消息.在定义一个消息后,往往我们还要定义针对该消息的WPARAM甚至是LPARAM.WPARAM和LPARAM是什么,可 ...

  8. 【转】各种消息下wParam及lParam值的含义

    转载自:http://bbs.fishc.com/forum.php?mod=viewthread&tid=52668#lastpost 01.WM_PAINT消息 LOWORD(lParam ...

  9. WM_PAINT在微软官方定义中,wParam和lParam都没有使用,所以就被Delphi给重定义了这个消息,还增加了DC(Delphi可任意改写消息的结构)

    LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); Parameters wParam ...

随机推荐

  1. puppeteer

    const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); ...

  2. Unity Shader实现描边效果

    http://gad.qq.com/article/detail/28346 描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果.本篇文章和大家介绍下利用S ...

  3. asp.net 打印控件使用方法

    打印的效果及控制性虽然不是很好,但是也能勉强使用,应付一般的打印还是 可以的了.代码如下所示: 代码 复制代码 代码如下: //调用PrintControl.ExecWB(?,?)实现直接打印和打印预 ...

  4. bzoj 4559 [JLoi2016]成绩比较——拉格朗日插值

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4559 关于拉格朗日插值,可以看这些博客: https://www.cnblogs.com/E ...

  5. BZOJ2276:[POI2011]Temperature

    浅谈队列:https://www.cnblogs.com/AKMer/p/10314965.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?i ...

  6. ECMAScript 2016(ES7) 知多少

    ECMAScript 2016(ES7) 知多少 1. 数组方法 Array.prototype.includes(value : any) : boolean 2. 幂运算符 x ** y 扩展阅读 ...

  7. 用Python+Django1.9在Eclipse环境下开发web网站

    最近想学习一下python django, 按网上各位大神们的说明,试着做了一下,这里记录下来,做个笔记. 参考 http://www.cnblogs.com/linjiqin/p/3595891.h ...

  8. LTE-V2X车联网无线通信技术发展

    2017年9月7日,国家制造强国建设领导小组车联网产业发展专项委员会第一次全体会议在北京召开.会议要求“要加大关键产品研发攻关力度,完善测试验证.技术评价.质量认证等公共服务平台,促进LTE-V2X车 ...

  9. 2015 浙江省赛 H - May Day Holiday

    H - May Day Holiday As a university advocating self-learning and work-rest balance, Marjar Universit ...

  10. 查看,创建,删除,映射rbd镜像

    标签(空格分隔): ceph,ceph实验,pg 1. 创建镜像: [root@node3 ~]# rbd create testpool/foo --size 1024 2. 查看镜像信息: [ro ...