[wxWidgets] Button-Rahmen zeichnen?



  • Hallo,

    wie kann ich mithilfe von wxWidgets denn einen Button malen? Also kein funktionierendes Control, sondern nur das aussehen zeichnen.

    Danke!


  • Mod

    Man könnte ein Bild statt dessen darstellen, welches dann halt ein Screenshot des Controls ist.
    Aber für was brauchst du das?



  • Ich will eine erweiterte Buttonklasse schreiben. Oder wie mache ich das am besten, wenn nicht den Rahmen selber zeichnen?


  • Mod

    Hm, gibts viele Möglichkeiten.
    Evtl. reicht schon ein Bitmapbutton, welchen man mittels eines MemoryDCs füttert.
    Ansonsten findest du evtl. auch was bei wxCode.
    Was soll denn deine erweiterte Buttonklasse können?



  • Sie soll zB. Bitmap-Buttons mit nem Label daneben darstellen können usw.

    Gibt's in der WinAPI nicht so Funktionen, mit denen man die Standardrahmen usw. zeichnen kann? Sowas muss es doch auch für wxWidgets geben, oder?


  • Mod

    Also BitmapButtons mit Label gibts afaik bei wxCode schon.
    Ansonsten musst du dir mal die Button Klassen anschauen, wie da was
    gezeichnet wird, aber da ja wxWidgets versucht die OS Api zu wrappen,
    wird es den Button wohl nicht selber zeichnen.

    Evtl. suchst du mal im offiziellen wxForum, da gabs schon Threads zu diesem Thema.



  • m_ schrieb:

    Gibt's in der WinAPI nicht so Funktionen, mit denen man die Standardrahmen usw. zeichnen kann? Sowas muss es doch auch für wxWidgets geben, oder?

    wx Kapselt diese Funktionen (schau dir mal die uxtheme.h an). Die funktioniert aber nur wenn Visual Styles aktiv sind.

    Ich habe meinen Button einfach gebastelt, indem ich von wxButton abgeleitet habe, immer das Ownerdraw-Flag setze (das macht wx nur wenn man die Text-Farbe ändert) und den Button dann selbst Zeichne. Sind Themes aktiv, verwende ich die uxtheme.h, wenn nicht male ich es selbst (ist total billig, sind nur eine Handvoll Linien).

    Der Grund warum ich einen eigenen Button brauchte ist, dass die original WX-Buttons das Theme ignorieren, wenn man die Text-Farbe ändert, was einfach beschissen aussieht (einige Buttons geskinnt, andere nicht).


  • Mod

    frenki schrieb:

    m_ schrieb:

    Gibt's in der WinAPI nicht so Funktionen, mit denen man die Standardrahmen usw. zeichnen kann? Sowas muss es doch auch für wxWidgets geben, oder?

    wx Kapselt diese Funktionen (schau dir mal die uxtheme.h an). Die funktioniert aber nur wenn Visual Styles aktiv sind.

    Ich habe meinen Button einfach gebastelt, indem ich von wxButton abgeleitet habe, immer das Ownerdraw-Flag setze (das macht wx nur wenn man die Text-Farbe ändert) und den Button dann selbst Zeichne. Sind Themes aktiv, verwende ich die uxtheme.h, wenn nicht male ich es selbst (ist total billig, sind nur eine Handvoll Linien).

    Der Grund warum ich einen eigenen Button brauchte ist, dass die original WX-Buttons das Theme ignorieren, wenn man die Text-Farbe ändert, was einfach beschissen aussieht (einige Buttons geskinnt, andere nicht).

    Hm, interessant 🙂
    Könntest du einen kleinen Beispielcode posten?



  • Also, zunächst im Konstruktor von meinem abgeleiteten Button das Ownerdraw-Flag setzen:

    wxGDButton::wxGDButton(wxWindow *parent, wxWindowID id, const wxString& label, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name)
    :wxButton(parent, id, label, pos, size, style, validator, name)
    {
       long s = GetWindowLong(GetHwnd(), GWL_STYLE);
       s |= BS_OWNERDRAW;
       SetWindowLong(GetHwnd(), GWL_STYLE, s);
    }
    

    Die originale Button-Klasse ruft im Falle der Ownerdraw-Zeichne-Mich-Message die virtuelle Funktion MSWOnDraw() auf, die habe ich überschrieben um den Button zu Zeichnen. Der Entscheidene Teil:

    wxUxThemeEngine *pTheme = wxUxThemeEngine::Get(); // benötigt #include <wx/msw/uxtheme.h>
       if (pTheme && !pTheme->IsAppThemed()) pTheme = NULL;
    
       if (pTheme) {
          wxUxThemeHandle hTheme(this, L"BUTTON");
          if (hTheme) {
             long flags = PBS_NORMAL;
             if (state & ODS_DISABLED) flags = PBS_DISABLED;
             else if (pushed) flags = PBS_PRESSED;
             else if (m_mouseOver) flags = PBS_HOT;
             else if (selected) flags = PBS_DEFAULTED;
    
             pTheme->DrawThemeBackground(hTheme, (HDC)dc.GetHDC(), BP_PUSHBUTTON, flags, &lpDIS->rcItem, NULL);
          }
       }
       else {
          // Paar Linien ziehen, der Win95-Button halt. Megabillig.
       }
    
       // Hier noch den Text reinmalen, in meinem Fall zusätzlich wahlweise auch noch 'nen Icon.
    

    Edit: Da fällt mir noch was wichtiges ein: Die wxUxTheme.h ist (oder war zumindest damals, als ich das gemacht habe) nicht dokumentiert. Sie ist aber total billig, importiert einfach die Funktionen aus der UXTHEME.DLL und reicht die Parameter 1:1 weiter. Die benötigten Informationen kann man also problemlos der MSDN entnehmen.



  • Alles klar, danke.


Anmelden zum Antworten