Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 解释SetWindowsHookEx/WH_键盘的正确逻辑_.net_Winapi_User32_Setwindowshookex_Wh Keyboard Ll - Fatal编程技术网

.net 解释SetWindowsHookEx/WH_键盘的正确逻辑

.net 解释SetWindowsHookEx/WH_键盘的正确逻辑,.net,winapi,user32,setwindowshookex,wh-keyboard-ll,.net,Winapi,User32,Setwindowshookex,Wh Keyboard Ll,将消息从with转换为按键的有用表示形式的正确方法是什么 我知道这很可能需要理解本地键盘的映射。(注意:我只考虑按键的时间,而不是为了简单起见按键的释放时间) 大体上讲,似乎有三种情况: 按下特殊键(Ctrl/Escape/Shift/Alt) 按标准键(A-Z,0-9,等等…注意A和A都读作A) 一些难以定义的情况,如数字键盘和F1-F12 可以根据需要处理特殊密钥,并且在中有一些有用的查找 但如果我(在英国英语键盘上)使用感叹号,它会被检测为Shift-Down 1 Shift-up 由

将消息从with转换为按键的有用表示形式的正确方法是什么

我知道这很可能需要理解本地键盘的映射。(注意:我只考虑按键的时间,而不是为了简单起见按键的释放时间)

大体上讲,似乎有三种情况:

  • 按下特殊键(Ctrl/Escape/Shift/Alt)
  • 按标准键(
    A-Z
    0-9
    ,等等…注意
    A
    A
    都读作
    A
  • 一些难以定义的情况,如数字键盘和F1-F12
可以根据需要处理特殊密钥,并且在中有一些有用的查找

但如果我(在英国英语键盘上)使用感叹号,它会被检测为Shift-Down 1 Shift-up

由于我的挂钩水平太低(我相信),无法在代码通过键盘“转换”层后获得代码,我很好奇如何正确解释它们

至于我为什么要这么做。它一开始是为我编写的媒体播放器提供便捷快捷方式的一种方式,该播放器可以在任何地方工作,甚至在游戏中也可以(有些游戏似乎会截取按键并阻止它们传播到操作系统)。事实上,我已经有足够的东西满足我的需要,只要是我在使用这个应用程序(只有可能的用户),但我的好奇心被激发了,如果我想的话,我该如何做得更进一步。

取决于语言(以及它对死键的使用),这可能非常复杂
ToAsciiEx
适用于简单的情况,但如果涉及到死键或输入法,事情很快就会变得非常复杂

有一系列关于键盘布局和的文章,这是一个创建键盘布局的工具(将键映射到字符的最简单方法)。当一组击键映射到单个字符时,将使用键盘布局生成器。在这些情况下,可以进行映射,但当需要多个键来确定字符时,映射会变得有些棘手


日语、汉语或朝鲜语等语言没有从击键到字符的单一映射。对于这些语言,需要一个输入法编辑器;它们通常使用,这是一组广泛的API,输入法编辑器(和其他文本服务,如手写识别和语音识别)使用这些API与应用程序通信,以确定从击键到字符的映射。因为使用IME从击键到字符的映射是由代码定义的,所以低级键盘钩子通常根本无法执行此映射。

Eric完全正确,没有简单的方法可以做到这一点。我在下面附上了我的“尽力而为”的代码,这让我获得了95%的成功率(使用
ToUnicodeEx

它不能正确捕捉特殊(输入法/死键)字符(英国英语键盘上的
的AltGr-4)。但是,它确实存在,(因此它不会干扰正在键入的高级组合键)

请注意,这段代码还没有准备好生产,需要正确的错误处理等。它也只在一些键盘布局上进行了测试。YMMV

公共声明函数unhookwindowshookx Lib“user32”(
ByVal hHook作为整数)作为整数
公共声明函数SetWindowsHookEx Lib“user32”别名“SetWindowsHookExA”(
ByVal idHook作为整数,
ByVal lpfn作为键盘挂钩代表,
ByVal hmod作为整数,
ByVal dwThreadId(作为整数)作为整数
私有声明函数GetAsyncKeyState库“user32”(
ByVal vKey(作为整数)作为整数
私有声明函数CallNextHookEx Lib“user32”(
ByVal hHook作为整数,
ByVal nCode作为整数,
ByVal wParam作为整数,
ByVal lParam作为KBDLLHOOKSTRUCT)作为整数
公共结构KBDLLHOOKSTRUCT
作为整数的公共vkCode
作为整数的公共扫描码
作为整数的公共标志
作为整数的公共时间
公共dwExtraInfo作为整数
端部结构
'低级别键盘常数
私有常量HC_操作为整数=0
私有常量LLKHF_扩展为整数=&H1
作为整数注入的私有常量LLKHF_=&H10
私有常量LLKHF_ALTDOWN为整数=&H20
Private Const LLKHF_UP为整数=&H80
私有常量WH\u键盘LL为整数=13&
作为整数的公用键盘句柄
将函数tounicodex Lib“user32”(wVirtKey作为UInteger,wScanCode作为UInteger,lpKeyState作为Byte(),ByVal lpChar作为System.Text.StringBuilder,cchBuff作为Integer,wFlags作为UInteger,dwhkl作为IntPtr)公开声明为Integer
将函数GetKeyboardState Lib“user32”(lpKeyState为Byte())声明为布尔值
公共声明函数GetKeyState Lib“user32”(keyCode为整数)为Short
私有函数ConvertToUnicode(LPRAM作为KBDLLHOOKSTRUCT)作为字符串
选择Case lParam.vkCode
案例8
返回“{Backspace}”
案例9
返回“{Tab}”
其他情况
将SB设置为新系统。Text.StringBuilder()
Dim KeyState(255)作为字节
'这个函数的输出实际上没有被使用,但它强制Api
'来计算键代码的修饰符
Dim ModifierState为整数
GetKeyState(修改器状态)
Dim KeyStateStatus为布尔值=GetKeyboardState(KeyState)
如果不是,则说明状态
返回“”
如果结束
ToUnicodeEx(CUInt(lParam.vkCode),
CUInt(lParam.scanCode),
键状态,SB,SB容量,0,
InputLanguage.CurrentInputLanguage.Handle)
把某人送回原处
结束选择
端函数
公用函数键盘回调(字节码为整数,
ByVal wParam作为整数,
ByRef lParam作为KBDLLHOOKSTRUCT)作为整数
尝试
调暗键为字符串=无
If(lParam.flags和LL