ClistCtrl OnCustomDraw



  • Hallo Leute,

    ich will bei meinem CListCtrl die Hintergrundfarbe und Textfarbe des markierten Eintrags mit und ohne Fokus selbst definieren.
    Nach reichlich Recherche bin ich auf folgende Lösung gekommen, um zumindest mal die nicht markierten Einträge frei zu editieren:

    void CMyListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
    {
       NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
       *pResult = CDRF_DODEFAULT;
       switch (pLVCD->nmcd.dwDrawStage)
       {
          case CDDS_PREPAINT:
    	*pResult = CDRF_NOTIFYITEMDRAW;
    	break;
    
          case CDDS_ITEMPREPAINT:
    
    	pLVCD->clrText = RGB(0,0,0); // Schriftfarbe
    	pLVCD->clrTextBk = RGB(240,0,0); // Hintergrundfarbe
    
    	*pResult = CDRF_DODEFAULT;
    	break;
    
          default:
    	*pResult = CDRF_DODEFAULT;
    	break;
       }
    }
    

    Ich denke von hier aus müsste es nur noch ein kleiner Schritt sein, um das markierte Element zu editieren. Leider konnte ich aus den zwei,drei Artikeln von codeproject/codeguru über dieses Thema nichts diesbezüglich rauslesen.

    Kann mir jemand auf die Sprünge helfen? Dankeschön.


  • Mod

    Dein Code hat nichts mit dem editieren von Items in List Ctrls zu tun, sondern nur mit dem individuellen Zeichnen.

    Und wriklich gesucht hast Du vermutlich auch nicht sonst wärst Du bei www.codeproject.com sofot fündig geworden:
    http://www.codeproject.com/KB/list/editing_subitems_in_listcontrol.aspx

    Wenn Du mit "Editieren" allerdings "Zeichnen" meinst dann lies das hier:
    http://www.codeguru.com/cpp/controls/listview/customdrawing/article.php/c4195/
    http://www.codeguru.com/cpp/controls/listview/customdrawing/article.php/c4199/



  • Zugegeben, "editieren" ist in diesem Kontext missverständlich. Ich meine die Farben anpassen.

    Und mit

    lola82 schrieb:

    Leider konnte ich aus den zwei,drei Artikeln von codeproject/codeguru über dieses Thema nichts diesbezüglich rauslesen.

    meinte ich die beiden letzten Artikel.

    Nach meinem Verständnis wird unter

    case CDDS_ITEMPREPAINT:
    

    vor dem zeichnen festgelegt welche Farbe für das Item verwendet wird. Wie passe ich nun aber die Farben von markierten Items an (mit und ohne Fokus)?


  • Mod

    Daskannst Du doch mit GetItemState erfragen...



  • Danke,Martin. So, ich habs nun erweitert:

    void CMyListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
    {
       NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
       *pResult = CDRF_DODEFAULT;
       switch (pLVCD->nmcd.dwDrawStage)
       {
          case CDDS_PREPAINT:
    	*pResult = CDRF_NOTIFYITEMDRAW;
    	break;
          case CDDS_ITEMPREPAINT:
    
            if(GetItemState((int)pLVCD->nmcd.dwItemSpec,CDIS_SELECTED)==CDIS_SELECTED){
    
    	   pLVCD->clrText = RGB(0,0,0); // Schriftfarbe
    	   pLVCD->clrTextBk = RGB(240,0,0); // Hintergrundfarbe
    
            }
            else *pResult = CDRF_DODEFAULT;
    	break;
    
          default:
    	*pResult = CDRF_DODEFAULT;
    	break;
       }
    }
    

    Da jetzt alles standardmäßig dargestellt wird und nicht mehr alles in rot, kombiniere ich messerscharf, dass das Programm bei einer Änderung des selektierten Items zwar dort die Hintergrundfarbe auf rot setzt, dann aber wieder irgendwie/irgendwo auf die Standardfarbe zurückgesetzt wird und mit dieser auch gemalt wird.

    *pResult = CDRF_SKIPDEFAULT;
    

    innerhalb der if-Klammer brachte auch nix. Kannst Du mir noch nen finalen Hinweis geben?



  • Ich bin jetzt etwas irritiert: ist es so easy, dass es euch zu blöd ist - oder kann mir wirklich niemand helfen?

    Sollte doch eigentlich schon sehr oft vorgekommen sein!


  • Mod

    Wenn Du die Farbe änderst musst Du das IMHO durch CDRF_NEWFONT mitteilen!



  • Martin Richter schrieb:

    Wenn Du die Farbe änderst musst Du das IMHO durch CDRF_NEWFONT mitteilen!

    Nein, CDRF_NEWFONT muss nur zurückgegeben werden, wenn der Font geändert wird.

    @lola82: CDRF_DODEFAULT muss auch nach dem Setzen der Farben zuückgegeben werden:

    if (GetItemState((int) pLVCD->nmcd.dwItemSpec, CDIS_SELECTED) == CDIS_SELECTED)
        {
            pLVCD->clrText = RGB(0,0,0); // Schriftfarbe
            pLVCD->clrTextBk = RGB(240,0,0); // Hintergrundfarbe
        }
        *pResult = CDRF_DODEFAULT;
        break;
    

    Hier ein kleines Beispiel: http://blogs.msdn.com/oldnewthing/archive/2005/07/13/438381.aspx



  • @sri: CDRF_DODEFAULT bewirkt auch nicht, dass das markierte Element seine Farbe ändert...



  • Dann vermute ich, dass die Listenansicht bei markierten Elementen zwingend seine eigene Farbe (Systemfarbe für ausgewählte Elemente) verwendet. Dann würde Dir nicht anderes übrig bleiben, als wirklich jedes Element selbst zu zeichnen. Das ist möglich (mache ich in meinen Anwendungen auch), aber nicht ganz einfach.


Anmelden zum Antworten