ColorChangeIconButton - BugWorkaround?

  • Es ist mir nicht gelungen einen farbigen Button mit OnmouseOver-Effekt UND transparentem .ico zu erstellen.
    Wahrscheinlich wegen des GUI-Bugs werden die transparenten Teile eines .ico Files immer in der Farbe der GUI-BG-Color dargestellt.
    Ein möglicher Weg dies (mit einfachen Mitteln) zu umgehen ist es die ButtonFarbe unter dem Icon gleichzeitig mit der GUI-BG-Color zu wechseln.
    Das klappt prima, solange ich nur einen Button habe. Habe ich mehrere Buttons brauche ich für jeden Button eine subGUI ...

    Das habe ich hier mal umgesetzt. Macht dies Methode wirklich Sinn?
    Oder gibt es da inzwischen leichtere Workarounds?
    (ich habe stundenlang gesucht, aber just diese Problemlösung des Icons nicht gefunden)

    Im Beispiel habe ich 24 Buttons, weil ich die Kapazität von GUIGetMsg() testen wollte, scheint aber zu gehen.
    Beim Clicken wird nur in die Console geloggt (keine Action).
    Außerdem wäre mein nächstes Ziel dass die GUI beim Aufbau nicht so sehr flackert (habe bisher - offensichtlich - nicht viel mit GUIs gearbeitet).
    Programmierstil und Ordentlichkeit sind furchtbar :love: sorry ist work in prgoress!

    Vorschau:


    IconButtonHoverEffect.au3:


    Freu mich :party: über Feedback!

  • Hier nochmal ein ganz einfaches Beispiel um das Problem darzustellen:
    1. Button (nicht eingefärbt) mit .ico funtz perfekt, aber eben nur mit dem default-weiß
    2. Button (eingefärbt) jetzt ist das .ico weg
    3. Button (ein gefärbtes Label mit Icon) ist immer nur transparent,
    wenn der Hintergrund des Bildes mit der des GuiBG identisch ist. ("See this bug!")

    Als Lösungsweg ohne WinApi/GDI+ .. hab ich nichts anderes gefunden. So lässt sich auch ein Button mit States Static/Hover/Press gestalten.
    Das ist aber auch das Limit der Methode für Buttons mit State-orientierten Farben, denn ab 2 Buttons in unterschiedlichen States funktioniert das natürlich nicht mehr. Also Workaround 2 eine (sub)GUI pro Button setzen. (siehe erster Post).

    Einmal editiert, zuletzt von SOLVE-SMART (5. Dezember 2025 um 14:38)

  • Hi, ja, ohne WinAPi/GDI+ wird es schwierig. Ich denke, dein Workaround im ersten Beispiel funktionierte schon recht gut. Da hatte ich auf die schnelle auch keine bessere Lösung gesehen.

    Da du dir die Mühe mit dem weiteren Bespiel gemacht hast gehe ich mal davon aus, dass du eine andere/bessere Lösung möchtest.
    Ich hab also mal gebastelt und eine recht elegante Lösung gefunden, denke ich. Ich verpacke das ganze in eine eigene GuiCtrlCreateIconEx -Funktion. Intern wird dabei ein GuiCtrlCreateGraphic verwendet, bei dem die Pixel entsprechend gesetzt werden.
    Ich denke die Performance könnte noch verbessert werden (z.B. GDIPlus global laden/entladen (_GDIPlus_StartUp/Shutdown) oder eine ganz andere Methode zu verwenden mit z.B. GuiCtrlCreatePic).
    Die Verwendung ist aber mit einem Funktionsaufruf recht elegant und es kann danach wie ein normales AutoIt-Ctrl verwendet werden (Es ist halt nur ein GraphicCtrl).

    Ich hoffe das hilft dir weiter :)

  • Hi Kanashius,
    danke für deine antwort & Lösung. diese behebt das Problem, wie es sein soll und GUICtrlSetBkColor() funktioniert!
    das icon on-the-fly umzumalen hatte ich auch schon in Betracht gezogen. Allerdings würde ich die Icons bei solch einem Aufwand dann auch gerne für den nächsten Start speichern*. (und an diesem Punkt bekam ich aus GDI+ nur jpg's und keine .ico).
    "bei dem die Pixel entsprechend gesetzt werden" was passiert da? wieso funzt das ico danach auf allen farben? ich dachte zunächst das icon wird repariert und ich könnte es dann in diesem Zustand speichern, und beim nächsten Start aus dem .ico ohne Umwandlung laden.
    (ginge das??? - das wäre genau das was ich suche!)
    Aber da siegt wohl nur mein Wunschdenken über die Realität :)

    Dann werde ich mal ein kleines Farb-Button Menü mit deiner Methode basteln und vorstellen.

    Merci!!

    *Kurz zum Hintergrund:
    mein quicklauncher öffnet kleine GUI-Menüs mit Icons per Geste und Hotkeys. Diese erstelle ich beim ersten Einlesen und speicher die Icons (weil ich einige auch tauschen möchte).
      

    Die meisten Menüs haben weniger als 8 Icons, da wäre die Performance theoretisch nicht so wichtig.
    diese wollte ich nun in einer Art Windows-Start-Menü als Hauptmenü zusammenführen. Daher war ich mal nach einer brauchbaren Lösung für viele Buttons.

  • Moin,

    wenn Du ein Label als Buttonersatz nehmen willst, könnte das auch so funktionieren:

    Einmal editiert, zuletzt von SOLVE-SMART (5. Dezember 2025 um 14:38)

  • Velted wow, dass ergebnis sieht gleich aus wie bei Kanashius nur mit weniger code.

    Kann mir jemand das bitte noch final bestätigen:
    "Man kann einen .ico file nicht so manipulieren, dass er in AutoIt per GUICtrlCreateIcon() geladen wird und nicht den Transparenz-Bug aufweist!"

    EDIT: hab das erst jetzt kapiert!
    Velted zeichnet das Icon einfach richtig (ohne bug mit WinAPI) auf ein Label.
    Kanashius Weg "repariert" die transparenten Pixel auf einem GraphicHandle.
    Und mein "Workaround" zeichnet eine neue sub-gui die ihren wahren BG nie zeigt und der Button ist auch nur ein Label.
    Das funktioniert zwar, ohne Einsatz von extra-Bibliotheken aber auf Kosten von Programmierkomfort.

    Tendentiell ist für mich die Methode von Velted am geeignetsten. Ich werde mal die Tage einen Performance-Test für alle 3 Methoden machen und berichten!

    ich hab hier mal alle 3 Versionen hinzugefügt und mit OnMouseOver Effekten belegt. Funzen alle super!
    Besonders beim Button-Handling zeigt sich aber der Mehraufwand meiner Methode (da wäre eine Handler-Funktion sinnvoll - im nächsten Post verbessert.)

    GUI-Button-Test: (Originale, Kanashius, Velted, UPIA)

    Der Code:

    5 Mal editiert, zuletzt von SOLVE-SMART (5. Dezember 2025 um 14:38) aus folgendem Grund: Editiert!

  • wenn ich für meine "methode" einfach ein label auf der hGUI unter die subGUI platzieren kann ich den hover-status mit GUIGetCursorInfo($hGUI) auslesen. damit reduziert sich der button-handling code auch wesentlich. letztenendes wird sich aber doch jeder der mehrere OnMouseOver Buttons kontrollieren will einen button-händler basteln.

    das noch zur ergänzung, meine Buttons etwas schlanker mit einem zusätzlichen Label:

    2 Mal editiert, zuletzt von SOLVE-SMART (5. Dezember 2025 um 14:37)

  • Moin,

    hier kommt die Methode "Velted2". Die sollte das Leben deutlich einfacher machen:

    Bei den Includes kann wahrscheinlich noch 'entschlackt' werden. Und das Zeichnen des Buttons könnte man noch verfeinern bzw. an Win 11 anpassen. Für den Start sollte es aber reichen.

    Viel Spaß!

    Edit 05.12.25 13:13: _WinAPI_DrawIconEX() korrigiert

    2 Mal editiert, zuletzt von SOLVE-SMART (5. Dezember 2025 um 14:37) aus folgendem Grund: Tippfehler

  • jetzt weiß ich wofür diese wm_notify geschichte gut ist :) große erkenntnis für das button-handling, sehr geil! 8|
    mir ist ab diesem punkt nicht klar, welchen nachteil es hat ob mein button ein label, grafikhandle oder ein echter button ist!
    "Das Zeichnen des Buttons könnte man noch verfeinern bzw. an Win 11 anpassen"
    das würde mich auch interessieren (habe die gui-stlyes probiert aber die sind nicht wirklich der bringer.
    hat der echte button hier vorteile, weil er besser dargestellt werden kann?

  • Moin UPIA,

    der 'echte' Button liefert bei NM_CUSTOMDRAW den 'Hover' Status automatisch.

    "Das Zeichnen des Buttons könnte man noch verfeinern bzw. an Win 11 anpassen"

    Die Styles bringen Dir hier nichts, weil der Button komplett selbst gezeichnet wird.

  • Moin UPIA,

    vielleicht gefällt Dir diese Version von Func WM_NOTIFY() besser:

    Einmal editiert, zuletzt von SOLVE-SMART (6. Dezember 2025 um 23:17)

  • der 'echte' Button liefert bei NM_CUSTOMDRAW den 'Hover' Status automatisch.

    okay, mächtig! das wm_notify zu lesen ist wirklich schick. letztenendes muss halt doch der Farbeimer ran und das Icon wieder draufgeballert werden - dafür aber vollends kompatibel!

    Ich hab die Buttons auf die Schnelle nicht abrunden können wie den Default. Das sollte aber doch mit den Styles gehen?!

  • AutoIt
    		If @OSVersion = "WIN_11" Then
    			$hRgn = _WinAPI_CreateRoundRectRgn(0, 0, $aSettings[0], $aSettings[1], 9, 9)
    		Else
    			$hRgn = _WinAPI_CreateRectRgn(0, 0, $aSettings[0], $aSettings[1])
    		EndIf

    Moin, was zeigt bei Dir MsgBox(0, "OSVersion", @OSVersion) an?

    Einmal editiert, zuletzt von SOLVE-SMART (6. Dezember 2025 um 23:17)

  • hi.
    Sehe jetzt erst, deine überarbeitete wm_notify. Funzt einwandfrei bei mir!
    ich bin auf win11. danke für die info! Jetzt kapier ich auch wie dieses Script funktioniert, dass ich eine zeitlang her gefunden habe:

    Schönen Sonntag!