仅响应第一个WM_KEYDOWN通知?

时间:2009-09-01 14:28:08

标签: c windows winapi notifications

Win32应用程序如何只响应第一个WM_KEYDOWN通知? MSDN文档声明位30“指定先前的密钥状态。如果密钥在发送消息之前关闭,则值为1,如果密钥已启动则为零。”但是我的WndProc中第30位总是0。

case WM_KEYDOWN:
    // ToDo - stop multiple notifications for repeating keys
    printf("WM_KEYDOWN %i %i", wParam, lParam & 30);
    return 0;

lParam& 30 错误的方式要求这个?我做错了吗?

4 个答案:

答案 0 :(得分:11)

为了测试第30位,不要用30与AND,而是用1<< 30。

const bool isBitSet = lParam & (1 << 30);

答案 1 :(得分:4)

要得到第30位,你需要这个:

(lParam & 0x40000000)

另一种方法是使用位0-15来获得重复计数:

int repeatCount = (lParam & 0xffff)

并且只在重复计数为0(或可能为1;我不确定第一条消息是否重复计数为0或1,并且从文档中不清楚)时才执行任何操作。

答案 2 :(得分:2)

按位AND (lParam & 0x4000000)可以使用,但您可以使用Windows.h中包含的定义(您已经用于WM_KEYDOWN)轻松地使其更具可读性:

case WM_KEYDOWN:
    if((HIWORD(lParam) & KF_REPEAT) == 0) //process wParam
    return 0;

HIWORD取最重要的16位。

KF_REPEAT(= 0x4000)标记表示重复WM_KEYDOWN消息的位的位置。

当重复标志关闭(初始按键)时,这些值的按位AND等于0,并且每次后续时间等于1(自动重复功能),直到释放该键为止。

这是一件小事,但它对提高代码的可读性有很大帮助。 0x40000000对读者没有任何意义,而KF_REPEAT可以推断出很多。

答案 3 :(得分:0)

做lParam&amp;的问题30是这里,'30'在这里被认为是十进制的,当转换成二进制时将是'11110'。因此,你没有测试第30位,只是得到了lparam&amp;的结果。 11110.

希望这有助于澄清问题。