Welcome, Guest
Username: Password: Remember me
Hier wird Deutsch gesprochen
  • Page:
  • 1

TOPIC:

ListView Spaltenüberschrift färben 06 Aug 2022 10:52 #23222

  • lagraf
  • lagraf's Avatar
  • Topic Author


  • Posts: 338
  • Hallo zusammen,
    einzelne Zeilen und Zellen eines ListViews kann ich mit einer Hintergrundfarbe versehen. Kann man die Spaltenüberschriften in VO auch einfärben?

    Please Log in or Create an account to join the conversation.

    ListView Spaltenüberschrift färben 06 Aug 2022 16:29 #23223

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3366
  • Hallo Franz,
    Färben der Spaltentitel geht mit VO genausowenig wie das Färben der Zellen - das geht nur mit Einsatz von Windows API.
    Leider habe ich das bisher noch nie gebraucht, und kann das nur auf den "Mr. Listview" verweisen. Wenn jemand das weiß, dann er.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    ListView Spaltenüberschrift färben 08 Aug 2022 06:36 #23224

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Hallo Franz,

    ich habe etwas ausgegraben das ohne zusätzlichem Aufwand zumindest in einer Konstellation funktionieren würde.

    Die NM_CUSTOMDRAW Header-Benachrichtigungen landen beim owner, also bei der Listview.Es ist kein Problem die Text- und Hintergrundfarbe eines Headeritem zu ändern wenn die cctl6.man *nicht* eingebunden ist. Ist allerdings die cctl6.man eingebunden kann die Hintergrundfarbe nicht so einfach geändert werden. Leite mal - um das unerschiedliche Verhalten zu sehen - eine deiner Listviews von der LVHeaderColoring Klasse ab, und starte dann deine ANwendung einmal mit und einmal ohne eingebundener cctl6.man. Also mal mit und mal ohne dieser Zeile kompilieren:
    RESOURCE CREATEPROCESS_MANIFEST_RESOURCE_ID RC_RT_MANIFEST %appwizdir%\cctl6.man

    Gruß
    Karl-Heinz

    CLASS LVHeaderColoring INHERIT ListView
    
    METHOD Dispatch ( oEv ) CLASS LVHeaderColoring 
    LOCAL oEvent := oEv AS Event
    LOCAL struNotify AS _winNMHDR 
    LOCAL pNMCustomDraw AS _winNMCUSTOMDRAW
    LOCAL dwDrawStage, dwItem AS DWORD
    LOCAL hdc AS PTR 
    LOCAL iRetValue AS INT 
    
    
    	IF oEvent:message == WM_NOTIFY 
    		
                                                
    		struNotify := PTR ( _CAST , oEvent:lParam ) 
    
    //		
    //   https://docs.microsoft.com/en-gb/windows/win32/controls/about-custom-draw#changing-fonts-and-colors 
    //
    
    		IF struNotify._code == NM_CUSTOMDRAW 
    		   
    			pNMCustomDraw := PTR( _CAST , oEvent:lParam ) 
    				
    			dwDrawStage := pNMCustomDraw.dwDrawStage 
    			dwItem := pNMCustomDraw.dwItemSpec
    			hdc := pNMCustomDraw.hdc
    			
    			iRetValue := CDRF_DODEFAULT
    
    				
    			DO CASE 
    			CASE dwDrawStage == CDDS_PREPAINT 
    				
    				iRetValue := CDRF_NOTIFYITEMDRAW
    				                    
    		
    			CASE dwDrawStage == CDDS_ITEMPREPAINT  
    				
    				// Text- und Hintergrundfarbe des ersten und dritten Headeritem ändern. 
    				
    				IF dwItem == 0  .OR. dwItem == 2  
    				
    					IF IsAppThemed()  
    						
    						// Schön war´s ;-), aber SetBkColor() hat keine Wirkung wenn die cctl6.man eingebunden ist, da
    						// dann das (interne) Zeichnen des theme background immer Vorfahrt hat. Deshalb müsste  
    						// man nun den Headeritem komplett selbst zeichnen und anstatt CDRF_DODEFAULT dann CDRF_SKIPDEFAULT
    						// zurückgegeben. 
    						
    						SetBkColor ( hdc , Color { COLORCYAN }:Colorref  )  
    						SetTextColor ( hdc , Color { COLORRED}:Colorref  ) 
    
    					ELSE	   					
                      
    						// ist die cctl6.man nicht eingebunden wird die gewünschte Hintergrundfarbe sichtbar. 
    						
    						SetBkColor ( hdc , Color { COLORRED }:Colorref  )
    						SetTextColor ( hdc , Color { COLORWHITE}:Colorref    )
    						                                            
    					ENDIF
    					
    
    				ENDIF  	
    		      
    		      	
     	
    			ENDCASE 
    				
    		
    			RETURN SELF:EventReturnValue := iRetValue
    			
    			 
    		ENDIF
    		
    		
    	ENDIF
    		
    
    	RETURN SUPER:Dispatch ( oEvent )

    Please Log in or Create an account to join the conversation.

    ListView Spaltenüberschrift färben 08 Aug 2022 08:49 #23226

    • lagraf
    • lagraf's Avatar
    • Topic Author


  • Posts: 338
  • Wolfgang: Zum Färben der Zeilen verwende ich Windows API.
    Karl-Heinz: Das Färben des Headers sollte allerdings dynamisch funktionieren, abhängig vom Inhalt des Files, das in den ListView geladen wird. Wäre das damit möglich?

    Please Log in or Create an account to join the conversation.

    ListView Spaltenüberschrift färben 08 Aug 2022 10:27 #23227

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Hallo Franz,

    Du kennst ja die Symbolnamen der Spalten. Anhand der Namen können die numerischen Positionen ermittelt werden. Diese würden im Dispatch() mit dem Inhalt der "dwItem" var verglichen. Jeder Treffer würde dann den entsprechenden HeaderItem einfärben.

    DIe erweiterte LVHeaderColoring Klasse sieht so aus
    CLASS LVHeaderColoring INHERIT ListView 
    PROTECT _aCols := {} AS ARRAY 
    
    METHOD SetColoredHeaders ( aSymColumns ) CLASS LVHeaderColoring
    LOCAL i AS DWORD 
    
    	FOR i := 1 UPTO ALen ( aSymColumns ) 
    		AAdd ( _aCols , SELF:__GetColumnIndexFromSymbol (aSymColumns[i] ) -1 ) 	// zero based !	
    	NEXT
    	
    	RETURN SELF

    Dann im Dispatch() die Zeile
    IF dwItem == 0  .OR. dwItem == 2 
    ersetzen mit
    IF ALen ( _aCols ) > 0 .AND. AScan ( _aCols , dwItem ) > 0

    und letztlich in der PostInit() des Fensters die Symbolnamen festlegen..
    oDCYourLV:SetColoredHeaders ( { #YourCol1, #YOurCol3 , etc. }  ) 

    Gruß
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    ListView Spaltenüberschrift färben 08 Aug 2022 14:58 #23229

    • lagraf
    • lagraf's Avatar
    • Topic Author


  • Posts: 338
  • Hallo Karl-Heinz,
    ich habs so eingebaut, dass das Färben des LV Headers von aussen durch setzen einer Protected Variablen in LVHeaderColoring abhängig von den importierten Daten gesteuert wird.
    Danke für den Code!
    Franz

    Please Log in or Create an account to join the conversation.

    ListView Spaltenüberschrift färben 08 Aug 2022 16:25 #23230

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Hallo Franz,

    was mich noch interessieren würde: Hast Du die cctl6.man eingebunden oder nicht ?

    Gruß
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    ListView Spaltenüberschrift färben 08 Aug 2022 17:23 #23232

    • lagraf
    • lagraf's Avatar
    • Topic Author


  • Posts: 338
  • Die cctl6.man habe ich nicht eingebunden, damit der Background gefärbt wird. Wenn ich sie einbinde, dann wird nur die Schrift gefärbt nicht aber der Background.

    Please Log in or Create an account to join the conversation.

    ListView Spaltenüberschrift färben 14 Aug 2022 11:29 #23302

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • so, nun funktioniert das themed customdraw ( siehe aef im Anhang )

    Das Zeichnen findet in der Dispatch() der LV Klasse statt - wo ich auch noch ein paar zusätzliche Dinge dokumentiert habe. Muss ein HeaderItem gezeichnet werden sieht der Ablauf so aus:

    - OpenThemeData()
    - DrawThemeBackground()
    - FillRect()
    - SetText()
    - CloseThemeData()

    P.S. Wenn man die FillRect() Zeile deaktiviert sieht man was DrawThemeBackground() bewirkt.

    Happy VO- und X#ing ;-)

    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Last edit: by Karl-Heinz.

    ListView Spaltenüberschrift färben 14 Aug 2022 12:41 #23304

    • lagraf
    • lagraf's Avatar
    • Topic Author


  • Posts: 338
  • Hallo Karl-Heinz,
    ich sehs mir Ende August nach meinem Urlaub in den Dolomiten an, danke! Mir hätte aber auch schon die Variante ohne cctl6.man genügt, hat auch funktioniert.
    LG Franz

    Please Log in or Create an account to join the conversation.

    ListView Spaltenüberschrift färben 05 Sep 2022 17:42 #23650

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Da - wie bereits erwähnt - während der Header Customdraw-Benachrichtigungen nie der status CDIS_HOT übermittelt wird habe ich als workaround die LV-Methode __IsItemHot (dwItem) erstellt. Wie der Name andeutet gibt die Methode nur dann .t. zurück wenn sich die - nicht gedrückte - Maus über einem bestimmten item befindet. Der "Hot" Status eines item wird dargestellt indem die Hintergrundfarbe etwas aufgehellt wird.

    Wird im Dialog die neue CheckBox "Mimic Default HeaderBackgroundDrawing" selektiert, wird auch der Hintergrund der registrierten Items genau so gezeichnet wie das System das tun würde. Gesteuert wird das ganze in der LV-Dispatch() mit Hilfe der protect var _lMimicHeaderDefaultBackgroundDrawing.

    Zudem kann man nun auch:

    1. Dem Header einen Font zuweisen - via Property HeaderFont
    2. Die Höhe des Header festlegen - via Property HeaderHeight

    Um die Höhe des Headers zu ändern ist ein subclassing des Header notwendig. In der WinProc wird dann die HDM_LAYOUT message ausgewertet.

    Im angehängten Image ist zu sehen, dass der item "Erstellt am:" mit einem anderen Font als die restlichen Items gezeichnet wird. Der Font für den "Erstellt am:" item wird während dem customdraw - siehe LV-Dispatch() - eingesetzt.

    P.S. Für den Franz habe ich noch die beiden letzten Checkboxen hinzugefügt ;-)

    to be continued ...

    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    • Page:
    • 1
    Moderators: wriedmann