Page 1 of 2
ListView Spaltenüberschrift färben
Posted: Sat Aug 06, 2022 8:52 am
by lagraf
Hallo zusammen,
einzelne Zeilen und Zellen eines ListViews kann ich mit einer Hintergrundfarbe versehen. Kann man die Spaltenüberschriften in VO auch einfärben?
ListView Spaltenüberschrift färben
Posted: Sat Aug 06, 2022 2:29 pm
by wriedmann
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
ListView Spaltenüberschrift färben
Posted: Mon Aug 08, 2022 4:36 am
by Karl-Heinz
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:
Code: Select all
RESOURCE CREATEPROCESS_MANIFEST_RESOURCE_ID RC_RT_MANIFEST %appwizdir%cctl6.man
Gruß
Karl-Heinz
Code: Select all
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 )
ListView Spaltenüberschrift färben
Posted: Mon Aug 08, 2022 6:49 am
by lagraf
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?
ListView Spaltenüberschrift färben
Posted: Mon Aug 08, 2022 8:27 am
by Karl-Heinz
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
Code: Select all
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
ersetzen mit
Code: Select all
IF ALen ( _aCols ) > 0 .AND. AScan ( _aCols , dwItem ) > 0
und letztlich in der PostInit() des Fensters die Symbolnamen festlegen..
Code: Select all
oDCYourLV:SetColoredHeaders ( { #YourCol1, #YOurCol3 , etc. } )
Gruß
Karl-Heinz
ListView Spaltenüberschrift färben
Posted: Mon Aug 08, 2022 12:58 pm
by lagraf
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
ListView Spaltenüberschrift färben
Posted: Mon Aug 08, 2022 2:25 pm
by Karl-Heinz
Hallo Franz,
was mich noch interessieren würde: Hast Du die cctl6.man eingebunden oder nicht ?
Gruß
Karl-Heinz
ListView Spaltenüberschrift färben
Posted: Mon Aug 08, 2022 3:23 pm
by lagraf
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.
ListView Spaltenüberschrift färben
Posted: Sun Aug 14, 2022 9:29 am
by Karl-Heinz
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
ListView Spaltenüberschrift färben
Posted: Sun Aug 14, 2022 10:41 am
by lagraf
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