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. Friesel

Beiträge von Friesel

  • GDIPlus-HoverButton Problem

    • Friesel
    • 12. Juni 2017 um 14:22

    Hi!

    Wenn du es so machst, wie autoiter es empfiehlt (ich würde allerdings ein Local Static Flag verwenden), wirst du feststellen, daß der Aufruf von _GDIPlus_GraphicsFillRect im else Zweig einen Fehler wirft.

    Da ich aber im Moment weder Zeit, noch Lust habe, den Fehler zu ergründen und außerdem kein großer Fan von GDI bin, hier ein Vorschlag zur Umsetzung des Hover Buttons mit Labels:

    Spoiler anzeigen
    AutoIt
    #include <StaticConstants.au3>
    #include <GUIConstantsEx.au3>
    
    
    Global $hGui = GUICreate("Hover Label", 400, 70)
    Global $idLabelBackground = GUICtrlCreateLabel("", 17, 17, 366, 36)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlSetBkColor(-1, 0xF0F0F0)
    Global $idLabelFrame = GUICtrlCreateLabel("", 19, 19, 362, 32, $SS_BLACKFRAME)
    GUICtrlSetState(-1, $GUI_DISABLE)
    Global $idLabelHover = GUICtrlCreateLabel("Please hover brother!", 20, 20, 360, 30, BitOR($SS_CENTER, $SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFF0000)
    GUICtrlSetFont(-1, 12, 400)
    
    
    GUISetState()
    
    
    Global $bHoverFlag = 0
    Do
    	$idMsg = GUIGetMsg()
    	Switch $idMsg
    		Case $idLabelHover
    			MsgBox(0, "", "Successfully hovered!")
    	EndSwitch
    	$aMousePos = GUIGetCursorInfo($hGui)
    	Switch IsArray($aMousePos)
    		Case True
    			Select
    				Case $aMousePos[4] = $idLabelHover And $bHoverFlag = 0
    					GUICtrlSetBkColor($idLabelHover, 0x00FF00)
    					GUICtrlSetBkColor($idLabelBackground, 0x000000)
    					GUICtrlSetData($idLabelHover, "Click me now!")
    					GUICtrlSetFont($idLabelHover, 16, 800)
    					$bHoverFlag = 1
    				Case $aMousePos[4] <> $idLabelHover And $bHoverFlag = 1
    					GUICtrlSetBkColor($idLabelHover, 0xFF0000)
    					GUICtrlSetBkColor($idLabelBackground, 0xF0F0F0)
    					GUICtrlSetData($idLabelHover, "Please hover brother!")
    					GUICtrlSetFont($idLabelHover, 12, 400)
    					$bHoverFlag = 0
    			EndSelect
    	EndSwitch
    Until $idMsg = $GUI_EVENT_CLOSE
    Alles anzeigen


    Ist ganz flott in 10 Minuten runtergeschrieben und läßt sich vermutlich eleganter lösen, aber es sollte gut verständlich sein und zeigen, wie einfach man es sich machen kann...ganz ohne GDI :rock:
    Erweiterte Animationen, wie bei "OnClick" sind mit Labels auch kein Problem...

    Beste Grüße, Friesel

  • Bräuchte Hilfe bei der Umsetzung meiner IP Abfrage

    • Friesel
    • 18. Mai 2017 um 11:30
    Zitat von alpines

    http://myexternalip.com/raw ;)

    Auf diesen Seiten ist sowas wie der PHP-Einzeiler aus meinem Tipp installiert 8)

  • Bräuchte Hilfe bei der Umsetzung meiner IP Abfrage

    • Friesel
    • 18. Mai 2017 um 00:46
    Zitat von alpines


    Das Pattern. Hört sich nicht nur besser an sondern passt auch mit dem deutschen Artikel zu 'das Muster'.

    Ja, hast recht. Hat mir mittlerweile auch MS Word bestätigt ;)

    Zitat von alpines


    Kann man so machen, dann kann man sich aber auch die \d-Teile sparen, weil es auf der Seite sicherlich nur einen Bereich mit title="Copy to clipboard"<ip></strong> gibt.
    Wenn man es unbedingt mit RegEx machen will sollte man auch die IP-Ranges betrachten und ins Pattern einpflegen, denn nach deiner Lösung wäre 999.999.999.999 akzeptiert.


    Du hast meinen Text nicht wirklich durchgelesen, oder?

    Zitat von Friesel

    Beide Pattern matchen einen Bereich von 0.0.0.0 (bzw. 000.000.000.000) bis 999.999.999.999, der Pattern von _StringBetween matcht ALLES was zwischen ...><... steht.
    Das lässt sich natürlich noch weiter spezialisieren, in dem man wirklich ausschließlich den Bereich von 0.0.0.0 bis 255.255.255.255 abdeckt, ist aber hier meiner Meinung nach nicht nötig.


    Weiterhin schreibe ich "Da Du nach einem Regex Pattern fragst..." und das _StringBetween auch nur einen regülären Ausdruck benutzt.
    Zwischen den Zeilen kann man mit etwas gutem Willen durchaus erkennen, das ich Regex in diesem Fall nicht unbedingt für notwendig erachte (abgesehen vom letzten, verallgemeinerten Pattern, das halt auch diverse Änderungen im Quelltext berücksichtigen kann.

  • Bräuchte Hilfe bei der Umsetzung meiner IP Abfrage

    • Friesel
    • 18. Mai 2017 um 00:12

    Hi!

    1. Das was Alpines und BLinz schreiben... ;)

    2. Da Du nach einem Regex Pattern fragst...
    _StringBetween selbst benutzt auch nur einen sehr simplen Regex Pattern, nämlich folgenden:

    '(?i)title="Copy to clipboard">(.*?)</strong>' (case insensitive)

    der Pattern (oder heißt es "das" Pattern?) lässt sich noch auf IP's anpassen, z.B. so:

    '(?i)title="Copy to clipboard">(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})</strong>'

    oder so:

    '(?i)title="Copy to clipboard">((?:\d{1,3}\.){3}\d{1,3})</strong>'

    Beide Pattern matchen einen Bereich von 0.0.0.0 (bzw. 000.000.000.000) bis 999.999.999.999, der Pattern von _StringBetween matcht ALLES was zwischen ...><... steht.
    Das lässt sich natürlich noch weiter spezialisieren, in dem man wirklich ausschließlich den Bereich von 0.0.0.0 bis 255.255.255.255 abdeckt, ist aber hier meiner Meinung nach nicht nötig.


    Der Nachteil bei allen diesen Pattern ist, sobald sich der Quelltext der Seite ändert, wird die IP darin nicht mehr gefunden. Man kann versuchen, dem entgegenzuwirken, in dem man den Pattern verallgemeinert. Etwa in dieser Art:
    '(?i)title=".+">((?:\d{1,3}\.){3}\d{1,3})</.+>'
    Jetzt kann sich sowohl der Titel, als auch das Attribut (strong) ändern, ohne das die IP "verloren" geht.


    3. Hier noch ein Tipp, wenn du ganz unabhängig von Seiten wie whoer.net sein willst (ich selbst mache es auch so):
    Besorg dir irgendeinen kostenlosen HTTP-Server (z.B. bei http://bplaced.net) und lade dort ein PHP-Script hoch, das die IP eines Besuchers anzeigt.

    PHP
    <?php
        echo $_SERVER['REMOTE_ADDR'];  
    ?>

    Das obige Skript in eine Textdatei kopieren, diese in "index.php" umbenennen und ins Stammverzeichnis deines Servers hochladen.
    Wenn jetzt jemand diese Seite (mit "deinName.bplaced.net") aufruft, wird nichts als dessen IP-Adresse angezeigt und du kannst dir _StringBetween oder reguläre Ausdrücke sparen, weil _WinHttpSimpleRequest nur die IP zurückgibt.


    Viel Erfolg, Friesel

  • Ich finde keinen Fehler:

    • Friesel
    • 29. April 2017 um 09:01
    Zitat von alpines

    Die "unterste Ebene" von der du sprichst nennt sich das globale Scope.
    Es ist nicht verkehrt vor der Variable global zu schreiben, wenn es einem dabei hilft den Code leserlicher zu gestalten.
    Es ist einfach nur überflüssig aber der Code wird dadurch kaum an Geschwindigkeit im Interpreter verlieren.

    Bei Arrays ist es sowieso notwendig (wenn man kein Dim) verwendet um sie überhaupt erstellt zu kriegen.
    Außerdem kann man dazu noch die Variablen deklarieren ohne ihnen einen Inhalt zu geben.

    Dessen bin ich mir natürlich in allen Punkten bewußt.
    Ich wollte das nur nochmal herausstellen, weil man gerade bei Anfängern immer wieder sieht, dass sie "auf der untersten Ebene" (ja, ich weiß wie das richtig heißt, wollte es aber Anfängerfreundlich formulieren :D ) Variablen lokal deklarieren und denken, es hätte eine Auswirkung.
    Trotz allem gebe ich dir recht, das hätte ich besser formulieren können ;)

  • Ich finde keinen Fehler:

    • Friesel
    • 29. April 2017 um 08:43
    Zitat von pltnpcs



    Ich finde keinen Fehler

    Guter Witz...die einzigen Zeilen, die keinen Fehler enthalten, sind von Koda generiert :rofl:
    Ich werde jetzt bewußt nicht auf die einzelnen Fehler eingehen, weil dir ganz offensichtlich die einfachsten Grundlagen fehlen.

    Bevor du dich an sowas wagst, solltest du viel, viel lesen, Tutorials durcharbeiten UND verstehen.
    Vor allem solltest du die Hilfe zu den von dir verwendeten Befehlen und hier besonders die Anmerkungen durchlesen ("Remarks", falls du die englische Hilfe hast) :rtfm:
    Hättest du das getan, wären dir viele Fehler sicherlich nicht unterlaufen.

    Nichts­des­to­trotz, weils dafür keine Standard Lösung gibt, hier mein Vorschlag, um das Input Feld auszulesen, wenn die Enter Taste gedrückt wird.
    Eins noch vorweg: NIEMALS HotKeySet für die eigene Gui verwenden, wenn es sich vermeiden läßt. So wie du es "programmiert" hast, wird die Enter Taste im ganzen System blockiert.
    Um das Input Feld so zu verwenden wie du es planst, kannst du z.B. sogenannte "Accelerator keys" verwenden:

    Spoiler anzeigen
    AutoIt
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WinAPI.au3>
    
    
    ;"Global" ist hier eigendlich überfüssig, weil ALLE Variablen auf der "untersten Ebene" Global sind, egal wie sie deklariert werden
    Global $hGui = GUICreate("Demo", 400, 100)
    ;Controls
    Global $idInput = GUICtrlCreateInput("", 10, 10, 380, Default)
    Global $hInput = GUICtrlGetHandle($idInput) ;die Funktion "_WinAPI_GetFocus" benötigt ein Handle, keine ID
    Global $idLabelOutput = GUICtrlCreateLabel("", 10, 40, 380, 50, BitOR($SS_CENTERIMAGE, $SS_CENTER))
    ;Accelerator key
    Global $idDummy = GUICtrlCreateDummy()
    Global $aAccelKeys[1][2] = [["{ENTER}", $idDummy]]
    GUISetAccelerators($aAccelKeys, $hGui)
    
    
    GUISetState(@SW_SHOW, $hGui)
    
    
    While True
    	$idMsg = GUIGetMsg()
    	Switch $idMsg
    		Case $GUI_EVENT_CLOSE
    			;beendet nicht das Skript, sondern springt nur aus der While/WEnd Schleife.
    			;Exit (Zeile 37) ist eigendlich überflüssig, weil keine weiteren Befehle folgen.
    			;Die Funktion wird nur ausgeführt, wenn sie aufgerufen wird
    			ExitLoop
    		Case $idDummy
    			;Befehle können auch hier ausgeführt werden. Nicht nötig eine Funktion aufzurufen, ist aber übersichtlicher
    
    
    			;==> reagiert nur, wenn die Input Box Fokus hat.
    			;==> Die Fokus Abfrage man auch weglassen, wenn Input immer ausgelesen werden soll (solange die Gui Fokus hat)
    			If _WinAPI_GetFocus() = $hInput Then
    				_BeliebigeFunktion()
    			EndIf
    	EndSwitch
    WEnd
    
    
    Exit
    
    
    Func _BeliebigeFunktion()
    	GUICtrlSetData($idLabelOutput, GUICtrlRead($idInput))
    	GUICtrlSetData($idInput, "")
    EndFunc
    Alles anzeigen

    Viel Erfolg beim Lernen, Friesel

  • Scite Speicherfehler

    • Friesel
    • 21. April 2017 um 21:16

    Hi!

    Sowas ist mir auch mal passiert.
    Bei mir war die Festplatte, auf der das Script gespeichert war, defekt. Datenrettung hatte ich erfolglos versucht.

    Das Gute daran ist, wenn man ein Programm/Projekt komplett neu von Grund auf erstellt, wird es (zumindest bei mir) deutlich besser... ;)

    In diesem Sinne, versuch das Ganze positiv zu sehen :thumbup:

    LG Friesel

  • WinAPIGdi: Seltsames Verhalten bei Skalierung eines Bildes mit _WinAPI_AdjustBitmap

    • Friesel
    • 19. März 2017 um 10:37

    Vielen Dank für den Hinweis. Werde ich mir ansehen...
    Witzigerweise hatte ich die UDF sogar schon auf Festplatte, aber nie wirklich reingeschaut, und außerdem vergessen, dass ich sie überhaupt hatte...

  • Funktionen zur Anzeige von Markierungen

    • Friesel
    • 19. März 2017 um 09:32

    Moin!

    Ich habe mich schon vor einiger Zeit an etwas Ähnlichem versucht. Hab das Programm aber nie zuende geführt.
    Der Ansatz ist vieleicht etwas unorthodox, kommt aber ganz ohne GDI aus und benötigt nur ein "bisschen" WinApi ;)

    Es funktioniert für beliebige Fenster, was das Ganze komplizierter macht, als bei der Verwendung von selbst erstellen Guis. Daher musste ich auch die Bewegung des Child Fensters registrieren und nicht wie es sein sollte, des Parent Fensters.
    Wenn dir das so rum nicht gefällt, solltest du dir den Befehl _WinAPI_SetParent in Verbindung mit _WinAPI_SetWindowLong ansehen. Damit kann man ein beliebiges Fenster mit dem Popup Style versehen und als Child einbinden.

    Die Klassen bzw. Namen der Controls kannst du ja mit einem Tool wie Au3Info anzeigen lassen und entsprechend im Skript verwenden. Ansonsten gibts hier eine UDF von Großvater, die alle Controls eines Fensters ausliest (noch nicht von mir getestet).
    Du kannst selbstverständlich auch beliebig mit GDI+ in der transparenten Gui malen, aber der Einfachheit halber habe ich Labels verwedet.

    Funktioniert ziemlich gut mit Scite oder Au3Info als zu "verunstaltendem" Fenster. Andere Fenster, wie z.B. die AutoIt Hilfe oder der Explorer machen Probleme, was ich aber nicht weiter ergründet habe. Musst du einfach mal selbst rumprobieren ;)

    Die Funktionen "_TagControl" und "_CreateThickFrame" habe ich bewusst getrennt, so dass man mit "_CreateThickFrame" eigene Rahmen "von Hand" erstellen kann.
    Achtung: Später gezeichnete Rahmen überlagern komplett vorher erstellte.

    Hier das Skript (nicht das Sauberste:(

    Spoiler anzeigen
    AutoIt
    #include <WindowsConstants.au3>
    #include <GUIConstants.au3>
    #include <StaticConstants.au3>
    #include <WinAPI.au3>
    #include <WinAPIShPath.au3>
    #include <Array.au3>
    #include <GDIPlus.au3>
    
    
    Opt("MustDeclareVars", 1)
    
    
    Global $iPid, $iXParent, $iYParent, $iWidthParent, $iHeightParent, $idFirstControl, $idLastControl
    Global $hWin, $aPos, $iClientHeight, $hChild, $idButtonClose, $idButtonDelete, $hTimerP, $iMsg
    
    
    _Au3InfoDemo() ;Au3Info starten und einige Controls umranden
    
    
    ;Demo mit Scite starten (Scite muss geöffnet sein)
    $hWin = WinGetHandle("[CLASS:SciTEWindow]")
    $aPos = WinGetPos($hWin, "")
    If IsArray($aPos) Then
    	;Koordinaten auf popup Fenster umrechnen
    	$iXParent = $aPos[0]
    	$iYParent = $aPos[1]
    	$iWidthParent = $aPos[2] - 16
    	$iHeightParent = $aPos[3] - 8
    Else
    	Exit ;kein Array, keine Demo ;)
    EndIf
    $iClientHeight = $iHeightParent - _WinAPI_GetClientHeight($hWin) ;Höhe des Parent Fensters ohne Titelleiste und Menü
    $hChild = GUICreate("childish", $iWidthParent, $iHeightParent, -5, -56, BitOR($WS_BORDER, $WS_POPUP, $WS_MINIMIZEBOX, $WS_SYSMENU), BitOR($WS_EX_MDICHILD, $WS_EX_LAYERED, $WS_EX_TOOLWINDOW), $hWin)
    GUISetBkColor(0xF0F0F0)
    
    
    $idButtonClose = GUICtrlCreateButton("Overlay schließen", $iWidthParent - 139, 29, 139, 22)
    $idButtonDelete = GUICtrlCreateButton("Controls durchlaufen", $iWidthParent - 278, 29, 139, 22)
    
    
    ;nur zu Demozwecken um durch die Controls zu iterieren
    Global $aSciteControls[] = ["[CLASS:ToolbarWindow32]", "[CLASS:SciTeTabCtrl]", "[CLASS:Scintilla; INSTANCE:1]", "[CLASS:Scintilla; INSTANCE:2]", "[CLASS:msctls_statusbar32]"]
    
    
    _WinAPI_SetLayeredWindowAttributes($hChild, 0xF0F0F0, 0)
    ;~ _WinAPI_SetLayeredWindowAttributes($hChild, 0xF0F0F0, 255) ;==> ohne Fade Effekt hier Transparenz setzen und obige Zeile loeschen/auskomentieren
    GUIRegisterMsg($WM_MOVE, "_WM_MOVE") ;wenn Child bewegt wird, wird ich Parent bewegt
    
    
    ;"Titelleiste" als letztes zeichnen, damit sie über allen anderen Rahmen liegt
    GUICtrlCreateLabel("", 26, 0, $iWidthParent - 162, 29, -1, $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    
    
    GUISetState(@SW_SHOW, $hChild)
    
    
    _CtrlIterate() ;Controls nacheinander einrahmen und Disko machen ;)
    _ShowAll() ;alle auf einmal zeigen
    
    
    $hTimerP = TimerInit()
    Do
    	$iMsg = GUIGetMsg()
    	Switch $iMsg
    		Case $idButtonDelete
    			For $iID = $idFirstControl - 1 To $idLastControl Step 2
    				GUICtrlDelete($iID)
    				GUICtrlDelete($iID + 1)
    			Next
    			_CtrlIterate()
    			_ShowAll()
    	EndSwitch
    	;wenn Programm aus dem Skript gestartet wurde und geschlossen wird, endet auch das Skript
    	If TimerDiff($hTimerP) > 100 And $iPid Then ;nicht übertrieben häufig überprüfen, weil das zu Lasten von GUIGetMsg ist
    		Switch ProcessExists($iPid)
    			Case False
    				Exit
    		EndSwitch
    		$hTimerP = TimerInit()
    	EndIf
    Until $iMsg = $idButtonClose
    
    
    _FadeOut() ;Programmende
    
    
    
    
    Func _ShowAll() ; IMMER alle Labels unmittelbar nacheinander erstellen, damit man durch iterieren kann
    	Local $idLabelTest, $aCtrlPos
    	;Rueckgabewert ist die ID des jeweiligen inneren (Text-)Labels -> bei Bedarf auf ausseren Label in den Fktn "_TagControl" und "_CreateThickFrame" umstellen
    	;nur benötigte Variablen zuweisen
    	$idFirstControl = 	_TagControl("[CLASS:ToolbarWindow32]", 0xFF0000, 1) ;IDs vom ersten und letzten Label werden zum iterieren in _CtrlIterate() benötigt
    				_TagControl("[CLASS:SciTeTabCtrl]", 0x0000FF, 2)
    	$idLabelTest = 		_TagControl("[CLASS:Scintilla; INSTANCE:1]", 0x00FF00, 10)
    				_TagControl("[CLASS:Scintilla; INSTANCE:2]", 0xFFFF00, 6)
    	$idLastControl = 	_TagControl("[CLASS:msctls_statusbar32]", 0x0F0F0F)
    	;zwei Rahmen "von Hand" erstellen
    	$aCtrlPos = ControlGetPos($hChild, "", $idLabelTest)
    	If IsArray($aCtrlPos) Then
    		$idLastControl = _CreateThickFrame($aCtrlPos[0] + $aCtrlPos[2] * 2 / 3, $aCtrlPos[1], $aCtrlPos[2] / 3, $aCtrlPos[3], 0xFF7700, 16, "Benutzerdefinierter Rahmen")
    		$aCtrlPos = ControlGetPos($hChild, "", $idLastControl)
    		If IsArray($aCtrlPos) Then
    			$idLastControl = _CreateThickFrame($aCtrlPos[0], $aCtrlPos[1], $aCtrlPos[2], $aCtrlPos[3] / 2 - 20, 0x41D5C4, 8, "Benutzerdefinierter Rahmen")
    		EndIf
    	EndIf
    	_FadeIn()
    EndFunc   ;==>_ShowAll
    
    
    Func _CtrlIterate()
    	Local $idTemp
    	GUICtrlSetState($idButtonClose, $GUI_HIDE)
    	GUICtrlSetState($idButtonDelete, $GUI_HIDE)
    	For $iControl = 0 To UBound($aSciteControls) - 1
    		$idTemp = _TagControl($aSciteControls[$iControl], 0xFF0000, 4)
    		_FadeIn()
    		Sleep(500)
    		Local $iColor = 0x00FF00
    		For $iFlicker = 1 To 10
    			$iColor = BitXOR($iColor, 0x00FF00, 0xFFFF00) ;gehört in jede Sammlung: Wechsel zwischen zwei Werten
    			GUICtrlSetBkColor($idTemp - 1, $iColor)
    			GUICtrlSetColor($idTemp, $iColor)
    			Sleep(100)
    		Next
    		GUICtrlSetBkColor($idTemp - 1, 0xFF0000) ;äusserer Label
    		GUICtrlSetColor($idTemp, 0xFF0000) ;innerer Label
    		_FadeOut()
    		GUICtrlDelete($idTemp - 1)
    		GUICtrlDelete($idTemp)
    	Next
    	GUICtrlSetState($idButtonClose, $GUI_SHOW)
    	GUICtrlSetState($idButtonDelete, $GUI_SHOW)
    EndFunc   ;==>_CtrlIterate
    
    
    Func _TagControl($sName, $iColor = 0xFF0000, $iThickness = 4)
    	Local $aControlPos, $idLabel = ""
    	Select
    		Case $iColor = Default Or $iColor = -1
    			$iColor = 0xFF0000
    		Case $iThickness = Default Or $iThickness = 4
    			$iThickness = 4
    	EndSelect
    
    
    	$aControlPos = ControlGetPos($hWin, "", ControlGetHandle($hWin, "", $sName))
    	If IsArray($aControlPos) Then
    		$idLabel = _CreateThickFrame($aControlPos[0], $aControlPos[1] + $iClientHeight, $aControlPos[2], $aControlPos[3], $iColor, $iThickness, $sName)
    	EndIf
    	Return $idLabel
    EndFunc   ;==>_TagControl
    
    
    Func _CreateThickFrame($iXpos, $iYpos, $iWidth, $iClientHeightght, $iColor = 0xFF0000, $iThickness = 4, $sText = "")
    	Local $idLabel
    	Select
    		Case $iColor = Default Or $iColor = -1
    			$iColor = 0xFF0000
    		Case $iThickness = Default Or $iThickness = 4
    			$iThickness = 4
    	EndSelect
    
    
    	GUICtrlCreateLabel("", $iXpos, $iYpos, $iWidth, $iClientHeightght)
    	GUICtrlSetState(-1, $GUI_DISABLE)
    	GUICtrlSetBkColor(-1, $iColor)
    	$idLabel = GUICtrlCreateLabel($sText, $iXpos + $iThickness, $iYpos + $iThickness, $iWidth - $iThickness * 2, $iClientHeightght - $iThickness * 2, BitOR($SS_CENTER, $SS_CENTERIMAGE))
    	GUICtrlSetFont(-1, -1, 900)
    	GUICtrlSetColor(-1, $iColor)
    	Return $idLabel
    EndFunc   ;==>_CreateThickFrame
    
    
    Func _FadeIn()
    	For $i = 1 To 255 Step 5
    		_WinAPI_SetLayeredWindowAttributes($hChild, 0xF0F0F0, $i)
    		Sleep(6)
    	Next
    EndFunc   ;==>_FadeIn
    
    
    Func _FadeOut()
    	For $i = 255 To 0 Step -5
    		_WinAPI_SetLayeredWindowAttributes($hChild, 0xF0F0F0, $i)
    		Sleep(4)
    	Next
    EndFunc   ;==>_FadeOut
    
    
    Func _WM_MOVE($hChild, $iMsg, $wParam, $lParam)
    	Local $aPos = WinGetPos($hChild)
    	If UBound($aPos) = 4 Then
    		WinMove($hWin, "", $aPos[0] - 8, $aPos[1])
    	EndIf
    	Return $GUI_RUNDEFMSG
    EndFunc   ;==>_WM_MOVE
    
    
    Func _Au3InfoDemo()
    	$iPid = Run(_WinAPI_PathRemoveFileSpec(@AutoItExe) & (@CPUArch = "X86" ? "\Au3Info.exe" : "\Au3Info_x64.exe"))
    	ProcessWait($iPid)
    	$hWin = WinGetHandle("[CLASS:Au3Info]")
    	$aPos = WinGetPos($hWin, "")
    	If IsArray($aPos) Then
    		;Koordinaten auf popup Fenster umrechnen
    		$iXParent = $aPos[0]
    		$iYParent = $aPos[1]
    		$iWidthParent = $aPos[2] - 16
    		$iHeightParent = $aPos[3] - 8
    	Else
    		Exit
    	EndIf
    	$iClientHeight = $iHeightParent - _WinAPI_GetClientHeight($hWin)
    	$hChild = GUICreate("childish", $iWidthParent, $iHeightParent, -5, -56, BitOR($WS_BORDER, $WS_POPUP, $WS_MINIMIZEBOX, $WS_SYSMENU), BitOR($WS_EX_MDICHILD, $WS_EX_LAYERED, $WS_EX_TOOLWINDOW), $hWin)
    	GUISetBkColor(0xF0F0F0)
    	$idButtonClose = GUICtrlCreateButton("Overlay schließen", $iWidthParent - 139, 29, 139, 22)
    	_WinAPI_SetLayeredWindowAttributes($hChild, 0xF0F0F0, 0)
    ;~ 	_WinAPI_SetLayeredWindowAttributes($hChild, 0xF0F0F0, 255) ;==> ohne Fade Effekt hier Transparenz setzen und obige Zeile loeschen/auskomentieren
    	GUIRegisterMsg($WM_MOVE, "_WM_MOVE")
    	;"Titelleiste" als letztes zeichnen, damit sie über allen anderen Rahmen liegt
    	GUICtrlCreateLabel("", 26, 0, $iWidthParent - 162, 29, -1, $GUI_WS_EX_PARENTDRAG)
    	GUICtrlSetBkColor(-1, 0xFFFFFF)
    	GUISetState(@SW_SHOW, $hChild)
    	_TagControl("[CLASS:Edit; INSTANCE:1]", 0x00FF00, 1)
    	_TagControl("[CLASS:Edit; INSTANCE:2]", 0x00FF00, 1)
    	_TagControl("[CLASS:Edit; INSTANCE:3]", 0x00FF00, 1)
    	_TagControl("[CLASS:Edit; INSTANCE:4]", 0x00FF00, 1)
    	_TagControl("[CLASS:SysTabControl32]", 0xFF0000, 2)
    
    
    	_FadeIn()
    
    
    	$hTimerP = TimerInit()
    	Do
    		$iMsg = GUIGetMsg()
    		;wenn Programm aus dem Skript gestartet wurde (wie hier Au3Info) und geschlossen wird, endet auch das Skript bzw wird das Child Fenster geschlossen
    		If TimerDiff($hTimerP) > 100 And $iPid Then ;nicht übertrieben häufig überprüfen, weil das zu Lasten von GUIGetMsg ist
    			Switch ProcessExists($iPid)
    				Case False
    					$iPid = 0
    					GUIDelete($hChild)
    					Return
    			EndSwitch
    			$hTimerP = TimerInit()
    		EndIf
    	Until $iMsg = $idButtonClose
    
    
    	$iPid = 0
    	_FadeOut()
    	GUIDelete($hChild)
    EndFunc   ;==>_Au3InfoDemo
    Alles anzeigen

    Das sieht zwar jetzt nach sehr viel Code aus, aber das Meiste ist nur Demo.
    Was du letzten Endes brauchst, ist die Erstellung der Child Gui und die Funktionen "_TagControl" und "_CreateThickFrame"

    ==> siehe Funktion "_Au3InfoDemo"


    Anmerkung: Ich war nie wirklich zufrieden damit, was wohl auch der Grund ist, weshalb ich nicht weiter gemacht habe.

    • die Größe des "Parent" Fensters läßt sich ändern, ohne dass die Child Gui sich ändert (kann man verbessern, denke ich).
    • an bestimmten Stellen ist es möglich, das "Parent" Fenster ohne das Child zu bewegen. Immerhin funktioniert aber das minimieren...
    • der Fenstertitel wird überdeckt

    Beste Grüße, Friesel

  • WinAPIGdi: Seltsames Verhalten bei Skalierung eines Bildes mit _WinAPI_AdjustBitmap

    • Friesel
    • 16. März 2017 um 18:46

    Mahlzeit!

    Ich habs dann jetzt doch erstmal mit "WM_ERASEBKGND" in Verbindung mit _WinAPI_UpdateWindow umgesetzt.

    Das ist auch bei übergroßen Bildern wie im unten stehenden Beispiel sehr performant:

    Spoiler anzeigen
    AutoIt
    #include <GUIConstants.au3>
    #include <WinAPIGdi.au3>
    #include <GdiPlus.au3>
    
    
    Global $hGui = GUICreate("Beweg mich außerhalb des Desktops und zurück!", 3000, 3000, 0, 0)
    Global $idPic = GUICtrlCreatePic("", 0, 0, 3000, 3000)
    If Not InetGet("https://interfacelift.com/wallpaper/7yz4ma1/04106_wwww_1920x1080.jpg", @TempDir & "/04106_wwww_1920x1080.jpg") Then Exit
    
    
    GUIRegisterMsg($WM_ERASEBKGND, "_WM_ERASEBKGND")
    
    
    GUISetState()
    
    
    _SetPic($HALFTONE)
    
    
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    
    
    _SetPic()
    
    
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    
    
    Func _SetPic($iHalftone = Default)
    	_GDIPlus_StartUp()
    	Local $hImage = _GDIPlus_ImageLoadFromFile(@TempDir & "/04106_wwww_1920x1080.jpg")
    	Local $hBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    	Local $hResize = _WinAPI_AdjustBitmap($hBmp, 3000, 3000, $iHalftone)
    	;~ 	_SendMessage(GUICtrlGetHandle($idPic), 0x0172, 0, $hResize)
    	GUICtrlSendMsg($idPic, 0x0172, 0, $hResize)
    	_WinAPI_DeleteObject($hResize)
    	_WinAPI_DeleteObject($hBmp)
    	_GDIPlus_ImageDispose($hImage)
    	_GDIPlus_Shutdown()
    EndFunc
    
    
    Func _WM_ERASEBKGND()
    	_WinAPI_UpdateWindow($hGui)
    	Return True
    EndFunc
    Alles anzeigen


    Falls aber dennoch jemand eine Lösung für mein ursprüngliches Problem anzubieten hat, wäre ich nicht abgeneigt.
    Deshalb lasse ich das Thema auch vorerst offen...

    Beste Grüße, Friesel!

  • WinAPIGdi: Seltsames Verhalten bei Skalierung eines Bildes mit _WinAPI_AdjustBitmap

    • Friesel
    • 16. März 2017 um 15:32

    Hallo zusammen!

    Ich möchte ein Bild auf eine Gui zeichnen. Da auch PNG's zur Verwendung kommen, muss ich einen "Umweg" nehmen, um trotzdem GUICtrlCreatePic verwenden zu können.
    Der Vorteil ist, dass man sich dann nicht mehr um re-paint Aktionen kümmern muss, wenn sich Teile der Gui außerhalb des Desktops befinden.
    Des weiteren sieht das mit Hilfe des StretchBltMode "Halftone" skalierte Bild deutlich besser aus. (Info: _WinAPI_AdjustBitmap verwendet _WinAPI_SetStretchBltMode, um den Modus zu setzen)

    Leider tritt ein (für mich) nicht nachvollziebarer Effekt auf: Das im Modus Halftone skalierte Bild wird NICHT neu gezeichnet, wenn sich ein Teil der Gui außerhalb des Desktops befindet.
    Im Gegensatz dazu funktioniert ohne Verwendung des Modus alles wie es sollte.

    Hier ein kleines Testskript:

    Spoiler anzeigen
    AutoIt
    #include <GUIConstants.au3>
    #include <WinAPIGdi.au3>
    #include <GdiPlus.au3>
    
    
    Global $hGui = GUICreate("Beweg mich außerhalb des Desktops und zurück!", 1280, 720)
    Global $idPic = GUICtrlCreatePic("", 0, 0, 1280, 720)
    If Not InetGet("https://interfacelift.com/wallpaper/7yz4ma1/04106_wwww_1920x1080.jpg", @TempDir & "/04106_wwww_1920x1080.jpg") Then Exit
    
    
    GUISetState()
    
    
    ;Bildteile außerhalb des Desktops werden gelöscht, wenn $HALFTONE bei der Skalierung verwendet wird
    _SetPic($HALFTONE)
    
    
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    
    
    ;Bild bleibt komplett erhalten, wenn das Fenster außerhalb des Desktops bewegt wird
    _SetPic()
    
    
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    
    
    Func _SetPic($iHalftone = Default)
    	_GDIPlus_StartUp()
    	Local $hImage = _GDIPlus_ImageLoadFromFile(@TempDir & "/04106_wwww_1920x1080.jpg")
    	Local $hBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    	Local $hResize = _WinAPI_AdjustBitmap($hBmp, 1280, 720, $iHalftone)
    	;~ 	_SendMessage(GUICtrlGetHandle($idPic), 0x0172, 0, $hResize)
    	GUICtrlSendMsg($idPic, 0x0172, 0, $hResize)
    	_WinAPI_DeleteObject($hResize)
    	_WinAPI_DeleteObject($hBmp)
    	_GDIPlus_ImageDispose($hImage)
    	_GDIPlus_Shutdown()
    EndFunc
    Alles anzeigen


    Wenn jemand eine vollkommen andere Variante für mein Vorhaben hat, würde ich auch die nehmen, allerdings nichts mit "WM_ERASEBKGND" bzw "WM_PAINT".
    Mein Ziel ist ja, genau das zu umgehen, weil ich denke das meine Methode performanter ist.

    Beste Grüße, Friesel!

  • Daten aus einer XML-Datei auslesen und auswerten

    • Friesel
    • 1. März 2017 um 17:07

    Mahlzeit!

    Um der heiligen Vielfalt Willen und weil ich schon angefangen hatte, hier eine etwas andere Herangehensweise.
    Funktioniert mit den gegebenen Daten einwandfrei und wird auch keine Probleme machen, wenn sich die XML-Struktur nicht ändert.
    Zum Testen kannst du auch einfach den Inhalt der XML-Datei in die Zwischenablage kopieren und das Programm laufen lassen:

    Spoiler anzeigen
    AutoIt
    ;diese beiden Zeilen aktivieren und die Zeile mit "ClipGet" auskommentieren, wenn aus einer Datei anstatt aus der Zwischenablge gelesen werden soll
    ;~ Global $sXMLDaten = FileRead(@ScriptDir & "\drucker.xsl")
    ;~ $aDrucker = StringSplit($sXMLDaten, "<Drucker>", 1)
    ;Der Einfachheit halber zum Testen einfach die XML Daten in die Zwischenablage kopieren und analysieren lassen
    $aDrucker = StringSplit(ClipGet(), "<Drucker>", 1)
    Global $sUnterZehn = "", $sAusgabe = ""
    Global $aToner[] = ["Cyan", "Magenta", "Yellow", "Black"]
    For $sDrucker In $aDrucker
    ;~ 	$aAlleWerte = StringRegExp($sDrucker, "(?s)<((?!/?Toner).+?>.+?)</.+?>", 3) ;==> filtert auch die Tags, ist aber unnötig
    	$aAlleWerte = StringRegExp($sDrucker, "(?s)<(?!/?Toner).+?>(.+?)</.+?>", 3)
    ;~ 	_ArrayDisplay($aAlleWerte) ;aktivieren um die Array Indizes zu identifizieren
    	If IsArray($aAlleWerte) Then
    		$sAusgabe = "Drucker " & $aAlleWerte[0] & ":" & @CRLF
    		For $i = 0 To 3
    			$iProzent = Round($aAlleWerte[11 + $i] / $aAlleWerte[16 + $i] * 100, 2)
    			If $iProzent < 10 Then
    				$sAusgabe &= $aAlleWerte[6 + $i] & "(" & $aToner[$i] & ")" & " = " & $iProzent & "% Tinte" & @CRLF ; die IP ist in $aAlleWerte[3], falls benötigt
    			EndIf
    		Next
    		$sUnterZehn &= $sAusgabe & @CRLF
    	EndIf
    Next
    ConsoleWrite($sUnterZehn);nur zur Kontrolle, kann wech
    MsgBox(0, "", $sUnterZehn);nur zur Kontrolle, kann wech
    ;falls jeweils an eine bestehende Datei angehägt werden soll, $FO_APPEND anstatt $FO_OVERWRITE
    $hFileOpen = FileOpen(@ScriptDir & "\UnterZehnProzent.txt", $FO_OVERWRITE)
    FileWrite($hFileOpen, $sUnterZehn)
    FileClose($hFileOpen)
    ShellExecute(@ScriptDir & "\UnterZehnProzent.txt") ;nur zur Kontrolle, kann wech
    Alles anzeigen


    Ich will Oscar nicht in die Parade fahren, aber wie gesagt, ich hatte es halt auch fertig.
    Also wieso nicht? :rolleyes:

    Beste Grüße, Friesel

    *edit*
    war noch ein kleiner Fehler drin, der verhinderte, dass die Toner Namen korrekt erkannt werden. Ist repariert ;)

  • Schleife in Schleife

    • Friesel
    • 28. Februar 2017 um 00:30

    Hallo!

    Ich hab mal schnell was zusammengeklöppelt.
    Ich muss allerdings zugeben, dass ich "_isPressed" noch nie verwendet habe und mir daher eventuelle "Feinheiten" der Funktion nicht bekannt sind :whistling:

    Die zweite Schleife habe ich in eine Funktion ausgelagert, weil's so übersichtlicher ist.
    Die jeweils innere While/WEnd Schleife dient dazu, dass man nicht ständig hin und her springt, wenn man die F-Taste gedrückt hält.

    Spoiler anzeigen
    AutoIt
    #include <Misc.au3> ; Binde die Misc.au3 ein( für _IsPressed)
    
    
    $hDLL = DllOpen("user32.dll")
    
    
    While Sleep(20)
    	If _IsPressed("20") Then
    		ConsoleWrite("Tue irgendwas in der Hauptschleife und falls ich ein Bot bin, möge mich der Blitz beim Schei* treffen!" & @CRLF)
    	EndIf
    	If _IsPressed("46") Then
    		While _IsPressed("46", $hDLL)
    			Sleep(20)
    		WEnd
    		ConsoleWrite(@CRLF & "F-Taste gedrückt -> Sprung nach _PressFunc()..." & @crlf)
    		_PressFunc()
    	EndIf
    WEnd
    
    
    DllClose($hDLL)
    
    
    Func _PressFunc()
    	While Sleep(20)
    		If _IsPressed("46", $hDLL) Then
    			While _IsPressed("46", $hDLL)
    				Sleep(20)
    			WEnd
    			ConsoleWrite(@CRLF & "F-Taste gedrückt -> Zurück zur Basis..." & @crlf)
    			Return
    		EndIf
    	WEnd
    EndFunc
    Alles anzeigen
    Zitat von rexderruede

    Die Hauptschleife soll unabhängig davon immer weiter laufen.

    Falls du Funktionen in der Hauptschleife weiter nutzen willst, während du in der Unterschleife bist, wirds komplizierter. Da gehe ich jetzt nicht drauf ein...

    Beste Grüße, Friesel

  • Wann ist AutoIt nicht mehr die richtige Wahl

    • Friesel
    • 27. Februar 2017 um 21:21

    Hi!

    Zitat von BananaJoe

    Hallo,
    das kann ich natürlich nicht auf AutoIt sitzen lassen :P

    Eines möchte ich gleich vorweg klarstellen:
    Ich mag AutoIt sehr und wollte es mit meinem Post sicher NICHT diskreditieren.

    Zitat von BananaJoe

    Folgendes Programm liefert das Ergebnis für die Zahl 2147483647 in 0.05 Sekunden - und das auf meiner langsamen Kiste mit noch gefühlten 10 weiteren Anwendungen die laufen.

    Das mein "Algorithmus" extrem uneffektiv ist, ist mir auch klar. Man muss ja nur ungerade Zahlen und als Obergrenze für den Dividenden Wurzel n anstatt n nehmen (wobei es noch effektivere Algorithmen gibt).
    Aber mir ging es ja nicht darum, möglichst schnell eine Primzahl zu ermittlen, sondern möglichst viele Berechnungen anzustossen (als eine Art Benchmark).
    Wie ich schon sagte, ist die Funktion isPrime in beiden Sprachen identisch, und genau dadruch ist es ja erst möglich, einen Vergleich anzustellen.

  • Wann ist AutoIt nicht mehr die richtige Wahl

    • Friesel
    • 26. Februar 2017 um 14:05

    Hi!

    Hier mal ein ziemlich beeindruckendes Beispiel, um Oscar's Aussage, was die Geschwindigkeit betrifft, zu untermauern.
    Das Programm ermittelt, ob die übergebene Zahl eine Primzahl ist, oder nicht.
    Die AutoIt Funktion _isPrime() tritt gegen eine identische Funktion in "C" geschrieben an, die sich in der DLL befindet.
    Die DLL musst du natürlich hier aus dem Anhang runterladen und in das gleiche Verzeichnis packen, wie das AutoIt Programm.

    Spoiler anzeigen
    AutoIt
    ;zB: 2147483647 => mit "C": ca. 5 Sekunden / Mit AutoIt um die 23 MINUTEN!!!
    Do
    	$iZahl = InputBox("Primzahltest", "")
    	_Eingabe($iZahl)
    Until $iZahl = ""
    
    
    Func _isPrime($iTestit)
    	$aRet = DllCall(@ScriptDir & "\PimzahlenDLL.dll","boolean:cdecl","isPrime","uint64",$iTestit)
    	if IsArray($aRet) Then Return $aRet[0]
    	Return True
    EndFunc
    
    
    Func _isPrimeAu3($iTestit)
    	For $i = 2 To $iTestit - 1
    		If Mod($iTestit, $i) = 0 Then Return False
    	Next
    	Return True
    EndFunc
    
    
    Func _Eingabe($iZahl1)
    	$iZahl = Int($iZahl1)
    	if $iZahl > 0 Then
    		$hStart = TimerInit()
    		_Ausgabe(_isPrime($iZahl), $iZahl, $hStart, "C...")
    		$hStart = TimerInit()
    		_Ausgabe(_isPrimeAu3($iZahl), $iZahl, $hStart, "AutoIt...")
    	EndIf
    EndFunc
    
    
    Func _Ausgabe($bFlag, $iZahl, $hStart, $sLang)
    	Switch $bFlag
    		Case True
    			MsgBox(0, "Berechnung in " & $sLang, $iZahl & " ist eine Primzahl" & @CRLF & @CRLF & "Dauer der Berechnung in Sekunden: " & Round(TimerDiff($hStart) / 1000, 2))
    		Case False
    			MsgBox(0, "Berechnung in " & $sLang, $iZahl & " ist keine Primzahl" & @CRLF & @CRLF & "Dauer der Berechnung in Sekunden: " & Round(TimerDiff($hStart) / 1000, 2))
    	EndSwitch
    EndFunc
    Alles anzeigen


    Um dir die Wartezeit zu ersparen, hier sind die Ausgaben für die Zahl 2147483647:
    [Blockierte Grafik: http://i.imgur.com/nz5NEZL.png][Blockierte Grafik: http://i.imgur.com/y5sGb4n.png]


    Ich habe übrigens mal diese Berechnung in C, C++(.NET), C#, Java und Delphi gegeneinander laufen lassen.
    Waren alle ähnlich schnell mit leichtem Vorsprung für Delphi (vermute mal weil, Delpi nicht mit .NET "belastet" ist.

    *edit*
    Copy/Paste Fail beim Quellcode. Die Ausgabe für TRUE hatte eine fixen Wert anstatt einer Berechnung. Ist aber jetzt korrigiert. Sorry!

    Schönen Gruß, Friesel

    Dateien

    PimzahlenDLL.zip 4,49 kB – 410 Downloads
  • 1D Array Splitten mit Regex

    • Friesel
    • 24. Februar 2017 um 12:30

    Tachchen!

    Da du eingangs nach einer Regex Lösung gefragt hast, hier mein Vorschlag.
    Der Pattern lässt sich noch flexibler gestalten, aber wenn die Struktur immer gleich ist, sollte das genügen.
    Sind nur zwei Zeilen:

    Spoiler anzeigen
    AutoIt
    #include<Array.au3>
    global $aTestArray[] = ["cn=DASISTMEIN TEXT,ou=dsgfdsg,fdgdfsg", _
    			"cn=DASISTMEIN LEBLINGS TEXT,ou=dsgfdsg,fdgdfsg", _
    			"cn=DASISTNICHTDEIN TEXT,ou=tralla,lalla", _
    			"cn=DASISTNICHTDEIN LEBLINGS TEXT,ou=ddfgdf,fdgdkkkuzfsg", _
    			"cn=DASISTDEIN klein geschriebener TEXT,ou=dsgfdsg,fdgdfsg", _
    			"cn=DASISTDEIN nicht gross geschriebener LEBLINGS TEXT,ou=wsngs,,,gdfsg", _
    			"CN=GruppeBackup_R,OU=test,DC=com,DC=int", _
    			"CN=GruppeBackup_C,OU=test,DC=com,DC=int", _
    			"CN=Gruppehouskeeping_R,OU=test,DC=com,DC=int", _
    			"CN=Gruppehouskeeping_R,OU=test,DC=com,DC=int"]
    ;==>
    $sTestString = _ArrayToString($aTestArray)
    $aRestArray = StringRegExp($sTestString, "(?i)cn=(.+?),", 3)
    ;<==
    _ArrayDisplay($aRestArray)
    Alles anzeigen


    Entspricht nicht deinem Code-Schnipsel, aber du fragtest ja nach einen neuen Array, dass den geänderten Text enthalten soll.

    Beste Grüße, Friesel


    Ps: wundert mich, dass niemand was mit Regex gemacht hat. Hab ich vieleicht was in der Fragestellung falsch verstanden? :/
    wobei es ja heisst, dass die String Funktionen schneller sind, als regex, vieleicht lags ja daran...

  • if GuiCtrlRead(var) = 1 then setstate(lock/hide) else setstate(unlock/show)

    • Friesel
    • 23. Februar 2017 um 10:14
    Zitat von alpines

    Ist um ehrlich zu sein keine gute Idee wenn Code danach noch kommt.Wenn ich für die einzelnen If-Zweige noch weitere Sachen erledigen möchte, dann muss ich nach den Zeilen mit den ternären Operatoren nochmal eine If-Verzweigung einbauen weil ich die dort nicht unterkriege.

    Wenn man sich genug Mühe gibt, kann man alles schlecht reden ;(

    Ich sage ja nicht dass man ternäre Operatoren immer und überall benutzen sollte. Für den gegebenen Fall von Candyland halte ich sie aber für sehr geeignet.

    Ich benutze zB sowas, wenn ich eine GUI initialisiere, bei der die Einstellungen in der Registry gespeichert sind.
    Da hab ich sogar quasi 3 states: Ein, Aus und Default (wobei Default natürlich auch entweder Ein oder Aus ist).
    So zum Beispiel:

    AutoIt
    GUICtrlSetState($idCheckBox, (RegRead("HKEY_CURRENT_USER\Software\Irgendwas", "Irgendwas anderes") = $GUI_UNCHECKED) ? $GUI_UNCHECKED : $GUI_CHECKED)


    Wenn der Registry Wert nicht existiert (Default) wird $GUI_CHECKED übergeben.
    Ansonsten wird der state aus dem vorhandenen Registry Schlüssel ausgelesen.


    Zitat von BugFix

    Poooh - DAS kann tödlich sein. Nicht in diesem Fall, aber Konstanten enthalten oft Kombinationen von Werten. Wenn du dann addierst, wird unter Umständen eine völlig andere Kombination als gewollt entstehen.Deshalb dafür ausschliesslich BitOr verwenden (so wie bei der Abfrage BitAnd).

    Ich bin mir der Problematik durchaus bewußt. Habe mich auch immer dran gehalten BitOr zu verwenden, bis ich neulich nach 2-Jähriger AutoIt Abstinenz folgendes im Helpfile gelesen habe:

    Zitat von GUICtrlSetState

    State values can be summed up as for example $GUI_DISABLE (128) + $GUI_HIDE (32) sets the control in an disabled and hidden state.

    Bei Styles und ähnlichem nutze ich aber weiterhin BitOr, keine Angst ;)

    Beste Grüße, Friesel

  • if GuiCtrlRead(var) = 1 then setstate(lock/hide) else setstate(unlock/show)

    • Friesel
    • 23. Februar 2017 um 07:46

    Hi Candy!


    Entschuldige, ich hätte vieleicht doch ein bisschen mehr erklären sollen ;)


    Also, "ternär" bedeutet, dass der gesamte Ausdruck aus 3 Teilen besteht:

    • links vom Fragezeichen steht ein (Boolescher) Ausdruck, der entweder TRUE oder FALSE ergibt (bzw. ergeben MUSS) *
    • der erste Wert rechts von Fragezeichen (und links vom Doppelpunkt) wird verwendet, wenn der Ausdruck TRUE ergibt
    • der zweite Wert rechts vom Doppelpunkt wird enspechend beim Ergebnis FALSE verwendet

    *kurze Erläuterung zu Booleschen Ausdrücken:

    • z.B.: (3+4) = (10-3) ergibt TRUE (also 7=7 -> TRUE) / ensprechend ist 3=4 FALSE
    • hier muss aber nicht zwingend ein Vergleichsausdruck stehen.
    • Es geht zB auch eine einzelne Variable: Hat diese irgend einen Wert ausser 0 ist sie TRUE. Hat sie keinen Wert, wurde aber deklariert oder hat den Wert 0, ist sie FALSE...


    Mein Beispiel mit dem Menü Haken sieht "übersetzt" in If/Then Schreibweise so aus:

    AutoIt
    If GUICtrlRead($idHakenItem) = $GUI_UNCHECKED + $GUI_ENABLE Then
    	GUICtrlSetState($idHakenItem, $GUI_CHECKED + $GUI_ENABLE)
    Else
    	GUICtrlSetState($idHakenItem, $GUI_UNCHECKED + $GUI_ENABLE)
    EndIf


    Bitte beachte, dass ich extra die Konstanten und nicht wie vorher die addierten Werte verwendet habe.
    Gerade als Anfäger können diese nichtssagenden Zahlen sehr verwirrend sein und so oder so machen Konstanten ein Script sehr viel besser lesbar...


    Ich hoffe, das war einigermassen verständlich erklärt.


    Beste Grüße, Friesel

  • if GuiCtrlRead(var) = 1 then setstate(lock/hide) else setstate(unlock/show)

    • Friesel
    • 23. Februar 2017 um 01:59

    Mahlzeit!

    Als sehr großer Fan ternärer Operatoren kann ich dir nur folgendes nahe legen:

    Spoiler anzeigen
    AutoIt
    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    #Region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("This is a Form", 360, 85, 450, 414)
    $Checkbox1 = GUICtrlCreateCheckbox("Funktion Aktivieren", 120, 8, 113, 17)
    $Input1 = GUICtrlCreateInput("Irgendwas", 120, 40, 121, 21)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $Input = GUICtrlCreateLabel("Input", 80, 40, 28, 17)
    $Checkbox2 = GUICtrlCreateCheckbox("Extra", 256, 40, 97, 17)
    GUICtrlSetState(-1, $GUI_DISABLE)
    ;==> zusätzliches Beispiel
    $idHakenMenu = GUICtrlCreateMenu("&Haken Menü")
    $idHakenItem = GUICtrlCreateMenuItem("Abgehakt?", $idHakenMenu)
    ;<== zusätzliches Beispiel
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###
    While 1
    	$nMsg = GUIGetMsg()
    	Switch $nMsg
    		Case $GUI_EVENT_CLOSE
    			Exit
    		Case $Checkbox1
    			GUICtrlSetState($Input1, (GUICtrlRead($Checkbox1) = $GUI_CHECKED) ? $GUI_ENABLE : $GUI_DISABLE)
    			GUICtrlSetState($Checkbox2, (GUICtrlRead($Checkbox1) = $GUI_CHECKED) ? $GUI_ENABLE : $GUI_DISABLE)
    		;==> zusätzliches Beispiel
    		Case $idHakenItem
    			GUICtrlSetState($idHakenItem, (GUICtrlRead($idHakenItem) = 68) ? 65 : 68) ; 68 = $GUI_UNCHECKED + $GUI_ENABLE // 65 = $GUI_CHECKED + $GUI_ENABLE
    		;<== zusätzliches Beispiel
    	EndSwitch
    WEnd
    Alles anzeigen

    Besonders elegant lässt es sich damit zwischen zwei states eines Controls wechseln.
    Siehe im Code mein Beispiel mit dem Menü-Haken.
    Der Einfachheit halber habe ich die Konstanten direkt addiert, da Menu Items immer zwei Status haben, allerdings ist von solchen "Magic Numbers" grundsätzlich abzuraten :D

    Beste Grüße, Friesel

    Ps: Ternäre Operatoren sind eigendlich sehr einfach, wenn man das Prinzip mal verstanden hat. Ansonsten kannst gerne fragen...

  • OnePlus 2

    • Friesel
    • 19. August 2015 um 20:43

    Hi!

    Angeblich hat dieser Shop beide Versionen des 2 vorrätig und diese können auch schon bestellt werden:
    http://www.efox-shop.com/oneplus-2-4gb-…ss-bil-g-303280

    Ich denke, der Shop ist vertrauenswürdig (hat sogar deutschen Support), aber selbstverständlich alle Angaben ohne Gewähr ;)

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™