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 错误的方式要求这个?我做错了吗?
答案 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.
希望这有助于澄清问题。