Eigener Button - Frage zum Style/zur Funktion



  • Und auch da macht es keinen Sinn. Und dann macht dort weder BeginPaint,EndPaint noch ReleaseDC Sinn!

    Geb ich dir völlig recht. Ich benutze diese Projektmappe lediglich für Versuche. Da ich den Code zum Teil von nem anderen Beitrag kopiert hab,
    habe ich auch nicht so darauf geachtet, wie "unschön" der Code ist. Mir war nur wichtig, das es funktioniert.
    Ich weiss, das ist echt blöd von mir, werde es auch noch umschreiben.

    Jedoch bleiben meine Fragen immer noch offen(siehe ersten Post).

    Wie kann ich die 3 Zustände korrekt anzeigen(Fehler siehe ersten Post).
    Und kann man den weissen Rechteck vom Button entfernen?


  • Mod

    Du hast doch schon eine Antwort.
    Der weiße Bereich entsteht doch dadurch, dass Dien Bild nicht den Bereich des Buttons füllt.

    Also entweder einen "non rectangular control" bauen. (Habe ich schon gechrieben GidF). Oder den Hintergrund korrekt vorbereiten und nur den "eigentlichen Button" transparent in den Hintergrund zeichnen.



  • Du hast doch schon eine Antwort.
    Der weiße Bereich entsteht doch dadurch, dass Dien Bild nicht den Bereich des Buttons füllt.

    Ach so, ich hatte gehofft, das man den Button irgendwie ganz "ausblenden" könnte. Naja, danke.

    Also entweder einen "non rectangular control" bauen. (Habe ich schon gechrieben GidF). Oder den Hintergrund korrekt vorbereiten und nur den "eigentlichen Button" transparent in den Hintergrund zeichnen.

    Ok, werd ich dann so machen.

    Kleine Frage noch. Es gibt ja diese Item-States wie ODS_DEFAULT oder ODS_SELECTED.
    Wie genau kann ich es machen, dass auch ein eigenes Bild für den fall, das sich die Maus darüber befindet, angezeigt wird?


  • Mod

    need help schrieb:

    Kleine Frage noch. Es gibt ja diese Item-States wie ODS_DEFAULT oder ODS_SELECTED.
    Wie genau kann ich es machen, dass auch ein eigenes Bild für den fall, das sich die Maus darüber befindet, angezeigt wird?

    ODS_HOTLIGHT gibt es IMHO nutr für Comboboxen.

    Aber wo hast Du den hier ein Problem?
    1. Kannst Du beim Zeichnen prüfen ob der Cursor im/auf dem Button steht.
    2. Kannst Du DeinenButton subclassen und so auch mitbekommen wenn die Maus über den Button fährt.
    3. Gibt es TrackMouseEvent mit dem man sogar mit bekommt, dass das Fenster verlassen wird. Da gibt es auch WM_MOUSEHOVER etc...



  • Soweit ich das jetzt verstanden habe(MSDN), sendet TrackMouseEvent unter anderem die Messages WM_MOUSEHOVER & WM_MOUSELEAVE,
    die ich dann bequem abfangen und dem entsprechend darauf reagieren kann.

    Ich bin mir jetzt aber nicht ganz sicher, wo ich die Funktion TrackMouseEvent aufrufen soll. Etwa bei WM_PAINT? Wäre
    toll, wenn du mir da weiterhelfen würdest.



  • in WM_MOUSEMOVE



  • Stimmt, hatte ich total vergessen.



  • Leute, ich komme echt nicht klar. Ich versuche schon die ganze Zeit mit Regions und GDI+(Graphics::Image) meinen Button zu zeichnen. Doch ich weiss nicht,
    wie genau ich das machen muss.

    case WM_DRAWITEM:
    		{
    			pdis = (LPDRAWITEMSTRUCT)lParam;
            }
    

    Ich weiss einfach nicht, wie ich weiter vorgehen muss. Habe mit HRGN und SetWindowRgn() herumprobiert. Wenn ich zum Beispiel eine Ellipse setze,
    dann wird es auch angezeigt, jedoch auch das weisse Rechteck des Buttons.

    Ich weiss, für euch ist es lästig, aber kann mir jemand bitte sagen, wie ich mein Vorhaben umsetzen kann?
    Habe mir auch schon manches im Netzt angeschaut, z.b. das http://www.rohitab.com/discuss/topic/26786-irregular-shaped-buttonswin32/.



  • Hast Du den Button-Style BS_OWNERDRAW gesetzt, sonst erhälst Du nie WM_DRAWITEM?



  • Achte darauf, dass Du das HRGN-Handle nach erfolgreichem SetWindowRgn nicht löschst. Das System übernimmt das Handle und legt keine Kopie an.



  • Hast Du den Button-Style BS_OWNERDRAW gesetzt, sonst erhälst Du nie WM_DRAWITEM?

    Klar hab ich.

    Achte darauf, dass Du das HRGN-Handle nach erfolgreichem SetWindowRgn nicht löschst. Das System übernimmt das Handle und legt keine Kopie an.

    Ja, darauf achte ich auch.

    Wie schon oben geschrieben, wird das Region auch angezeigt, wenn ich z.b. eine Ellipse mit SetWindowRgn() setzte. Nur das Problem ist,
    das diese Ellipse im weissen Rechteck des Buttons ist, dieser also nicht verschwindet. Weiss jemand da weiter?

    Außerdem, kann mir jemand sagen, wie ich ein Bild(Graphics::Image) mit Alpha(PNG)
    durch Regions oder so als meinen Button definieren kann?
    Bei mir klappt es wie schon gesagt nicht.


  • Mod

    Hast Du WS_CLIPCHILDREN definiert? Dann zeichnet das Parent nicht den Untergrund.
    Ansonsten wenn die Region wirklich korrekt gesetzt ist zeichnet das Parent auch den Untergrund.

    Ansonsten habe Ich Dir Transparent BLT schon genannt...



  • Hast Du WS_CLIPCHILDREN definiert?

    Ja, habe ich. Ich habe jetzt mal zum Testen folgenden Code Kopiert:

    case WM_DRAWITEM:
    		{
    			LPDRAWITEMSTRUCT lpdiControl = (LPDRAWITEMSTRUCT)lParam;
    
                if(lpdiControl->CtlType == ODT_BUTTON)
    			{
                    HRGN hrgnButton1 = CreateRectRgn(0, 0, 0, 0);
                    GetWindowRgn(lpdiControl->hwndItem, hrgnButton1);
                    RECT rcClient; GetClientRect(lpdiControl->hwndItem, &rcClient);
    
                    FillRect(lpdiControl->hDC, &lpdiControl->rcItem, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
    
                    if(lpdiControl->itemState & ODS_SELECTED)
    				{
                        rcClient.top += 1, rcClient.left += 1;
                        HRGN hrgnButton2 = CreateEllipticRgnIndirect(&rcClient);
                        FillRgn(lpdiControl->hDC, hrgnButton1, (HBRUSH)GetStockObject(BLACK_BRUSH));
                        FillRgn(lpdiControl->hDC, hrgnButton2, (HBRUSH)GetStockObject(BLACK_BRUSH));
                        DeleteObject(hrgnButton2);
                    }
    				else
    				{
                        rcClient.bottom -= 1, rcClient.right -= 1;
                        HRGN hrgnButton2 = CreateEllipticRgnIndirect(&rcClient);
                        FillRgn(lpdiControl->hDC, hrgnButton1, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
                        FillRgn(lpdiControl->hDC, hrgnButton2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
                        DeleteObject(hrgnButton2);
                    }
    			}
    		}
    

    Den Code habe ich von http://www.rohitab.com/discuss/topic/26786-irregular-shaped-buttonswin32/ vom Beispiel von Napalm.

    Bei mir sieht das so aus:
    Normal -> http://s7.directupload.net/images/131206/ha2h3inv.jpg
    Geklickt -> http://s14.directupload.net/images/131206/blg3rsgv.jpg

    Wie man sieht, wird das ganze Rechteck mit der Farbe gefüllt, die ich bei der Ellipse als Normal-Zustand habe.

    Vielleicht mach ich auch nur einen dummen Fehler. Wäre also über Antworten glücklich!


  • Mod

    Wie Du unschwer sehen kannst Hast Du nicht das Fenster selbst auf eine abweichende Region gesetzt. Sondern Du zeicnest nur in diese Region.



  • Wie Du unschwer sehen kannst Hast Du nicht das Fenster selbst auf eine abweichende Region gesetzt. Sondern Du zeicnest nur in diese Region.

    Ok, stimmt. Jetzt klappt es. Jedoch komme ich irgendwie nicht mit meinen Bildern(PNG's) weiter.

    Du hast mir ja vorgeschlagen, das ich es mit TransparentBlt() versuchen sollte. Jedoch wird dort eine bestimmte Farbe angegeben,
    die als transparent zu setzen ist. Ich habe hier aber PNG's mit Alpha, die ich benutzen möchte(Geht ja mit GDI+).

    Ich würde es gerne mit AlphaBlend() und der BLENDFUNCTION-Struktur machen. Bis hier hin komme ich noch klar. Jedoch komme ich nicht darauf,
    wie ich dann die HDC an meinen Button verknüpfe, so das nur mein Bild zu sehen ist und dass garnichts vom Button("weisses Rechteck") angezeigt wird.

    Hoffe ihr versteht, was ich meine und könnt mir helfen.

    ⚠ PS: Sorry, das ich erst jetzt antworte, jedoch konnte ich nicht vorher.



  • Wahrscheinlich antwortet keiner mehr, weil ihr schon ganz genervt wegen mir seit.

    Jedoch komme ich einfach nicht weiter. Kann mir jemand bei meinem Vorhaben weiterhelfen? Immerhin habe ich ja nichts "großes" vor. Von daher sollte es doch
    jemanden geben, der sich vielleicht ein bischen Zeit für mich nimmt.
    Vielleicht ist die Lösung auch ganz einfach und direkt "vor meiner Nase", jedoch komme ich grad nicht drauf.

    Danke schon mal, an alle, die sich die Mühe machen, diesen Beitrag zu lesen und evtl. eine Antwort posten 👍


Anmelden zum Antworten