Diskussion zu [Skripte] control hover effekt ohne fehler

  • OK, ich nehme deine Herausforderung an. 8o

    Welche Methode einfacher ist, lässt sich mit folgender Aufgabe leicht feststellen: In einem gegebenen Grundgerüst mit einer GUI gibt es 3 Labels mit hellgrauem Hintergrund ($g_Color_Old). Nun soll ein Hover-Effekt eingebaut werden, mit dem die Labels beim Hovern einen hellblauen Hintergrund bekommen ($g_Color_New). Wenn du jetzt eine Lösung mit CallBack einbaust, wird das bestimmt aufwendiger, als mit der oben genannten Routine ohne CallBack.

    Gegeben ist folgendes Grundgerüst. Wie würde deine CallBack-Lösung aussehen?

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Hier meine Lösung mit "Hover effect easy PB". Ich finde, das ist einfach.

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

    • Offizieller Beitrag

    Wie würde deine CallBack-Lösung aussehen?

    Für die Abfrage, ob die Maus über dem Control ist, ist GUIGetCursorInfo das probateste Mittel.

    Was aber an deiner Lösung nicht so schön ist, deine Funktion zum HooverCheck läuft ständig (ca. alle 50 ms), auch wenn die Maus nicht bewegt wird.

    Deshalb habe ich in meiner Variante die Mausbewegung (eine Callback-Funktion) als Auslöser genommen.

    P.S.

    Falls die Frage kommt, warum ich nicht WM_MOUSEMOVE mit GUIRegisterMessage verwendet habe: WM_MOUSEMOVE sendet seine Nachrichten nicht an das Parent. D.h., wenn ich über einem Ctrl bin und habe die Nachricht für das Fenster registriert, bekommt dieses davon nichts mit.

  • Was aber an deiner Lösung nicht so schön ist, deine Funktion zum HooverCheck läuft ständig (ca. alle 50 ms), auch wenn die Maus nicht bewegt wird.

    Das ist, damit der Code einfach bleibt. 8o Der ständig laufende HoverCheck ist vielleicht nicht schön, aber er schadet ja nicht. Wer will, kann das in eine Timer-Funktion auslagern oder in eine CallBack-Funktion oder was anderes. Das Abfragen für den HoverCheck in der MainLoop ist nur fürs Demo. Der eigentliche Kern des Codes ist in der Funktion HoverEffect_ColorBK(), alles andere ist Beiwerk, das ich versucht habe, so einfach wie möglich zu halten. So habe ich z.B. auch auf die Prüfung verzichtet, ob die GUI aktiv ist. Wenn ein anderes Fenster über der GUI gezeigt wird und ein Label halb verdeckt, sieht man schön, dass das Label trotzdem die Farbe wechselt.

    Zu deinem Code.

    Ich bin sehr beeindruckt! Dass eine CallBack-Lösung so kompakt sein kann, hätte ich nicht vermutet. :thumbup:Schön zu sehen ist auch, dass du für den Hover-Effekt ebenfalls die Lösung von Health verwendet hast. If $ID_last <> $ID_Hoover Then ...

    MouseMove hatte ich in meinem Code bewust nicht verwendet, weil alle Codes, die ich gefunden hatte, mit MouseMove versagten. Z.B. blieben beim schellen Hovern Controls im Hover-Effekt stecken, usw. In deiner CallBack Lösung läuft der HoverCheck auch ständig, nur halt in einem CallBack statt in einer Schleife. Das sieht man schön, wenn man ein anderes Fenster aktiviert und mit der Maus über die Labels deiner inaktiven GUI fährt.

    Ein Detail hat mir besonders gefallen: Das Zuweisen des Array-Elements an eine Nicht-Array-Variable. $ID_Hoover = GUIGetCursorInfo($Form1)[4]. Mich hat in meiner Lösung ein wenig gestört, dass an so vielen Stellen die Array-Variable mit Index-Angabe stand. Deine Idee mit der Nicht-Array-Variablen finde ich viel übersichtlicher. Wie gesagt, es ist nur ein Detail, aber ich finde es sehr nützlich.

    _WinAPI_GetModuleHandle(0) <= Aus der AutoIt Hilfe: "Falls dieser Parameter das Schlüsselwort Null ist, ..."

    Ist in AutoIt 0 und Null das Gleiche? Ich habs probiert und beides hat funktioniert.

    Edit: In letzter Zeit wird beim Posten das Layout öfter mal verändert. Habs korrigiert. :)

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

    • Offizieller Beitrag

    Schön zu sehen ist auch, dass du für den Hover-Effekt ebenfalls die Lösung von Health verwendet hast.

    Naja, das ist keine "Lösung", sondern simple Programmierlogik, die du in hunderten Skripten findest: Vergleiche aktuellen Zustand/Wert mit letztem Zustand/Wert.

    In deiner CallBack Lösung läuft der HoverCheck auch ständig, nur halt in einem CallBack statt in einer Schleife.

    Definitiv NEIN!

    Eine Callbackfunktion wird erst auf ein bestimmtes Ereignis hin aktiv. In meiner Funktion auf LowLevel - Mausaktionen.

    Setze einfach in die erste Zeile der Funktion ein ConsoleWrite('Callback' & @CRLF) und du wirst sehen, dass ausschließlich bei Mausaktionen in die Konsole geschrieben wird.

    • Offizieller Beitrag

    Die Idee von BugFix mit dem Hook finde ich sehr gut, aber ich würde es etwas anders umsetzen:

    Edit: Code noch etwas gekürzt.

  • Falls die Frage kommt, warum ich nicht WM_MOUSEMOVE mit GUIRegisterMessage verwendet habe: WM_MOUSEMOVE sendet seine Nachrichten nicht an das Parent. D.h., wenn ich über einem Ctrl bin und habe die Nachricht für das Fenster registriert, bekommt dieses davon nichts mit.

    Wobei es hier auch eine "Besonderheit" gibt:

    WM_MOUSEMOVE message

    Posted to a window when the cursor moves. If the mouse is not captured, the message is posted to the window that contains the cursor. Otherwise, the message is posted to the window that has captured the mouse.

    https://docs.microsoft.com/en-us/windows/…ev/wm-mousemove

    SetCapture function ==>> _WinAPI_SetCapture ( $hWnd )

    Sets the mouse capture to the specified window belonging to the current thread. SetCapture captures mouse input either when the mouse is over the capturing window, or when the mouse button was pressed while the mouse was over the capturing window and the button is still down. Only one window at a time can capture the mouse. If the mouse cursor is over a window created by another thread, the system will direct mouse input to the specified window only if a mouse button is down.

    https://docs.microsoft.com/en-us/windows/…user-setcapture

    Related

    https://docs.microsoft.com/en-us/windows/…user-getcapture

    https://docs.microsoft.com/en-us/windows/…-releasecapture

    Ginge das nicht auch hiermit?

    TrackMouseEvent function ==>> _WinAPI_TrackMouseEvent ( $hWnd, $iFlags [, $iTime = -1] )

    Posts messages when the mouse pointer leaves a window or hovers over a window for a specified amount of time.

    https://docs.microsoft.com/en-us/windows/…trackmouseevent

  • BugFix   Oscar In euren Codes ist die Beschreibung der Farben vertauscht. ;)

    Uralter Thread, aber bis heute der einzige, den ich gefunden habe, der einen einfachen Code für Hover-Effekte zeigt und wirklich funktioniert.

    Also "einfacher" ist wahrscheinlich Ansichtssache. Ich empfinde Callbacks als erheblich einfacher.

    Mit ein wenig Abstand ist mir nun bewust, dass wir aneinander vorbei geredet haben. In diesem Thread geht es um den Hover-Effekt. Als du von CallBacks geredet hast, die du als einfacher empfindest, ging ich natürlich davon aus, dass auch du den Hover-Effekt meinst. Dem ist jedoch nicht so, denn du hast lediglich den Aufruf in die CallBack-Procedur verlagert, der Code für den Hover-Effekt ist der gleiche. Wie gesagt, da haben wir wohl aneinander vorbei geredet. :)

    Naja, das ist keine "Lösung", sondern simple Programmierlogik, die du in hunderten Skripten findest: Vergleiche aktuellen Zustand/Wert mit letztem Zustand/Wert.

    Das klingt ein wenig nach "Ei des Kolumbus". ... Aber ist schon ok, Meinungen sind unterschiedlich. 8o

    Ich hatte dutzende Beiträge und Codes durchgelesen und dabei verschiedene Hover-UDFs nur oberflächlich angesehen, da sie mehr als 500 Zeilen Code umfassten. In diesem Thread hier war der einzige einfache* Code, den ich bis heute gefunden habe, der das Problem ohne die genannten Fehler gelöst hat!

    * Der Code für den Hover-Effekt von Health hat weniger als 10 Zeilen.

    Ich danke euch für eure Beteiligung an dem Thema und für die Code-Snippets, die ihr gepostet habt. Wiedermal konnte ich einiges daraus lernen. :rock:

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Oscar

    Dein Code hat leider einen Fehler. :( Wenn man Label 2 beim Erstellen (Zeile 27) eine andere Farbe gibt, wird sie nach dem Hovern auf die Hover-NormalColor gesetzt. Label 2 sollte jedoch unverändert bleiben.

    AutoIt
    Global $Label2 = GUICtrlCreateLabel("Label2", 208, 88, 92, 33, BitOR($SS_CENTER, $SS_CENTERIMAGE, $WS_BORDER))
    ; GUICtrlSetBkColor(-1, $COLOR_NORMAL)
    GUICtrlSetBkColor(-1, 0xFFFF00) ; <== gelb

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Wenn man Label 2 beim Erstellen (Zeile 27) eine andere Farbe gibt, wird sie nach dem Hovern auf die Hover-NormalColor gesetzt. Label 2 sollte jedoch unverändert bleiben.

    Stimmt... so aber nicht mehr...

  • Also wenn man es schonmal macht kann man auch direkt eine UDF daraus basteln^^

    Hier mal meine Interpretation der Angelegenheit (nicht ausgefeilt und nicht aufgeräumt, nur als Denkanstoß gedacht).

    Also ansich fände ich es schlau, wenn man sich nicht auf die Hintergrundfarbe beschränkt, sondern in der mouseProc zu einer (frei wählbaren) AutoIt-Funktion weiterleitet die dann als "Hover Event" automatisch aufgerufen wird. Dann hat man vollen Zugriff auf das Ctrl und kann damit anstellen was auch immer man will. Wenn man das ganze wrappt hat man als einzige Funktion mit der der User Kontakt hat noch GuiCtrlSetHoverProc übrig, die Funktionen die man selbst schreiben muss (als User) sind so trivial, dass das jeder hinbekommen sollte (also das was im Hintergrund läuft sieht kompliziert aus, davon merkt der Anwender aber nichts).

    lg

    M

  • Hallo Leute, ihr könnt den Fehler von BugFix übernehmen, müsst ihr aber nicht! :D

    Global Const $COLOR_HOOVER = 0xD7EDFF ; helles grau blau

    Global Const $COLOR_NORMAL = 0xE6E6E6 ; helles blau grau

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Also ansich fände ich es schlau, wenn man sich nicht auf die Hintergrundfarbe beschränkt, sondern in der mouseProc zu einer (frei wählbaren) AutoIt-Funktion weiterleitet die dann als "Hover Event" automatisch aufgerufen wird. Dann hat man vollen Zugriff auf das Ctrl und kann damit anstellen was auch immer man will.

    Ist alles schon drin, siehe Posting #1.

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

    • Offizieller Beitrag

    Um vielleicht nochmal auf den Grund zur Erstellung dieser Version durch den TE zurückzukommen:

    Er bemängelte die Zuverlässigkeit der Callback Version.

    Das kann damals durchaus Gültigkeit gehabt haben. Im April 2008 war die aktuelle Version von AutoIt die 3.2.10.0. In dieser Version wurden erstmals eingeführt DllCallbackRegister(), DllCallbackGetPtr() und DllCallbackFree(). Für diese Funktionen gab es noch spätere Fixes bis zur Version 3.3.10.0 im Jahr 2013.

    Ich kann für diese Funktionen nach heutigem Stand keinerlei Probleme ausmachen.

    Wenn dies also der primäre Grund für die In-Loop-Version war, ist diese heute obsolet. Natürlich kann man sie auch weiterhin nutzen. Aber sollte nicht auch immer das Augenmerk darauf gerichtet sein, Code möglichst optimal zu gestalten? Und statt in einer Schleife ständig eine Abfrage durchzuführen, diese nur auf ein gewünschtes Ereignis hin auszulösen, stellt ohne jeden Zweifel eine Optimierung dar.

    Effizienz lässt sich mal ganz grob gesagt, darauf herunterbrechen, wie viel Takte ein Prozessor rattern muss, um zum Resultat zu kommen. Dabei ist es eher zweitrangig, wenn der Code optisch größer ist (mehr Zeilen enthält).

    Aber dies ist nur meine Meinung. ;)

  • Um vielleicht nochmal auf den Grund zur Erstellung dieser Version durch den TE zurückzukommen:

    Er bemängelte die Zuverlässigkeit der Callback Version.

    Das ist nicht richtig! :( Der TE bemängelt nicht die Zuverlässigkeit der CallBack Version, sondern die Zuverlässigkeit des Hover-Codes. Es ging in diesem Thread um den Hover-Effekt und darum, den Hover-Effekt ohne "Fehler" darzustellen. In den Postings #4 und #5 wird deutlich dargestellt, dass der Code für den Hover-Effekt in den damaligen UDFs auch ohne CallBacks fehlerhaft war.

    Als BugFix die CallBacks ansprach, dachte ich natürlich, dass damit eine andere Methode für den Hover-Effekt geht. Aber er verwendet den gleichen Hover-Effekt-Code, den Health in Posting #1 zeigt. Der Titel des Threads heißt "control hover effekt ohne fehler" und NICHT "wie rufe ich den Hover-Effekt ab besten auf"! CallBack-Routinen haben nichts mit dem Hover-Effekt zu tun, sondern sind lediglich Möglichkeiten, den Code vom Hover-Effekt aufzurufen!

    Ich finde es schade, dass der Thread gekapert wurde, um CallBacks zu diskutieren. Die CallBack-Routinen hier ermöglichen keinen Hover-Effekt, sie dienen nur dem Aufruf des Hover-Codes, den man auch mithilfe der Hauptschleife machen kann oder über einen Timer. Auch darüber könnte man diskutieren, aber das alles ist zweitrangig, denn es ging eigentlich um den Code für den Hover-Effekt.

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

    • Offizieller Beitrag

    Ich finde es schade, dass der Thread gekapert wurde, um CallBacks zu diskutieren.

    Ich stimme dir insofern zu, dass die Diskussion hier fehl am Platz ist. Ich werde dem Rechnung tragen und die Posts in einen eigenen Thread verschieben.

    Die CallBack-Routinen hier ermöglichen keinen Hover-Effekt, sie dienen nur dem Aufruf des Hover-Codes, den man auch mithilfe der Hauptschleife machen kann oder über einen Timer. Auch darüber könnte man diskutieren, aber das alles ist zweitrangig, denn es ging eigentlich um den Code für den Hover-Effekt.

    Das sehe ich völlig anders.

    Was löst den Hover Effekt aus? - Die Maus wird bewegt und begibt sich in die Fläche eines Control.

    Ergo ist die Aufgabe: Erkenne ob die Maus gegenüber ihrer letzten Position auf ein (anderes) Control gewechselt ist.

    Und es ist schon ein gravierender Unterschied, wie diese Erkennung initiiert wird:

    • kontinuierliches Prüfen, ob sich was getan hat
      oder
    • nur das Ereignis überwachen, das ein Hovern ermöglicht

    Das sind völlig unterschiedliche Ansätze das Hovern zu detektieren.

    Der Titel des Threads heißt "control hover effekt ohne fehler" und NICHT "wie rufe ich den Hover-Effekt ab besten auf"!

    Man kann den Hover-Effekt nicht aufrufen. Man kann ausschließlich überwachen, ob er auftritt. Und das wäre auch dann ein aussagekräftigerer Titel für diesen Thread: "Überwachung des Hover Effektes für ein Control ohne Fehler"

  • Ich finde es schade, dass der Thread gekapert wurde, um CallBacks zu diskutieren.

    Nun ja, da bist du aber nicht ganz unschuldig dran... denn anstelle einen 12 Jahre alten Thread auszugraben, hättest du besser einen eigenen erstellt, in dem du auf diesen hier verweist.

    Ob via Hauptschleife oder Timer... beides ist Polling, das möglichst vermieden werden sollte.