Unterschiedlicher Button Style

  • Hallo alle zusammen.
    Ich bin vermutlich nur zu blöd aber ich bekomme es einfach nicht "schön" hin.
    Das kleine Script unter XP um das es geht nutzt die resources.au3 um alle benötigten Bilddaten in die EXE einzubinden.

    Desweitern wollte ich die beim deaktivieren eines Controls entstehenden "leeren" Buttons mit einer grau hinterlegten Version des Bildes füllen. Und genau hier komme ich nicht weiter.


    Der folgende Code erzeugt einen Dreidimensional erscheinenden Button.

    Wenn man diesen mit GUICtrlSetState($button0, $GUI_DISABLE) deaktiviert bekomme ich im Fenster einen leeren grauen Button.

    Wenn ich die ImageList verwende:

    Und diesen mit GUICtrlSetState($button0, $GUI_DISABLE) deaktiviert bekomme ich im Fenster den Button mit dem hinterlegten deaktiviert Bild.

    Leider ist aber der Style des Buttons Flach.

    Ich hätte ihn aber gerne wie im ersten Beispiel!

    Ich habe mich schon mal an den _GUICtrlButton_SetStyle versucht, aber die zeigen keine gewünschte Wirkung.

    Und die Idee dem Knopf jedesmal beim Deaktivieren das entsprechende andere Verfahren zuzuweisen habe ich als unpraktisch verworfen.

    Gibt es da nicht eine "bessere" Lösung ?

  • Hi,

    wenn Du (D)einer Schaltfläche ein Bitmap als Hintergrund zuweist, dann setzt AutoIt für diese Schaltfläche das Ownerdraw-Style-Flag ($BS_OWNERDRAW) und somit wird die Schaltfläche von AutoIt gezeichnet.

    Kurz gesagt, ohne mehr oder weniger großen Aufwand geht es nicht anders.

    Du könntest natürlich versuchen mit GIMP Deine Bitmap entsprechend dem 3D-Stil der Standard-Schaltflächen anzupassen ...


    Gruß
    Greenhorn


  • Danke für die Antwort,
    aber etwas macht mich daran stutzig, wieso schafft es denn das erste Beispiel, also "_ResourceSetImageToCtrl" aus dem Button etwas 3D ähnliches zu zaubern.
    Und warum habe ich keine Möglichkeit das auch für den Zustand Deaktiviert zu setzen.
    Ich hab auch schon mal in der recources.au3 gestöbert, aber dazu verstehe ich dann doch zu wenig von den Funktionen die da ablaufen.
    Es würde ja reichen wenn das Bitmap immer angezeigt würde. Im Augenblick habe ich 2 Buttons mit 2 Bildern die ich immer hin und her tausche. Funktioniert, ist aber, wie schon erwähnt, aus meiner Sicht erher unschön.

    Gruß Shrike

    • Offizieller Beitrag

    Funktioniert, ist aber, wie schon erwähnt, aus meiner Sicht erher unschön.


    Was ist daran "unschön"? Es ist funktionell, einfach zu handhaben und erfüllt seinen Zweck zur Zufriedenheit. Und wenn du es zur "schönen" Lesbarkeit im Skript in eine Funktion auslagerst (State setzen und Bildzuweisung) ist doch alles im grünen Bereich.
    Und zusätzlich ist diese Lösung auch noch diejenige, die die wenigsten Ressourcen beansprucht - finde ich "schön". ;)

  • Hi,
    also besonders sparsam finde ich das nicht, nicht das wir uns falsch verstehen.
    Unter Win7 kann ich dem aktiven Knopf ein Bild zuweisen, ihn deaktivieren und ein anderes Bild zuweisen => 1xKnopf-2xBild (funzt super, und nebenbei da gibts keinen 3D Effekt)
    Wenn das gleiche Programm unter Win XP läuft kann ich das nicht! Dann bekomme ich das 2te Bild nicht angezeigt, sonder immer einen leeren Knopf (Hintergrund, standard grau)
    Also Tricksen => 1x(aktiver)Knopf-1xBild UND 1x(dektivierter) Knopf-1xImagelist mit 4xBild
    Und dann die "unschöne" Konstruktion den deaktivierten Knopf außerhalb der Gui zu erzeugen und ihn beim "deaktivieren" gegen den "aktivierten" auszutauschen.
    Das sieht so aus...

    und irgendwie glaube ich nicht das resourcenschonend ist... gehen tut das natürlich... habe ich derzeit so im Einsatz ;)
    Aber ich wollte ja was lernen und es "besser" machen.

    • Offizieller Beitrag

    Mir scheint, dass du etwas viel Aufwand betreibst.
    Ich wende das i.A. so an:

    [autoit]

    $picBtnActive = "Pfad_aktive_Btn.bmp"
    $picBtnDeactive = "Pfad_deaktive_Btn.bmp"
    ...
    ...
    $Btn_1 = GUICtrlCreateButton('', 10, 10, 25, 25, $BS_BITMAP)
    GUICtrlSetImage(-1, $picBtnActive)
    ...
    ...

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _Switch($_ID) ; Status ändern und gleichzeitig Bild wechseln
    If BitAND(GUICtrlGetState($_ID), $GUI_DISABLE) Then
    GUICtrlSetState($_ID, $GUI_ENABLE)
    GUICtrlSetImage($_ID, $picBtnActive)
    Else
    GUICtrlSetState($_ID, $GUI_DISABLE)
    GUICtrlSetImage($_ID, $picBtnDeActive)
    EndIf
    EndFunc

    [/autoit]
  • Da hast du natürlich recht...habe das grade noch mal ausprobiert.
    WENN ich die Daten in dem Verzeichnis als BMPs liegen hätte würde das so gehen..
    Ich will das jetzt nicht weiter erläutern, aber aus einem sehr triftigen Grund habe ich sie in die EXE integriert.
    Aber der Test hat mir dann gezeigt das das wohl eindeutig an der resources.au3 liegt.
    Vielleicht sollte ich mal Zedna auf den Senkel gehen... oder es findet sich jemand der mir die tieferen dahinterliegenden API-Aufrufe in 2 Worten einfach erklärt ;)
    Sonst muß ich wohl bei dem etwas umständlichen Verfahren bleiben... funktioniert ja.

  • ... oder es findet sich jemand der mir die tieferen dahinterliegenden API-Aufrufe in 2 Worten einfach erklärt...


    Moin,

    es reicht eigentlich LoadImage, GetModuleHandle und SendMessage mit BM_SETIMAGE für das was Du vorhast ...

    Spoiler anzeigen
    [autoit]

    #include <Constants.au3>
    #include <ButtonConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $g_hInstance = GetModuleHandle (0)
    ...
    $Btn_1 = GUICtrlCreateButton('', 10, 10, 25, 25, $BS_BITMAP)
    $hBmp = LoadImage ($g_hInstance, "BUTTON_BMP_1", $IMAGE_BITMAP, 0, 0, $LR_SHARED)
    GUICtrlSendMsg ($Btn_1, $BM_SETIMAGE, $IMAGE_BITMAP, $hBmp)
    ...
    ...

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Switch($_ID) ; Status ändern und gleichzeitig Bild wechseln

    [/autoit] [autoit][/autoit] [autoit]

    Local $hBmp

    [/autoit] [autoit][/autoit] [autoit]

    If BitAND(GUICtrlGetState($_ID), $GUI_DISABLE) Then
    GUICtrlSetState($_ID, $GUI_ENABLE)
    $hBmp = LoadImage ($g_hInstance, "BUTTON_BMP_1", $IMAGE_BITMAP, 0, 0, $LR_SHARED)
    GUICtrlSendMsg ($_ID, $BM_SETIMAGE, $IMAGE_BITMAP, $hBmp)
    Else
    GUICtrlSetState($_ID, $GUI_DISABLE)
    $hBmp = LoadImage ($g_hInstance, "BUTTON_BMP_2", $IMAGE_BITMAP, 0, 0, $LR_SHARED)
    GUICtrlSendMsg ($_ID, $BM_SETIMAGE, $IMAGE_BITMAP, $hBmp)
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;...

    [/autoit] [autoit][/autoit] [autoit]

    Func GetModuleHandle ($lpModuleName)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aRes = DllCall ("kernel32.dll", "HANDLE", "GetModuleHandleW", "ptr", $lpModuleName)
    If @error Then _
    Return @error

    [/autoit] [autoit][/autoit] [autoit]

    Return $aRes[0]

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func LoadImage ($hinst, $lpszName, $uType, $cxDesired, $cyDesired, $fuLoad)

    [/autoit] [autoit][/autoit] [autoit]

    Local $type = "ptr"

    [/autoit] [autoit][/autoit] [autoit]

    If (IsString ($lpszName)) Then $type = "wstr"

    [/autoit] [autoit][/autoit] [autoit]

    Local $aRes = DllCall ("user32.dll", 'HANDLE', 'LoadImageW', _
    'HANDLE' , $hinst, _
    $type , $lpszName, _
    'UINT', $uType, _
    'int' , $cxDesired, _
    'int' , $cyDesired, _
    'UINT', $fuLoad)
    If @error Then _
    Return @error

    [/autoit] [autoit][/autoit] [autoit]

    Return $aRes[0]

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit]

    Gruß
    Greenhorn


  • Ja.. danke, super, damit kann ich die Bilder aus der EXE direkt verwenden :thumbup: gleich mal eingebaut

    :( Aber unter Windows XP bleibt mein Problem bestehen, auch mit diesem Verfahren kein Bild in einem deaktivierten Button ?(
    Es ist zum Haareausraufen.. wie schon gesagt, unter Windows 7 geht das ALLES!!! in jeder der möglichen Kombis. Ich habe das mal Synchron laufen lassen. Obwohl ich da ob des fehlenden 3D Eindruckes gleich die Imagelist als einziges Verfahren genommen hätte, bzw gar kein 2tes Bild brauchen würde da mit der Deaktivierung eine passende Bildveränderung einhergeht.
    Wenn ich das unter Windows XP mache und 1x, 1x reicht!!, mit GUICtrlSendMsg() oder dem _ResourceSetImageToCtrl() ein Bild in den Button lade funktioniert das Laden mit _GUICtrlButton_SetImageList und somit die Anzeige eines Bildes für den deaktivierten Zustand nicht mehr. Und mit GUICtrlSendMsg() kein Bild im deaktivierten Button..unter WinXP!
    Was bitte hat sich da geändert? Schreibt der da einen zusätzlichen ControlStatus oder Style? Reicht es dann vielleicht den rückgängig zu machen?
    Ich habe noch 2 Buttons mit Icons in der Form, da geht das alles ohne Fehler mit 1x Icon laden, Button deaktivieren, schon ist das Icon grau aber gut zu erkennen.

    Oder liegt das am BMP?? muß ich das für XP auf jpg oder png ändern?

    So langsam glaube ich auch daran das ich die Imagelist benutzen und den 3D effekt per Hand reinmalen muß, würde zumindest schneller gehen.

  • Zitat

    Oder liegt das am BMP?? muß ich das für XP auf jpg oder png ändern?


    Um Gottes willen, nein. Bloß keine Pengs, Pongs usw., damit machst Du Dir das Leben nur unnötig schwer.
    Das hat mit XP zu tun. XP unterstützt Bilder in Schaltflächen nicht wirklich. Da musst Du i.d.R. auf Ownerdraw umschalten.
    Ist das denn so wichtig ? In zwei Jahren ist eh der Zug für XP abgefahren. Funktionalität geht vor Klicki-Bunti. ;)


    Gruß
    Greenhorn