我正在寻找创建自定义键盘布局,主要用于键入unicode数学符号。我需要的符号集非常大,我想出的方案涉及多种布局和特殊组合。
我输入`(反引号)一次,而我得到一个特殊字符,我们将用*表示。通过键入其他键,我获得与特定主题相关的特定键盘布局。 (我想用一个特殊符号替换后面的刻度,这样我就记住它是一种控制代码。通过键入两次,我得到一个正常的后退滴答)
以下是一些示例映射:
*s -> Set theory layout:
[ -> ∈ (element of)
o -> ∅ (empty set)
*r -> General math:
s -> ∫ (integral sign)
S -> ∬ (double integral sign)
*e -> Misc operators:
8 -> ∗ (convolution asterisk)
* -> ⋆ (star operator)
*g -> Greek alphabet
输入=
之类的字符后,我可以输入一些其他特殊组合来修改该字符。例如:
*x -> Negates the previous character:
= -> ≠ (unequal)
≡ -> ≢ (negation of three line equality)
*w -> Expands the previous character:
∫ -> ∭ (triple integral)
∬ -> ⨌ (quad integral)
映射是助记符。我可以想象将我想要的所有符号塞进一个布局中,但它将无法使用,所以我想尝试坚持这个方案或类似的东西。
键盘适用于Windows环境,但我不会自己编写键盘DLL。我调查了它,这太复杂了。
现在,我正在寻找AHK寻求解决方案。可以在AHK(或类似的东西)中完成吗?如果是这样,你能告诉我一些让我入门的例子吗?
我还想知道是否有其他方法可以做到这一点。
我知道Microsoft键盘布局创建器,并且过去曾使用它,但它不够强大。我也知道Tavultesoft的Keyman,我知道它可以做我想要的事情,但它的价格非常昂贵,所以它不是一个选择。
答案 0 :(得分:3)
您可以使用AutoHotkey完成所需。
棘手的部分是:您需要动态分配热键和Hotstrings。前者可以使用Hotkey - 命令,后者尚未实现,可能永远不会实现。
您可以将它们写入新的.ahk文件并单独执行该脚本,或使用polyethene's really awesome dynamical regEx hotstring creator。 autohotkey.net的存储库已经停机多年,但我找到了脚本here。
要运行以下示例脚本,您需要将该脚本下载到Hotstrings.ahk
并将其放在主.ahk文件所在的目录中。
但是,我无法将布局转换器热键分配给
`
,所以我将其设置为ä
。
我知道这个网站不是代码提供商网络,但我对此问题也很感兴趣。
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#include Hotstrings.ahk
lastKey := ""
; KEYS OF THE NORMAL LAYOUT WHICH SHOULD BE NEGATABLE:
hotstrings("=", "_equals") ;
; CHOOSE LAYOUT OR NEGATE/EXPAND LAST CHARACTER:
:*?:ä::
; backSpacePressed: ; wtf is this? sorry just saw this now. Does not belong here, does not belong anywhere
sendRaw *
tooltip,
(
n normal layout
s set theory
r general math
x negate previous
w expand previous
{esc} cancel
), %A_CaretX%, %A_CaretY%
input, layout, L1, {Escape}, s,r,e,g,x,w
send {Backspace} ; remove the *
if layout in n,s,r,e,g,x,w
{
tooltip, %layout%, %A_CaretX%, %A_CaretY%
; RESET
if layout = n
{
reset_all_hotstrings()
; KEYS OF THE NORMAL LAYOUT WHICH SHOULD BE NEGATABLE:
hotstrings("=", "_equals")
}
; NEW LAYOUT
else if layout = s
{
reset_all_hotstrings()
; SET THEORY SHORTCUTS
hotstrings("o", "_emptySet")
hotstrings("\[", "_elementOf")
}
else if layout = r
{
reset_all_hotstrings()
; MATH SHORTCUTS
hotstrings("s", "_integral")
hotstrings("S", "_doubleIntegral")
hotstrings("=", "_identical")
}
; and so on
; ...
; EDIT PREVIOUS CHARACTER
else if layout = x
{
send {backSpace}
if lastKey = identical
sendUnicodeChar(0x2262)
else if lastKey = equals
sendUnicodeChar(0x2260)
}
; EXPAND PREVIOUS CHARACTER
else if layout = w
{
send {backSpace}
if lastKey = integral
sendUnicodeChar(0x222D)
else if lastKey = doubleIntegral
sendUnicodeChar(0x2A0C)
}
}
else
{
tooltip, cancelled, %A_CaretX%, %A_CaretY%
}
sleep, 500
tooltip
return
reset_all_hotstrings() {
hotstrings("=")
hotstrings("\[")
hotstrings("o")
hotstrings("s")
hotstrings("S")
; and so on
}
; NORMAL LAYOUT SHORTCUTS:
_equals:
sendUnicodeChar(0x003D)
lastKey = equals
return
; SPECIAL LAYOUT SHORTCUTS:
_emptySet:
;sendUnicodeChar(0x00D8)
altNumpad(0216)
; to find out numpad combination or unicode: press WIN+R, type in "charmap"
; or for unicode only, go to http://www.fileformat.info/info/unicode/category/index.htm
; (sendUnicodChar() needs 0x before the unicode string)
;altNumpad(0248)
;send Ø
;send ø
; choose whatever works best for you
lastKey = emptySet
return
_elementOf:
sendUnicodeChar(0x2208)
lastKey = elementOf
return
_integral:
sendUnicodeChar(0x222B)
lastKey = integral
return
_identical:
sendUnicodeChar(0x2261)
lastKey = identical
return
_doubleIntegral:
sendUnicodeChar(0x222C)
lastKey = doubleIntegral
return
; -------------------------------------------
altNumpad(numbers) {
stringSplit, n, numbers
setkeydelay, 100
send {alt down}
loop, %n0%
{
t := n%a_index%
send {numpad%t%}
}
send {alt up}
}
SendUnicodeChar(charCode)
{
VarSetCapacity(ki, 28 * 2, 0)
EncodeInteger(&ki + 0, 1)
EncodeInteger(&ki + 6, charCode)
EncodeInteger(&ki + 8, 4)
EncodeInteger(&ki +28, 1)
EncodeInteger(&ki +34, charCode)
EncodeInteger(&ki +36, 4|2)
DllCall("SendInput", "UInt", 2, "UInt", &ki, "Int", 28)
}
EncodeInteger(ref, val)
{
DllCall("ntdll\RtlFillMemoryUlong", "Uint", ref, "Uint", 4, "Uint", val)
}
^e::reload
显然还有很大的改进空间,显然