Hintergrund von eigener Komponente transparent



  • Hi Leute.
    Wie kann ich den Hintergrund von einer eigenen Komponente transparent machen? Also so wie es zum Beispiel bei einem leeren TImage ist?
    Danke fuer alle Antworten.
    MfG Aoeke



  • Indem du sie von einer Komponente ableitest, die noch kein "Aussehen" hat (z.B. TGraphicControl) und dann keinen Hintergrund malst. (Beim aktualisieren Invalidate() mit nutzen, damit alles, was _unter_ der Komponente liegt mitgezeichnet wird)



  • Dankeschoen, das funktioniert schonmal.
    Aber da faellt gleich das naechste Problem: Wie kann ich den Hintergrund bei Canvas->TextRect(...) transparent machen? Ich habs schon mit der Api-Funktion SetBkMode(...) aber das funktioniert nicht. Wie kann ich das machen?
    MfG Aoeke



  • ich weiss ja nicht, bei mir funzt dass ...

    // hintergrund nicht verarbeiten
    SetBkMode(FCanvas->Handle, TRANSPARENT);
    
    // text zeichnen
    DrawText(FCanvas->Handle, "BlahBlah", -1, &CRect, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
    


  • DANKESCHOEN!
    MfG Aoeke



  • Ich habe doch noch eine Frage:

    Dasd schrieb:

    (Beim aktualisieren Invalidate() mit nutzen, damit alles, was _unter_ der Komponente liegt mitgezeichnet wird)

    Wo genau sollte ich jetzt dieses Invalidate() benutzen? Ich habe es jetzt bei den Zuweisungsfunktionen der Eigenschaften [SetCaption, ...] und bei den Nachrichtenverarbeitungsfunktionen (was fuer ein Wort :D) [WM_LBUTTONDOWN, ...] anstatt Paint() eingesetzt. Das laesst allerdings noch zu wuenschen uebrig, da die Komponente jetzt ziemlich oft neu gezeichnet wird, und es so haeufig flackert [ <- beim MouseEnter, MouseOut, ...].
    Wie kann ich das verbessern?
    MfG Aoeke



  • du brauchst doch deine komponente nur neu zeichnen, wenn...

    1. form bewegt oder resized wurde (WM_WINDOWPOSCHANGED)
    2. form aktiv oder inaktiv wurde (WM_ACTIVATE)
    3. eventuell wenn auflösung geändert wurde (WM_DISPLAYCHANGE)
    4. hintergrund gelöscht wurde (WM_ERASEBKGND)

    probiers mal mit denen und sag bescheid, ob es was hilft!



  • Naja, ich denke nicht, dass das reicht, da ich ja alleine schon neu zeichnen muss, wenn sich die Caption aendert, oder die horizontale Ausrichtung der Caption und bei den meisten anderen Aenderungen einer Eigenschaft, weil sonst wird das ja nicht aktualisiert? Oder seh ich da was falsch?
    Zur Info: Es handelt sich bei der Komponente um einen Button.



  • na wenn du die caption änderst, ist schon klar, dass du da neu zeichnen musst, aber du änderst ja nicht 10 mal in der sekunde die caption...

    hast du den button von TButton abgeleitet? dann übernimmt dort normalerweise die parent-klasse das zeichnen.

    ansonsten poste (oder link zum downloaden) mal den source-code, damit ich mir ein bild machen kann...



  • Nee, ich habe den Button von TGraphicControl abgeleitet, um ihn eben transparent machen zu koennen, was ja auch klappt.
    Und posten werde ich den Code lieber nicht, da das doch ganz schoen viele zeilen sind, da der button eine Menge Funktionen hat...
    Aber du kannst dir ja den Code hier herunterladen. Aber Achtung: Er ist fast garnicht auskommentiert. Aber ich denke man kann das groebste trotzdem verstehen.
    Danke fuer deine Muehen...
    MfG Aoeke



  • kurzer abriss und sachen zum verbessern (teils für übersicht)

    1. Paint ist virtuell und so auch zu deklarieren
    -> virtual void __fastcall Paint(void);

    2. andere virtuelle methoden sollten nicht public sein
    3. alle unsinnigen Get-Methodenentfernen
    -> beispiel

    int __fastcall TMGButton::GetBorderWidth()
    {
    	return( fBorderWidth );
    }
    

    macht keinen sinn, sei denn du willst die eigenschaft vor der rückgabe noch auswerten oder verändern!

    // besser so
    __property int BorderWidth = { read = fBorderWidth, write = SetBorderWidth};
    

    4. bei allen Set-Methoden vorher überprüfen, ob die eigenschaft sich tatsächlich geändert hat.

    void __fastcall TMGButton::SetBorderWidth(int Value)
    {
      if (fBorderWidth != Value)
      { 
        // wert zu weisen
        fBorderWidth = Value;
    
        // steuerelement neu zeichnen
        Invalidate();
      }
    }
    

    5. schau mal ob du nicht in der Paint-Methode einige der if-else-dinger durch eine cleverere schreibweise entfernen kannst... sonst ist das viel zu unübersichtlich
    6. wenn button geklickt wird, wird er im moment nicht geklickt gezeichnet.
    7. am anfang sollte borderstyle vielleicht nicht unbedingt bsNone sein, da man sonst nix sieht

    komisch ist bei mir jetzt, dass Paint() scheinbar durch Invalidate() gar nicht aufgerufen wird, erst nach dem minimieren und maximieren tut sich bei mir optisch was. ansonsten sollte es mit Invalidate() schon gehen.



  • Als erstes: Danke fuer deine Muehen.
    [snip]
    Ja.. Dann muss ich das mal alles ändern und dann mal schauen.. Ich poste dann alles weitere.
    Danke
    MfG Aoeke

    Edit:
    Zitate bitte auf das Notwendigste beschränken. Danke!



  • Also, neuester Stand:

    • Paint ist jetzt virtuell
    • die anderen Methoden sind noch public aber nicht mehr virtuell
    • Das mit den unsinnigen Methoden aendere ich nicht, da er die Daten sonst zur Laufzeit falsch liest!
    • Bei den Set-Methoden ueberpruefe ich jetzt immer, ob sich der Wert veraendert hat.
    • Ich habe folgendes herausgefunden: Ich hatte vorher schonmal mein Problem mit dem default geschildert. Also dass der die Eigenschaft zum Programmstart, also zur Laufzeit immer wieder auf den Wert von default setzt. Das will ich aber nicht so. Er soll den Wert setzen, wenn ich mir die Kompo auf die Form ziehe und die Eigenschaften dann beim Start (Laufzeit) so lassen, wie ich sie zur Entwurfszeit eingestellt habe. Wie gesagt geht das mit default aber nicht. 😞
      Setze ich die Werte im Konstruktor, funktioniert es bei einigen, aber nicht bei allen. Bei einer Bool-Eigenschaft Active funktioniert es zum Beispiel, und bei der Bool-Eigenschaft Enabled wieder nicht! 😡 Mich kot** das langsam an!!! Wie kann ich das machen, dass die Eigenschaften, wenn ich mir die Kompo auf die Form ziehe, alle einen vordefinierten Wert besitzen und die dann beim Start so gelassen werden? Ich bin glaube ich zu bloed dafuer :(. Bei anderen Komponenten klappt das doch auch.. 😞

    MfG Aoeke


Anmelden zum Antworten