@t[Így készül a billentyűzet]~~META:date created = 2011-08-29~~ Ú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 [[meg_szoftvertamogatasabb|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. [[http://autohotkey.com|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 //prevchar//ban, 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 failed``nErrorLevel = %ErrorLevel%``n%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 [[a_windowsom_talcaja|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 //send//del, mert különben egyes programok nem reagálnak rájuk mint gyorsbillentyűkre. Emiatt viszont a //prevchar//t 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 //caps//ot é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 //uni//val 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 pedigif(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. @CHAR[5c] 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 //meed//et 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. @blogf[ékezetes_betű döglött_billentyű függvény cirill görög számtech billentyűzet programozás AutoHotkey programjaim TESZ]