Verständnissfrage zu WM_DRAWITEM



  • Also ich erkläre mal was ich erreichen will und was ich schon ausprobiert habe. Das Ziel ist es die Selektionmark-Farben und Selektionmark-Textfarbe eines Listviews im Reportstyle zu ändern.
    Zuerst habe ich versucht das über NM_CUSTOMDRAW zu bewerkstelligen, das hat leider nicht funktioniert.
    Nun bin ich dran das über den Style LVS_OWNERDRAWFIXED und der Message WM_DRAWITEM zu bewerkstelligen. Da ich in der DRAWITEMSTRUCT nirgendwo einen Hinweis auf die Subitems gefunden habe, kann ich mir das nur so erklären, daß ich nun beim Erhalten der Message WM_DRAWITEM die komplette Zeile des Listviews mit meinem Texten, also auch die der Subitems und den dazugehörigen Icons füllen muss, ist diese Annahme richtig?


  • Mod

    Bzgl. WM_DRAWITEM, Ja Du musst alles selber machen.

    Und was ist Dein Problem mit NM_CUSTOMDRAW. Damit geht das doch auch!



  • Ok hier mal mein Quellcode für NM_CUSTOMDRAW:

    LRESULT CALLBACK EH_LVCustomDraw(LPARAM lParam){
    
    	LPNMLVCUSTOMDRAW		cd;
    
    	cd = (LPNMLVCUSTOMDRAW)lParam;
    	if(!(cd->nmcd.uItemState & CDIS_FOCUS)){				//alle Items ohne Focus werden normal gezeichnet
    		return CDRF_DODEFAULT;
    	}
    	switch(cd->nmcd.dwDrawStage){
    		case CDDS_PREPAINT:
    			return CDRF_NOTIFYITEMDRAW;
    		case CDDS_ITEMPREPAINT:
    			return CDRF_NOTIFYSUBITEMDRAW;
    		case CDDS_SUBITEM | CDDS_ITEMPREPAINT:{
    			switch(cd->iSubItem){
    				case 0:{
    					cd->clrText   = RGB(209, 209, 209);
    					cd->clrTextBk =RGB(0, 128, 0);
    					return CDRF_NEWFONT;
    				}
    				case 1:{
    					cd->clrText   = RGB(209, 209, 209);
    					cd->clrTextBk =RGB(0, 128, 0);
    					return CDRF_NEWFONT;
    				}
    				case 2:{
    					cd->clrText   = RGB(209, 209, 209);
    					cd->clrTextBk =RGB(0, 128, 0);
    					return CDRF_NEWFONT;
    				}
    				case 3:{
    					cd->clrText   = RGB(209, 209, 209);
    					cd->clrTextBk =RGB(0, 128, 0);
    					return CDRF_NEWFONT;
    				}
    			}
    		}
    	}
    	return CDRF_DODEFAULT;
    }
    

    und im Event Handler dieser Aufruf:

    case NM_CUSTOMDRAW:
    		return EH_LVCustomDraw(lParam);
    

    Ich tendiere zwar dahingehend, daß ich die Message WM_DRAWITEM auswerten werde, aber auch wenn ich den Ansatz über NM_CUSTOMDRAW nicht verwende, wäre ich dir dankbar wenn du mir sagst wo mein Fehler liegt.


  • Mod

    1. Wichtige Frage: Ist das eine DialogProc?
    Dann wäre ein SetWindowLong(...DWL_MSGRESULT...) nötig!
    2. IMHO wäre CDRF_DODEFAULT der richtige Returnwert!

    Ansonsten:
    Das Beispiel ändert auch die Textfarbe (zwar in anderem Kontext), aber es ist ein funktionierender Code.

    http://blogs.msdn.com/oldnewthing/archive/2005/07/13/438381.aspx



  • Danke erstmal für die schnelle Antwort
    zu 1: nein das Fenster ist kein Dialog, es ist ein Child Fenster
    zu 2: wenn ich dich richtig verstanden habe soll ich CDRF_NEWFONT gegen CDRF_DODEFAULT austauschen? Gut hab ich gemacht leider mit dem gleichen Ergebniss, daß die Selektionmark nach wie vor in Systemfarben gezeichnet wird.

    Also um sicher zu gehn, daß der Text und der Texthintegrund mit den von mir gewünschten Farben dargestellt wird habe ich einfach mal die Zeile geändert:

    if(!(cd->nmcd.uItemState & CDIS_FOCUS)){
    

    in:

    if((cd->nmcd.uItemState & CDIS_FOCUS)){
    

    wie man von dem Programm erwarten sollte wurden die nicht ausgewählten Items nun mit den modifizierten Farben dargestellt, dies geschiet sowohl mit dem von mir vorher geposteten Code, als auch mit den nach deinem Vorschlag modifizierten Code. Wo könnte der Fehler noch liegen?


  • Mod

    Dir ist der Unterschied zwischen CDIS_FOCUS und CDIS_SELECTED klar?



  • Naja bei CDIS_FOCUS ist der Item Selected und hat den Keyboardfocus, bei CDIS_SELECTED kann er sich auch in einem inaktiven Fenster befinden, ist dies korrekt?

    Ok testhalber änder ich den Code mal folgendermassen und enferne diese Zeilen:

    if(!(cd->nmcd.uItemState & CDIS_FOCUS)){
            return CDRF_DODEFAULT;
        }
    

    dann sollte der Listvie ja egal was ausgewählt ist in jeder Zeile gleich aussehen, tut er aber nicht, die Zeile mit der Selectionmark hat wieder die Systemfarben, alle andern Zeilen liefern das gewünsche Ergebinss. Was soll ich da jetzt machen?



  • Ist schon ärgerlich herauszufinden, daß bei einem Listview Childfenster, das den Extended Style LVS_SHOWSELALWAYS erhalten hat für jedes Item das Flag CDIS_SELECTED gesetzt ist, wenn man NM_CUSTOMDRAW auswerten. Ich hab das unter Win98se und winxp ausprobiert. In der MSDN steht nix darüber, kann mir das jemand mal erklären?


Anmelden zum Antworten