1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Kanashius

Beiträge von Kanashius

  • Verschiedene Werte beim Auslesen eines NFC-Tags

    • Kanashius
    • 23. Februar 2024 um 12:31

    Ich hab das ganze mal etwas uebersichtlicher umstrukturiert. Jetzt musst du eigentlich nur noch die _processInput und _exitWithNumber aendern.

    AutoIt
    #include <WinAPISys.au3>
    #include <WinAPIConstants.au3>
    #include <WindowsConstants.au3>
    
    OnAutoItExitRegister('_OnExit') ; Freigeben der Ressourcen bei Skriptende
    Global $mHookData[]
    $mHookData["keyProc"] = Null
    $mHookData["hook"] = 0
    _InitKeyHook()
    
    Local $iTimer = TimerInit(), $iTimeOutSec=5
    While Sleep(10)
    	If TimerDiff($iTimer)>$iTimeOutSec*1000 Then Exit 999 ; Timeout wenn kein NFC-Tag gelesen wird
    WEnd
    
    Func _OnExit()
    	_WinAPI_UnhookWindowsHookEx($mHookData.hook)
    	DllCallbackFree($mHookData.keyProc)
    EndFunc   ;==>_OnExit
    
    Func _processInput($sInput)
    	; $sInput = "1D70536A031080"
    	; $sInput = "36046403873762845"
    	; ConsoleWrite("INPUT: "&$sInput&@crlf)
    	If StringLen($sInput) = 17 Then ; ??? is a normal integer number => Example: 36046403873762845
    		_exitWithNumber(Number($sInput))
    	ElseIf StringLen($sInput) = 14 Then ; ??? is a hex number => Example: 1D70536A031080
    		_exitWithNumber(Number("0x"&$sInput))
    	EndIf
    	Exit 815 ; Was not a valid input
    EndFunc
    
    Func _exitWithNumber($iNumber)
    	; ConsoleWrite("exit with "&$iNumber&@crlf)
    	$iNumber = Mod($iNumber, 1000000) ; Make sure to return only the last 6 numbers
    	ConsoleWrite($iNumber&@crlf)
    	Exit ($iNumber) ; ??? return value
    EndFunc
    
    Func _KeyProc($nCode, $wParam, $lParam)
    	Local static $sInput = ""
    	$sPattern = @CRLF
    	Local $tKEYHOOKS, $sChar
    	$tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
    	If $nCode < 0 Then Return _WinAPI_CallNextHookEx($mHookData.hook, $nCode, $wParam, $lParam)
    	If $wParam = $WM_KEYDOWN Then
    		Local $iAscii = _WinAPI_MapVirtualKey($tKEYHOOKS.vkCode, $MAPVK_VK_TO_CHAR)
    		Local $sChar = Chr($iAscii)
    		If $iAscii = 13 Then ; Enter pressed
    			_processInput($sInput)
    			$sInput = ""
    		Else
    			$sInput &= $sChar
    		EndIf
    		Return -1 ; Eingabe wird nicht an das System weitergeleitet
    	EndIf
    	Return _WinAPI_CallNextHookEx($mHookData.hook, $nCode, $wParam, $lParam)
    EndFunc   ;==>_KeyProc
    
    Func _InitKeyHook()
    	If $mHookData.keyProc = Null Then
    		$mHookData.keyProc = DllCallbackRegister('_KeyProc', 'long', 'int;wparam;lparam')
    		Local $hmod = _WinAPI_GetModuleHandle(0)
    		$mHookData.hook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($mHookData.keyProc), $hmod)
    	EndIf
    EndFunc   ;==>_InitKeyHook
    Alles anzeigen

    Ich bin mir nur komplett unsicher, wann du was bei den Zahlen abschneiden willst...

    Bei der Dezimalzahl wolltest du die letzten 6 Zahlen... Bei der Hexadezimalen schreibweise auf einmal die ersten 8??? Das macht keinen Sinn. Ich hab die Umwandlung von Hexadezimal zu Dezimal implementiert, was genau damit passieren soll musst du wissen^^
    Wenn du selbst experimentieren willst kannst du die ConsoleWrite Zeilen in den Funktionen auskommentieren, dann solltest du jedesmal sehen, was genau eingelesen wird und was daraus gemacht wird.

    Du solltest auch echt ueberdenken, die Zahl mit dem ExitCode zurueck zu geben... der ist eigentlich nur dafuer da, Fehlercodes zurueckzugeben... Fuer so etwas schreibt man normal mit ConsoleWrite in den STDOUT, der von anderen Programmen weiterverarbeitet werden kann und dadurch auch komplexere Daten zurueckgeben kann. Gleichzeitig ist das Ergebnis dann auch in der Konsole zu lesen.

    Ich hoffe, das hilft dir weiter.

    LG, Kanashius

  • Verschiedene Werte beim Auslesen eines NFC-Tags

    • Kanashius
    • 22. Februar 2024 um 12:41

    Dein Problem ist die Nutzung des ExitCodes als Rueckgabewert, wofuer das nicht ausgelegt ist.

    Der ExitCode ist ein Integer. Dein String mit der eingelesenen Nummer wird also von AutoIt automatisch in ein Integer konvertiert. Der maximale Wert fuer ein Integer ist 2147483647... schaut bekannt aus? Deine Zahl ist viel groesser als der maximale Integer Wert, also macht AutoIt aus der umwandlung das beste, was es kann und gibt den hoechstmoeglichen Wert aus.

    Du solltest ein ConsoleWrite($g_sAusweisNr&@crlf) machen, bevor du das Programm mit (Exit) verlaesst. Dann wird der String ausgegeben, den du eingelesen hast.

  • Data Collection-Variables / Maps in AutoIt - Status?

    • Kanashius
    • 19. Februar 2024 um 16:35

    Ich denke, das hier duerfte die meisten Verwendungszwecke von Maps abdecken:

    AutoIt
    Local $mData[]
    $mData["value1"] = "Value 1"
    ConsoleWrite($mData.value1&@crlf)
    Local $mMapOther[]
    $mData["value2"] = $mMapOther
    $mData["value2"]["something"] = "Some Thing"
    ConsoleWrite($mData.value2.something&@crlf)
    $mData.value2.something = "Some Other Thing"
    ConsoleWrite($mData.value2.something&@crlf)
    ConsoleWrite("--------------------------"&@crlf)
    For $i in $mData
    	ConsoleWrite(VarGetType($i)&": "&$i&@CRLF)
    Next
    ConsoleWrite("--------------------------"&@crlf)
    For $key in MapKeys($mData)
    	ConsoleWrite($key&" = "&VarGetType($mData[$key])&": "&$mData[$key]&@CRLF)
    Next
    ConsoleWrite("--------------------------"&@crlf)
    If MapExists($mData, "value1") Then ConsoleWrite("Value 1: "&$mData["value1"]&@crlf)
    MapRemove($mData, "value1")
    If Not MapExists($mData, "value1") Then ConsoleWrite("Value 1 is missing"&@crlf)
    Alles anzeigen

    Dabei solltest du darauf achten, dass du immer beim ersten zuweisen eines Wertes den Key in [ ] angeben musst. Bei verschachtelten Maps fuer alle Keys, auch wenn der davor schon existiert (siehe $mData["value2"]["something"]).
    Ansonsten kannst du mit der Punkt schreibweise Werte auslesen und ueberschreiben. Also mit z.B. $mData.value = 1. Das hat den Vorteil, dass SciTe dir das beim Tippen als Vorschlag gibt und du dir nicht alle Keys auswendig merken musst (Was z.B. bei Mars Variablen der Fall ist.)

    MapAppend hab ich mal rausgelassen, weil ichs noch nie gebraucht habe... Bei ner Map geht es ja genau darum, dass ich Key-Value-Paare haben will... warum also mit Integers arbeiten, da nutz ich persoenlich lieber Arrays (auch wenn man es natuerlich als "dynamisches Array" nutzen kann, wie Mars bereits erwaehnte, dann macht s ggf. Sinn).

    Ich finde es tatsaechlich etwas unintuitiv, dass bei einem "For $val in $mData" die Values durchlaufen werden und nicht die Keys. In allen anderen Sprachen die ich kenne werden die Keys (oder KeyValue-Paar-Objekte) iteriert und man kann dann damit die Values abfragen. Hier muss man leider erst alle Keys als Array holen (MapKeys) und die dann iterieren, was das ganze etwas umstaendlich macht :(


    Ich hoffe, das hilft dir weiter,

    LG Kanashius

  • Unit Testing in Autoit

    • Kanashius
    • 17. Februar 2024 um 13:22

    Der Hauptpunkt ist meiner Meinung nach einfach die Projektgroesse.

    Fuer ein kleineres Projekt sind Unit Tests ein recht grosser Aufwand zu einem recht kleinen nutzen, weil es uebersichtlich genug ist, um manuell zu testen.

    Wenn ein Projekt richtig gross ist, mit millionen Zeilen an Code, dann werden sie nicht nur zum testen genutzt, sondern teilweise auch zum entwickeln. Es ist einfach ein riesiger Aufwand, die Funktionen in der Gesamtumgebung zu entwickeln, wenn das compilieren+starten der Anwendung mehrere Minuten dauert und es sehr viele unterschiedliche Variablen gibt, die einem da rein pfuschen koennen (unzaehlige verschiedene Parameter, die alle getestet werden muessen). Da werden die Unittests nach der Spezifikation geschrieben, was passieren soll und mit denen entwickelt man dann seinen Code. Wenn dann alles soweit funktioniert, wird der branch nach code review gemerged und der neue Code wird ueber Nacht in die Hauptcodebase eingefuegt und mit dem gesamt System getestet (natuerlich auch mit Unittests).

    In dem Fall muss man also sowieso die Tests schreiben, einfach nur um beim entwickeln den eigenen Code mal laufen zu lassen, ohne dass jedesmal ne Menge Zeit drauf geht; Von Aenderungen (auch durch Kollegen, die den Code vorher noch nicht gesehen haben) mal ganz abgesehen.


    Von daher ist mein Anspruch: Unittests sobald das Projekt gross genug ist oder der Code oefter geaendert werden soll. Ausserdem gibts immer Unittests fuer alle Schnittstellen nach aussen, um Sicherzustellen, dass dort nicht ausversehen irgendwas uebersehen wird und das dann ne Sicherheitsluecke darstellt (Stichwort Rest-API,... mit ner Menge an Funktionen nach aussen; ein Berechtigungscheck vergessen und jeder kann Daten abfragen; Sowas darf nicht passieren).

  • Code Kata - Galgenraten

    • Kanashius
    • 8. Februar 2024 um 13:48

    Ich hab mich jetzt auch mal an die GUI gemacht :)
    Vielleicht habt ihr ja mehr Glueck als ich ^^

    AutoIt
    #AutoIt3Wrapper_Change2CUI=y
    #pragma compile(Console, true)
    #include <GUIConstantsEx.au3>
    #include <GDIPlus.au3>
    #include <WinAPISysWin.au3>
    Opt("GUIOnEventMode", 1)
    
    Global $bConsole = false ; Change to True to enable console mode
    Global $bGui = true, $bShowFps = False, $mData[]
    
    If $bGui Then
    	_startGui()
    Else
    	_startConsoleGame()
    EndIf
    
    Func _WordList()
        Local Const $aList[] = _
            [ _
                'autoit', _
                'c#', _
                'go', _
                'java', _
                'javascript', _
                'matlab', _
                'php', _
                'python', _
                'ruby', _
                'sql' _
            ]
    
        Return $aList
    EndFunc
    
    
    Func _startConsoleGame()
    	While True
    		_startGame(_initGame())
    		If @error Then ExitLoop
    		$sRequest = _readInput($bConsole, "Möchtest du nocheinmal spielen? Ja (y) or Nein (n)?")
    		If $sRequest<>"y" Then ExitLoop
    	WEnd
    EndFunc
    
    Func _startGui()
    	_GDIPlus_Startup()
    	_startNewGuiGame()
    	$mData["width"] = 800
    	$mData["height"] = 600
    	$mData["hwnd"] = GUICreate("Galgenraten", $mData.width, $mData.height)
    	GUISetOnEvent($GUI_EVENT_CLOSE, "_close", $mData.hwnd)
    	GUISetState(@SW_SHOW, $mData.hwnd)
    
    	Local $iInputWidth = 300, $iBtnWidth = 70, $iGap = 5, $iRowWidth = $iInputWidth+$iBtnWidth*2+$iGap*2, $iInputHeight = $mData.height-100
    	$mData["gallowsStartX"] = $mData.width/2
    	$mData["gallowsStartY"] = $mData.height-$iInputHeight-$iGap
    	$mData["gallowsStrength"] = 10
    	$mData["inputSend"] = GUICtrlCreateInput("", ($mData.width-$iRowWidth)/2, $iInputHeight, $iInputWidth, 35)
    	GUICtrlSetState($mData.inputSend, $GUI_FOCUS)
    	GUICtrlSetFont(-1,20)
    	GUICtrlSetBkColor(-1, 0x00BB00)
    	$mData["btnSend"] = GUICtrlCreateButton("Send", ($mData.width-$iRowWidth)/2+$iInputWidth+$iGap, $iInputHeight, $iBtnWidth, 35)
    	GUICtrlSetFont(-1,20)
    	GUICtrlSetBkColor(-1, 0x00BB00)
    	GUICtrlSetOnEvent($mData.btnSend, "_letterSend")
    	$mData["btnNew"] = GUICtrlCreateButton("New", ($mData.width-$iRowWidth)/2+$iInputWidth+$iGap*2+$iBtnWidth, $iInputHeight, $iBtnWidth, 35)
    	GUICtrlSetBkColor(-1, 0x00BB00)
    	GUICtrlSetFont(-1,20)
    	GUICtrlSetOnEvent($mData.btnNew, "_startNewGuiGame")
    	Local $arAccellerators = [["{ENTER}", $mData.btnSend]]
    	GUISetAccelerators($arAccellerators)
    
    
    	$mData["graphicGui"] = _GDIPlus_GraphicsCreateFromHWND($mData.hwnd)
    	$mData["bitmap"] = _GDIPlus_BitmapCreateFromGraphics($mData.width, $mData.height, $mData.graphicGui)
    	$mData["graphic"] = _GDIPlus_ImageGetGraphicsContext($mData.bitmap)
    	_GDIPlus_GraphicsSetSmoothingMode($mData.graphic, 2)
    	$mData["bgBitmap"] = _GDIPlus_BitmapCreateFromGraphics($mData.width, $mData.height, $mData.graphic)
    	$mData["bgGraphic"] = _GDIPlus_ImageGetGraphicsContext($mData.bgBitmap)
    	_GDIPlus_GraphicsSetSmoothingMode($mData.bgGraphic, 2)
    	$mData["penGarrows"] = _GDIPlus_PenCreate(0xFFBB8800, Int($mData.gallowsStrength))
    	$mData["penPerson"] = _GDIPlus_PenCreate(0xFF000000, Int($mData.gallowsStrength/2))
    	$mData["brushGras"] = _GDIPlus_BrushCreateSolid(0xFF00BB00)
    	$mData["brushSun"] = _GDIPlus_BrushCreateSolid(0xFFFFFFF00)
    	$mData["brushClouds"] = _GDIPlus_BrushCreateSolid(0xFFEEEEEE)
    	$mData["brushRed"] = _GDIPlus_BrushCreateSolid(0xFFFF0000)
    	_drawBackground($mData)
    	_updateDrawingRegion($mData)
    
    	Local $mDrawData[]
    	$mData["drawData"] = $mDrawData
    	$mData["drawData"]["sec"] = @SEC
    	$mData["drawData"]["frames"] = 0
    	$mData["drawData"]["oldFrames"] = 0
    
    	While True
    		If $mData.drawData.sec<>@SEC Then
    			$mData.drawData.oldFrames = $mData.drawData.frames
    			$mData.drawData.frames = 0
    			$mData.drawData.sec = @SEC
    		EndIf
    		; _drawBackground($mData) ; look at the cool background randomization :P
    		_drawGui($mData)
    		$mData.drawData.frames += 1
    	WEnd
    EndFunc
    
    Func _startNewGuiGame()
    	Local $mGameData = _initGame()
    	$mData["gameData"] = $mGameData
    	$mData.gameData.left = 10
    	$mData["gameData"]["success"] = False
    	GUICtrlSetState($mData.inputSend, $GUI_ENABLE)
    	GUICtrlSetState($mData.btnSend, $GUI_ENABLE)
    	GUICtrlSetState($mData.inputSend, $GUI_FOCUS)
    EndFunc
    
    Func _letterSend()
    	Local $sInput = StringLower(GUICtrlRead($mData.inputSend))
    	GUICtrlSetData($mData.inputSend, "")
    	If $sInput<>"" And Not $mData.gameData.success Then
    		If StringLen($sInput)>1 Then
    			If StringLower($mData.gameData.word)=$sInput Then
    				$mData.gameData.success = True
    				$mData.gameData.left = 0
    			Else
    				$mData.gameData.left -= 1
    			EndIf
    		Else
    			If Not MapExists($mData.gameData.tries, $sInput) Then
    				$mData["gameData"]["tries"][$sInput] = $sInput
    				If Not StringInStr(StringLower($mData.gameData.word), $sInput) Then $mData.gameData.left -= 1
    			EndIf
    		EndIf
    		If _isWordGuessed($mData.gameData) Then
    			$mData.gameData.success = True
    			$mData.gameData.left = 0
    		EndIf
    	EndIf
    	If $mData.gameData.success or $mData.gameData.left = 0 Then
    		GUICtrlSetState($mData.inputSend, $GUI_DISABLE)
    		GUICtrlSetState($mData.btnSend, $GUI_DISABLE)
    	EndIf
    EndFunc
    
    Func _updateDrawingRegion(ByRef $mData)
    	Local $hRegion = _GDIPlus_RegionCreateFromRect(0, 0, $mData.width, $mData.height)
    	Local $hChild = _WinAPI_GetWindow($mData.hwnd, $GW_CHILD)
    	Local $aRect
    	Do
    		$aRect = ControlGetPos($hChild, "", 0)
    		_GDIPlus_RegionCombineRect($hRegion, $aRect[0], $aRect[1], $aRect[2], $aRect[3], 3)
    		$hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT)
    	Until Not $hChild
    	_GDIPlus_GraphicsSetClipRegion($mData.graphicGui, $hRegion)
    	_GDIPlus_RegionDispose($hRegion)
    EndFunc
    
    Func _drawGui(ByRef $mData)
    	_GDIPlus_GraphicsDrawImageRect($mData.graphic, $mData.bgBitmap, 0, 0, $mData.width, $mData.height)
    	Local $iGallowsHeight = $mData.height*0.3, $iGallowsWidth = $mData.width*0.15
    	If Not $mData.gameData.success Then
    		If $mData.gameData.left < 10 Then _GDIPlus_GraphicsDrawLine($mData.graphic, $mData.gallowsStartX, $mData.gallowsStartY+1, $mData.gallowsStartX, $mData.gallowsStartY-$iGallowsHeight, $mData.penGarrows)
    		If $mData.gameData.left < 9 Then _GDIPlus_GraphicsDrawLine($mData.graphic, $mData.gallowsStartX-$mData.gallowsStrength/2, $mData.gallowsStartY-$iGallowsHeight, $mData.gallowsStartX+$iGallowsWidth-$mData.gallowsStrength/2, $mData.gallowsStartY-$iGallowsHeight, $mData.penGarrows)
    		If $mData.gameData.left < 8 Then _GDIPlus_GraphicsDrawLine($mData.graphic, $mData.gallowsStartX+$iGallowsWidth-$mData.gallowsStrength, $mData.gallowsStartY-$iGallowsHeight, $mData.gallowsStartX+$iGallowsWidth-$mData.gallowsStrength, $mData.gallowsStartY-$iGallowsHeight*0.8, $mData.penGarrows)
    		If $mData.gameData.left < 7 Then _GDIPlus_GraphicsDrawLine($mData.graphic, $mData.gallowsStartX, $mData.gallowsStartY-$iGallowsHeight+$iGallowsHeight*0.2, $mData.gallowsStartX+$iGallowsHeight*0.2,$mData.gallowsStartY-$iGallowsHeight, $mData.penGarrows)
    	EndIf
    	Local $iPersonMid = $mData.gallowsStartX+$iGallowsWidth-$mData.gallowsStrength, $iPersonTop = $mData.gallowsStartY-$iGallowsHeight*0.8, $iFactor = 0
    	If $mData.gameData.success Then
    		$iPersonMid = $mData.gallowsStartX
    		$iFactor = 0.2
    	ElseIf $mData.gameData.left = 0 Then
    		_GDIPlus_GraphicsFillEllipse($mData.graphic, $iPersonMid-$iGallowsHeight*0.1, $iPersonTop, $iGallowsHeight*0.2, $iGallowsHeight*0.2, $mData.brushRed)
    	EndIf
    	If $mData.gameData.left < 6 Then _GDIPlus_GraphicsDrawEllipse($mData.graphic, $iPersonMid-$iGallowsHeight*0.1, $iPersonTop, $iGallowsHeight*0.2, $iGallowsHeight*0.2, $mData.penPerson)
    	If $mData.gameData.left < 5 Then _GDIPlus_GraphicsDrawLine($mData.graphic, $iPersonMid, $iPersonTop+$iGallowsHeight*0.2, $iPersonMid, $iPersonTop+$iGallowsHeight*0.6, $mData.penPerson)
    	If $mData.gameData.left < 4 Then _GDIPlus_GraphicsDrawLine($mData.graphic, $iPersonMid, $iPersonTop+$iGallowsHeight*0.6, $iPersonMid-$iGallowsWidth*0.2, $iPersonTop+$iGallowsHeight*0.8, $mData.penPerson)
    	If $mData.gameData.left < 3 Then _GDIPlus_GraphicsDrawLine($mData.graphic, $iPersonMid, $iPersonTop+$iGallowsHeight*0.6, $iPersonMid+$iGallowsWidth*0.2, $iPersonTop+$iGallowsHeight*0.8, $mData.penPerson)
    	If $mData.gameData.left < 2 Then _GDIPlus_GraphicsDrawLine($mData.graphic, $iPersonMid, $iPersonTop+$iGallowsHeight*0.3+$iGallowsWidth*$iFactor, $iPersonMid-$iGallowsWidth*0.2, $iPersonTop+$iGallowsHeight*0.5-$iGallowsHeight*$iFactor, $mData.penPerson)
    	If $mData.gameData.left < 1 Then _GDIPlus_GraphicsDrawLine($mData.graphic, $iPersonMid, $iPersonTop+$iGallowsHeight*0.3+$iGallowsWidth*$iFactor, $iPersonMid+$iGallowsWidth*0.2, $iPersonTop+$iGallowsHeight*0.5-$iGallowsHeight*$iFactor, $mData.penPerson)
    
    	Local $iLetterWidth = $mData.height*0.066, $iLetterMid = Int($mData.width/2), $iLetters = StringLen($mData.gameData.word), $iLetterLeft = $iLetterMid - Int(($iLetterWidth*$iLetters)/2)
    	For $i=0 To Ubound($mData.gameData.letters)-1 Step 1
    		Local $sString = MapExists($mData.gameData.tries, $mData.gameData.letters[$i])?$mData.gameData.letters[$i]:"_"
    		If $mData.gameData.left = 0 Then $sString = $mData.gameData.letters[$i]
    		_GDIPlus_GraphicsDrawString($mData.graphic, $sString, $iLetterLeft+$i*$iLetterWidth, $mData.height*0.2, Default, $mData.height*0.033)
    	Next
    
    	If $bShowFps Then _GDIPlus_GraphicsDrawString($mData.graphic, $mData.drawData.oldFrames, $mData.width-5-8*StringLen($mData.drawData.oldFrames), 5)
    	_GDIPlus_GraphicsDrawImageRect($mData.graphicGui, $mData.bitmap, 0, 0, $mData.width, $mData.height)
    EndFunc
    
    Func _drawBackground(ByRef $mData)
    	_GDIPlus_GraphicsClear($mData.bgGraphic, 0xFF33BBFF)
    	; hills
    	Local $iHills = 5, $iHillsHeight = $mData.height*0.25, $iHillsStart = $mData.height - $iHillsHeight, $iHillWidth = Int($mData.width/$iHills), $iHillMaxHeight = $mData.height*0.05
    	If Mod($iHillMaxHeight, 2)>0 Then $iHills+=1 ; make sure amount of hills is odd
    	Local $arHillPoints[5+$iHills*2][2]
    	$arHillPoints[0][0] = UBound($arHillPoints)-1
    	$arHillPoints[1][0] = -10
    	$arHillPoints[1][1] = $iHillsStart
    	$arHillPoints[UBound($arHillPoints)-3][0] = $mData.width + 10
    	$arHillPoints[UBound($arHillPoints)-3][1] = $iHillsStart
    	$arHillPoints[UBound($arHillPoints)-2][0] = $mData.width + 10
    	$arHillPoints[UBound($arHillPoints)-2][1] = $mData.height + 10
    	$arHillPoints[UBound($arHillPoints)-1][0] = -10
    	$arHillPoints[UBound($arHillPoints)-1][1] = $mData.height + 10
    	For $i=2 to UBound($arHillPoints)-4 Step 2
    		Local $iLeft = (($i-2)/2)*$iHillWidth
    		$arHillPoints[$i][0] = Random($iLeft-Int($iHillWidth*0.1), $iLeft+Int($iHillWidth*0.1), 1)
    		$arHillPoints[$i][1] = $iHillsStart
    		$arHillPoints[$i+1][0] = Random($arHillPoints[$i][0] + ($iHillWidth/2) -Int($iHillWidth*0.1), $arHillPoints[$i][0] + ($iHillWidth/2) +Int($iHillWidth*0.1), 1)
    		$arHillPoints[$i+1][1] = $iHillsStart-Random(Int($iHillMaxHeight*0.2), Int($iHillMaxHeight*0.6), 1)
    	Next
    	Local $iMidHill = 1+Int((UBound($arHillPoints)-4)/2)
    	$arHillPoints[$iMidHill][0] = (($iMidHill-2)/2)*$iHillWidth
    	$arHillPoints[$iMidHill][1] = $iHillsStart
    	$arHillPoints[$iMidHill+1][0] = $arHillPoints[$iMidHill][0] + ($iHillWidth/2)
    	$arHillPoints[$iMidHill+1][1] = $iHillsStart-$iHillMaxHeight
    	$mData.gallowsStartX = $arHillPoints[$iMidHill+1][0]
    	$mData.gallowsStartY = $arHillPoints[$iMidHill+1][1]
    	_GDIPlus_GraphicsFillClosedCurve($mData.bgGraphic, $arHillPoints, $mData.brushGras)
    
    	; sun
    	Local $iSunRadius = $mData.width*0.1, $iSunGap = 20 ; percent
    	_GDIPlus_GraphicsFillEllipse($mData.bgGraphic, $mData.width-$iSunRadius-$iSunGap, $iSunGap, $iSunRadius, $iSunRadius, $mData.brushSun)
    
    	; clouds
    	Local $iClouds = 3, $iCloudWidth = (($mData.width-$iSunRadius-$iSunGap*2)/$iClouds), $iCloudGap = $mData.height*0.083, $iCloudRadius = $mData.width*0.03, $iCloudWidth2=$iCloudWidth/2, $iCloudWidth3=$iCloudWidth/4
    	For $i=0 to $iClouds-1 Step 1
    		For $j=0 to 7 Step 1
    			Local $iX = $i*$iCloudWidth+$iCloudWidth2-$iCloudGap/2
    			Local $iY = $iCloudGap
    			Local $iWidth = $iCloudRadius*3
    			Local $iHeight = $iCloudRadius
    			_GDIPlus_GraphicsFillEllipse($mData.bgGraphic, Random($iX-$iCloudWidth3,$iX+$iCloudWidth3,1), $iY+Random(0,$iCloudRadius,1), $iWidth, $iHeight, $mData.brushClouds)
    		Next
    	Next
    EndFunc
    
    Func _close()
    	_GDIPlus_BrushDispose($mData.brushGras)
    	_GDIPlus_BrushDispose($mData.brushSun)
    	_GDIPlus_BrushDispose($mData.brushClouds)
    	_GDIPlus_BrushDispose($mData.brushRed)
    	_GDIPlus_PenDispose($mData.penGarrows)
    	_GDIPlus_PenDispose($mData.penPerson)
    	_GDIPlus_BitmapDispose($mData.bitmap)
    	_GDIPlus_GraphicsDispose($mData.graphic)
    	_GDIPlus_GraphicsDispose($mData.graphicGui)
    	_GDIPlus_Shutdown()
    	GUIDelete($mData.hwnd)
    	Exit
    EndFunc
    
    Func _initGame()
    	Local $mGameData[]
    	$mGameData["word"] = _selectWord()
    	$mGameData["letters"] = StringSplit(StringLower($mGameData.word), "", BitOR(1,2))
    	Local $mTries[]
    	$mGameData["tries"] = $mTries
    	$mGameData["left"] = StringLen($mGameData.word)*2
    	return $mGameData
    EndFunc
    
    Func _startGame(ByRef $mGameData)
    	ConsoleWrite("+---------------+"&@crlf)
    	ConsoleWrite("|--GALGENRATEN--|"&@crlf)
    	ConsoleWrite("+---------------+"&@crlf&@crlf)
    
    	ConsoleWrite("Errate ein Wort mit "&StringLen($mGameData.word)&" Buchstaben "&_generateOutput($mGameData)&" , aus der Kategorie Software Entwicklung."&@crlf)
    	ConsoleWrite("Du hast "&$mGameData.left&" Versuche, jeder falsche Buchstabe reduziert deine Versuche."&@crlf)
    
    	Local $bSuccess = False
    	While $mGameData.left>=0
    		Local $sInput = _requestNextLetter($bConsole)
    		If @error Then Return SetError(1, @error&":"&@extended, -1)
    		$sInput = StringLower($sInput)
    		If StringLen($sInput)>1 Then
    			If StringLower($mGameData.word)=StringLower($sInput) Then
    				$bSuccess = True
    				ExitLoop
    			EndIf
    			$mGameData.left-=1
    		Else
    			If Not MapExists($mGameData.tries, $sInput) Then
    				$mGameData["tries"][$sInput] = $sInput
    				If Not StringInStr(StringLower($mGameData.word), StringLower($sInput)) Then $mGameData.left-=1
    			EndIf
    		EndIf
    		If _isWordGuessed($mGameData) Then
    			$bSuccess = True
    			ExitLoop
    		EndIf
    		If $mGameData.left>=0 Then ConsoleWrite("Wort: "&_generateOutput($mGameData)&"("&$mGameData.left&" Versuche noch)"&@crlf)
    	WEnd
    	ConsoleWrite(@crlf)
    	If $bSuccess Then
    		ConsoleWrite("Gewonnen! "&$mGameData.left&" Versuche übrig, gut gemacht."&@crlf)
    	Else
    		ConsoleWrite("Verloren! Das gesuchte Wort war """&$mGameData.word&"""."&@crlf)
    	EndIf
    EndFunc
    
    Func _isWordGuessed(ByRef $mGameData)
    	For $i=0 To Ubound($mGameData.letters)-1 Step 1
    		If Not MapExists($mGameData.tries, $mGameData.letters[$i]) Then return False
    	Next
    	return True
    EndFunc
    
    Func _generateOutput(ByRef $mGameData)
    	Local $sResult = ""
    	For $i=0 To Ubound($mGameData.letters)-1 Step 1
    		If $i<>0 Then $sResult&=" "
    		$sResult&=MapExists($mGameData.tries, $mGameData.letters[$i])?$mGameData.letters[$i]:"_"
    	Next
    	return $sResult
    EndFunc
    
    Func _selectWord()
    	Local $arWords = _WordList()
    	return $arWords[Random(0 ,UBound($arWords)-1 , 1)]
    EndFunc
    
    Func _requestNextLetter($bConsole=False)
    	Local $sResult = _readInput($bConsole)
    	If @error Then return SetError(1, @error, "")
    	While $sResult = ""
    		$sResult = _readInput($bConsole, "Es muss mindestens ein Zeichen eingegeben werden. Versuch es noch einmal: ")
    		If @error Then return SetError(1, @error, "")
    	WEnd
    	return $sResult
    EndFunc
    
    Func _readInput($bConsole=False, $sText=Default, $sTitle=Default)
    	If $sText = Default Then $sText = "Gib einen Buchstaben oder ein Wort ein: "
    	If $sTitle = Default Then $sTitle = "Galgenraten"
    	If $bConsole Then
    		ConsoleWrite($sText)
    		Local $sInput = ""
    		While sleep(100)
    			$sInput = ConsoleRead()
    			If @error Then
    				ConsoleWriteError("Error reading from console input. Maybe the console does not provide an STDIN."&@crlf)
    				return SetError(1, 0, "")
    			EndIf
    			If @extended > 0 Then ExitLoop
    		WEnd
    		return StringReplace($sInput, @crlf, "")
    	Else
    		return InputBox($sTitle, $sText)
    	EndIf
    EndFunc
    Alles anzeigen

    Dateien

    grafik.png 81,01 kB – 0 Downloads
  • Komplette GUI als "Button"

    • Kanashius
    • 7. Februar 2024 um 21:56

    Ich wuerde eine Map nutzen. Damit bildet man Json sehr gut ab, und du hast nur eine Variable, die du speichern musst und im ganzen Script ueberall verwenden kannst.

    AutoIt
    Local $mData = _generateMap() ; generate map with default values
    $mData.other.something = False ; how to use, here with a map in map usage.
    ; Be careful, when creating new map entries, always use the $mMap["KEY"] writing, otherwise you will get error messages, reading/changing can be done with $mMap.KEY then
    ConsoleWrite(_toJson($mData)&@crlf)
    
    Func _generateMap()
    	Local $mData[]
    	$mData["datetime"] = "05.02.2024 20:30:53"
    	$mData["onlinestate"] = True
    	$mData["volt"] = 233.9
    	Local $arTest = [12, "numbers", True]
    	$mData["test"] = $arTest
    	Local $mOtherData[]
    	$mOtherData["something"] = True
    	$mOtherData.something = False
    	$mOtherData["123"] = 123
    	$mData["other"] = $mOtherData
    	return $mData
    EndFunc
    
    Func _toJson(ByRef $data, $iSpace = Default, $bRec = False)
    	If Not $bRec And Not IsMap($data) Then return SetError(1, 0, "First object needs to be a map!")
    	If $iSpace = Default Then $iSpace = "  "
    	Local $sJson = ""
    	If IsNumber($data) Then
    		$sJson = String($data)
    	ElseIf IsBool($data) Then
    		$sJson = StringLower($data)
    	ElseIf IsMap($data) Then
    		$sJson &= "{"&($bRec?"":@crlf)
    		Local $arKeys = MapKeys($data)
    		For $i=0 to UBound($arKeys)-1 Step 1
    			If $i>0 Then $sJson&=", "&($bRec?"":@crlf)
    			$sJson&=($bRec?"":$iSpace)&'"'&$arKeys[$i]&'": '&_toJson($data[$arKeys[$i]], $iSpace, True)
    		Next
    		$sJson &= ($bRec?"":@crlf)&"}"
    	ElseIf IsArray($data) Then
    		$sJson &= "["
    		For $i=0 to UBound($data)-1 Step 1
    			If $i>0 Then $sJson&=", "
    			$sJson&=_toJson($data[$i], $iSpace, True)
    		Next
    		$sJson &= "]"
    	Else ; assume string;   maybe add more types here, like binary/object/...
    		$sJson = '"'&String($data)&'"'
    	EndIf
    	return $sJson
    EndFunc
    Alles anzeigen


    Edit: Changed Bool to lowercase (thanks for the hint AspirinJunkie)

  • Komplette GUI als "Button"

    • Kanashius
    • 6. Februar 2024 um 15:12

    Wenn du es eh als Webseite haben moechtest, wuerde ich eher die Infos als JSON-Datei hochladen und eine Webseite erstellen, mit der du die json datei auslesen und das ganze dann auch (huebscher) darstellen kannst.

    Webseite:

    HTML
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
            <style>
                body, html{
                    width: 100%;
                    margin: 0;
                    background-color: #333;
                }
                .center{
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    position: absolute;
                }
                .grid{
                    --bg-color-hue: 120;
                    display: grid;
                    padding: 1rem;
                    grid-template-columns: 2fr 1fr 1fr 1fr;
                    grid-template-rows: repeat(10, 1fr);
                    background-color: hsl(var(--bg-color-hue), 70%, 50%);
                    box-shadow: hsl(var(--bg-color-hue), 70%, 30%) 0px 0px 10px 5px inset;
                }
                .grid-col-flex{
                    display: inline-flex;
                    flex-wrap: wrap;
                    gap: 0.5rem;
                }
            </style>
        </head>
        <body onload="startup()">
            <script>
                function startup(){
                    resetFields();
                    updateData();
                    setInterval(updateData, 10000); // update every 10 seconds
                }
                function getData() {
                    return fetch("./data.json").then((res) => {
                            if (!res.ok) {
                                throw new Error(`HTTP error! Status: ${res.status}`);
                            }
                            return res.json();
                        }).catch((error) => JSON.parse('{"error": "'+error+'"}'));
                }
                function updateData(){
                    getData().then(data=>{
                        if(data.hasOwnProperty("error")){
                            document.getElementById("solarpower").style.display = "none";
                            document.getElementById("error").textContent = data.error;
                            resetFields();
                            document.getElementById("error").style.display = "block";
                        }else{
                            document.getElementById("solarpower").style.display = null;
                            document.getElementById("error").style.display = "none";
                            resetFields();
                            for (const val in data) {
                                var elem = document.getElementById(val);
                                if(elem!=null)
                                    elem.textContent = data[val];
                            }
                            if(data.hasOwnProperty("onlinestate") && data.onlinestate){
                                document.getElementById("solarpower").style.setProperty("--bg-color-hue", "120");
                            }else{
                                document.getElementById("solarpower").style.setProperty("--bg-color-hue", "0");
                            }
                        }
                    });
                }
                function resetFields(){
                    let divs = document.getElementById("solarpower").getElementsByTagName("div");
                    for(let i = 0;i<divs.length;i++){
                        if(divs[i].hasAttribute("data-default")) {
                            divs[i].textContent = divs[i].getAttribute("data-default");
                        }
                    }
                }
            </script>
            <div class="center">
                <div id="error"></div>
                <div class="grid" id="solarpower">
                    <div style="grid-row: 1/1; grid-column: 1/5; margin:auto; font-weight: 700;">Balkonkraftwerk</div>
    
                    <div style="grid-row: 2; grid-column: 1/3; margin:auto;" id="datetime" data-default="--.--.-- --:--:--"></div>
                    <div style="grid-row: 2; grid-column: 3/4;">Online:</div>
                    <div style="grid-row: 2; grid-column: 4/5; width: 100%;" id="onlinestate"></div>
    
                    <div style="grid-row: 3; grid-column: 1;">Sonnenaufgang:</div>
                    <div style="grid-row: 3; grid-column: 2;" id="sunrise" data-default="--:--:--"></div>
                    <div style="grid-row: 4; grid-column: 1;">Sonnenuntergang:</div>
                    <div style="grid-row: 4; grid-column: 2;" id="sunset" data-default="--:--:--"></div>
                    <div style="grid-row: 5; grid-column: 1;">Start:</div>
                    <div style="grid-row: 5; grid-column: 2;" id="start" data-default="--:--:--"></div>
                    <div style="grid-row: 6; grid-column: 1;">Ende:</div>
                    <div style="grid-row: 6; grid-column: 2;" id="end" data-default="--:--:--"></div>
    
                    <div class="grid-col-flex" style="grid-row: 3; grid-column: 3;"><div id="volt" data-default="-"></div><div></div></div>
                    <div class="grid-col-flex" style="grid-row: 3; grid-column: 4;"><div>Max: </div><div id="voltmax" data-default="-"></div><div>V</div></div>
                    <div class="grid-col-flex" style="grid-row: 4; grid-column: 3;"><div id="hertz" data-default="-"></div><div>Hz</div></div>
                    <div class="grid-col-flex" style="grid-row: 4; grid-column: 4;"><div>Max: </div><div id="hertzmax" data-default="-"></div><div>Hz</div></div>
                    <div class="grid-col-flex" style="grid-row: 5; grid-column: 3;"><div id="watt" data-default="-"></div><div>W</div></div>
                    <div class="grid-col-flex" style="grid-row: 5; grid-column: 4;"><div>Max: </div><div id="wattmax" data-default="-"></div><div>W</div></div>
                    <div class="grid-col-flex" style="grid-row: 6; grid-column: 3;"><div id="ampere" data-default="-"></div><div>A</div></div>
                    <div class="grid-col-flex" style="grid-row: 6; grid-column: 4;"><div>Max: </div><div id="amperemax" data-default="-"></div><div>A</div></div>
                    <div class="grid-col-flex" style="grid-row: 7; grid-column: 3;"><div id="kwh" data-default="-"></div><div>kWh</div></div>
                    <div class="grid-col-flex" style="grid-row: 7; grid-column: 4;"><div id="kwhd" data-default="-"></div><div>kWh/Tag</div></div>
    
                    <div class="grid-col-flex" style="grid-row: 9; grid-column: 1;"><div>Taktung: </div><div id="timing" data-default="-"></div><div>sec.</div></div>
                    <div class="grid-col-flex" style="grid-row: 9; grid-column: 2;"><div>Log: </div><div id="log" data-default="-"></div></div>
                </div>
            </div>
        </body>
    </html>
    Alles anzeigen

    Json data.json:

    Code
    {
      "datetime": "05.02.2024 20:30:53",
      "onlinestate": true,
      "sunrise": "07:59:00",
      "sunset": "17:30:00",
      "start": "08:09:41",
      "end": "17:19:11",
      "volt": 233.9,
      "voltmax": 235.5,
      "hertz": 50.2,
      "hertzmax": 50.2,
      "watt": 0.0,
      "wattmax": 585.4,
      "ampere": 0.000,
      "amperemax": 1.934,
      "kwh": 23.048,
      "kwhd": 2.374,
      "timing": 600,
      "log": true
    }
    Alles anzeigen

    Das ganze spart Datenvolumen beim Hochladen und aktualisiert sich automatisch alle 10 Sekunden. Du musst also nurnoch statt dem Screenshot die JSON Textdatei hochladen ;)

    grafik.png

  • Problem mit dem Edit-Control

    • Kanashius
    • 5. Februar 2024 um 17:55

    Ich hab mal rumprobiert und konnte leider keinen Style,... finden, der das aendern koennte...

    Ich vermute, die Balken sind initial da, weil das Event, mit dem der Fokus vom Edit genommen wird nach dem aktuellen "button klick event" (Case $idBtn_Anzeigen) ausgefuehrt wird und das fenster da schon neugezeichnet wird und danach erst der Fokus vom Edit genommen wird.

    Ich konnte es loesen, indem ich das Edit disable ($GUI_DISABLE) und das ganze aus der aktuellen event loop rausnehme mit "AdlibRegister". Ich hoffe, das ist fuer dich eine akzeptable Loesung...

    AutoIt
    #include-once
    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <WinAPIGdi.au3>
    
    Opt("MustDeclareVars", 1)
    
    Global $idBtn_Anzeigen, $idEdiText, $hGUI_Hauptfenster, $GUI_Msg, $idLbl_Wartehinweis
    
    ; Das Fenster des GUI erstellen.
    $hGUI_Hauptfenster = GUICreate("TEST TEST TEST", 830, 185, -1, -1)
    GUISetBkColor(0x3680FF)
    
    ; Das Textfenster (Edit-Control) erstellen.
    $idEdiText = GUICtrlCreateEdit("", 30, 30, 768, 40, BitOR($ES_CENTER, $ES_MULTILINE))
    
    $idBtn_Anzeigen = GUICtrlCreateButton("Label anzeigen.", 250, 128, 310, 40, BitOR($SS_CENTER, $BS_PUSHLIKE))
    GUICtrlSetFont(-1, 12, 400, 0, "Tahoma")
    GUICtrlSetBkColor(-1, 0x00FF00)
    
    ; Das Label mit dem Wartehinweis erstellen.
    $idLbl_Wartehinweis = GUICtrlCreateLabel("", 214, 23, 372, 89)
    
    GUICtrlSetBkColor(-1, 0x707070)
    GUICtrlSetState(-1, $GUI_HIDE)
    
    GUISetState(@SW_SHOW, $hGUI_Hauptfenster)
    
    While 1
    	$GUI_Msg = GUIGetMsg()
    	Switch $GUI_Msg
    		Case $GUI_EVENT_CLOSE ; Symbol <Fenster schließen>
    			GUIDelete($hGUI_Hauptfenster)
    			ExitLoop
    		Case $idBtn_Anzeigen ; Button <Label anzeigen.>
    			; Das Label für den Wartehinweis anzeigen.
    			AdlibRegister("_disable")
    	EndSwitch
    WEnd
    
    Func _disable()
    	AdlibUnRegister("_disable")
    	GUICtrlSetState($idEdiText, $GUI_DISABLE)
    	GUICtrlSetState($idLbl_Wartehinweis, $GUI_SHOW)
    EndFunc
    Alles anzeigen
  • Code Kata - Galgenraten

    • Kanashius
    • 5. Februar 2024 um 17:31

    Hi,

    Ich dachte mir ich hab grad nen moment und könnte auch mal wieder programmieren :)

    Nette Idee von dir.

    Hier meine Lösung (Teil 1&2) ca. 80min.:

    Spoiler anzeigen
    AutoIt
    #AutoIt3Wrapper_Change2CUI=y
    #pragma compile(Console, true)
    
    #include "word-list.au3"
    
    Global $bConsole = false ; Change to True to enable console mode
    
    While True
    	_startGame()
    	If @error Then ExitLoop
    	$sRequest = _readInput($bConsole, "Möchtest du nocheinmal spielen? Ja (y) or Nein (n)?")
    	If $sRequest<>"y" Then ExitLoop
    WEnd
    
    Func _startGame()
    	ConsoleWrite("+---------------+"&@crlf)
    	ConsoleWrite("|--GALGENRATEN--|"&@crlf)
    	ConsoleWrite("+---------------+"&@crlf&@crlf)
    
    	Local $mData[]
    	$mData["word"] = _selectWord()
    	$mData["letters"] = StringSplit(StringLower($mData.word), "", BitOR(1,2))
    	Local $mTries[]
    	$mData["tries"] = $mTries
    	$mData["left"] = StringLen($mData.word)*2
    
    	ConsoleWrite("Errate ein Wort mit "&StringLen($mData.word)&" Buchstaben "&_generateOutput($mData)&" , aus der Kategorie Software Entwicklung."&@crlf)
    	ConsoleWrite("Du hast "&$mData.left&" Versuche, jeder falsche Buchstabe reduziert deine Versuche."&@crlf)
    
    	Local $bSuccess = False
    	While $mData.left>=0
    		Local $sInput = _requestNextLetter($bConsole)
    		If @error Then Return SetError(1, @error&":"&@extended, -1)
    		$sInput = StringLower($sInput)
    		If StringLen($sInput)>1 Then
    			If StringLower($mData.word)=StringLower($sInput) Then
    				$bSuccess = True
    				ExitLoop
    			EndIf
    			$mData.left-=1
    		Else
    			If Not MapExists($mData.tries, $sInput) Then
    				$mData["tries"][$sInput] = $sInput
    				If Not StringInStr(StringLower($mData.word), StringLower($sInput)) Then $mData.left-=1
    			EndIf
    		EndIf
    		If _isWordGuessed($mData) Then
    			$bSuccess = True
    			ExitLoop
    		EndIf
    		If $mData.left>=0 Then ConsoleWrite("Wort: "&_generateOutput($mData)&"("&$mData.left&" Versuche noch)"&@crlf)
    	WEnd
    	ConsoleWrite(@crlf)
    	If $bSuccess Then
    		ConsoleWrite("Gewonnen! "&$mData.left&" Versuche übrig, gut gemacht."&@crlf)
    	Else
    		ConsoleWrite("Verloren! Das gesuchte Wort war """&$mData.word&"""."&@crlf)
    	EndIf
    EndFunc
    
    Func _isWordGuessed(ByRef $mData)
    	For $i=0 To Ubound($mData.letters)-1 Step 1
    		If Not MapExists($mData.tries, $mData.letters[$i]) Then return False
    	Next
    	return True
    EndFunc
    
    Func _generateOutput(ByRef $mData)
    	Local $sResult = ""
    	For $i=0 To Ubound($mData.letters)-1 Step 1
    		If $i<>0 Then $sResult&=" "
    		$sResult&=MapExists($mData.tries, $mData.letters[$i])?$mData.letters[$i]:"_"
    	Next
    	return $sResult
    EndFunc
    
    Func _selectWord()
    	Local $arWords = _WordList()
    	return $arWords[Random(0 ,UBound($arWords)-1 , 1)]
    EndFunc
    
    Func _requestNextLetter($bConsole=False)
    	Local $sResult = _readInput($bConsole)
    	If @error Then return SetError(1, @error, "")
    	While $sResult = ""
    		$sResult = _readInput($bConsole, "Es muss mindestens ein Zeichen eingegeben werden. Versuch es noch einmal: ")
    		If @error Then return SetError(1, @error, "")
    	WEnd
    	return $sResult
    EndFunc
    
    Func _readInput($bConsole=False, $sText=Default, $sTitle=Default)
    	If $sText = Default Then $sText = "Gib einen Buchstaben oder ein Wort ein: "
    	If $sTitle = Default Then $sTitle = "Galgenraten"
    	If $bConsole Then
    		ConsoleWrite($sText)
    		Local $sInput = ""
    		While sleep(100)
    			$sInput = ConsoleRead()
    			If @error Then
    				ConsoleWriteError("Error reading from console input. Maybe the console does not provide an STDIN."&@crlf)
    				return SetError(1, 0, "")
    			EndIf
    			If @extended > 0 Then ExitLoop
    		WEnd
    		return StringReplace($sInput, @crlf, "")
    	Else
    		return InputBox($sTitle, $sText)
    	EndIf
    EndFunc
    Alles anzeigen

    Bin schon gespannt, was noch für Lösungen kommen.

  • VLC noch aktuell? [2024]

    • Kanashius
    • 28. Januar 2024 um 17:47

    Keine Ahnung, ob die UDF noch funktioniert, ich kenn sie nicht. VLC ist was interfaces angeht aber eig. recht konsistent und aendert nicht so viel, wenns also nicht grad Fenster emulation ist, funktioniert es vmtl. noch.

    Bei deinem Script solltest du direkt ne Fehlermeldung bekommen, weil $item nicht existiert. Ausserdem solltest du $vlc auch mal was zuweisen, wenn du es spaeter verwenden willst (z.B. den Rueckgabewert von _GUICtrlVLC_Create???).

    Vielleicht solltest du dir nochmal die Basics vom Programmieren anschauen, also wie Variablen funktionieren,...

  • MAPs - Datenstruktur/ Typ direkt abspeichern?

    • Kanashius
    • 21. Januar 2024 um 21:15

    Das direkte auslesen des Speichers hätte dir auch nicht wirklich geholfen.

    Datenstrukturen sind nicht zwingend alle auf einem Haufen im Speicher. Es wird viel mit Referenzen gearbeitet, also wo bei einem Objekt nur die Adresse der anderen Objekte gespeichert sind und nicht die Objekte selbst. Die befinden sich dann irgendwo anders im Speicher. Es müsste also sowieso die ganze Struktur durchgegangen werden um die Daten zu finden und zu speichern. Außerdem geht dabei ggf. der Datentyp verloren, da der nicht im Speicher angegeben wird, sondern sich von den Zusammenhängen des Programmes ergibt.

    Das serialisieren von AspirinJunkie ist also tatsächlich die einfachste und beste Methode.

  • revert im laufenden script.

    • Kanashius
    • 16. Januar 2024 um 19:00

    Nein, das geht so nicht. Solange die Datei als Programm ausgeführt wird, kann sie nicht verändert werden. Dein Cloudsync kann das auch nicht und wird die Änderung erst aufs Zielsystem kopieren, wenn das Programm nicht mehr läuft.

    Die einzige einfache Lösung wäre das Programm extern alle 4 Stunden zu starten. Entweder mit dem Windows Task Scheduler, oder mit einem zweiten anderen Programm.

    Dann wäre die Datei nur kurz gesperrt, während das Programm ausgeführt wird und danach direkt wieder freigegeben um verändert zu werden.

  • Eingabe(such)feld mit Löschmöglichkeit

    • Kanashius
    • 8. Januar 2024 um 11:46

    Es ist auch moeglich, einen Hintergrundtext zu setzen, der automatisch beim reinklicken weggeht:

    AutoIt
    $iInputSearch=GUICtrlCreateInput("",10,10,100)
    GUICtrlSendMsg(-1, 0x1501, 0, "Suchen ...")

    Das Icon brauchst du aber dann trotzdem noch anders.

    MfG, Kanashius.

  • Shoutbox compact

    • Kanashius
    • 27. November 2023 um 20:38

    Hi,

    Ich hab mir ein Script für Firefox-Greasemonkey geschrieben, was die Shoutbox kompakter macht und um 100px vergrößert, sodass man mehr als die letzten 1-2 Nachrichten lesen kann.

    Falls das noch jemand nutzen möchte:

    Code
    // ==UserScript==
    // @name     Autoit Shoutbox
    // @version  1
    // @grant    none
    // ==/UserScript==
    
    var cssStyle = document.createElement('style');
    cssStyle.type = 'text/css';
    cssStyle.appendChild(document.createTextNode(".userMessage p { margin: 0px; }")); // space around the text
    cssStyle.appendChild(document.createTextNode(".containerHeadline ~ .containerContent { margin-top: 0px; }")); // space between username and text
    cssStyle.appendChild(document.createTextNode(".shoutbox.classicDesign .shoutboxEntryList li.shoutboxEntry { padding: 0px; }")); // space around a message entry
    cssStyle.appendChild(document.createTextNode(".shoutbox { --shoutboxHeight: 350px; }")); // shoutbox height
    document.getElementsByTagName("head")[0].appendChild(cssStyle);
    Alles anzeigen

    Vorher/Nachher:

    Spoiler anzeigen

    MfG,

    Kanashius

  • Suche für Liste

    • Kanashius
    • 24. November 2023 um 18:45

    Hi :)
    Das hab ich tatsächlich übersehen :|

    Hier eine Lösung:

    AutoIt
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GUIListBox.au3>
    #include <ListBoxConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>
    
    Global $iWidth = 800, $iHeight = 600, $iSpace = 10, $iCtrlHeight = 25
    Global $arActions = [["Msgbox 1", "_msgbox", True], ["Msgbox 2", "_msgbox", True], ["Msgbox 3", "_msgbox", True], _
                         ["Msgbox 4", "_msgbox", True], ["Msgbox 5", "_msgbox", True], ["Msgbox 6", "_msgbox", True], _
                         ["Msgbox 7", "_msgbox", True], ["Msgbox 8", "_msgbox", True], ["Test Moin", "_testmoin", False], _
                         ["Just do", "_justdo"]]
    Global $arActionsCurr[UBound($arActions)]
    ;Local $arActions[300][3]
    ;For $i=0 To UBound($arActions)-1 Step 1
        ;$arActions[$i][0] = "Msgbox "&$i
        ;$arActions[$i][1] = "_msgbox"
        ;$arActions[$i][2] = True
    ;Next
    
    
    $hGui = GUICreate("Search test", $iWidth, $iHeight)
    GUISetFont(10, 800, 0, "MS Sans Serif")
    
    
    GUICtrlCreateLabel("Suche: ", $iSpace, $iSpace+5, 45, $iCtrlHeight-5)
    $iInputSearch = GUICtrlCreateInput("", 45+$iSpace*2, $iSpace, ($iWidth-45)-3*$iSpace, $iCtrlHeight)
    $hInputSearch = GUICtrlGetHandle($iInputSearch)
    GUICtrlSetCursor (-1, 5)
    
    $iListActions = GUICtrlCreateList("", $iSpace, $iSpace*2+$iCtrlHeight, $iWidth-2*$iSpace, $iHeight-3*$iSpace-$iCtrlHeight, BitOR($WS_BORDER, $WS_VSCROLL))
    $hListActions = GUICtrlGetHandle($iListActions)
    _FilterList()
    GUICtrlSetCursor (-1, 0)
    
    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
    GUISetState(@SW_SHOW)
    
    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                Exit
        EndSwitch
    WEnd
    
    Func _msgbox($iIndex)
        MsgBox(64, "Info", $arActions[$iIndex][0]&" >> At list index "&$iIndex&" was pressed.")
    EndFunc
    
    Func _testmoin()
        MsgBox(64, "Info", "Test Moin")
    EndFunc
    
    Func _justdo()
        MsgBox(64, "Info", "Just Do")
    EndFunc
    
    ; Error: 1 -> Illegal index argument
    ; Error: 2 -> No item selected
    ; Error: 3 -> Index not specified in action array
    Func _ActionListSelect($iIndex=Default)
        If $iIndex<>Default Then
            ; Check if the index is a number and in range
            If Not IsInt($iIndex) Or $iIndex<0 Or $iIndex>=_GUICtrlListBox_GetCount($iListActions) Then Return SetError(1, 0, -1)
            _GUICtrlListBox_SetCurSel($iListActions, $iIndex)
        EndIf
        $iIndex = _GUICtrlListBox_GetCurSel($iListActions)
        If $iIndex<0 Then Return SetError(2, 0, -1)
        _GUICtrlListBox_SetCurSel($iListActions, -1)
        If Not $iIndex<UBound($arActionsCurr) Then SetError(3, 0, -1)
        ConsoleWrite($iIndex&":"&$arActionsCurr[$iIndex]&@crlf)
        $iIndex = $arActionsCurr[$iIndex] ; map index from filtered to original
        If $arActions[$iIndex][1]<>"" Then
            If $arActions[$iIndex][2]<>"" Or $arActions[$iIndex][2] Then
                Call($arActions[$iIndex][1], $iIndex)
            Else
                Call($arActions[$iIndex][1])
            EndIf
        EndIf
    EndFunc
    
    Func _FilterList($sSearch="")
        _GUICtrlListBox_BeginUpdate($iListActions)
        _GUICtrlListBox_ResetContent($iListActions)
        Local $iCount = 0
        If $sSearch="" Then
            For $i=0 To UBound($arActions)-1 Step 1
                _GUICtrlListBox_AddString($iListActions, $arActions[$i][0])
                $arActionsCurr[$iCount] = $i
                $iCount+=1
            Next
        Else
            For $i=0 To UBound($arActions)-1 Step 1
                If StringInStr($arActions[$i][0], $sSearch, 0) Then
                    _GUICtrlListBox_AddString($iListActions, $arActions[$i][0])
                    $arActionsCurr[$iCount] = $i
                    $iCount+=1
                EndIf
            Next
        EndIf
        _GUICtrlListBox_EndUpdate($iListActions)
    EndFunc
    
    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        Local $iIDFrom = _WinAPI_LoWord($iwParam), $iCode = _WinAPI_HiWord($iwParam)
        Switch $ilParam
            Case $hInputSearch
                Switch $iCode
                    Case $EN_CHANGE
                        _FilterList(GUICtrlRead($iInputSearch))
                EndSwitch
            Case $hListActions
                If $iCode=$LBS_NOTIFY Then
                    _ActionListSelect()
                    If @error Then
                        Switch @error ; 1 cannot happen; no index provided
                            Case 2
                                MsgBox(16, "Error", "No Action was selected!")
                            Case 3
                                MsgBox(16, "Error", "There is no Action for the index of the selected item!")
                        EndSwitch
                    EndIf
                EndIf
        EndSwitch
        Return $GUI_RUNDEFMSG
    EndFunc
    Alles anzeigen

    MfG,

    Kanashius

  • Suche für Liste

    • Kanashius
    • 22. November 2023 um 22:34

    Hi,

    so würde ich das umsetzen.

    Ein Array mit allen Actions (2D mit Name zum anklicken, Function zum Aufrufen und ein Bool, ob der Index übergeben werden soll.

    Wenn man sich für WM_COMMAND Messages registriert, wird die Methode unten aufgerufen, wenn mit einem Control interagiert wird; Hier das anklicken in der Listbox und das Tippen im Inputfeld.

    Die Funktionen _ActionListSelect($iIndex=Default) und _FilterList($sSearch="") werden dann aufgerufen. Sie sind aber gleichzeitig auch so gestaltet, dass sie auch manuell aufgerufen werden können.

    Das mach ich z.B. um am Anfang die Liste zu füllen.

    AutoIt
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GUIListBox.au3>
    #include <ListBoxConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>
    
    Global $iWidth = 800, $iHeight = 600, $iSpace = 10, $iCtrlHeight = 25
    Global $arActions = [["Msgbox 1", "_msgbox", True], ["Msgbox 2", "_msgbox", True], ["Msgbox 3", "_msgbox", True], _
                         ["Msgbox 4", "_msgbox", True], ["Msgbox 5", "_msgbox", True], ["Msgbox 6", "_msgbox", True], _
                         ["Msgbox 7", "_msgbox", True], ["Msgbox 8", "_msgbox", True], ["Test Moin", "_testmoin", False], _
                         ["Just do", "_justdo"]]
    
    $hGui = GUICreate("Search test", $iWidth, $iHeight)
    GUISetFont(10, 800, 0, "MS Sans Serif")
    
    
    GUICtrlCreateLabel("Suche: ", $iSpace, $iSpace+5, 45, $iCtrlHeight-5)
    $iInputSearch = GUICtrlCreateInput("", 45+$iSpace*2, $iSpace, ($iWidth-45)-3*$iSpace, $iCtrlHeight)
    $hInputSearch = GUICtrlGetHandle($iInputSearch)
    GUICtrlSetCursor (-1, 5)
    
    $iListActions = GUICtrlCreateList("", $iSpace, $iSpace*2+$iCtrlHeight, $iWidth-2*$iSpace, $iHeight-3*$iSpace-$iCtrlHeight, BitOR($WS_BORDER, $WS_VSCROLL))
    $hListActions = GUICtrlGetHandle($iListActions)
    _FilterList()
    GUICtrlSetCursor (-1, 0)
    
    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
    GUISetState(@SW_SHOW)
    
    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                Exit
        EndSwitch
    WEnd
    
    Func _msgbox($iIndex)
        MsgBox(64, "Info", $arActions[$iIndex][0]&" >> At list index "&$iIndex&" was pressed.")
    EndFunc
    
    Func _testmoin()
        MsgBox(64, "Info", "Test Moin")
    EndFunc
    
    Func _justdo()
        MsgBox(64, "Info", "Just Do")
    EndFunc
    
    ; Error: 1 -> Illegal index argument
    ; Error: 2 -> No item selected
    ; Error: 3 -> Index not specified in action array
    Func _ActionListSelect($iIndex=Default)
        If $iIndex<>Default Then
            ; Check if the index is a number and in range
            If Not IsInt($iIndex) Or $iIndex<0 Or $iIndex>=_GUICtrlListBox_GetCount($iListActions) Then Return SetError(1, 0, -1)
            _GUICtrlListBox_SetCurSel($iListActions, $iIndex)
        EndIf
        $iIndex = _GUICtrlListBox_GetCurSel($iListActions)
        If $iIndex<0 Then Return SetError(2, 0, -1)
        _GUICtrlListBox_SetCurSel($iListActions, -1)
        If Not $iIndex<UBound($arActions) Then SetError(3, 0, -1)
        If $arActions[$iIndex][1]<>"" Then
            If $arActions[$iIndex][2]<>"" Or $arActions[$iIndex][2] Then
                Call($arActions[$iIndex][1], $iIndex)
            Else
                Call($arActions[$iIndex][1])
            EndIf
        EndIf
    EndFunc
    
    Func _FilterList($sSearch="")
        _GUICtrlListBox_BeginUpdate($iListActions)
        _GUICtrlListBox_ResetContent($iListActions)
        If $sSearch="" Then
            For $i=0 To UBound($arActions)-1 Step 1
                _GUICtrlListBox_AddString($iListActions, $arActions[$i][0])
            Next
        Else
            For $i=0 To UBound($arActions)-1 Step 1
                If StringInStr($arActions[$i][0], $sSearch, 0) Then _GUICtrlListBox_AddString($iListActions, $arActions[$i][0])
            Next
        EndIf
        _GUICtrlListBox_EndUpdate($iListActions)
    EndFunc
    
    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        Local $iIDFrom = _WinAPI_LoWord($iwParam), $iCode = _WinAPI_HiWord($iwParam)
        Switch $ilParam
            Case $hInputSearch
                Switch $iCode
                    Case $EN_CHANGE
                        _FilterList(GUICtrlRead($iInputSearch))
                EndSwitch
            Case $hListActions
                If $iCode=$LBS_NOTIFY Then
                    _ActionListSelect()
                    If @error Then
                        Switch @error ; 1 cannot happen; no index provided
                            Case 2
                                MsgBox(16, "Error", "No Action was selected!")
                            Case 3
                                MsgBox(16, "Error", "There is no Action for the index of the selected item!")
                        EndSwitch
                    EndIf
                EndIf
        EndSwitch
        Return $GUI_RUNDEFMSG
    EndFunc
    Alles anzeigen

    Ich hoffe, das hilft dir weiter.

    Mfg, Kanashius

  • _SQLite_Exec - Limit für Befehlslänge?

    • Kanashius
    • 20. November 2023 um 21:21

    Meines Wissens nach müssen nicht alle Inserts in ein _SQLite_Exec um in eine Transaktion ("BEGIN;...COMMIT;") zu kommen.

    Du solltest also einfach

    AutoIt
    _SQLite_Exec($hSQL, 'BEGIN TRANSACTION;')
    For $i=0 to 10 Step 1
        _SQLite_Exec($hSQL, StringFormat("INSERT INTO tab1 VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s');", $i, _
                             $aSplit[0], $aSplit[1], $aSplit[2], $aSplit[3], $aSplit[4], $aSplit[5]))
    Next
    _SQLite_Exec($hSQL, 'COMMIT;')

    aufrufen können.

    Ansonsten halt in mehrere Transaktionen aufteilen.

    Ich weiß nicht, ob die dann trotzdem als ein command gelten, oder nacheinander ausgeführt werden und nur für ein mögliches rollback relevant sind.

    Ansonsten dürfte das hier relevant sein:

    Code
    Maximum Length Of An SQL Statement
    
    The maximum number of bytes in the text of an SQL statement is limited to SQLITE_MAX_SQL_LENGTH which defaults to 1,000,000,000.
    
    If an SQL statement is limited to be a million bytes in length, then obviously you will not be able to insert multi-million byte strings by embedding them as literals inside of INSERT statements. But you should not do that anyway. Use host parameters for your data. Prepare short SQL statements like this:
    
        INSERT INTO tab1 VALUES(?,?,?); 
    
    Then use the sqlite3_bind_XXXX() functions to bind your large string values to the SQL statement. The use of binding obviates the need to escape quote characters in the string, reducing the risk of SQL injection attacks. It also runs faster since the large string does not need to be parsed or copied as much.
    
    The maximum length of an SQL statement can be lowered at run-time using the sqlite3_limit(db,SQLITE_LIMIT_SQL_LENGTH,size) interface.
    Alles anzeigen

    Die länge einer einzelnen insert value (die Musashi erwähnte) dürfte dabei nicht so relevant sein.

  • @SW_HIDE

    • Kanashius
    • 1. November 2023 um 02:35

    Hi :)

    C:\Utils32\svcl.exe /SetVolume "Stereomix" 80 ist Run("C:\Utils32\svcl.exe /SetVolume "Stereomix" 80, @SW_HIDE) ist kein valider AutoIt Code, von daher vermute ich einfach mal, dass du es mit Run versuchst...

    Dein Problem ist vermutlich, dass du " zeichen in dem Befehl hast, weil der Lautsprechername Leerzeichen enthält.

    In AutoIt werden Quotes (") für Strings genutzt. Um das Zeichen in einem String zu haben musst du entweder das Alternative Zeichen ' nutzen, um den String zu umschließen, oder du musst die " escapen, was in AutoIt mit Doppelung => "" gemacht wird.

    Also:

    AutoIt
    Local $sString
    $sString = "Dies ist ein String"
    $sString = 'Dies ist ein "String"'
    $sString = "Dies ist ein ""String"""
    $sString = "Dies ist ein " & '"' & "String" & '"'

    Um mehrfach den gleichen Code zu vermeiden und Fehlerbehandlung hinzuzufügen, würde ich das ganze vermutlich so, oder so ähnlich umsetzen:

    AutoIt
    ; https://www.nirsoft.net/utils/sound_volume_command_line.html
    Local $sNvidia = "NVIDIA High Definition Audio\Device\ROG PG348Q\Render", $sHighDef = "High Definition Audio Device\Device\Lautsprecher\Render", $sStereomix = "Stereomix", $sSpeaker = "Lautsprecher"
    
    _audioSetVolume($sStereomix, 80)
    If @error Then MsgBox(16, "Error", @error&":"&@extended)
    _audioSetState($sNvidia, False)
    If @error Then MsgBox(16, "Error", @error&":"&@extended)
    _audioSetState($sNvidia)
    If @error Then MsgBox(16, "Error", @error&":"&@extended)
    _audioSetDefault($sHighDef)
    If @error Then MsgBox(16, "Error", @error&":"&@extended)
    _audioSetVolume($sSpeaker, 60)
    If @error Then MsgBox(16, "Error", @error&":"&@extended)
    
    Func _audioSetVolume($sSpeaker, $iVolume)
        _runUtils("/SetVolume", $sSpeaker, String($iVolume))
        If @error Then Return SetError(@error, @extended, -1)
        Return 1
    EndFunc
    
    Func _audioSetDefault($sSpeaker, $bAll = True)
        If $bAll Then
            _runUtils("/SetDefault", $sSpeaker, "all")
        Else
            _runUtils("/SetDefault", $sSpeaker)
        EndIf
        If @error Then Return SetError(@error, @extended, -1)
        Return 1
    EndFunc
    
    Func _audioSetState($sSpeaker, $bEnable = True, $bAll = True)
        If $bAll Then
            _runUtils($bEnable?"/Enable":"/Disable", $sSpeaker, "all")
        Else
            _runUtils($bEnable?"/Enable":"/Disable", $sSpeaker)
        EndIf
        If @error Then Return SetError(@error, @extended, -1)
        Return 1
    EndFunc
    
    Func _runUtils($sCommand, $sParam0 = Default, $sParam1 = Default, $sParam2 = Default, $sParam3 = Default, $sParam4 = Default, $sParam5 = Default)
        For $i=0 To @NumParams-2 Step 1
            Local $sParam = String(Eval("sParam"&$i))
            If StringInStr($sParam, " ") Then $sParam='"'&$sParam&'"'
            $sCommand&=" "&$sParam
        Next
        ConsoleWrite("C:\Utils32\svcl.exe "&$sCommand&@crlf)
        Run("C:\Utils32\svcl.exe "&$sCommand, @ScriptDir, @SW_HIDE)
        ; or this:  ShellExecute("C:\Utils32\svcl.exe", $sCommand, @ScriptDir, @SW_HIDE)
        If @error Then Return SetError(1, @error, -1)
        ; todo: use the stdout to check if the command was successful
        Return 1
    EndFunc
    Alles anzeigen
  • MySQL - externe Datenbankabfrage

    • Kanashius
    • 30. Oktober 2023 um 20:36

    Hi :)
    Deine Fehlermeldung zeigt, dass die genutzte Version von MySQL zu alt ist und nicht mehr funktioniert.

    Laut https://github.com/BugFix/AutoIt_…sql_version.au3 nutzt die UDF MySQL 5.1.37

    Wenn man auf https://endoflife.date/mysql geht, kann man sehn, dass das schon länger nicht mehr unterstützt wird und nach dem was ich gelesen habe auch keine Verschlüsselung (TLS) unterstützt.

    Sprich: Jeder MITM (man in the middle) kann mitlesen, was du über die Verbindung sendest/empfängst.

    Wenn ne Webseite dir also die Verbindung damit erlaubt, würde ich mir überlegen den Anbieter zu wechseln, der scheint nämlich keinen großen Wert auf Sicherheit zu legen.

  • Fehlermeldungen unterdrücken allgemein

    • Kanashius
    • 25. Oktober 2023 um 21:22

    Ich würde sagen: Wissen ist macht ;) .

    Also füg am besten logging zu deinem Programm hinzu, sodass du herausfinden kannst, wo genau das Programm hängen bleibt, sodass du das beheben kannst.

    Ein "Hilfsprogramm" zum beenden ist keine wirklich gute Lösung, sondern nur ein (meiner Meinung nach schlechter) Workaround, weil das eigentliche Problem komplett ignoriert wird.

    Und ja, Fehlersuche+Behebung kann nervig sein, dafür wird man mit einem gut laufenden Programm belohnt :)

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™