unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, EasyListview, ImgList, StdCtrls, ExtCtrls, MPCommonUtilities, MPCommonObjects; type TUserData = record FirstName, LastName, Email, Street, City, Country: WideString; end; const COLUMNNAMES: array[0..4] of WideString = ( 'First Name', 'Last Name', 'Email', 'Address', 'Avator' ); USERDATA: array[0..2] of TUserData = ( (FirstName: 'Steve'; LastName: 'Jeremy'; Email: 'jeremy@bergsoft.net'; Street: 'Long Street 33'; City: 'Great City'; Country: 'Far Far Away'), (FirstName: 'Julia'; LastName: 'Miranda'; Email: 'julia@bergsoft.net'; Street: 'Long Street 33'; City: 'Great City'; Country: 'Far Far Away'), (FirstName: 'Bill'; LastName: 'Jeremy'; Email: 'jeremy@bergsoft.net'; Street: 'Long Street 33'; City: 'Great City'; Country: 'Far Far Away') ); type TTestData = class private FAvatar: TBitmap; FCity: WideString; FCountry: WideString; FEMail: WideString; FFirstName: WideString; FLastName: WideString; FMailBoxSize: Integer; FStreet: WideString; public constructor Create; destructor Destroy; override; property Avatar: TBitmap read FAvatar write FAvatar; property City: WideString read FCity write FCity; property Country: WideString read FCountry write FCountry; property EMail: WideString read FEMail write FEMail; property FirstName: WideString read FFirstName write FFirstName; property LastName: WideString read FLastName write FLastName; property MailBoxSize: Integer read FMailBoxSize write FMailBoxSize; property Street: WideString read FStreet write FStreet; end; type TForm1 = class(TForm) ELV: TEasyListview; procedure FormShow(Sender: TObject); procedure ELVItemFreeing(Sender: TCustomEasyListview; Item: TEasyItem); procedure ELVPaintHeaderBkGnd(Sender: TCustomEasyListview; ACanvas: TCanvas; ARect: TRect; var Handled: Boolean); procedure ELVItemCustomView(Sender: TCustomEasyListview; Item: TEasyItem; ViewStyle: TEasyListStyle; var View: TEasyViewItemClass); procedure ELVColumnCustomView(Sender: TCustomEasyListview; Column: TEasyColumn; var View: TEasyViewColumnClass); private { Private declarations } public { Public declarations } end; // There are lots of helpful methods in the descendents of TEasyViewReportItem for default drawing TCustomViewReportItem = class(TEasyViewReportItem) public function CalculateDisplayRect(Item: TEasyItem; Column: TEasyColumn): TRect; override; function ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; override; function SelectionHit(Item: TEasyItem; SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; override; function SelectionHitPt(Item: TEasyItem; ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; override; procedure ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject); override; procedure PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean); override; procedure PaintText(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas; LinesToDraw: Integer); override; end; TCustomViewColumn = class(TEasyViewColumn) public procedure Paint(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType); override; end; type TEasyHeaderHack = class(TEasyHeader); TEasyColumnHack = class(TEasyColumn); var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormShow(Sender: TObject); var i: Integer; Item: TEasyItem; TestData: TTestData; begin ELV.BeginUpdate; try ELV.CellSizes.Report.Height := 100; ELV.Header.Columns.Clear; ELV.Header.Sizeable := False; ELV.Header.Draggable := False; for i := 0 to 2 do begin Item := ELV.Items.Add; TestData := TTestData.Create; TestData.FirstName := USERDATA[i].FirstName; TestData.LastName := USERDATA[i].LastName; TestData.Street := USERDATA[i].Street; TestData.City := USERDATA[i].City; TestData.Country := USERDATA[i].Country; TestData.Email := USERDATA[i].Email; TestData.MailBoxSize := 10 + Random(30) + Random(10); // Remeber to free this in the ItemFreeing event Item.Data := TestData; end; ELV.Header.FixedSingleColumn := True; finally ELV.EndUpdate(); end end; procedure TForm1.ELVItemFreeing(Sender: TCustomEasyListview; Item: TEasyItem); begin Item.Data.Free end; procedure TForm1.ELVPaintHeaderBkGnd(Sender: TCustomEasyListview; ACanvas: TCanvas; ARect: TRect; var Handled: Boolean); begin Handled := True; end; { TCustomViewColumn } procedure TCustomViewColumn.Paint(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType); var R: TRect; RectArray: TEasyRectArrayObject; Width, i: Integer; DrawTextFlags: TCommonDrawTextWFlags; begin ItemRectArray(Column, RectArray); Width := RectWidth(RectArray.BoundsRect) div (High(COLUMNNAMES) + 1); R := RectArray.BoundsRect; R.Right := R.Left + Width; for i := 0 to High(COLUMNNAMES) do begin ACanvas.Brush.Color := clLtGray; ACanvas.FrameRect(R); LoadTextFont(Column, ACanvas); ACanvas.Brush.Color := clWhite; DrawTextFlags := [dtEndEllipsis, dtCenter, dtVCenter]; DrawTextWEx(ACanvas.Handle, COLUMNNAMES[i], R, DrawTextFlags, 1); R.Left := R.Right - 1; R.Right := R.Right + Width; end end; { TTestData } constructor TTestData.Create; begin Avatar := TBitmap.Create; Avatar.LoadFromFile('Donkey.bmp'); end; destructor TTestData.Destroy; begin Avatar.Free; inherited Destroy; end; { TCustomViewReportItem } function TCustomViewReportItem.CalculateDisplayRect(Item: TEasyItem; Column: TEasyColumn): TRect; begin Result:= inherited CalculateDisplayRect(Item, Column); end; function TCustomViewReportItem.ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; begin // Anywhere in the Label Rect is a valid "Text" area Result := RectArray.LabelRect; end; function TCustomViewReportItem.SelectionHit(Item: TEasyItem; SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; begin Result:= inherited SelectionHit(Item, SelectViewportRect, SelectType); end; function TCustomViewReportItem.SelectionHitPt(Item: TEasyItem; ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; begin // Anywhere is a valid hit point Result:= True; end; procedure TCustomViewReportItem.ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject); begin inherited ItemRectArray(Item, Column, ACanvas, Caption, RectArray); // The Text is the same as the Label RectArray.TextRect := RectArray.BoundsRect; RectArray.TextRect.Right := Item.OwnerListview.ClientWidth; InflateRect(RectArray.TextRect, -4, -4); InflateRect(RectArray.FullFocusSelRect, 2, 2); RectArray.FullFocusSelRect := RectArray.TextRect; RectArray.SelectionRect := RectArray.FullFocusSelRect; RectArray.FocusChangeInvalidRect := RectArray.FullFocusSelRect; end; procedure TCustomViewReportItem.PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean); var R: TRect; begin if Column.Index = 0 then begin R := RectArray.BoundsRect; R.Right := R.Left + TEasyListview( Item.OwnerListview).ClientWidth; R.Left := 0; if Item.Index mod 2 <> 0 then begin ACanvas.Brush.Color := RGB(191, 239, 254); ACanvas.FillRect(R); end; end end; procedure TCustomViewReportItem.PaintText(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas; LinesToDraw: Integer); var R: TRect; DrawTextFlags: TCommonDrawTextWFlags; Hilight: Boolean; Size: TSize; MyData: TTestData; Header: TEasyHeaderHack; HeaderRight: Integer; begin if Column.Index = 0 then begin Header := TEasyHeaderHack( TEasyListview( Item.OwnerListview).Header); HeaderRight := TEasyColumnHack( Header.LastColumn).DisplayRect.Right; // This was set in the ItemRectArray override R := RectArray.TextRect; R.Right := HeaderRight; R.Left := R.Left + 4; Hilight := (Item.Selected or Item.Hilighted); MyData := TTestData( Item.Data); // Load the object inspector default font in a disabled mode LoadTextFont(Item, 0, ACanvas, Hilight); ACanvas.Font.Color := clGray; DrawTextFlags := [dtEndEllipsis, dtLeft, dtVCenter]; Size := TextExtentW('User Name:', ACanvas); R.Bottom := R.Top + Size.cy; DrawTextWEx(ACanvas.Handle, 'User Name:', R, DrawTextFlags, 1); LoadTextFont(Item, 0, ACanvas, Hilight); Size := TextExtentW(MyData.LastName, ACanvas); R.Top := R.Bottom + 1; R.Bottom := R.Top + Size.cy; DrawTextWEx(ACanvas.Handle, MyData.LastName, R, DrawTextFlags, 1); Size := TextExtentW(MyData.FirstName, ACanvas); R.Top := R.Bottom + 1; R.Bottom := R.Top + Size.cy; DrawTextWEx(ACanvas.Handle, MyData.FirstName, R, DrawTextFlags, 1); R.Top := R.Bottom + 30; R.Bottom := R.Top + 10; R.Right := R.Left + 60; ACanvas.Brush.Color := clGray; ACanvas.FrameRect(R); InflateRect(R, -2, -2); R.Right := R.Left + MyData.MailBoxSize; if Item.Index mod 2 <> 0 then ACanvas.Brush.Color := clGreen else ACanvas.Brush.Color := RGB(191, 239, 254); ACanvas.Rectangle(R); R := RectArray.TextRect; R.Right := HeaderRight; R.Left := 150; // Load the object inspector default font in a disabled mode LoadTextFont(Item, 0, ACanvas, Hilight); if Item.Index mod 2 = 0 then ACanvas.Font.Color := RGB(202, 242, 255) else ACanvas.Font.Color := RGB(0, 143, 191); DrawTextFlags := [dtEndEllipsis, dtLeft, dtVCenter]; Size := TextExtentW(MyData.EMail, ACanvas); R.Bottom := R.Top + Size.cy + 20; DrawTextWEx(ACanvas.Handle, MyData.EMail, R, DrawTextFlags, 1); if Item.Index mod 2 = 0 then LoadTextFont(Item, 0, ACanvas, Hilight); Size := TextExtentW(MyData.Street, ACanvas); R.Top := R.Bottom + 1; R.Bottom := R.Top + Size.cy; DrawTextWEx(ACanvas.Handle, MyData.Street, R, DrawTextFlags, 1); Size := TextExtentW(MyData.City, ACanvas); R.Top := R.Bottom + 1; R.Bottom := R.Top + Size.cy; DrawTextWEx(ACanvas.Handle, MyData.City, R, DrawTextFlags, 1); Size := TextExtentW(MyData.Country, ACanvas); R.Top := R.Bottom + 1; R.Bottom := R.Top + Size.cy; DrawTextWEx(ACanvas.Handle, MyData.Country, R, DrawTextFlags, 1); R := RectArray.TextRect; R.Right := HeaderRight; R.Left := 300; // Load the object inspector default font in a disabled mode LoadTextFont(Item, 0, ACanvas, Hilight); ACanvas.Font.Color := clGray; DrawTextFlags := [dtEndEllipsis, dtLeft, dtVCenter]; Size := TextExtentW('Avatar:', ACanvas); R.Bottom := R.Top + Size.cy; DrawTextWEx(ACanvas.Handle, 'Avatar:', R, DrawTextFlags, 1); Size := TextExtentW('Avatar:', ACanvas); R.Top := R.Bottom + 1; R.Bottom := R.Top + Size.cy; ACanvas.Brush.Color := RGB(0, 143, 191); ACanvas.FrameRect(Rect(R.Left - 1, R.Top - 1, MyData.Avatar.Width + R.Left + 1, MyData.Avatar.Height + R.Top + 1)); ACanvas.Draw(R.Left, R.Top, MyData.Avatar) end end; procedure TForm1.ELVItemCustomView(Sender: TCustomEasyListview; Item: TEasyItem; ViewStyle: TEasyListStyle; var View: TEasyViewItemClass); begin if ViewStyle = elsReport then View := TCustomViewReportItem end; procedure TForm1.ELVColumnCustomView(Sender: TCustomEasyListview; Column: TEasyColumn; var View: TEasyViewColumnClass); begin View := TCustomViewColumn; end; end.