windowsdelphilistviewdelphi-xe2columnheader

Delphi: ListView (vsReport) single column header caption with custom font color?


In a ListView with vsReport ViewStyle, how can I customize the font color of just any single column header caption? For example (the second column header caption has a red font color): enter image description here


Solution

  • I would handle the NM_CUSTOMDRAW header notification code and respond to this notification message with the CDRF_NEWFONT return code at the CDDS_ITEMPREPAINT rendering stage. The following code shows how to extend list view controls to have the event for specifying header item font color:

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ComCtrls, CommCtrl, StdCtrls;
    
    type
      TGetHeaderItemFontColorEvent = procedure(Sender: TCustomListView;
        ItemIndex: Integer; var FontColor: TColor) of object;
      TListView = class(ComCtrls.TListView)
      private
        FHeaderHandle: HWND;
        FOnGetHeaderItemFontColor: TGetHeaderItemFontColorEvent;
        procedure WMNotify(var AMessage: TWMNotify); message WM_NOTIFY;
      protected
        procedure CreateWnd; override;
      published
        property OnGetHeaderItemFontColor: TGetHeaderItemFontColorEvent read
          FOnGetHeaderItemFontColor write FOnGetHeaderItemFontColor;
      end;
    
    type
      TForm1 = class(TForm)
        ListView1: TListView;
        procedure FormCreate(Sender: TObject);
      private
        procedure GetHeaderItemFontColor(Sender: TCustomListView;
          ItemIndex: Integer; var FontColor: TColor);
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    { TListView }
    
    procedure TListView.CreateWnd;
    begin
      inherited;
      FHeaderHandle := ListView_GetHeader(Handle);
    end;
    
    procedure TListView.WMNotify(var AMessage: TWMNotify);
    var
      FontColor: TColor;
      NMCustomDraw: TNMCustomDraw;
    begin
      if (AMessage.NMHdr.hwndFrom = FHeaderHandle) and
        (AMessage.NMHdr.code = NM_CUSTOMDRAW) then
      begin
        NMCustomDraw := PNMCustomDraw(TMessage(AMessage).LParam)^;
        case NMCustomDraw.dwDrawStage of
          CDDS_PREPAINT:
            AMessage.Result := CDRF_NOTIFYITEMDRAW;
          CDDS_ITEMPREPAINT:
          begin
            FontColor := Font.Color;
            if Assigned(FOnGetHeaderItemFontColor) then
              FOnGetHeaderItemFontColor(Self, NMCustomDraw.dwItemSpec, FontColor);
            SetTextColor(NMCustomDraw.hdc, ColorToRGB(FontColor));
            AMessage.Result := CDRF_NEWFONT;
          end;
        else
          AMessage.Result := CDRF_DODEFAULT;
        end;
      end
      else
        inherited;
    end;
    
    { TForm1 }
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ListView1.OnGetHeaderItemFontColor := GetHeaderItemFontColor;
    end;
    
    procedure TForm1.GetHeaderItemFontColor(Sender: TCustomListView;
      ItemIndex: Integer; var FontColor: TColor);
    begin
      case ItemIndex of
        0: FontColor := clRed;
        1: FontColor := clGreen;
        2: FontColor := clBlue;
      end;
    end;
    
    end.
    

    The whole project you can download from here. Here's the result of the above example:

    enter image description here