Autohotkey:发送5位十六进制unicode字符

5
我一直在尝试找到一种重新映射键盘并发送5位十六进制Unicode字符的方法。这里描述的方法:ahk Send仅支持4位十六进制代码{U+nnnn}。我知道过去,autohotkey没有本地支持unicode,因此需要一些函数来实现,也许这就是我的解决方案。
示例:
#If GetKeyState("CapsLock","T")
+u::Send {U+1D4B0}

那个结果是 "풰" 而不是逗号,而 "풰" 的代码是 {U+D4B0},这意味着 AHK 仅读取最后的4个数字。即使需要创建新功能,我该如何修复它?谢谢 -Mark
4个回答

4

Unicode值大于0xFFFF的字符必须编码为两个代理对:

+u:: SendInput ,{U+D835}{U+DCB0}

以下是需要翻译的内容:

这是一个将Unicode码点转换为代理对的算法,该码点范围为0x10000到0x10FFFF,摘自wikipedia

首先从码点中减去0x10000,得到一个在0xFFFFF范围内的数字。

然后将数字右移10位并加上0xD800,得到高代理项。

取数字的最低十位并加上0xDC00,得到低代理项。


谢谢!这个可以用了,现在我需要学习代理对,你能告诉我在哪里可以学到更多关于它的知识吗?或者甚至一个包含所有代码的表格也会非常有帮助。 - markymark
哇,我花了数小时在几个月的时间里试图弄清楚这个问题。尝试了很多聪明的方法。然后我意识到问题只出现在5位unicode点上,于是我谷歌搜索并找到了这个答案。它非常有效! - KANJICODER

0
我从上面获取了2501的解决方案,并将其转化为可工作的ahk脚本。我已经断断续续地搜索了几个月,寻找这个解决方案!
+u:: FUNC_SEND_UNICODE( 0x1D4B0 )

FUNC_SEND_UNICODE(func_args)
{

    /*
    ;commented out proof of concept code:
    str := ""
    u1  := Chr( 0xD835 )
    u2  := Chr( 0xDCB0 )
    str := u1 . u2

    bk := clipboard
    clipboard := str
    send, ^v

    sleep,200
    clipboard := bk
    */

    ;bk == "clipboard [B]ac[K]up
    bk := clipboard


    ;chunk of data that needs to be cut into
    ;two chunks.
    ful := func_args + 0


    /*  commented out testing code, using original
        sample input of stack overflow post
    ;msgbox,ful:[%ful%]
    ;for testing. Expecting input to be equal to
    ;the value in the post.
    if(ful != 0x1D4B0 ){
        msgbox,"[WHATTHEHECK]"
    }
    */


    ;Subtract 0x10000 from ful, gets number 
    ;in range(rng) 0x0 to 0xFFFFFF inclusive
    rng := ful - 0x10000
    if(rng > 0xFFFFF)
    {
        msgBox,[Step1 Resulted In Out Of Range]
    }

    ;Do shifting and masking, then check to make
    ;sure the value is in the expected range:
    big_shif := (rng >>   10)
    lit_mask := (rng & 0x3FF)
    if(big_shif > 0x3FF)
    {
        msgBox,[MATH_ERROR:big_shif]
    }
    if(lit_mask > 0x3FF)
    {
        msgBox,[MATH_ERROR:lit_mask]
    }

    big := big_shif + 0xD800
    lit := lit_mask + 0xDC00
    if(big < 0xD800 || big >= 0xDBFF){
        msgBox, [HIGH_SURROGATE_OUT_OF_BOUNDS]
    }
    if(lit < 0xDC00 || lit >= 0xDFFF){
        msgBox, [LOW_SURROGATE_OUT_OF_BOUNDS]
    }

    ;Convert code points to actual characters:
    u1 := Chr( big )
    u2 := Chr( lit )

    ;concatentate those two characters to
    ;create our final surrogate output:
    str := u1 . u2

    ;set it equal to clipboard, and send
    ;the clipboard. This is a hack.
    ;send,%str% works fine in google chrome,
    ;but fails in notepad++ for some reason.
    ;tried appending EOF, STX, ETX control codes
    ;along with output, but to no effect.
    clipboard := str
    send, ^v

    ;Must sleep before restoring clipboard,
    ;otherwise, the clipboard will get
    ;overwritten before ctrl+v has the chance
    ;to output the character. You'll end up just
    ;pasting whatever was originally on the
    ;clipboard.
    sleep,200
    clipboard := bk

    return
}

0

一个2501的答案的实现。

  1. 监听;u
  2. 接着是结束字符(例如;Return
  3. 等待一系列按键,如1D4B0
  4. ;结尾时输入结束
  5. 如果Unicode字符小于65536,则直接发送所需的Unicode字符;否则计算代理对
  6. 插入所需的Unicode字符

:?:`;u::
    Input, keys, , `;
    if (StrLen(keys) < 5)
        Send {U+%keys%}
    else {
        keys := "0x" + keys
        num := keys - 0x10000
        w1 := Format("{:x}", (num >> 10) + 0xD800)
        w2 := Format("{:x}", (num & 1023) + 0xDC00)
        Send {U+%w1%}{U+%w2%}
    }
    return

参考资料:


-1

来自互联网的某个地方:sendunicodechar(0x1D4B0)

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)
}

编辑:可能因为缺少来源而被下降了评分。我不记得我几年前从哪里得到它了。但是当我使用它时,它运行得非常顺畅。


我以前找到过这些功能,但它们似乎连对于4位十六进制代码都不起作用,我当时测试过了,现在再测试还是不行。也许它们只能在旧版的 AHK 上运行。 - markymark
你在用Win10吗? 在Win7 64位系统上,这对我有用。 - phil294
是的,Win10 64位系统,ahk版本为1.1.22.09。 - markymark

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