Link to home
Start Free TrialLog in
Avatar of Peter Kiers
Peter KiersFlag for Netherlands

asked on

Question about a color rows in my own listview component

Dear Experts,

I have this to color the rows of a listview:

procedure TMainForm.PkListv1CustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
  if Odd(Item.Index) then
    PkListv1.Canvas.Brush.Color := clGray
  else
    PkListv1.Canvas.Brush.Color := clWindow;
end;

I am making my own listview-component, can this code above
be build in the component itself, i guess i have to use the onpaint
event, but I have no clue how to start. Does someone has the
experience with that?

Greetings, Peter
unit PkListView;

interface

uses
  SysUtils, Classes, Controls, ComCtrls, Windows;

type
  PkListv = class(TListView)
  private
    { Private declarations }
  protected
    { Protected declarations }
   FHeaderHandle: HWND;
   function GetHeaderHeight:Integer;
   procedure SetHeaderHeight(h:Integer);
  public
    { Public declarations }
    constructor Create(AOwner: TComponent);
    destructor Destroy();
  published
    { Published declarations }
   property HeaderHeight:Integer read GetHeaderHeight write SetHeaderHeight;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [PkListv]);
end;

{ PkListv }

const
  LVM_FIRST = $1000;
  LVM_GETHEADER = LVM_FIRST + 31;

constructor PkListv.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

end;

destructor PkListv.Destroy;
begin
  inherited;
end;

function PkListv.GetHeaderHeight: Integer;
Var
  Rc:TRect;
begin
 Result:=0;
 FHeaderHandle:=SendMessage(Handle, LVM_GETHEADER, 0, 0);
 If GetWindowRect(FHeaderHandle, rc)
  Then Result := rc.Bottom - rc.Top
end;

procedure PkListv.SetHeaderHeight(h: Integer);
begin
 FHeaderHandle:=SendMessage(Handle, LVM_GETHEADER, 0, 0);
 SetWindowPos( FHeaderHandle, 0 , 0, 0, Width, h, 0 );
 InvalidateRect(FHeaderHandle,nil,True);
end;

end.

Open in new window

Avatar of Emmanuel PASQUIER
Emmanuel PASQUIER
Flag of France image

you'll have to override TCustomListView.CustomDrawItem method that is calling this event, see Delphi code below :

function TCustomListView.CustomDrawItem(Item: TListItem; State: TCustomDrawState;
  Stage: TCustomDrawStage): Boolean;
begin
  Result := True;
  if (Stage = cdPrePaint) and Assigned(FOnCustomDrawItem) then FOnCustomDrawItem(Self, Item, State, Result);
  if Assigned(FOnAdvancedCustomDrawItem) then FOnAdvancedCustomDrawItem(Self, Item, State, Stage, Result);
end;
  PkListv = class(TListView)
  private
    { Private declarations }
  protected
    { Protected declarations }
   FHeaderHandle: HWND;
   function GetHeaderHeight:Integer;
   procedure SetHeaderHeight(h:Integer);
   function CustomDrawItem(Item: TListItem; State: TCustomDrawState;
      Stage: TCustomDrawStage): Boolean; override;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent);
    destructor Destroy();
  published
    { Published declarations }
   property HeaderHeight:Integer read GetHeaderHeight write SetHeaderHeight;
  end;

implementation
...

function PkListv.CustomDrawItem(Item: TListItem; State: TCustomDrawState;
  Stage: TCustomDrawStage): Boolean;
begin
 if Odd(Item.Index) 
  then Canvas.Brush.Color := clGray
  else Canvas.Brush.Color := clWindow;
 Result:= inherited CustomDrawItem(Item,State,Stage);
end;

Open in new window

Avatar of Peter Kiers

ASKER

How do you do that?

How do you know that the customdrawitem has to be changed?

Peter

In order to test your code I have to put data in the rows of the listview:
How can I fill a line of text dynamicly?

procedure TMainForm.btnTESTClick(Sender: TObject);
var
  MyListv: PkListv;
  MyListCol : TListColumn;
begin
  MyListv:= PkListv.Create(Self);
  MyListv.Parent := self;
  MyListv.Align := alTop;
  MyListv.Height := 300;
  MyListv.ViewStyle := vsReport;
  MyListv.GridLines := True;
  MyListv.ColumnClick := False;
  MyListv.SmallImages := ImageList1;
  MyListv.HeaderHeight:=20;
  MyListv.Items <==================================
  MyListCol := MyListv.Columns.Add;
  MyListCol.Alignment := taLeftJustify;
  MyListCol.Width := 150;
  MyListCol.Caption := 'Naam';
end;
ASKER CERTIFIED SOLUTION
Avatar of Emmanuel PASQUIER
Emmanuel PASQUIER
Flag of France image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks it works.

Peter