打破LPARAM变量&看着一组比特

时间:2011-08-05 09:59:21

标签: c++ winapi bit-manipulation bit

我知道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;

4 个答案:

答案 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",则可以找到示例代码,其中显示了如何检查LPARAMWPARAM中嵌入的不同值。因为每条消息都有自己的WPARAM和LPARAM处理,所以通常最简单的方法就是查看其他人如何处理和复制。 MSDN也有例子。位集操作是一整套算术,因此在这里解释它是不切实际的。