关于位运算符实现的问题

今天在看SDK教学文章的时候,发现了一个关于位运算符的问题
首先附上关键代码段:

case WM_LBUTTONDOWN: { hitPoint.x = LOWORD(lParam); hitPoint.y = HIWORD(lParam); MouseClick = TRUE; InvalidateRect(hWnd,NULL,TRUE); } break;

解释下这个代码段:
处理当鼠标左键被按下的时候,保存存储在lParam中的鼠标所在的x,y的位置。但是它是如何被保存的呢?

这里引用了一个结构体hitPoint,我找到它的定义:

POINT hitPoint;

找到关于lParam的定义:

LPARAM lParam;

然后再找到POINT这个结构体变量的定义:

typedef struct tagPOINT { LONG x; LONG y; } POINT, *PPOINT;
最后找到两处宏定义:
#define LOWORD(l) ((WORD)(l)) #define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))
找到LPARAM的类型重定义
typedef LONG_PTR LPARAM; typedef _W64 long LONG_PTR, *PLONG_PTR; long LONG_PTR
最后再看看WORD和DWORD的类型重定义:
typedef unsigned short WORD; 无符号16位整数

typedef unsigned long DWORD; 无符号32位整数
额,好不容易终于转到了,那么long就是32位有符号整数了。找到了这些东西,现在再来看看宏是怎么处理位运算的。
hitPoint.x = LOWORD(lParam);
这个时候经过宏
#define LOWORD(l) ((WORD)(l))处理会变成

hitPoint.x = ((WORD)(lParam));
还记得刚才lParam的定义吧,是long类型的,而
WORD是unsigned short类型的,这里做了强制类型转换,
使得hinPoint.x得到了低16位的lParam值

再看看
hitPoint.y = HIWORD(lParam);
经过宏替换后

hitPoint.y = ((WORD)(((DWORD)(lParam) >> 16) & 0xFFFF));

这样,我们举个例子好了
首先假设一下lParam的值如下:
左(高位) 右(低位)
1110000101010111 0001010101110001
强制类型转变DWORD后 1110000101010111 0001010101110001
右移16位后 1111111111111111 1110000101010111
按位与运算 & 000000000000000 1111111111111111
------------------------------------------------------------------------

1111111111111111 1110000101010111


最后强制类型转换得到低位的16位 1110000101010111
其实这个数值就是lParam的高16位的值,大家看是不是这样的?

如此一来,我们就将原来lParam = 1110000101010111 0001010101110001
经过语句后最终变成了我们想要得到的效果:

hitPoint.x = 0001010101110001
hitPoint.y = 1110000101010111

好了,我的疑惑现在终于解开了,两个变量终于得到了鼠标x,y轴的坐标了

^_^
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值