1

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

我对GetAsyncKeyState 了如指掌,但是如果您的程序不是 Windows 中的前台任务,并且当第一次启动程序时,在打开窗口之前它不是前台任务,则此功能不起作用。

程序为 WIN32/C++/MFC/32 位。有任何想法吗?


添加的附加信息: 这是在 64 位 Win8 上运行的。此外,虽然我只提到了 GetAsyncKeyState,但我也尝试过GetKeyState,但结果并没有真正反映当前状态,而且根本没有用Alt

这是在打开主窗口之前从我的应用程序类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运行时,所有三个变量都始终返回零。

当我运行GetKeyboardState块时,有时会得到指示Shift和/或Control已被按下的结果。也就是说,最近的某个时间被按下,但不一定与当前状态匹配,并且它永远不会返回除零之外的任何内容Alt

请注意,可以删除带有Sleep的前两行,而根本不改变结果。我添加了它们,这样我就可以确定在程序实际运行时按键发生了。

4

2 回答 2

2

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

仔细挑选你的魔法键,它们往往会妨碍点击桌面快捷方式。我发现 Scroll Lock 键在这种情况下很有用。不用于任何事情,它通常甚至有一个灯并且它会锁定状态,因此可以打开而不会使键盘恐慌。

于 2013-04-21T22:28:26.007 回答
0

我不确定您对该函数的导入是否正确,因为您正在将它的结果转换为short应该short已经存在的结果。我也遇到了问题,GetAsyncKeyState我通过更正导入解决了它:

// C#
[DllImport("user32.dll", SetLastError = true)]
static extern short GetAsyncKeyState(int virtualKey);

出于一个奇怪的原因,它有时只在我得到int结果时才起作用。

于 2013-07-05T11:00:47.883 回答