TreeView Node selbst malen => Font->Color geht nicht ???



  • Hallo

    habe eine TreeView und befülle diese auf der ersten Ebene z.B. so:

    27.1UA (Lager):TA:01
    80.1OA (Verwaltung):AB:10

    usw.

    Diese Nodes (Level/Ebene 0) will ich selbst zeichnen. Die
    einzelnen Blöcke sollen dabei unterschiedliche Farben haben,
    also z.B.

    27.1UA = hellblau
    (Lager) = grau
    :TA = dunkleblau
    :01 = dunkelblau

    So sieht mein Quellcode dazu aus:

    void __fastcall TForm23::frm23_tv3_VerbindungAdvancedCustomDrawItem(TCustomTreeView *Sender, TTreeNode *Node, TCustomDrawState State, TCustomDrawStage Stage, bool &PaintImages, bool &DefaultDraw)
    {try {										                                  // Fehlerroutine Start
     Integer iInd,iStil,iB,iPos; TColor f1,f2;                                      // Vars definieren
     AnsiString zInh,zOrt,zNamSc,zNamPa,zNamPo;                                     // Vars definieren
     TFontStyles s1;								                                // Vars definieren
     TTreeView *Tree;								                               // vorbereiten
     TRect CRect;									                               // vorbereiten
    
     if(Node==NULL) { return; }							                         // Einsprung prüfen
     Tree = dynamic_cast<TTreeView *>     (Sender);                  		       // Sender als TTreeView casten
     if(Stage!=cdPostPaint) { return; }                                             // wenn diese Funktion nicht nach dem kompletten Zeichnen des Nodes kommt, dann Abbruch
    
                                                                                    // ab hier den fertig gezeichneten Node mit allem überzeichnen
    
     s1   =TFontStyles();                                                           // Font keine Eigenschaften
     zInh =Node->Text;								                              // Nodebeschriftung
     iInd =Node->Index;								                             // Eintragsindex ermitteln
     iStil=DT_LEFT;                                                                 // Standardstil
     f1   =clWhite; f2=clBlue;       						                       // Farben Standard
     if(Tree->Enabled==false) { f2=clGray; }                                        // wenn Contrll gesperrt ist...
    
     CRect=Node->DisplayRect(true);							                     // Koord. des Texteintrages
     if(Node->Level!=0) { DefaultDraw=true; return; }				               // nicht erste Ebene, dann fertig
    
     zInh  ="|"+StringReplace(zInh,":","|",TReplaceFlags() << rfReplaceAll)+"|";    // z.B. aus '27.1UA (Lager):TA:01' wird '|27.1UA (Lager)|TA|01|'
     zNamSc=    DatenPipe(1,1,zInh,"!!");                                           // Schrank (Ort) ausschneiden = 27.1UA (Lager)
     zNamPa=":"+DatenPipe(1,2,zInh,"!!");                                           // Panel         ausschneiden = TA
     zNamPo=":"+DatenPipe(1,3,zInh,"!!");                                           // Port-ID       ausschneiden = 01
    
     zOrt  ="";                                                                     // Voreinstellung
     iPos  =zNamSc.AnsiPos(" (");                                                   // Standort hängt hinter Schrankname dran (Lager)
     if(iPos>0) {                                                                   // ja, dann trennen
      zOrt  =Trim(zNamSc.SubString(iPos+1,zNamSc.Length()-iPos));                   // nur (Lager) ausschneiden
      zNamSc=Trim(zNamSc.SubString(1,iPos));                                        // nur Schrankname ausschneiden 27.1UA
     }                                                                              // ende if(iPos>0
    
     Tree->Canvas->Brush->Color=clWhite;                                            // HG Farbe
     Tree->Canvas->FillRect(CRect);                                                 // Fläche erst füllen
    
      // Diese Farbe nimmt er noch, die anderen danach nicht mehr???:
     Tree->Canvas->Font->Color =f2 ;                                                // VG Farbe
     Tree->Canvas->Font->Name  ="Tahoma";                                           // Schriftart
     Tree->Canvas->Font->Size  =7;                                                  // Schriftgrösse
     Tree->Canvas->Font->Style =s1;                                                 // Schriftstil
     DrawText(Tree->Canvas->Handle,zNamSc.c_str(),-1,&CRect,iStil | DT_VCENTER | DT_SINGLELINE); // Text schreiben
    
     CRect.Left+=Tree->Canvas->TextWidth(zNamSc)+1;                                 // und nach rechts gehen
     Tree->Canvas->Font->Color =clGray;                                             // VG Farbe
     DrawText(Tree->Canvas->Handle,zOrt.c_str()  ,-1,&CRect,iStil | DT_VCENTER | DT_SINGLELINE); // Text schreiben
    
     f2=clNavy; if(Tree->Enabled==false) { f2=clGray; }                             // PANELNAME SCHREIBEN
     CRect.Left+=Tree->Canvas->TextWidth(zOrt)+1;                                   // und nach rechts gehen
     Tree->Canvas->Font->Color =f2;                                                 // VG Farbe
     DrawText(Tree->Canvas->Handle,zNamPa.c_str(),-1,&CRect,iStil | DT_VCENTER | DT_SINGLELINE); // Text schreiben
    
                                                                                    // PORT ID SCHREIBEN
     CRect.Left+=Tree->Canvas->TextWidth(zNamPa)+1;                                 // und nach rechts gehen
     Tree->Canvas->Font->Color =f2;                                                 // VG Farbe
     DrawText(Tree->Canvas->Handle,zNamPo.c_str(),-1,&CRect,iStil | DT_VCENTER | DT_SINGLELINE); // Text schreiben
    
     } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "TForm23::frm23_tv3_VerbindungCustomDrawItem()", MB_OK); }  // Fehler anzeigen
    }
    

    Bei Listboxen, Combos, StringGrids usw. funktioniert das so einwandfrei.
    Hat jemand eine Idee, warum es bei dem TreeView so nicht geht...?
    😕
    Danke im voraus und Gruß
    Stefan



  • Ich hatte mal ähnliche Probleme, ich glaube das Setzen von Font Attributen löst ein Neuzeichnen der betreffenden aus. Bin daher auf die Win32 Funktionen SetTextColor umgestiegen, um das zu verhindern:

    ::SetTextColor( Tree->Canvas->Handle, clBlack );
    

    Edit:
    SetTextColor anstannt SetColor



  • Hallo DocShoe,

    vielen Dank! 🙂

    Auf Anhieb funktioniert; nur verstehe ich nicht, warum
    das bei allen anderen Controls funktioniert, und nur bei
    den TreeViews nicht. Irgendeiner hat hier Mist gebaut:
    Microsoft oder Borland. Es ärgert mich immer wieder, das
    Jahr für Jahr neue Versionen für teures Geld auf den Markt
    gebracht werden, aber niemand mal eine Version vernünftig
    fehlerbereinigt 😡 Aber damit muss man ja leider immer
    mehr mit leben...

    Um so hilfreicher sind solche Foren... 👍

    Gruss Stefan



  • Das Problem ist, dass Änderungen am Font Objekt normalerweise ein Neuzeichnen der Komponente nach sich zieht, was ja auch Sinn macht. Nur man sich in einem OnxxxDraw Callback befindet sollte das nicht so sein, da das Ändern des Font in einer Zeichenmethode nicht ungewöhnlich ist. Wie man´s auch dreht und wendet, einmal macht´s so mehr Sinn, mal andersherum.
    Inzwischen habe ich eigene Wrapper für Win32 Funktionen und benutze fast nur noch die, weil die VCL auch längst nicht alles anbietet, was die Win32 API kann.

    Was die Versionspflege und Fixes angeht erwarte ich inzwischen nichts mehr von Borland/Codegear/Embarcadero. Der Verein hat in den letzten 4 Jahren zwei Mal den Besitzer gewechselt, die sich wahrscheinlich einen D**** um alte Versionen kümmern und stattdessen lieber neue Versionen mit neuen Features auf den Markt bringen, statt bestehende Bugs zu beheben.


Anmelden zum Antworten