Upload failed. Maybe wrong permissions?

User Tools

Site Tools




Így készül a billentyűzet

Úgy gondoltam, elmesélem, mit tud a jelenlegi billentyűzetprogramom és hogyan tudja. A TESZ-szel való munka végre alkalmat adott elkészíteni egy igazán komoly billentyűzetet, amiről már röviden meséltem, de most már elmondanám részletesen. Forráskódokkal, így az olvasó is elkészítheti a sajátját!
  A billentyűzetet magát is TESZ-nek hívják, mert kifejezetten a szótár számára készült, bár minden egyéb célra is ezt használom. AHK-ban írtam, és már négyezer-kétszáz sorra rúg a kódja, a sok ékezetes betű miatt.
  Kezdjük az elején. Mindössze nyolc globális változónk van, layout, aki a kiosztást tárolja (0: magyar, 1: cirill, 2: görög, további értékek majd később), ansi, a magyar billentyűzet ő és ű betűinek beállítására, autocaps az automata nagybetűs módhoz, caps a következő betű nagybetűzéséhez, és accenthotkeys, aki azt mondja meg, hogy működnek-e a döglött billentyűink. Ki-be lehet őket kapcsolni, mert rengeteg programfunkcióval összevesznek, például a modern programokban a Ctrl-T nyit új fület és a Ctrl-W csukja be a régit, de nálunk ezek ékezeteket adnak. A három utolsó változó a prevchar az előzőként összeállított karakter tárolására, k az éppen elkészítendő karakter számára és storedchar egy további karakternek, az ismétlőfunkcióhoz.
  Van néhány hotkeyhez nem kötött rutinunk és függvényünk.
  A legfontosabb az uni függvény, a program egyetlen olyan része, amit nem én írtam, készen vettem át az AHK egyik fórumából. Arra szolgál, hogy a hexakódban megadott karaktert kiküldje a rendszernek. Az itt használt példány egyúttal tárolja is prevcharban, de csak ezt a két sort írtam hozzá.

uni( p_text ) ; 4 DllCalls/char + 1, reduced from 20/char + 1
{
global prevchar
prevchar:=p_text
event_count := ( StrLen(p_text)//4 )*2
VarSetCapacity( events, 28*event_count, 0 )
base = 0
Loop % event_count//2
}
StringMid code, p_text, 4*A_Index-3, 4
code = 0x4%code%
 
DllCall("RtlFillMemory", "uint", &events + base, "uint",1, "uint", 1)
DllCall("ntoskrnl.exeRtlFillMemoryUlong", "uint",&events+base+6, "uint",4, "uint",code)
base += 28
 
DllCall("RtlFillMemory", "uint", &events + base, "uint",1, "uint", 1)
DllCall("ntoskrnl.exeRtlFillMemoryUlong", "uint",&events+base+6, "uint",4, "uint",code|(2<<16))
base += 28
{
result := DllCall( "SendInput", "uint", event_count, "uint", &events, "int", 28 )
if ( ErrorLevel or result < event_count )
MsgBox SendInput failed0096nErrorLevel = %ErrorLevel%0096n%result% events of %event_count%
}

Én sem értem, de elég, hogy működik.
  Van négy függvényünk switchtwo… switchfive néven, amik arra szolgálnak, hogy 2, 3, 4, 5 karakter között lehessen cserélgetni. Megmutatom a hármast.

switchthree(a, b, c)
{
global prevchar, k
if(prevchar==a)
  k:=b
if(prevchar==b)
  k:=c
if(prevchar==c)
  k:=a
}

Hívni úgy lehet őket, hogy például

switchtwo("004f", "00d6") ; O Ö

vagy

switchthree("006f", "020d", "0151") ; o ȍ ő

A döglött billentyűk rutinjaiban ilyen sorok vannak, a végükön megjegyzésben mindig ki vannak írva a karakterek is. Az első példa az umlaut rutinjából való, a második a dupla vesszőéből, ami mindkét irányú dupla vesszőt megcsinálja. (És azért először a fordítottat, mert az gyakran kell a délszláv nyelvekhez, a magyar ő betű meg amúgy is rajta van a rendes billentyűzeten, csak a teljesség kedvéért van meg itt is.)
  A rutinok segítségével két–öt betű tekergethető ugyanannak a döglött billentyűnek a nyomkodásával. A legtöbbször csak kettőt váltogatunk, ugyanazt az ékezetet föltesszük, levesszük. Ezt a függvényt a mostani állás szerint több mint ezerhatszáz helyről hívjuk meg, ami viszont nem jelent ugyanennyi különböző karaktert: a többékezetes betűket több helyről is el kell érnünk. (1454-féle karaktert tudunk előállítani, nem számítva az U+0080 alatti kódokat, de persze nem mindet döglött billentyűkkel.) Három karaktert több mint ötven helyen váltogatunk, négyet hét helyen, ötös csoportunk pedig csak három van.

Lássuk tovább. Van egy ikoncserélő rutinunk, ezt nem mutatom, mert más alkalmazásnál úgyis teljesen másképpen kell megírni; az éppen bekapcsolt üzemmódváltozók alapján összeállítja az érvényes ikon nevét és kiteszi. Huszonöt különböző ikonfile-t használunk, egyet itt is megmutattam. Az ikon bal felső sarkában a színes téglalap jelzi a kiosztást: zöld = magyar, piros = cirill, kék = görög. A jobb felső sarokban a K betű színe az automata nagybetűt jelzi: barna = kikapcsolva, zöld = bekapcsolva és a következő betű kicsi lesz, fehér = bekapcsolva és a következő betű nagy lesz. Balra lent a Č betű mutatja a döglött billentyűket: barna = kikapcsolva, sárga = be. Jobbra lent pedig az ANSI üzemmód A betűje, barna = kikapcsolva, piros = be. Ez például blogíráshoz kell, mert a blogot mindmáig ANSI-ban írom. És van egy ikon, ami az egész billentyűzet kikapcsolt állapotát jelzi.

Lássuk mármost a billentyűk rutinjait. Három csoportba sorolhatók: funkció-, írógép- és döglött billentyűk. Kezdjük a funkcióbillentyűkkel: nyolcan vannak.
  Ctrl ` kapcsolja ki-be az egész billentyűzetet.
  Win ` váltja az automata nagybetűt.
  Alt ` váltja az ANSI módot.
  PrintScreen, Scroll Lock és Pause kapcsol magyar, cirill, illetve görög kiosztásra.
  LShift & RShift kapcsolja be-ki a döglött billentyűket. Vagyis az összes hotkeyra kiad egy toggle parancsot, átváltja az accenthotkeys változót (aminek az értékét voltaképpen csak az ikonválasztásnál használjuk) és meghívja az ikonmutató rutint.
  LControl & RControl „megöli” az előző karaktert. Ez akkor kell, ha egy döglött billentyű önálló karakterét akarjuk használni, de előzőleg már lenyomtunk egy olyan betűt, amire a dögbill hatással van. Például a Ctrl-P a pont ékezet dögbillje. Ha e Ctrl-P-t nyomunk, ė betűt fogunk kapni. Ugyanakkor önállóan a Ctrl-P a középső pontot · adja. Ha egymás után kell e és középső pont, akkor a kettő között megöljük az előző karaktert: e, két Ctrl egyszerre, Ctrl-P. Eredmény: e·. A megölést a kurzormozgató billentyűk, az Enter és a szóköz is elvégzi, mert nagyon kellemetlen, ha az előző szóban, esetleg a szöveg egész más részén percekkel ezelőtt utoljára leütött betűre a később megnyomott dögbill még mindig reagál.

Az írógépbillentyűk egyszerűen a beállított üzemmódnak megfelelően kiválasztják a szükséges karaktert. Részlet az A betű kódjából:

$a::
if(layout=0)
{
  if(autocaps=1 and caps=1)
  {
    send A
    prevchar:="0041"
  }
  else
  {
    send a
    prevchar:="0061"
  }
  caps=0
  gosub showicon
}

Itt azért kell némi magyarázat. Az angol ábécé betűit nem az uni függvénnyel küldjük ki, hanem senddel, mert különben egyes programok nem reagálnak rájuk mint gyorsbillentyűkre. Emiatt viszont a prevchart külön be kell állítani a betű kódjára, hogy egy esetleges későbbi dögbill tudjon rájuk reagálni. A rutin egyébként kétfelé ágazik: ha nagybetűs módban vagyunk (autocaps) és most éppen nagybetűt kell adni (caps), akkor nagy A-t küld ki, különben kicsit. Aztán rögtön nullázza a capsot és újrarajzoltatja az ikont.
  Nézzük meg a latin részletet egy ékezetes betűnél.

$-::
if(layout=0)
{
  if(autocaps=1 and caps=1)
  uni("00dc") ; Ü
  else
  uni("00fc") ; ü
}
caps=0
gosub showicon

Amint látható, itt nincs send, egyből unival megy ki a karakterünk. Mindegyik ilyen, két kivétellel: az ő és ű esetén el kell döntenünk, Unicode legyen-e vagy ANSI.

$[::
if(layout=0)
{
  if(autocaps=1 and caps=1)
    if(ansi=1)
      uni("00d5") ; Õ
    else
      uni("0150") ; Ő
  else
    if(ansi=1)
      uni("00f5") ; õ
    else
      uni("0151") ; ő
  caps=0
  gosub showicon
}

A cirill és görög betűk ugyanígy jönnek, például:

if(layout=1)
{
if(autocaps=1 and caps=1)
  uni("0414") ; Д
else
  uni("0434") ; д
caps=0
gosub showicon
}

Mint látható, az automata nagybetűzést a cirillnél és a görögnél is szolgáltatjuk, én nagyon tudom ajánlani, egyszer kell végigírogatni és rengeteg időt megtakarít az ember használat közben.
  A pont, Shift-1 és Shift-/ billentyűk beépített funkciójukat adják (. ! ?), emellett pedig

if(autocaps=1)
{
caps=1
gosub showicon
}

– minden szócséplés helyett. A számjegyek 1-től 9-ig egyszerűen csak kiküldik a számjegyet, de emellett a kódját is tárolják, mert némelyik dögbill számjegyre is reagál.
  Magyar írógépkiosztásunk a következő:
  ű 1 2 3 4 5 6 7 8 9 ö ü ó í
  q w e r t y u i o p ő ú
  a s d f g h j k l é á
  z x c v b n m , . -
  illetve Shifttel
  0 ! * ’ % / = ( ) Ö Ü Ó Í
  Q W E R T Y U I O P Ő Ú
  A S D F G H J K L É Á
  Z X C V B N M ; : ?
  Figyelmet érdemel, hogy az ű betűnek nincs nagy párja, a nulla jön helyette, mert a nagy hosszú Ű nagyon ritka betű, és az automata nagybetűvel könnyen előállítható. Az aposztróf pedig nem a régimódi U+0027 ' aposztróf, hanem a rendes nyomdai U+2019 ’ változat.
  A cirill kiosztás nem arra szolgál, hogy oroszok vagy bolgárok tudjanak vele dolgozni: saját magamnak csináltam. Tehát ilyen:
  ј 1 2 3 4 5 6 7 8 9 0 ё э ъ
  щ ш е р т ь у и о п
  а с д ф г х й к л
  з ч ц в б н м , . -
  A Ј betű a szerb j, egyszerűen azért, mert nem tudtam hova tenni és volt egy szabad billentyűm kéznél. Ctrl-lal, dögbill módban az ukrán és a szerb ábécé betűi mind megvannak. A magánhangzók a hangsúlyjeles változataikat adják, amik nincsenek meg a Unicode-ban, én rajzoltam meg őket a TESZ számára, tehát csak a TESZ-hez való fontban jelennek meg. De állandóan kellenek.
  A görög kiosztás:
  varia 1 2 3 4 5 6 7 8 9 0 makron periszpomeni hipogegrammeni
  θ ω ε ρ τ ψ υ ι ο π daszia pszili
  α σ δ φ γ η ϑ κ λ dialitika oxia
  ζ ξ χ ς β ν μ , . ;
  A görögnél a dögbillek sima billentyűk, Ctrl nélkül. Önállóan az ékezetek önálló alakjait adják; a dialitika billentyűje az ano teleiát, a makroné pedig a keraiát, Shifttel az alsót. Dögbillként Shift-makron = vrachy. A Shift-V és Shift-J nem ad karaktert.

Van továbbá egy garnitúra speciális karakterünk, amik kiosztástól függetlenül elérhetők, ezeket érdemes felvenni más nyelvű billentyűzeteknél is.
  Win gombbal:
  - ° (fokjel)
  = ©
  \ §
  [ +
  ] – (gondolatjel)
  ; _ (aláhúzásjel)
  ' " (ASCII idézőjel)
  , „
  . ”
  / …
  Shift-Winnel:
  1 ¡
  = &
  [ #
  ] $
  / ¿

Ctrl-lal:
  [ [
  ] ]
  , <
  . >

S végül a dögbillek. Ctrl-lal jön mindegyik, ezt külön nem is mondom, a teljes készlet:
  ' vessző, ć ǵ ḱ ĺ ḿ stb., összesen vagy százhúsz karakter, hiszen a TESZ-nek nagyon bőséges készlete van.
  - fordított vessző, à è ỳ, kilencven darab.
  T vízszintes vonal, ā ē ȳ, kereken száz.
  ; hacsek, č š ž, ötven darab.
  A kalap, â ĉ ĵ, közel hetven darab.
  P felső pont, ċ ġ ż, nyolcvan.
  L alsó pont, ạ ẹ ḳ, nyolcvan.
  D umlaut, ä ö ẅ, nyolcvan.
  S tilde, ã ñ ỹ, negyven.
  U csónak, ă ğ ŭ, hatvan.
  M fordított csónak, ȃ ȇ ȓ, húsz.
  O karika, å ů, húsz.
  Q karika alul, ḁ, húsz.
  J farkinca, ą ç ļ, ötven.
  W dupla vessző, ȁ ȑ ű, közel húsz.
  K áthúzás, đ ł ø, húsz.
  E kis e alakú ékezet (o, u, v, w fölött használták a középkorban), tíz.
  1 hacsek alul (lefelé mutató hegyes), harminc.
  2 kalap alul, ḓ ḙ, negyven.
  3 balra mutató hegyes alul, húsz.
  4 jobbra mutató hegyes alul, harminc.
  5 vidám, ḫ, negyven.
  6 szomorú (lefelé mutató ívelt alul), közel húsz.
  7 index (felső vagy alsó indexbe tett betűk), negyven.
  8 cirill (külön dögbill a fonetikai céllal használt э л ъ ь betűk számára).
  9 egyéb ékezetek: aláhúzás, alsó tilde, alsó umlaut, aposztróf stb., negyven.
  \ fejreállított betű, ǝ ɐ ɔ, harminc.
  / egyéb speciális módosítások, hetven. Itt van például az f betűből a ſ, az s-ből a ß, az a-ból az æ stb.
  Végül pedig a Ctrl-= az ismétlőgomb: az esetleg három-négy gombnyomással előállított utolsó karaktert még egyszer kiteszi. Nagyon praktikus, ha ugyanaz a betű többször van a szóban, mert például hosszú mássalhangzó, vagy magánhangzó, ami végigvonul a szón, hiszen a rokon nyelvekben is megvan a hangrendi egyeztetés. Ráadásul nekem van egy betűcserélő gombom is, a Tab (nem része ennek a billentyűzetnek, az Abbyyhez való külön makrócsomag tartalmazza), ez felcseréli a kurzor előtt levő két betűt. Így ha egy olyan szóra van szükségem, mint medve, de mondjuk az e-k helyén két egyforma, nagyon bonyolult betű, akkor leütöm az m-et, elkészítem a bonyolult betűt, aztán nyomok egy ismétlést: most mee van odaírva, két bonyolult e betűvel. Lenyomom a d-t és meedet kapok, lenyomom a Tabot, lesz belőle mede, lenyomom a v-t, lesz medev, megint a Tabot, és kész a medve. Mindez azért, mert az ismétlőgomb nem tesz különbséget bonyolult és egyszerű betű között (megtehetné, de ez nem volt nekem fontos), tehát ha a medv után nyomnám le, akkor a v-t ismételné.
  Ezt a rakosgatósdit ritkán szoktam csinálni, főleg ha a bonyolult betű példányai messzebb vannak egymástól; olyankor inkább összerakom a betű mindegyik példányát újra. Nem tart soká.

Lássuk mármost a dögbillek programját konkrétan. Legyen a példa a cirillesítő, ami csak négy betűt tartalmaz.

$^8::
k:=""
switchtwo("0065", "044d") ; e е
switchtwo("006c", "043b") ; l л
switchtwo("0071", "044a") ; q ъ
switchtwo("0079", "044c") ; y ь
if(k<>"")
{
  send {bs}
  uni(k)
}

Ez az egész. A switchtwo dolga eldönteni, hogy mit adjunk vissza. Ha az előző karakter e betű volt, akkor egy cirill e-t tesz a k változóba; ha l volt, akkor л-et, és így tovább. Ha k nem üres, vagyis a switchtwo talált valamit, akkor kiküldünk egy backspace-t, ezzel töröljük az eredeti betűt, és kiküldjük az új karaktert.
  Ha a Ctrl-8-at úgy találtuk megnyomni, hogy a felsorolt négy cirill betű valamelyike volt előzőleg kiküldve (kézzel megnyomva vagy egy előző Ctrl-8 által előállítva, ez mindegy), akkor a switchtwo azt is észreveszi, és kiküldi helyette a megfelelő latin betűt.

Magát a billentyűzetprogramot nem tervezem publikálni. Annyira speciális, egyedi feladatra készült, hogy más felhasználásra nemigen alkalmas. De az itt leírt módszertani ismertetés segítségével az olvasó már elkészítheti a sajátját – vagy megkérhet engem, hogy csináljak neki. Szívesen. Imádok ilyeneket bütykölni.

»»»»»»