2016-04-12 9 views
4

Ich habe versucht, eine Möglichkeit zu finden, meine Tastatur neu zuordnen und senden 5-stellige Hex Unicode-Zeichen, die hier beschriebene Methode: ahk Send unterstützt nur 4-stellige Hex-Codes {U + nnnn} Ich weiß, dass autohotkey in der Vergangenheit Unicode nicht nativ unterstützt hat, daher wurden einige Funktionen benötigt, um das zu tun, vielleicht ist das die Lösung für mich.Autohotkey: Senden Sie 5-stellige Hexadezimal Unicode-Zeichen

Beispiel:

#If GetKeyState("CapsLock","T") 
+u::Send {U+1D4B0} 

Die Ergebnisse aus dh 풰 statt, und der Code für 풰 ist {U + D4B0}, was bedeutet, wird AHK nur die letzten 4 Ziffern zu lesen. Wie kann ich das beheben, auch wenn ich dafür neue Funktionen ausführen muss?

Dank

-Mark

Antwort

2

Unicode-Werte größer als 0xFFFF als zwei Ersatzpaar codiert werden muß:

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

Hier ist der Algorithmus einen Unicode-Codepunkt , die in konvertieren Bereich 0x10000 bis 0x10FFFF, Ersatzpaare, paraphrasiert von wikipedia:

Zuerst subtrahiere 0x10000 von dem Codepunkt, um eine Nummer im Bereich 0xFFFFF zu erhalten.

Dann rechts verschieben, um die Zahl von 10 Bits und füge 0xD800 zu dem hohen Surrogat zu bekommen.

Nehmen Sie die niedrigsten zehn Bits der Nummer und fügen 0xDC00 zu den Low Surrogate

+0

Danke! Dieser funktioniert, jetzt muss ich etwas über Ersatzpaare lernen, könntest du mir zeigen, wo ich mehr darüber erfahren kann? Oder sogar eine Tabelle mit allen Codes wäre sehr hilfreich. – markymark

+0

@markymark Siehe das Update. – 2501

+0

Wow. Ich habe Stunden damit verbracht, dies innerhalb weniger Monate herauszufinden. Ich habe viele clevere Dinge versucht. Dann erkannte ich, dass das Problem nur mit 5-stelligen Unicode-Punkten auftrat, googelte es und fand diese Antwort. Und es funktioniert super! –

-1

Von irgendwo im Internet zu bekommen: 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) 
} 

bearbeiten. wahrscheinlich wurde bc der fehlenden Quelle downvoted. Ich weiß einfach nicht mehr wo ich es herbekommen habe. Aber als ich es vor ein paar Jahren benutzt habe, hat es einwandfrei funktioniert.

+0

Ich fand diese Funktionen vor und sie scheinen nicht zu arbeiten, auch für 4-stellige Hex-Codes, ich testete es damals und gerade jetzt und es hat immer noch nicht funktioniert für mich. Vielleicht haben sie in einer älteren Version von AHK gearbeitet. – markymark

+0

verwendest du win10? in win7 64bit, hat es es für mich getan. – Blauhirn

+0

Ja, Win10 64, ahk-Version: 1.1.22.09 – markymark

0

Ich nahm die 2501-Lösung von oben und verwandelte sie in ein funktionierendes ahk-Skript. Ich habe monatelang nach dieser Lösung gesucht!

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