- Offizieller Beitrag
Das Thema von rollod hatte mich an meine frühjugendlichen Erfahrungen mit dem Morsen erinnert (schon weit über 40 Jahre her). Also habe ich mich mal rangesetzt und eine UDF erstellt, die geeignet ist um sowohl das Geben als auch das Hören zu trainieren. Frei nach Hans Grade heißt es beim Morsen: "Lerne Hören, dann kannst du geben." - Ich weiß noch, wie wir die ersten Monate immer nur die Kopfhörer auf hatten und mit dem Bleistift dann die empfangenen Dit's und Dah's notiert haben. Dabei wollten wir doch endlich mal die Morsetaste bedienen.
Übrigens: Die Computermaus ist nicht optimal geeignet zum Morsen. Beim Geben soll der Geber sich vor (und nicht unter) der Hand befinden. Ist aber sicher nur für Hardcorefunker von entscheidender Bedeutung. In der UDF wird aber als Gebertaste "rechte CTRL-Taste" verwendet.
• Mit der UDF kann ich eine Gui zur Entgegennahme der Morsezeichen registrieren. Nur wenn diese aktiv ist, wird R-CTRL ausgewertet.
• Es lassen sich Ctrl (Input/Edit) zum Anzeigen der erkannten Zeichen und zum Anzeigen des aus den Zeichen dekodierten Textes registrieren.
• Weiterhin kann ein Ctrl (Edit empfohlen) als Log registriert werden. Hier werden die erkannten DOWN-Time und UP-Time der Gebertaste angezeigt. Überschreitet die UP-Time 7 Basiseinheiten (> Wortpause), wird [UP IDLE] angezeigt.
• Text kann in Morsezeichen konvertiert werden.
• Eine Zeichenfolge von Morsezeichen kann akustisch (Beep-Funktion) ausgegeben werden, wahlweise mit zusätzlicher Konsolenausgabe jedes dekodierten Zeichens. Die Basiseinheit bei Beep-Ausgabe ist auf 120 ms festgelegt. Das ist relativ lang, aber wenn man das verkürzt, kommt die Audioausgabe nicht mehr mit.
Natürlich wäre es schick, wenn man beim Geben auch einen Beep hören könnte. Aber das übersteigt die Fähigkeiten eines PC. Beep ist eine Funktion mit definierter Zeit, somit könnte ich erst mit abgeschlossenem Tastendruck die DOWN-Time für Beep verwenden, hätte also immer ein Delay in der Länge des zuletzt gegebenen Zeichens. Wie ein Film mit schlecht synchronisierter Tonspur.
Und nacheinander Beeps mit kurzem Intervall auszuführen solange die Taste gedrückt ist, ist nur solange eine gute Idee, bis man das Ergebnis zum ersten mal gehört hat.
In der UDF setze ich die Keyboardeinstellungen auf max. Delay und min. Wiederholfrequenz (wird beim Beenden zurückgesetzt). Das ist nicht zwingend erforderlich, reduziert u.U. aber die Aufrufhäufigkeit der Callback-Funktion.
Ich habe ausgiebig kommentiert, ein Blick in den Code sollte somit eventuelle Fragen schon weitestgehend klären.
Übrigens ist es gar nicht so einfach mehrere Dah hintereinander einzugeben. "3-Units-Down/1-Unit-Up/3-Units-Down/1-Unit-Up/3-Units-Down/Up" - da braucht man schon ein gutes Zeitgefühl. Anfangs wird man meist die 1-Unit Sequenzpause überschreiten und schon wird die Eingabe als Zeichenpause gewertet und statt dem gewollten O steht da TTT.
;-- TIME_STAMP 2021-01-04 13:58:50 v 0.1
#include-once
#include <GuiEdit.au3>
#include <WinAPIConstants.au3>
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
Opt('MustDeclareVars', 1)
#cs
- Es wird eine ganz bestimmte feste Zeiteinheit gewählt.
- Die Länge eines Punktes (Dit) dauert eine Zeiteinheit.
- Die Länge eines Striches (Dah) dauert drei Zeiteinheiten.
- Die Punkte bzw. Striche, die jeweils ein Zeichen darstellen, werden durch eine Pause von einer Zeiteinheit getrennt.
- Die Pause zwischen den Darstellungen zweier verschiedener Zeichen beträgt drei Zeiteinheiten.
- Die Pause zwischen Zeichensequenzen, die zwei verschiedene Wörter darstellen, beträgt 7 Zeiteinheiten.
A B C D E F G H I J K L M
.- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. --
N O P Q R S T U V W X Y Z
-. --- .--. --.- .-. ... - ..- ...- .-- -..- -.-- --..
Ä Ö Ü ß ; Umlaute, "ß" und ";" sind nicht ITU-konform
.-.- ---. ..-- ...--.. -.-.-.
1 2 3 4 5 6 7 8 9 0
.---- ..--- ...-- ....- ..... -.... --... ---.. ----. -----
Full stop (period) ............................................................................. [.] .−.−.−
Comma .......................................................................................... [,] −−..−−
Colon or division sign ......................................................................... [:] −−−...
Question mark (note of interrogation or request for repetition of a transmission not understood) [?] ..−−..
Apostrophe ..................................................................................... [’] .−−−−.
Hyphen or dash or subtraction sign ............................................................. [–] −....−
Fraction bar or division sign .................................................................. [/] −..−.
Left-hand bracket (parenthesis) ................................................................ [(] −.−−.
Right-hand bracket (parenthesis) ............................................................... [)] −.−−.−
Inverted commas (quotation marks) (before and after the words) ................................. ["] .−..−.
Double hyphen .................................................................................. [=] −...−
Understood ..................................................................................... VE ...−.
Error (eight dots) ............................................................................. HH ........
Cross or addition sign ......................................................................... [+] .−.−.
Invitation to transmit ......................................................................... K −.− (als Wort)
Wait ........................................................................................... AS .−...
End of work .................................................................................... SK ...−.−
Starting signal (to precede every transmission)................................................. CT −.−.−
Multiplication sign ............................................................................ X −..− (als Wort)
Commercial at .................................................................................. [@] .––.-.
#ce
OnAutoItExitRegister('OnMorseExit')
Global $g_MorseUnit = 80 ; Dauer einer Einheit in ms
Global $g_MorseBeepUnit = 120 ; Dauer einer Einheit in ms für die Audioausgabe - Langsamer ist nicht sinnvoll, da kommt die Ausgabe nicht hinterher
Global $g_MorseF = 2500 ; Frequenz in Hz (Audioausgabe)
Global $g_MorseCharCB = ' ' ; Symbol für Zeichenpause
Global $g_MorseCharWB = ' ' ; Symbol für Wortpause (darf nicht dasselbe Zeichen, wie Zeichenpause sein!)
Global $g_hKeyProc = Null, $g_hHook
Global $g_bMorseKeyIsDown = False ; Zustand Morsetaste (Up/Down)
Global $g_MorseKeyUpTimer ; Timer für Messung: Morsetaste nicht gedrückt
Global $g_MorseKeyDownTimer ; Timer für Messung: Morsetaste gedrückt
Global $g_MorseKeyTimeUp ; gemessene Zeit: Morsetaste nicht gedrückt
Global $g_MorseKeyTimeDown ; gemessene Zeit: Morsetaste gedrückt
Global $g_bMorseIDLE = True ; Wenn keine neue Eingabe erfolgt, würde jede Pause der Länge 7 als Sequenz "Wortpause" gewertet.
; Das kann hiermit abgefangen werden. (Es dürfen keine zwei Pausen aufeinander folgen)
; Da beim Start derselbe Zustand, wie bei Mehrfachpause besteht: Vorbelegung mit "True"
Global $g_MorseStr = '' ; zum Verketten der Sequenzen
Global $g_MorseSeq = '' ; Sequenz (Dit/Dah)
Global $aMorse[][] = [ _
['A','.-'],['B','-...'],['C','-.-.'],['D','-..'],['E','.'],['F','..-.'],['G','--.'],['H','....'],['I','..'],['J','.---'],['K','-.-'],['L','.-..'],['M','--'], _
['N','-.'],['O','---'],['P','.--.'],['Q','--.-'],['R','.-.'],['S','...'],['T','-'],['U','..-'],['V','...-'],['W','.--'],['X','-..-'],['Y','-.--'],['Z','--..'], _
['1','.----'],['2','..---'],['3','...--'],['4','....-'],['5','.....'],['6','-....'],['7','--...'],['8','---..'],['9','----.'],['0','-----'], _
['Ä','.-.-'],['Ö','---.'],['Ü','..--'],['ß','...--..'],[';','-.-.-.'], _
['.','.-.-.-'],[',','--.--'],[':','---...'],['?','..--..'],["'",'.----.'],['-','-....-'],['/','-..-.'],['(','−.−−.'],[')','−.−−.−'],['"','.-..-.'],['=','-...-'], _
['VE','...-.'],['HH','........'],['+','.-.-.'],['AS','.-...'],['SK','...-.-'],['CT','-.-.-'],['@','.--.-.']]
Global $oMorseSend = ObjCreate("Scripting.Dictionary")
Global $oMorseRecv = ObjCreate("Scripting.Dictionary")
For $i = 0 To UBound($aMorse) -1
$oMorseSend.Add($aMorse[$i][0],$aMorse[$i][1])
$oMorseRecv.Add($aMorse[$i][1],$aMorse[$i][0])
Next
Global $g_MorseGui ; GUI, die die Morsesignale empfängt
Global $g_MorseRawIn = Null ; [optional] Ctrl, in das die erkannten Morsesymbole eingetragen werden
Global $g_MorseDecIn = Null ; [optional] Ctrl, in das die aus den erkannten Morsesymbolen dekodierten Textzeichen eingetragen werden
Global $g_MorseLog = Null ; [optional] Ctrl, in das die Zeiten (DOWN-Time, UP-Time) protokolliert werden
Global $g_MorseRawBreakCount ; [optional] für mehrzeiliges Ctrl, Anzahl der Zeichen, nach denen ein Zeilenumbruch eingefügt wird
Global $g_MorseDecBreakCount ; [optional] für mehrzeiliges Ctrl, Anzahl der Zeichen, nach denen ein Zeilenumbruch eingefügt wird
Global $g_MorseLogCount ; [optional] für mehrzeiliges Ctrl, Anzahl der Aufrufe, nach denen ein Zeilenumbruch eingefügt wird
Global $g_tKBSettings = _KeyboardSetting() ; aktuelle Keyboardeinstellungen beim Start speichern
Func OnMorseExit()
If $g_hKeyProc <> Null Then
_WinAPI_UnhookWindowsHookEx($g_hHook)
DllCallbackFree($g_hKeyProc)
_KeyboardSetting($g_tKBSettings.Delay, $g_tKBSettings.Speed) ; nicht zwingend erforderlich
EndIf
EndFunc ;==>OnMorseExit
; Gui für Morse-UDF registrieren, Keyboard-Hook aktivieren, Adlib-Funktion zur Morse-Sequenz-Verarbeitung starten
Func _Morse_RegisterGui($_hWnd)
$g_MorseGui = $_hWnd
If $g_hKeyProc = Null Then
_KeyboardSetting(3, 0) ; Delay auf 1s und Wiederholrate auf 2 Zeichen/s (nicht zwingend erforderlich)
$g_hKeyProc = DllCallbackRegister("_Morse_KeyProc", "long", "int;wparam;lparam")
$g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($g_hKeyProc), _WinAPI_GetModuleHandle(0))
AdlibRegister('_Morse_BreakTime', 20)
EndIf
EndFunc ;==>_Morse_RegisterGui
; GuiCtrl-ID registrieren für Eintragen des Morsecodes
; $_iCharBreak: optional für mehrzeiliges Ctrl, Anzahl der Zeichen, nach denen ein Zeilenumbruch eingefügt wird
Func _Morse_RegisterRawIn($_ID, $_iCharBreak=0)
$g_MorseRawIn = $_ID
$g_MorseRawBreakCount = $_iCharBreak
EndFunc ;==>_Morse_RegisterRawIn
; GuiCtrl-ID registrieren für Eintragen des dekodierten Morsecodes
; $_iCharBreak: optional für mehrzeiliges Ctrl, Anzahl der Zeichen, nach denen ein Zeilenumbruch eingefügt wird
Func _Morse_RegisterDecodeIn($_ID, $_iCharBreak=0)
$g_MorseDecIn = $_ID
$g_MorseDecBreakCount = $_iCharBreak
EndFunc ;==>_Morse_RegisterDecodeIn
; GuiCtrl-ID registrieren für Loggen der UP/DOWN Zeiten, je UP und je DOWN ein Funktionsaufruf
; $_iCallBreak: optional für mehrzeiliges Ctrl, Anzahl der Aufrufe, nach denen ein Zeilenumbruch eingefügt wird
Func _Morse_RegisterLog($_ID, $_iCallBreak=0)
$g_MorseLog = $_ID
$g_MorseLogCount = $_iCallBreak
EndFunc ;==>_Morse_RegisterLog
; Morsefrequenz definieren für Audioausgabe
Func _Morse_SetFrequency($_i=-1) ; Standard(-1): 2500 Hz
$g_MorseUnit = ($_i < 0 ? 2500 : $_i)
Return $g_MorseUnit
EndFunc ;==>_Morse_SetFrequency
; Basislänge der Morseeinheit definieren
Func _Morse_SetUnit($_i=-1) ; Standard(-1): min = 30 ms
$g_MorseUnit = ($_i < 0 ? 30 : ($_i < 30 ? 30 : $_i))
Return $g_MorseUnit
EndFunc ;==>_Morse_SetUnit
; Trennzeichen im Morsecode nach Zeichenende definieren
Func _Morse_SetCharacterCharBreak($_s='') ; Standard(''): ' '
$g_MorseCharCB = ($_s = '' ? ' ' : $_s)
Return $g_MorseCharCB
EndFunc ;==>_Morse_SetCharacterCharBreak
; Trennzeichen im Morsecode nach Wortende definieren
Func _Morse_SetCharacterWordBreak($_s='') ; Standard(''): ' '
$g_MorseCharWB = ($_s = '' ? ' ' : $_s)
Return $g_MorseCharWB
EndFunc ;==>_Morse_SetCharacterWordBreak
; konvertiert einen Text in geschriebene Morsezeichen
; Zeichenende wird mit $g_MorseCharCB und Wortende mit $g_MorseCharWB markiert
Func _Morse_EnCrypt($_s)
Local $sMorse
$_s = StringUpper($_s)
Local $aSplit = StringSplit($_s, '')
For $i = 1 To $aSplit[0]
If $aSplit[$i] = ' ' Then ; Wortende
$sMorse = StringTrimRight($sMorse,1) & $g_MorseCharWB
ContinueLoop
EndIf
If $oMorseSend.Exists($aSplit[$i]) Then
$sMorse &= $oMorseSend.Item($aSplit[$i]) & $g_MorseCharCB
Else
$sMorse &= $aSplit[$i] & $g_MorseCharCB
EndIf
Next
Return StringTrimRight($sMorse, 1)
EndFunc ;==>_Morse_EnCrypt
; konvertiert einen Satz geschriebener Morsezeichen in Text
Func _Morse_DeCrypt($_p)
Local $sPhrase
Local $aWords = StringSplit($_p, $g_MorseCharWB, 1)
For $i = 1 To $aWords[0]
$sPhrase &= __Morse_DeCryptWord($aWords[$i]) & ' '
Next
Return $sPhrase
EndFunc ;==>_Morse_DeCrypt
; konvertiert eine Wortsequenz von Morsezeichen in Text
Func __Morse_DeCryptWord($_w)
Local $sWord, $aChars = StringSplit($_w, $g_MorseCharCB, 1)
For $i = 1 To $aChars[0]
$sWord &= __Morse_DeCryptChar($aChars[$i])
Next
Return $sWord
EndFunc ;==>__Morse_DeCryptWord
; konvertiert eine Zeichensequenz von Morsezeichen in Text
Func __Morse_DeCryptChar($_c)
If $oMorseRecv.Exists($_c) Then
Return $oMorseRecv.Item($_c)
Else
Return '[' & $_c & ']' ; unbekanntes Zeichen, wird wie erkannt zurückgegeben
EndIf
EndFunc ;==>__Morse_DeCryptChar
; fügt erkannte Morsesequenz in Ctrl ein (sofern registriert)
Func __Morse_AddRaw($_s)
If $g_MorseRawIn = Null Then Return
Local Static $h_RawIn = IsHWnd($g_MorseRawIn) ? $g_MorseRawIn : GUICtrlGetHandle($g_MorseRawIn)
Local Static $iCount = 0
If $g_MorseRawBreakCount > 0 Then
$iCount += 1
If $iCount = $g_MorseRawBreakCount Then
$_s &= @CRLF
$iCount = 0
EndIf
EndIf
_GUICtrlEdit_AppendText($h_RawIn, $_s)
EndFunc ;==>__Morse_AddRaw
; fügt aus Morsesequenz dekodiertes Zeichen in Ctrl ein (sofern registriert)
Func __Morse_AddDec($_s)
If $g_MorseDecIn = Null Then Return
Local Static $h_DecIn = IsHWnd($g_MorseDecIn) ? $g_MorseDecIn : GUICtrlGetHandle($g_MorseDecIn)
Local Static $iCount = 0
Local $sCRLF = ''
If $g_MorseDecBreakCount > 0 Then
$iCount += 1
If $iCount = $g_MorseDecBreakCount Then
$sCRLF = @CRLF
$iCount = 0
EndIf
EndIf
If ($_s = $g_MorseCharCB) Or ($_s = $g_MorseCharWB) Or ($_s = ' ') Then
_GUICtrlEdit_AppendText($h_DecIn, $_s & $sCRLF)
Else
_GUICtrlEdit_AppendText($h_DecIn, __Morse_DeCryptChar($_s) & $sCRLF)
EndIf
EndFunc ;==>__Morse_AddDec
; fügt DOWN/UP-Time in Ctrl ein (sofern registriert)
Func __Morse_AddLog($_s)
If $g_MorseLog = Null Then Return
Local Static $iCount = 0
Local Static $h_Log = IsHWnd($g_MorseLog) ? $g_MorseLog : GUICtrlGetHandle($g_MorseLog)
If $g_MorseLogCount > 0 Then
$iCount += 1
If $iCount = $g_MorseLogCount Then ; $g_MorseLogCount/2 Tastendrücke (Down und Up) nebeneinander, dann neue Zeile
$_s &= @CRLF
$iCount = 0
EndIf
EndIf
_GUICtrlEdit_AppendText($h_Log, $_s)
EndFunc ;==>__Morse_AddLog
; Akustische Wiedergabe eines mit "_Morse_EnCrypt" codierten Textes
Func _Morse_Beep($_sMorse, $_bConsoleOut=False)
Local Static $oLen = ObjCreate('Scripting.Dictionary')
Local Static $bAdd = False
If $bAdd = False Then
$bAdd = True
$oLen.Add('.', 1)
$oLen.Add('-', 3)
$oLen.Add('°', 3-1) ; Da nach jedem '.' oder '-' IMMER eine Pause von 1 folgt, ...
$oLen.Add('^', 7-1) ; ... wird dieser Wert bei Zeichen- und Wortende abgezogen.
EndIf
$_sMorse = StringReplace($_sMorse, $g_MorseCharWB, '^') ; Zeichen- u. Wortende durch Platzhalter mit 1 Zeichen Länge ersetzen ...
$_sMorse = StringReplace($_sMorse, $g_MorseCharCB, '°') ; ... um zeichenweises Verarbeiten zu gewährleisten
Local $aSplit = StringSplit($_sMorse, ''), $sCh = ''
For $i = 1 To $aSplit[0]
Switch $aSplit[$i]
Case '.', '-'
Beep($g_MorseF, $oLen.Item($aSplit[$i]) * $g_MorseBeepUnit) ; Beep in definierter Frequenz und Länge des Dit/Dah
Sleep($g_MorseBeepUnit) ; Pause von 1 Einheit, die nach jedem Dit/Dah folgt
If $_bConsoleOut Then
$sCh &= $aSplit[$i]
If $i = $aSplit[0] Then ConsoleWrite($oMorseRecv.Item($sCh) & @CRLF) ; letztes Zeichen erreicht -> Ausgabe erkanntes Zeichen
EndIf
Case '°', '^'
Sleep($oLen.Item($aSplit[$i]) * $g_MorseBeepUnit) ; Zeichen-/Wortpause in der entsprechenden Länge
If $_bConsoleOut Then
ConsoleWrite($oMorseRecv.Item($sCh)) ; bei Zeichen-/Wortpause das zuletzt erkannte Zeichen ausgeben
$sCh = '' ; Zeichen-Variable zurücksetzen
If $aSplit[$i] = '^' Then ConsoleWrite(' ') ; Wortpause: Leerzeichen als Worttrenner (Text) ausgeben
EndIf
EndSwitch
Next
EndFunc ;==>_Morse_Beep
;==============================================================================
; Callback-Function: wird erst gestartet, wenn dafür eine Gui registriert ist
;==============================================================================
Func _Morse_KeyProc($nCode, $wParam, $lParam)
Local Static $iUnit1_Max = 1.4 * $g_MorseUnit ; max. Dit-Länge und Pausenlänge zwischen zwei aufeinanderfolgenden Dit oder Dah
Local Static $iUnit3_Min = 0.6 * 3*$g_MorseUnit ; min. und
Local Static $iUnit3_Max = 1.4 * 3*$g_MorseUnit ; max Dah-Länge und Pausenlänge zwischen zwei aufeinanderfolgenden Zeichen
Local Static $bOnce = False
If ($nCode < 0) Or (Not BitAND(WinGetState($g_MorseGui), 8)) Then _ ; nicht verarbeiten, wenn registrierte Gui inaktiv
Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
Local $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
Local $vkCode = DllStructGetData($tKEYHOOKS, "vkCode")
If $vkCode <> 163 Then Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam) ; nur R-CTRL auswerten
If $wParam = $WM_KEYDOWN Then
If Not $bOnce Then ; bei erstmaligem Aufruf der Funktion Ausgabe der aktuellen Parameter in das Log
$bOnce = True
__Morse_AddLog(StringFormat('[DIT: <= %i ms, DAH: %i ms bis %i ms, SEQ: < %i ms, CHAR: %i ms bis %i ms]\n', _
$iUnit1_Max, $iUnit3_Min, $iUnit3_Max, $iUnit1_Max, $iUnit3_Min, $iUnit3_Max))
EndIf
$g_bMorseKeyIsDown = True
$g_MorseKeyDownTimer = TimerInit() ; Timer für DOWN-Time starten
$g_MorseKeyTimeUp = TimerDiff($g_MorseKeyUpTimer) ; UP-Time (Pausenzeit) messen und auswerten
__Morse_AddLog($g_bMorseIDLE ? '[UP IDLE]' : (StringFormat('[UP %03i] ', $g_MorseKeyTimeUp)))
If $g_bMorseIDLE Then ; IDLE-Mode, beim Start oder wenn Eingabepause > 7 Units
$g_bMorseIDLE = False ; IDLE-Mode beendet
; falls letzte Eingabe noch nicht verarbeitet
If $g_MorseStr <> '' Then
__Morse_AddDec($g_MorseStr) ; erkanntes Zeichen (dekodiert) in Dekodiert-Ctrl ausgeben
__Morse_AddRaw($g_MorseCharCB) ; Zeichen für Zeichentrennung in Raw-Ctrl ausgeben
$g_MorseStr = '' ; Stringvariable zurücksetzen
EndIf
Else ; Eingabemodus, UP-Time < 7 Units
Select
Case $g_MorseKeyTimeUp > $iUnit3_Min And _ ; Zeichenpause, Sequenzen des Zeichens ...
$g_MorseKeyTimeUp < $iUnit3_Max ; ... dekodieren und ausgeben
If $g_MorseStr <> '' Then
__Morse_AddDec($g_MorseStr) ; erkanntes Zeichen (dekodiert) in Dekodiert-Ctrl ausgeben
__Morse_AddRaw($g_MorseCharCB) ; Zeichen für Zeichentrennung in Raw-Ctrl ausgeben
$g_MorseStr = '' ; Stringvariable zurücksetzen
EndIf
Case $g_MorseKeyTimeUp < $iUnit1_Max ; Sequenzpause
; keine gesonderte Auswertung erforderlich,
EndSelect
EndIf
ElseIf $wParam = $WM_KEYUP Then
$g_bMorseKeyIsDown = False
$g_MorseKeyUpTimer = TimerInit() ; Timer für UP-Time starten
$g_MorseKeyTimeDown = TimerDiff($g_MorseKeyDownTimer) ; DOWN-Time (Taste gedrückt Zeit) messen und auswerten
__Morse_AddLog(StringFormat('[DOWN %03i] ', $g_MorseKeyTimeDown))
$g_MorseSeq = ''
Select
Case $g_MorseKeyTimeDown > $iUnit3_Max
$g_MorseSeq = '>' ; Tastendruck länger als max. Zeitraum für längstes Zeichen
Case $g_MorseKeyTimeDown > $iUnit3_Min And $g_MorseKeyTimeDown < $iUnit3_Max
$g_MorseSeq = '-' ; Dah
Case $g_MorseKeyTimeDown < $iUnit1_Max ; alles kürzer max. wird immer als Dit gewertet
$g_MorseSeq = '.' ; Dit
EndSelect
$g_MorseStr &= $g_MorseSeq ; Sequenz verketten
__Morse_AddRaw($g_MorseSeq) ; Sequenz in Raw-Ctrl ausgeben
EndIf
Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
EndFunc ;==>_Morse_KeyProc
; Auswertung der Pausen zwischen R-CTRL bei aktiver (registrierter) GUI
Func _Morse_BreakTime()
Local Static $iUnit7_Min = 7*$g_MorseUnit
If $g_bMorseKeyIsDown Then Return ; nur UP-Zyklus (Pause) auswerten
AdlibUnRegister('_Morse_BreakTime')
If TimerDiff($g_MorseKeyUpTimer) > $iUnit7_Min Then
If Not $g_bMorseIDLE Then ; Wortpause, kein IDLE
If $g_MorseStr <> '' Then ; falls letzte Eingabe noch nicht verarbeitet
__Morse_AddDec($g_MorseStr) ; erkanntes Zeichen (dekodiert) in Dekodiert-Ctrl ausgeben
$g_MorseStr = ''
EndIf
__Morse_AddRaw($g_MorseCharWB) ; Zeichen für Worttrennung in Raw-Ctrl ausgeben
__Morse_AddDec(' ') ; Leerzeichen für Worttrennung in Dekodiert-Ctrl ausgeben
$g_bMorseIDLE = True ; Beginn IDLE
EndIf
EndIf
AdlibRegister('_Morse_BreakTime', 20)
EndFunc ;==>_Morse_BreakTime
; #FUNCTION# ====================================================================================================================
; Name ..........: _KeyboardSetting
; Description ...: Abfragen (Standard "-1") oder Setzen der Keyboardeinstellungen in der Registry
; Parameters ....: $_iDelay (Default = -1) Verzögerung bis bei gedrückter Taste die Zeichenwiederholung aktiviert wird
; gültige Werte: 0 = 250ms, 1 = 500ms, 2 = 750ms, 3 = 1s
; ...............: $_iSpeed (Default = -1) Geschwindigkeit, mit der bei aktivierter Zeichenwiederholung das Zeichen wiederholt wird
; gültige Werte: "0" (2 Zeichen je Sekunde) bis "31" (30 Zeichen je Sekunde)
; ...............: $_iNumlockOnAtStartup (Default = -1) Numlock-Taste ist beim Start an oder aus
; gültige Werte: "0" = Aus, "2" = An
; Der Wert für Numlock wird beim Abmelden des Users mit dem dann aktuellen Zustand der Taste überschrieben.
; Return values .: Struktur mit den aktuellen Keyboardeinstellungen: ".Delay", ".Speed", ".NumlockOn"
; Author ........: BugFix
; ===============================================================================================================================
Func _KeyboardSetting($_iDelay=-1, $_iSpeed=-1, $_iNumlockOnAtStartup=-1)
Local $iDelay = RegRead("HKEY_CURRENT_USER\Control Panel\Keyboard", "KeyboardDelay")
Local $iSpeed = RegRead("HKEY_CURRENT_USER\Control Panel\Keyboard", "KeyboardSpeed")
Local $iInitIndicator = RegRead("HKEY_CURRENT_USER\Control Panel\Keyboard", "InitialKeyboardIndicators")
Local $tKeyboard = DllStructCreate("struct;int Delay;int Speed;int NumlockOn;endstruct")
; alle Parameter "-1" -> nur Auslesen
If $_iDelay = -1 And $_iSpeed = -1 And $_iNumlockOnAtStartup = -1 Then
$tKeyboard.Delay = $iDelay
$tKeyboard.Speed = $iSpeed
$tKeyboard.NumlockOn = $iInitIndicator
Return $tKeyboard
EndIf
If $_iDelay <> -1 Then
$_iDelay = ($_iDelay < 0 ? 0 : ($_iDelay > 3 ? 3 : $_iDelay))
RegWrite("HKEY_CURRENT_USER\Control Panel\Keyboard", "KeyboardDelay", "REG_SZ", $_iDelay)
$tKeyboard.Delay = RegRead("HKEY_CURRENT_USER\Control Panel\Keyboard", "KeyboardDelay")
Else
$tKeyboard.Delay = $iDelay
EndIf
If $_iSpeed <> -1 Then
$_iSpeed = ($_iSpeed < 0 ? 0 : ($_iSpeed > 31 ? 31 : $_iSpeed))
RegWrite("HKEY_CURRENT_USER\Control Panel\Keyboard", "KeyboardSpeed", "REG_SZ", $_iSpeed)
$tKeyboard.Speed = RegRead("HKEY_CURRENT_USER\Control Panel\Keyboard", "KeyboardSpeed")
Else
$tKeyboard.Speed = $iSpeed
EndIf
If $_iNumlockOnAtStartup <> -1 Then
$_iNumlockOnAtStartup = ($_iNumlockOnAtStartup < 0 ? 0 : ($_iNumlockOnAtStartup = 2 ? 2 : 0))
RegWrite("HKEY_CURRENT_USER\Control Panel\Keyboard", "InitialKeyboardIndicators", "REG_SZ", $_iNumlockOnAtStartup)
$tKeyboard.NumlockOn = RegRead("HKEY_CURRENT_USER\Control Panel\Keyboard", "InitialKeyboardIndicators")
Else
$tKeyboard.NumlockOn = $iInitIndicator
EndIf
Return $tKeyboard
EndFunc ;==>_KeyboardSetting
Alles anzeigen
;-- TIME_STAMP 2021-01-04 13:59:25 v 0.1
Opt('MustDeclareVars', 1)
#include "Morse.au3"
_Example_1()
_Example_2()
Func _Example_1()
_Morse_SetUnit(100) ; Basis-Einheit der Morsesequenzen festlegen (ms)
Global $g_hGui = GUICreate('Morsen', 700, 400)
_Morse_RegisterGui($g_hGui) ; Gui registrieren, nur wenn diese Gui aktiv ist, wird R-CTRL als Morsetaste ausgewertet
GUICtrlCreateLabel('Erkannte Morsezeichen', 10, 15)
Global $inMorseReceived = GUICtrlCreateInput('', 10, 30, 680, 30, BitOR($ES_LEFT, $ES_AUTOHSCROLL, $ES_READONLY))
GUICtrlSetBkColor(-1, 0x000090)
GUICtrlSetColor(-1, 0xFFFF00)
GUICtrlSetFont(-1, 14, 600, Default, 'Consolas')
_Morse_RegisterRawIn($inMorseReceived) ; Input registrieren zur Ausgabe der erkannten Morsezeichen
GUICtrlCreateLabel('Entspricht Klartext', 10, 80)
Global $inTextReceived = GUICtrlCreateInput('', 10, 95, 680, 30, BitOR($ES_LEFT, $ES_AUTOHSCROLL, $ES_READONLY))
GUICtrlSetBkColor(-1, 0x000090)
GUICtrlSetColor(-1, 0xFFFF00)
GUICtrlSetFont(-1, 12)
_Morse_RegisterDecodeIn($inTextReceived) ; Input registrieren zur Ausgabe der aus den Morsezeichen dekodierten Textzeichen
GUICtrlCreateLabel('Erfasste Tastendruck- und Pausenlängen. MORSETASTE ist <STRG-RECHTS>.', 10, 145)
Global $edButtonReceived = GUICtrlCreateEdit('', 10, 160, 680, 200, BitOR($GUI_SS_DEFAULT_EDIT, $ES_READONLY))
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetFont(-1, 9, Default, Default, 'Consolas')
_Morse_RegisterLog($edButtonReceived, 8) ; Edit registrieren zum Loggen DOWN/UP-Zeiten, nach 8 Aufrufen (je 4 DOWN und UP) erfolgt Zeilenumbruch
; individuelle Darstellung der Zeichen- und Wortpausen im erkannten Morsecode ($inMorseReceived)
_Morse_SetCharacterCharBreak('°') ; Standard: ' '
_Morse_SetCharacterWordBreak('^') ; Standard: ' '
GUISetState()
While True
Switch GUIGetMsg()
Case -3
Exit
EndSwitch
WEnd
EndFunc
Func _Example_2()
Local $sEncrypt = _Morse_EnCrypt('AutoIt ist eine leicht zu lernende Programmiersprache. Besonders leicht lassen sich damit wiederkehrende Aufgaben unter Windows automatisieren.')
ConsoleWrite('als Morsecode:' & @CRLF & $sEncrypt & @CRLF)
_Morse_Beep($sEncrypt, True) ; Audioausgabe und zusätzlich Console
EndFunc
Alles anzeigen