AutoHotkey:将韩语键重新映射为Ctrl

4

标准韩语键盘上的空格键两侧各有两个键(每边各一个),我想将它们重新映射为Control或Alt修饰键,这样我就可以使用比小指更强的手指进行交替操作了(我是Emacs用户)。

我猜问题在于它们似乎没有生成KeyUp事件,并且它们不像其他键一样重复。我用自动热键循环的方法得到了一个可怕的笨办法。我还用另一个非免费程序KeyManager做了类似的事情。我希望能有一些更高级的技巧或解决方法(AutoHotkey、驱动程序或其他方式)。

;Scan Code for Hanja Key
sc1F1::
Loop 10000
{
SetKeyDelay,-1
Send {Blind}{LCtrl DownTemp}
}
SetKeyDelay,-1
Send {Blind}{LCtrl Up}
Return

按住汉字键的键盘钩子输出:

你可以看到没有重复和弹起事件。

VK  SC  Type    Up/Dn   Elapsed Key     Window
74  03F     u   0.08    F5              
19  1F1     d   0.66    Hanja           
74  03F     d   9.58    F5       

更新:

尝试过的方法:

sc1F1 & t::Send {Blind}{LCtrl DownTemp}{t}{LCtrl Up}

结果:

按下 Hanja+t 后,热键触发,但是随后仅仅按下t就会再次执行相同的操作,LCtrl Up似乎没有生效。

Abe的基于SetTimer的重置方案也不错!感觉比我的原始代码更加优雅。然而,缺点是需要延迟-我必须调整我的输入速度以匹配延迟。

其他已测试的解决方案:

GetKeyState("vk19", "p")在脚本加载和一个初始按键后始终报告按下状态。即使我已经释放了该键也不会改变这种状态。

KeyWait也不能按预期工作。

sc1F1 up::traytip,, test在按下/释放任意次数后均未产生托盘提示。


请始终使用来自http://ahkscript.org/(当前版本,新官方网站)的AutoHotkey!来自autohotkey.com的AutoHotkey已过时,您可能在运行脚本时遇到一些问题!此外,如果您在获取未在AutoHotkey文档中列出的特殊键名称方面遇到任何问题,请查看此答案:http://stackoverflow.com/questions/24921492/macro-keys-not-detected-autohotkey/24927828#24927828 - vasili111
3个回答

1

Assem,

我还没有完成这个想法,但这是否是另一种方法? 它将显示哪些键被按下,直到(在这种情况下按下回车键),但您可以创建自己的“完成”条件,然后“组合”按键以创建Alt或Ctrl组合。

sc038:: ; Start when (in this case) the left Alt is pressed, {LAlt} is NOT listed in the input list....
input:=""
   Loop
   {
        Input, in, L1, {Enter}{LControl}{RControl}{RAlt}{LShift}{RShift}{LWin}{RWin}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{BS}{Capslock}{Numlock}{PrintScreen}{Pause}
        EL=%ErrorLevel%
        ToolTip, %EL% and %in% and %A_ThisHotkey%
        if EL = EndKey:Enter
        {
            ToolTip
            Sleep, 5000
            Break
        }
   }
Return

谢谢提供这个片段代码,但并不是我所期望的解决方案。Input似乎不支持修改键。因此,如果我要支持sc###(起始序列重新映射为Ctrl),然后Alt+某些键或Shift+某些键,我想这个循环将变得更加复杂? - assem
你说得没错,input函数不会把各种修饰键组合在一起处理,但是(根据传递的特殊按键参数),input函数会单独处理每个按下的键。我在想,如果你的按键组合以一个字母字符为结尾,你可以将其用作结束触发器...... - Robert Ilbrink
这是一个有趣的想法;实际上,它只需要跟踪额外的修饰键并在按下任何非修饰键时批量发送(例如 C-M-e 或 C-M-\ 或 C-u C-c . 等)。它可以像 ctrl 锁定键一样,重复批量发送直到切换或通过完成键终止。 - assem

1

让脚本发送{Ctrl down}
然后设置一个计时器,在所需的时间(例如600毫秒)后运行一个子程序
(-使其仅运行一次)
以发送{Ctrl up}

sc1F1::
Sendinput, {Ctrl Down}
SetTimer, Reset, -600
Return

Reset:
Sendinput, {Ctrl Up}
Return

→设置定时器←


如果你想将它变成一个切换按钮,即按一次发送Control+A,再按一次返回正常行为:

sc1F1::Flag:=!Flag

#If Flag
x::Sendinput, ^a
a::Sendinput, test
#If

变量Flag的值会在每次按下sc1F1时翻转,即Flag被设置为1或0。
#If Flag#If Flag = 1的简写形式。
此示例需要Autohotkey_L(新版/推荐版本),因为它使用了#If命令。
使用AHK基本语法,代码如下:
sc1F1::Flag:=!Flag

$x::
if Flag
    Send, ^a
Else
    Send, x
Return

使用大写锁定键(Capslock)代替sc1F1的其他选项/示例:

如果您只想使用该按钮作为修饰符,可以尝试使用&
此示例将Capslock键转换为修饰键(第一行保持大写锁定灯关闭):

SetCapsLockState, AlwaysOff

capslock & x::traytip,, %a_thishotkey%

如果你想让 Capslock 在单独按下时发送某些内容,你需要添加类似以下的内容:
capslock::Send, something

然后,只有在Capslock释放时才会发生“某事”。

→更多信息←


这里有一个例子,如果物理上按下了 CapslockXA 的表现会有所不同:

SetCapsLockState, AlwaysOff
#If GetKeystate("capslock","p")
x::traytip,, %a_thishotkey%
a::traytip,, %a_thishotkey%
#If

您也可以尝试设置一个变量(“Flag”),
然后使用计时器将其清除。

capslock::
Flag := 1
SetTimer, Reset, 600
Return

Reset:
Flag := 0
Return

#If Flag
x::Sendinput, ^a
a::Sendinput, test
#If

手册参考:
#If
GetKeyState()


另一个选项是安装键盘钩子。
然后,您可以使用内置变量a_priorkey检查最后按下的键是什么。
#InstallKeybdhook

x::
if (a_priorkey = "Capslock") {
    Traytip,, %a_thishotkey%
} Return

→更多关于内置变量的信息←


如果其他方法都失败了,你可以尝试:
通过注册表的“Scancode Map”重新映射


@abe 没错,它没有按预期工作。看起来就 AutoHotkey 而言,某种时间/延迟解决方案(或像 Robert 建议的终止键)是我所能期望的最好的解决方案。 - assem
@abe 是的,我刚测试了一下 - 气泡提示从未出现。我更新了原帖; 另外,对于您的标志情况,我需要支持几乎任何按键。Ctrl + 任何按键以及 Ctrl + [alt / shift] + 任何按键。我认为这就是为什么罗伯特建议采用这种方法的原因。 - assem
@assem 我在答案底部添加了该链接,并意识到我在第一个示例中放置了 SetTimer,Reset,600,这会每隔 600 毫秒不断调用 Reset。SetTimer,Reset,-600 只会调用一次。 - Honest Abe
@abe 感谢计时器更新;但是对于这个汉字键,注册表键映射并没有按预期工作。 - assem

0
也许我没有正确理解问题,但是我找到了这些键的关键特殊代码,这对我很有帮助:
SC11D:: RCtrl
SC138:: RAlt

不确定谁会使用Alt重映射,但为了完整起见...

在Win8上使用韩文微软输入法可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接