C++ToUnicodeEx()无法识别移位键,除非我有一个messgaebox()
C++ ToUnicodeEx() not recognizing shift key unless i have a messgaebox()
im在用C++编写键盘挂钩时遇到了一些问题。
我可以读取击键,但我正在尝试使用ToUnicodeEx()在按下shift键时转换击键。在我迄今为止的代码中,我有
i = ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);
MessageBox(MainnhWnd,keybuff, L"message", MB_OK | MB_ICONEXCLAMATION);
当我按下Shift+2时,我会弹出两个消息框,第一个是空的Shift键,第二个显示一个"@"字符。这是意料之中的事。
但是,如果我删除这个消息框,ToUnicodeEx()函数会转换击键,就好像没有使用shift键一样。我可以通过设置断点、使用命中计数器或将字符输出到程序窗口中的编辑框来实现这一点。
此外,当我包括MsgBox行并使用CapLock时,我的字母会相应地改变,但在我删除MsgBox后,它只使用程序启动时的大写锁定状态(程序启动时大写锁定打开,所有字母都是大写,反之亦然,程序启动时小写关闭,所有字母很小,即使我改变了大写锁定状态)
有人知道为什么我的钩子只记得开始时的键盘状态,除非我包括消息框吗?
我的钩子设置为:
theHook = SetWindowsHookEx ( WH_KEYBOARD_LL, (HOOKPROC) KeyEvent, exe, 0);
我的钩子回调函数是:
DLLEXPORT LRESULT CALLBACK KeyEvent(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode>=0) {
int i = 0;
KBDLLHOOKSTRUCT keyboard;
WCHAR keybuff[256]= {0};
if ((wParam == WM_KEYDOWN)|| (wParam == WM_SYSKEYDOWN)||(wParam == WM_SYSKEYUP)) {
keyboard = *((KBDLLHOOKSTRUCT*)lParam);
if (keyboard.vkCode == VK_RETURN) {
i += wsprintf (((LPWSTR)keybuff + i),L"[Return]rn");
}
else {
HKL keyboardlayout = GetKeyboardLayout(0);
GetKeyboardState((PBYTE)&keyState);
i = ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);
MessageBox(MainnhWnd,keybuff, L"message", MB_OK | MB_ICONEXCLAMATION);
}
if (keybuff>0) {
addToEditBox(keybuff);
}
}
}
return CallNextHookEx(theHook, nCode, wParam, lParam);
}
根据ToUnicodeEx函数的文档,您应该提供一个指向256字节数组的指针,该数组包含当前键盘状态(const BYTE *lpKeyState
)。数组中的每个元素(字节)都包含一个键的状态。如果设置了字节的高阶位,则键处于关闭状态。
在调用ToUnicodeEx
之前,应该将此数组设置为如下(伪代码):
enum Keys
{
ShiftKey = 16, // shift
ControlKey = 17, // ctrl
Menu = 18, // alt
Capital = 20, // caps lock
};
BYTE keyState[256]= {0};
if (Control key down)
keyState[Keys::ControlKey] = 0x80;
if (Shift key down)
keyState[Keys::ShiftKey] = 0x80;
if (Alt key down)
keyState[Keys::Menu] = 0x80;
if (Caps lock ON)
keyState[Keys::Capital] = 0x01;
当设置了keyState数组时,您可以调用:
ToUnicodeEx(keyboard.vkCode, keyboard.scanCode, (PBYTE)&keyState, (LPWSTR)&keybuff, sizeof(keybuff) / 16, 0,keyboardlayout);
我一直在像这样使用ToUnicodeEx
函数,它运行得很好
希望这对你有所帮助;)
相关文章:
- 如何确定我已使用非编码文件到达 EOF?
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 我在 C++ 代码中遇到错误警告:控制到达非空函数 [-Wreturn 类型] 的末尾
- 我想使用哈希图打印非重复的数字;
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 为什么我总是收到此错误:从类型为"农场动物"的右值初始化类型的非常量引用无效|
- 我想获取点的属性,它报告错误 C3867:"point::output_x":非标准语法;使用"&"创建指向成员的指针
- 如果我必须覆盖非虚拟成员函数怎么办
- 无法在clang Linux中分配非静态成员函数,但我可以在Visual Studio Windows中分配
- 为什么我收到错误消息,在'for'之前应收到非限定 id
- 转换为非标量误差是什么意思?我该如何解决?
- 如果我公开常量和非常量 API,我是否破坏了常量正确性?
- 为什么我不能在非常量表达式上使用此模板阶乘函数?
- 为什么我可以将 std::map 的键传递给一个期望非常量的函数?
- 当我输入非整数值时,我的二次方程代码终止,如何让它正确循环?
- "非静态数据成员之前需要构造函数" - 我是否使用"boost::variant"
- 我的C++模板失败:非模板结构的显式专用化
- 访问另一个类(系统)的非静态字段,就好像它是我自己的字段一样 - 优雅地
- 我可以超负荷运算符,以指针和非构造模板对象
- 我该如何允许类型的对象非专业化并在不使用指针的情况下识别何时是这种情况