On 02.12.2010 13:04, Ruthard Baudach wrote:
> Ich bin über Nordtast auf Neo aufmerksam geworden und absolut begeistert vom 
> Ebenenkonzept, das von Neo entwickelt wurde.
> 
> Leider habe ich auf diesem Weg AutoHotKey kennengelernt, und kann es in 
> meiner täglichen Arbeit nicht mehr missen.
> 
> Beides verträgt sich leider nicht, da der AutoHotkeyTreiber nicht neben einem 
> anderen AHK-Skript laufen kann.

So ist es leider.

> Nun bin ich soweit durch den Quellcode von neovars durchgestiegen, dass über 
> den allstarhook in keyhooks.ahk
> alle nur möglichen Hotkeys abgefangen und über AllStar() in varfunctions.ahk 
> an das System weitergereicht werden.
> 
> Über custom.ahk kann man sich hier einklinken.
> 
> Nur wie? Ich habe in Wiki und Mailarchiv keine Beschreibung gefunden, wie man 
> das Neovars-Skript erweitern kann.

Es gibt hier und da ein paar Anregungen, aber keine vollständige Doku.

> Ich brauche insbesondere die "Ur-AHK" Funktion einer Hotkeydefinition a lá
> 
> !a::
>       SendInput {F12}!abc{enter}
> 
> Wobei Hotstringdefinitionen a lá
> ::hi::hallo

So einfach ist das nicht. Die Neo-vars-Funktionen zum Aufruf von „Makros“ sind 
den Bedürfnissen eines Tastaturtreibers angepasst, nicht denen eines
Key-Makro-Tools.

Um eine Ersetzung durchzuführen, muss man sich eine Tastenkombination oder auch 
Tastenabfolge aussuchen, die noch nicht belegt ist. Typisch fangen
solche Tastenkombinationen mit Compose (M3+Tab) oder mit einer der toten Tasten 
an. Neo-vars kann jedoch _nicht_ die Strg- oder Alt-Taste in die
normale Betrachtung mit einbeziehen.

Weiters ist es mit Neo-vars nicht möglich, Hotstrings in der Art von 
AHK-Hotstrings zu verwenden. Ich halte diese Funktion aufgrund seiner Umsetzung
für ziemlich bescheiden: Erst muss man „hi“ tippen, dann noch eines der 
Trennzeichen, dann wird AHK selbständig die bereits getippten Zeichen löschen
und durch den String „hallo“ ersetzen. Klappt besonders schlecht, wenn man 
zwischen h und i oder auch zwischen i und dem Trennzeichen mit der Maus an
eine andere Stelle im Text oder gar in ein anderes Fenster klickt, dann 
passieren wundersame Dinge. Wie weit AHK hier Vorkehrungen trifft (Timeouts
zwischen den Tastendrücken, Mausclicks oder auch -Bewegungen zum Abbruch der 
Sequenz), weiß ich nicht, ich halte diese Form der Umsetzung weiterhin
für schlecht.

Ich will Dich aber nicht gänzlich frustrieren :) Es gibt im Wesentlichen 2 
bestehende Möglichkeiten, zu eigenen Funktionen zu kommen:

1. Du klinkst Dich in den Compose-Mechanismus ein.
==================================================

Dazu musst Du im wesentlichen 3 verschiedene Variablentypen kennen:

CM… : Wenn nach Anhängen des aktuellen Zeichens an die Compose-Sequenz 
%CompNew% eine Variable CM%CompNew% existiert, wird das aktuelle Zeichen nicht
ausgegeben (verschluckt) und auf das nächste Zeichen gewartet. Die 
Compose-Sequenz wächst um das aktuelle Zeichen.

CD…: Wenn nach Anhängen des aktuellen Zeichens an die Compose-Sequenz %CompNew% 
eine Variable CD%CompNew% existiert, wird die Compose-Sequenz gelöscht
und der Inhalt der Variable CM%CompNew% ausgegeben.

CF… (nach Überprüfung auf CM… und CD…): Wenn _ohne_ Anhängen des aktuellen 
Zeichens an die Compose-Sequenz %CompNew% eine Variable CF%Comp% existiert,
wird deren Inhalt ausgegeben und dann mit der Verarbeitung des aktuellen 
Zeichens bei leerer Compose-Sequenz fortgefahren.

Optional und für einzelne Zeichen kann es auch erstrebenswert sein, eine 
Variable CRC… zu definieren, damit das Wie-Mit-Neo-Skript eine
Reverse-Auflösung durchführen kann.

Beispiel A:

Durch Druck auf ~,r,r (kleines r) wird ein String ausgegeben:

CMT__tlde := 1
CMT__tldeU000072 := 1
CDT__tldeU000072U000072 := EncodeUniComposeA("hallo")

Das ganze lässt sich auch ganz schön in der Bildschirmtastatur mitverfolgen.

Beispiel B:

Durch Druck auf h,i,(space) wird ein String ausgegeben:

CMU000068 := 1
CFU000068 := "U000068"
CMU000068U000069 := 1
CFU000068U000069 := "U000068U000069"
CDU000068U000069U000020 := EncodeUniComposeA("hallo ")

Nach Drücken auf h wird erstmal garnichts ausgegeben, auch dann noch nicht, 
wenn danach ein i folgt. Hängst Du dann das Space an, wird der String
ausgegeben. Drückst Du nach h oder i eine andere Taste als die in der Sequenz, 
werden die bis dahin zurück gehaltenen Buchstaben auch ausgegeben. Wenn
man h,i auch mit anderen Trennern ersetzen lassen will, muss man für jede 
derartige Sequenz eine entsprechende CD…-Variable mit passendem Inhalt anlegen.

Beispiel C:

Durch Druck auf ♫,m,d soll ein bestimmtes Unicode-Zeichen ᘺ (U+163A: LARGE 
GERMAN CHANCELLOR CLEAVAGE), liebevoll auch „Märkels Dekolleté“ genannt,
ausgegeben werden:

CMS__Comp := 1
CMS__CompU00006D := 1
CDS__CompU00006DU000064 := "U00163A"
CRCU00163A .= " S__CompU00006DU000064"

Die CRC…-Variable bewirkt, dass Wie-Mit-Neo die entsprechende Sequenz angeben 
kann.

2. Du löst für spezielle Tastendrücke Unterprogrammaufrufe aus.
===============================================================

Das kann auf zwei Arten erfolgen: Direkt durch den Tastendruck oder als 
Ergebnis einer Compose-Sequenz. Direkt durch den Tastendruck ist schon sehr
low-level, Beispiele dafür findest Du bei den Modifier-Tasten, die auch durch 
CharStar geschleust werden, in varsfunctions.ahk. Zweiteres wird in den
verschiedenen Tools (tools.ahk) verwendet, um einen Unicode-Zeichengenerator, 
einen Generator für römische Zahlen, einen Unicode-Code-Decoder, einen
Taschenrechner und das bereits erwähnte Wie-Mit-Neo umzusetzen.

In jedem Fall musst Du Dich jetzt mit erweiterten Variablennamen und den zu 
ihrer Generierung vorgesehenen Funktionen herumschlagen. So gibt es
GUISYM, das bei der Verwaltung der Bildschirmtastatur-Anzeige für 
Funktionstasten hilft. Weiters gibt es spezielle Hooks im Code, über die man 
eigene
Prozeduren aufrufen kann.

CP… verwaltet die Zuordnung von Tastendrücken bei entsprechend aktivierter 
Ebene. Angehängt wird die Ebenennummer (1–8) und die Tastenposition, die
für höchstmögliche Kompatibilität für die meisten Tasten als VKxxSCxxx 
ausgeführt ist. In der Custom.ahk definiere ich beispielsweise CP3F11 zur
(De-)Aktivierung meines eigenen Layouts über M3+F11. Andere Tasten sollte man 
indirekt „adressieren“, da es Unterschiede zwischen den darunter
liegenden Windows-Layouts gibt. Der Variablenname für die Taste 3 (über dem 
Qwertz-e) auf Ebene 2 ist somit CP2%vksc004%.

PR… enthält für einen physikalischen Tastendruck die Information, ob die Taste 
noch als gedrückt gilt und welches Zeichen „losgelassen“ werden muss,
wenn die ursächliche Taste nicht mehr gedrückt ist. Siehe varsfunctions.ahk.

PP… wird in Zusammenhang mit Key-Repeats verwendet.

TransformProc, wenn definiert, dient zu einer sehr low-level-Ersetzung von 
Tastensignalen (drücken, loslassen) und findet beispielsweise im
Einhand-Neo Verwendung (einhandneo.ahk).

PressHookProc, wenn definiert, verweist auf eine Prozedur, die beim Drücken 
jeder Taste aufgerufen wird und diese somit abfangen bzw. auch ersetzen
kann. Einige Tools (tools.ahk) bedienen sich dieser Technik.

CharProc… sind Prozeduren, die aufgerufen werden, wenn ein Tastendruck zu einer 
Prozedur (statt zu einem Unicode- oder Sonderzeichen) auflöst. Die
Zuweisung CP3F11 := "P_AdNWt" sorgt also dafür, dass nach Druck auf M3+F11 die 
Prozedur CharProc_AdNWt() aufgerufen wird.

CharOutFilterProc, wenn definiert, verweist auf eine Prozedur, die bei der 
Zeichenausgabe filternd eingreifen kann. Diese Methode findet
beispielsweise in der Unicode-Zeichen-in-Hex-Umwandlung (♫dd) Verwendung 
(tools.ahk).

Übrigens sollte man bei der Ausgabe von Zeichen ausschließlich auf die 
gekapselten Funktionen von Neo-vars zugreifen, die da sind: CharOut,
CharOutDown, CharOutUp. Beim direkten Aufruf von AHKs Send-Funktionen könnten 
insbesondere Modifier an die Applikation gesendet werden, die dann die
Neo-vars-interne Verwaltung aushebeln und dann beispielsweise ein Shift hängen 
bleibt. CharOut() bekommt ein Sonder- oder Unicode-Zeichen als
7-Stellige Sequenz übergeben, beispielsweise: CharOut("U000020") oder 
CharOut("S___Ins"). Will man mehrere Zeichen ausgeben, muss das in einer Loop
passieren. Wie Du von einem UTF-8-String auf die entsprechenden Hex-Strings 
kommst, hast Du oben schon bei EncodeUniComposeA("hallo") gesehen.

Im Bereich der Sondertasten kommen noch ein paar Variablen ins Spiel: NOC…, 
DNCS…, UPCS…, CS…, UNSH… und DOSH… (varsfunctions.ahk,
keydefinitions.ahk). Zum Verständnis der Tastenbelegung ist überhaupt die ganze 
keydefinitions.ahk sehr lehrreich. CS… sind Shortcuts, die statt eines
Sonderzeichens oder eines entsprechenden Unicode-Zeichens über die normalen 
Send-Funktionen geschickt werden sollen. NOC… legt fest, für welche Tasten
das CapsLock nicht wirkt. UNSH… wird für sämtliche Zeichen mit Shortcut 
definiert, für die ein möglicherweise gerade gedrücktes Shift zum Senden
aufgehoben werden muss. DOSH… ist mehr oder weniger das Gegenteil von UNSH…, 
wird aber fast nicht verwendet. DNCS… und UPCS… sind Shortcuts, die nur
beim Drücken oder loslassen einer Taste entsprechend ersetzt werden. CS…, DNCS… 
und UPCS… können auch Sequenzen enthalten.



Wenn Du noch Fragen hast: Frag ruhig, ich werde versuchen, Dich nächstes Mal 
nicht so lange warten zu lassen.

lG,
– Mœsi

Antwort per Email an