GetAsyncKeyState的替代方案

时间:2013-04-21 21:33:24

标签: winapi

我需要检测 Shift Control 的各种组合,&在程序启动时按下 Alt 键。这必须在打开任何窗口之前发生。

我知道关于 GetAsyncKeyState 的所有内容但是如果您的程序不是Windows中的前台任务,并且当程序首次启动时,此功能不起作用,那么在窗口之前它不是前台任务打开。

程序是WIN32 / C ++ / MFC / 32位。有什么想法吗?


其他信息已添加:这是在64位Win8上运行的。另外,虽然我只提到了 GetAsyncKeyState ,但我还尝试了 GetKeyState 但结果并没有真正反映 CURRENT 状态,并且从未为 Alt

这是一个代码示例,取自我的app类 InitInstance 方法(实际上是MFC应用程序的main()),在主窗口打开之前。

#define USE_GETASYNCKEYSTATE (1)

// Following two lines are added for testing so there's a
// specific time to make sure keys are pressed
AfxMessageBox("Press keys after dismissing this message");
Sleep(2000);

#if USE_GETASYNCKEYSTATE
    short altKeyStatus = GetAsyncKeyState(VK_MENU) & 0x8000;
    short shiftKeyStatus = GetAsyncKeyState(VK_SHIFT) & 0x8000;
    short controlKeyStatus = (short)GetAsyncKeyState(VK_CONTROL) & 0x8000;
#else
    char kbBuf[256];
    GetKeyboardState( (PBYTE)kbBuf );
    short altKeyStatus = (short)kbBuf[VK_MENU];
    short shiftKeyStatus = (short)kbBuf[VK_SHIFT];
    short controlKeyStatus = (short)kbBuf[VK_CONTROL];
#endif

CString msg;
msg.Format("ALT: %d, SHIFT: %d, CTRL: %d", 
                altKeyStatus, shiftKeyStatus, controlKeyStatus );
AfxMessageBox(msg);

当它使用 GetAsyncKeyState 运行时,所有三个变量都会一直返回ZERO。

当我运行 GetKeyboardState 块时,我有时会得到结果,表明已按下 Shift 和/或 Control 。也就是说,最近某个时候按下了,但不一定与当前状态相匹配,并且对于 Alt 它永远不会返回任何值。

请注意,可以删除带有睡眠的前两行而不更改结果。我添加了它们,所以我可以确定在程序实际运行时发生了按键。

2 个答案:

答案 0 :(得分:2)

不,你倒退了。它是GetKeyState()不起作用,GetAsyncKeyState()没问题。您通常应该使用GetKeyState(),因为它返回键盘的缓冲状态。重要的是因为键盘消息在消息队列中缓冲。但是,当您的程序没有焦点或尚未创建消息队列时,这不起作用。后者就是你的情况。

小心选择你的魔术键,它们会妨碍点击桌面快捷键。我发现Scroll Lock键在这种情况下很有用。不是用于任何东西,它通常甚至有一个灯,它锁定状态所以可以打开而不会慌乱的键盘。

答案 1 :(得分:0)

我不确定您导入该功能是否正确,因为您将其结果转换为short,而short已经GetAsyncKeyState。我对// C# [DllImport("user32.dll", SetLastError = true)] static extern short GetAsyncKeyState(int virtualKey); 也有问题,我通过纠正导入来解决它:

int

由于一个奇怪的原因,当我{{1}}作为结果时,它只有有时