我知道LPARAM变量设置了某些位(在其中),用于标识诸如长按键和按键之类的信息。等,当我收到WM_KEYDOWN事件时。
所以我试图打破一个LPARAM变量&查看各个位值的组和&比特组和该值(例如,查看第16位至第24位及其中的值)。
我的问题:我不知道如何查看单个位和&比特组?如何拆分LPARAM变量&查看位值(以二进制,十六进制和十进制打印出来)。
到目前为止我有这个,但是在比特级别的工作让我很困惑,所以我不确定我是否真的在看24,25和十进制的第16位值&等
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_KEYDOWN:
{
// I know that a LPARAM variable is a 32 bit(or is it byte?) long variable. How would I look at the
// 16th bit value? How would I look that the value from the 16th to the 24th bit?
printf("A: %d, %d, %d\n", lParam >> 24, lParam >> 25, lParam >> 16 );
}
break;
答案 0 :(得分:3)
通常,您使用按位AND来检查是否设置了某个位:
unsigned int flags; // some flags
if (flags & 0x01) { } // bit 0 is set
if (flags & 0x02) { } // bit 1 is set
if (flags & 0x04) { } // bit 2 is set
...
if (flags & (1U << n)) { } // bit n is set
但是,不要依赖物理位值。相反,API定义描述标志含义的USEFUL_CONSTANTS:
LPARAM flags = ApiFunction();
if (flags & USEFUL_CONSTANT) { } // check if the flag is set
检查相关消息的API文档以找出定义的值。
更新:我认为在您的情况下,您实际上可能需要值而不仅仅是标志。因此,要获得最低16位的值,只需使用相应的位掩码对该值进行按位与:unsigned int repeat_count = flags & 0xFFFF;
注意,0xFFFF为二进制的1111111111111111。
答案 1 :(得分:3)
很多更简单的方法是声明自己的结构。
// information about key
union KeyInfo
{
// LPARAM
LPARAM lParam;
// bit-field
struct Bits {
WORD nRepeatCount: 16;
BYTE nScanCode : 8;
BYTE nExtended : 1;
BYTE nReserved : 4;
BYTE nContext : 1;
BYTE nPrevious : 1;
BYTE nTransition : 1;
};
};
也就是说,学习位算术和算法仍然是一个好主意。正如网络上有人所说,互联网上有大量资源可以通过谷歌找到。
编辑:请参阅this link,其中基本上展示了如何做我刚刚做过的事情。
答案 2 :(得分:2)
LPARAM
可以保存指针值,这对于64位兼容性非常重要。
检查第n位(0是最不重要的):
if (lParam & (1 << n)) { /*bit set*/ } else { /* bit not set*/ }
将其提取为0或1:
(lParam >> n) & 1
从位置Y提取X位:
(lParam >> Y) & ((1<<X)-1)
这首先将字节向下移动到最不重要的位置,然后创建一个X位宽的掩码来掩盖它们。
答案 3 :(得分:1)
这里最实用的是使用谷歌。例如,如果您使用Google "case WM_KEYDOWN"
,则可以找到示例代码,其中显示了如何检查LPARAM
和WPARAM
中嵌入的不同值。因为每条消息都有自己的WPARAM和LPARAM处理,所以通常最简单的方法就是查看其他人如何处理和复制。 MSDN也有例子。位集操作是一整套算术,因此在这里解释它是不切实际的。