关于位运算符实现的问题

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



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

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

POINT hitPoint;

找到关于lParam的定义:

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


最后找到两处宏定义:
 
找到LPARAM的类型重定义
 
 最后再看看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轴的坐标了
 
 ^_^
posted @ 2012-01-05 16:32  magic_box  阅读(189)  评论(0编辑  收藏  举报