Hallo liebes Forum,
Zuerst - schön dass AutoIt.de wieder da ist, habe heute morgen ja schon fast das weinen angefangen, als mir das Plesk-Panel aus dem Firefox entgegensprang :P.
Nun aber zu meinem Problem: Mich hat mal wieder die Langeweile gepackt, da hab ich meine alten PC Games durchgeguckt. Und siehe da: Black & White! Wie ich dieses Spiel geliebt habe
Also ein bisschen gespielt und dann doch keine Lust mehr gehabt (wie so oft bei mir ^^). Doch die Idee mit den Mausgesten hat mich irgendwie gepackt. Also hab ich gestern abend mal ein bisschen rumprobiert und habe das hier zusammengewurstelt:
Spoiler anzeigen
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <ArrayMore.au3>
#include <Array.au3>
#include <Misc.au3>
HotKeySet("{SPACE}","_stop")
HotKeySet("{TAB}","_recognizePath")
#region - GUI Create
GUICreate('Mausgesten Manager',120,155,-1,-1,"",$WS_EX_TOPMOST)
$Button_Go = GUICtrlCreateButton("Start",10,10,100,50)
$Button_Show = GUICtrlCreateButton("Show",10,70,100,50)
;~ $Combo_Geste = GUICtrlCreateCombo("",10,150,100,25)
GUISetState()
#endregion
$record = False
$drawn = False
$gesteTaste = "04"
Dim $Gesten[1] = ["Gesten"]
Dim $MousePath[1][2]
$MousePath[0][0] = "x"
$MousePath[0][1] = "y"
#region - GUI SelectLoop
While 1
$msg = GUIGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
Exit
Case $msg = $Button_Go
$record = True
Dim $MousePath[1][2]
$MousePath[0][0] = "x"
$MousePath[0][1] = "y"
_DrawPath()
Case $msg = $Button_Show
$MousePosNow = MouseGetPos()
For $i = 1 to UBound($MousePath)-1
MouseMove($MousePath[$i][0]+$MousePosNow[0],$MousePath[$i][1]+$MousePosNow[1],1)
Next
_ArrayDisplay($MousePath)
EndSelect
If _IsPressed($gesteTaste) Then _recognizePath()
WEnd
#endregion
Func _stop()
$record = false
EndFunc
Func _recognizePath()
If IsArray($MousePath) Then
If UBound($MousePath) > 1 Then
Local $tol = 150 ; Toleranz in Pixeln.
Local $pathtol = 0.66
Local $erfolg = False ; Toleranz bei vergleichen der Arrays
Do
Local $MouseStartPos = MouseGetPos()
Local $MousePosNow = MouseGetPos()
Local $S = 1
Dim $MouseDrawnPath[1][2]
$MouseDrawnPath[0][0] = "X"
$MouseDrawnPath[0][1] = "Y"
While _IsPressed($gesteTaste)
If $MousePosNow[0] <> MouseGetPos(0) OR $MousePosNow[1] <> MouseGetPos(1) Then
ToolTip("Ich passe auf...")
_Array2DAdd($MouseDrawnPath,MouseGetPos(0)-$MouseStartPos[0]&"|"&MouseGetPos(1)-$MouseStartPos[1])
$MousePosNow = MouseGetPos()
EndIf
WEnd
If UBound($MouseDrawnPath) > 1 Then
TrayTip("Ubounds","MousePath: "&UBound($MousePath)&@CRLF&"MouseDrawnPath: "&UBound($MouseDrawnPath),1)
If Ubound($MouseDrawnPath) > UBound($MousePath) Then
For $i = 1 to UBound($MousePath)-1
If Not (($MouseDrawnPath[$i][0] <= $MousePath[$i][0] + $tol) AND ($MouseDrawnPath[$i][0] >= $MousePath[$i][0] - $tol)) AND (($MouseDrawnPath[$i][1] <= $MousePath[$i][1] + $tol) AND ($MouseDrawnPath[$i][1] >= $MousePath[$i][1] - $tol)) Then
If $i/Ubound($MousePath) > $pathtol Then
MsgBox("","","Mausgeste zu "&Floor(($i/Ubound($MousePath))*100)&"% erkannt!"&@CRLF&" Dies wird als Erfolg gewertet.",5)
ExitLoop
Else
MsgBox("","","Mausgeste nicht erkannt! Fehler bei "&$i,1)
$drawn = True
ExitLoop
EndIf
Else
If $i = UBound($MousePath)-1 Then
MsgBox(64,"Success!!!","Gratulation ! Die mausgeste konnte erkannt werden.")
$drawn = True
ExitLoop
EndIf
EndIf
Next
ElseIf Ubound($MouseDrawnPath) <= UBound($MousePath) Then
For $i = 1 to UBound($MouseDrawnPath)-1
If Not (($MouseDrawnPath[$i][0] <= $MousePath[$i][0] + $tol) AND ($MouseDrawnPath[$i][0] >= $MousePath[$i][0] - $tol)) AND (($MouseDrawnPath[$i][1] <= $MousePath[$i][1] + $tol) AND ($MouseDrawnPath[$i][1] >= $MousePath[$i][1] - $tol)) Then
If $i/Ubound($MousePath) > $pathtol Then
MsgBox("","","Mausgeste zu "&Floor(($i/Ubound($MousePath))*100)&"% erkannt!"&@CRLF&" Dies wird als Erflog gewertet.",5)
ExitLoop
Else
MsgBox("","","Mausgeste nicht erkannt! Fehler bei "&$i,1)
$drawn = True
ExitLoop
EndIf
Else
If $i = UBound($MousePath)-1 Then
MsgBox(64,"Success!!!","Gratulation ! Die mausgeste konnte erkannt werden.")
$drawn = True
ExitLoop
EndIf
EndIf
Next
EndIf
EndIf
;~ If $drawn = True Then ExitLoop
ToolTip("")
Until Not _IsPressed($gesteTaste)
EndIf
EndIf
EndFunc
Func _DrawPath()
Local $MouseStartPos = MouseGetPos()
Local $MousePosNow = MouseGetPos()
While $record
If $MousePosNow[0] <> MouseGetPos(0) OR $MousePosNow[1] <> MouseGetPos(1) Then
_Array2DAdd($MousePath,MouseGetPos(0)-$MouseStartPos[0]&"|"&MouseGetPos(1)-$MouseStartPos[1])
$MousePosNow = MouseGetPos()
EndIf
WEnd
EndFunc
Leider funktioniert das ganze mehr schlecht als recht. Die Gesten müssen (fast) genauso gezeichnet werden wie sie aufgenommen wurden. Variable Größen oder zu starke Abweichungen von der orginalen Geste laufen darauf hinaus, dass die Geste nicht erkannt wird.
Ich habe das ganze bereits mit dem oben gezeigten Script probiert, sowie einer Version, die immer die Positionsänderung zur letzen Position aufzeichnet.
Spoiler anzeigen
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <ArrayMore.au3>
#include <Array.au3>
#include <Misc.au3>
HotKeySet("{SPACE}","_stop")
HotKeySet("{TAB}","_recognizePath")
#region - GUI Create
GUICreate('Mausgesten Manager',120,155,-1,-1,"",$WS_EX_TOPMOST)
$Button_Go = GUICtrlCreateButton("Start",10,10,100,50)
$Button_Show = GUICtrlCreateButton("Show",10,70,100,50)
;~ $Combo_Geste = GUICtrlCreateCombo("",10,150,100,25)
GUISetState()
#endregion
$record = False
$drawn = False
$gesteTaste = "04"
Dim $Gesten[1] = ["Gesten"]
Dim $MousePath[1][2]
$MousePath[0][0] = "x"
$MousePath[0][1] = "y"
#region - GUI SelectLoop
While 1
$msg = GUIGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
Exit
Case $msg = $Button_Go
$record = True
Dim $MousePath[1][2]
$MousePath[0][0] = "x"
$MousePath[0][1] = "y"
_DrawPath()
Case $msg = $Button_Show
$MousePosNow = MouseGetPos()
For $i = 1 to UBound($MousePath)-1
$MousePosNow = MouseGetPos()
MouseMove($MousePath[$i][0]+MouseGetPos(0),$MousePath[$i][1]+MouseGetPos(1),1)
Next
_ArrayDisplay($MousePath)
EndSelect
If _IsPressed($gesteTaste) Then _recognizePath()
WEnd
#endregion
Func _stop()
$record = false
EndFunc
Func _recognizePath()
If IsArray($MousePath) Then
If UBound($MousePath) > 1 Then
Local $tol = 150 ; Toleranz in Pixeln.
Local $erfolg = False
Local $pathtol = 0.66 ; Toleranz bei vergleichen der Arrays
While _IsPressed($gesteTaste)
Local $MouseStartPos = MouseGetPos()
Local $MousePosNow = MouseGetPos()
Local $S = 1
Dim $MouseDrawnPath[1][2]
$MouseDrawnPath[0][0] = "X"
$MouseDrawnPath[0][1] = "Y"
While _IsPressed($gesteTaste)
If $MousePosNow[0] <> MouseGetPos(0) OR $MousePosNow[1] <> MouseGetPos(1) Then
ToolTip("Ich passe auf...")
_Array2DAdd($MouseDrawnPath,MouseGetPos(0)-$MouseStartPos[0]&"|"&MouseGetPos(1)-$MouseStartPos[1])
$MousePosNow = MouseGetPos()
EndIf
WEnd
If UBound($MouseDrawnPath) > 1 Then
If Ubound($MouseDrawnPath) > UBound($MousePath) Then
For $i = 1 to UBound($MousePath)-1
If Not (($MouseDrawnPath[$i][0] <= $MousePath[$i][0] + $tol) AND ($MouseDrawnPath[$i][0] >= $MousePath[$i][0] - $tol)) AND (($MouseDrawnPath[$i][1] <= $MousePath[$i][1] + $tol) AND ($MouseDrawnPath[$i][1] >= $MousePath[$i][1] - $tol)) Then
MsgBox("","","Mausgeste nicht erkannt! Fehler bei "&$i,1)
_ArrayDisplay($MouseDrawnPath)
$drawn = True
ExitLoop
Else
If $i = UBound($MousePath)-1 Then
MsgBox(64,"Success!!!","Gratulation ! Die mausgeste konnte erkannt werden.")
$drawn = True
ExitLoop
EndIf
EndIf
Next
ElseIf Ubound($MousePath) > UBound($MouseDrawnPath) Then
For $i = 1 to UBound($MouseDrawnPath)-1
If Not (($MouseDrawnPath[$i][0] <= $MousePath[$i][0] + $tol) AND ($MouseDrawnPath[$i][0] >= $MousePath[$i][0] - $tol)) AND (($MouseDrawnPath[$i][1] <= $MousePath[$i][1] + $tol) AND ($MouseDrawnPath[$i][1] >= $MousePath[$i][1] - $tol)) Then
If $i/Ubound($MousePath) > $pathtol Then
MsgBox("","","Mausgeste zu "&Floor(($i/Ubound($MousePath))*100)&"% erkannt!"&@CRLF&" Dies wird als Erfolg gewertet.",5)
ExitLoop
Else
MsgBox("","","Mausgeste nicht erkannt! Fehler bei "&$i,1)
$drawn = True
ExitLoop
EndIf
Else
If $i = UBound($MousePath)-1 Then
MsgBox(64,"Success!!!","Gratulation ! Die mausgeste konnte erkannt werden.")
$drawn = True
ExitLoop
EndIf
EndIf
Next
EndIf
EndIf
If $drawn = True Then ExitLoop
ToolTip("")
WEnd
EndIf
EndIf
EndFunc
Func _DrawPath()
Local $MouseStartPos = MouseGetPos()
Local $MousePosNow = MouseGetPos()
While $record * sleep(10)
If $MousePosNow[0] <> MouseGetPos(0) OR $MousePosNow[1] <> MouseGetPos(1) Then
_Array2DAdd($MousePath,MouseGetPos(0)-$MousePosNow[0]&"|"&MouseGetPos(1)-$MousePosNow[1])
$MousePosNow = MouseGetPos()
EndIf
WEnd
EndFunc
Das funktioniert allerdings noch seltener, also hab ich das Konzept direkt wieder übern Haufen geworfen und arbeite mit Version 1 weiter. Oben genannte Probleme konnte ich schon eindämmen indem ich verschiedene Toleranzen eingebaut habe. Aber gefallen tut mir das ganze immer noch nicht. Wenn also jemand Ideen hat wie man das verbessern kann - Immer her damit! Ich bin für jeden Schubser in die richtige Richtung dankbar.
Bevor ichs vergesse: Ihr nehmt eine Geste auf indem ihr auf Start drückt, und beendet die Aufnahme mit der Leertaste. Mit Show könnt ihr euch die aufgenommene Geste noch einmal anzeigen lassen.