* modified customdraw listview patch from BeniBela

git-svn-id: trunk@9770 -
This commit is contained in:
marc 2006-08-29 23:33:15 +00:00
parent ecc5c01e5b
commit d05adb23c1
10 changed files with 411 additions and 23 deletions

View File

@ -564,6 +564,8 @@ type
TListItemFlag = (lifDestroying, lifCreated); TListItemFlag = (lifDestroying, lifCreated);
TListItemFlags = set of TListItemFlag; TListItemFlags = set of TListItemFlag;
TDisplayCode = (drBounds, drIcon, drLabel, drSelectBounds);
{ TListItem } { TListItem }
@ -576,6 +578,7 @@ type
FData: Pointer; FData: Pointer;
FImageIndex: Integer; FImageIndex: Integer;
FStates: TListItemStates; FStates: TListItemStates;
function GetChecked: Boolean;
function GetListView: TCustomListView; function GetListView: TCustomListView;
function GetState(const ALisOrd: Integer): Boolean; function GetState(const ALisOrd: Integer): Boolean;
function GetIndex: Integer; function GetIndex: Integer;
@ -586,6 +589,7 @@ type
procedure IntfUpdateText; procedure IntfUpdateText;
procedure IntfUpdateImages; procedure IntfUpdateImages;
procedure SetChecked(AValue: Boolean);
procedure SetState(const ALisOrd: Integer; const AIsSet: Boolean); procedure SetState(const ALisOrd: Integer; const AIsSet: Boolean);
procedure SetData(const AValue: Pointer); procedure SetData(const AValue: Pointer);
procedure SetImageIndex(const AValue: Integer); procedure SetImageIndex(const AValue: Integer);
@ -601,8 +605,11 @@ type
destructor Destroy; override; destructor Destroy; override;
procedure Delete; procedure Delete;
procedure MakeVisible(PartialOK: Boolean); procedure MakeVisible(PartialOK: Boolean);
function DisplayRect(Code: TDisplayCode): TRect;
function DisplayRectSubItem(subItem: integer;Code: TDisplayCode): TRect;
property Caption : String read FCaption write SetCaption; property Caption : String read FCaption write SetCaption;
property Checked : Boolean read GetChecked write SetChecked;
property Cut: Boolean index Ord(lisCut) read GetState write SetState; property Cut: Boolean index Ord(lisCut) read GetState write SetState;
property Data: Pointer read FData write SetData; property Data: Pointer read FData write SetData;
property DropTarget: Boolean index Ord(lisDropTarget) read GetState write SetState; property DropTarget: Boolean index Ord(lisDropTarget) read GetState write SetState;
@ -613,8 +620,7 @@ type
property Owner: TListItems read FOwner; property Owner: TListItems read FOwner;
property Selected: Boolean index Ord(lisSelected) read GetState write SetState; property Selected: Boolean index Ord(lisSelected) read GetState write SetState;
property SubItems: TStrings read GetSubItems write SetSubItems; property SubItems: TStrings read GetSubItems write SetSubItems;
property SubItemImages[const AIndex: Integer]: Integer property SubItemImages[const AIndex: Integer]: Integer read GetSubItemImages write SetSubItemImages;
read GetSubItemImages write SetSubItemImages;
end; end;
@ -751,6 +757,22 @@ type
TLVInsertEvent = TLVDeletedEvent; TLVInsertEvent = TLVDeletedEvent;
TLVSelectItemEvent = procedure(Sender: TObject; Item: TListItem; TLVSelectItemEvent = procedure(Sender: TObject; Item: TListItem;
Selected: Boolean) of object; Selected: Boolean) of object;
//currently the draw events are only called from the win32 interface
TLVCustomDrawEvent = procedure(Sender: TCustomListView; const ARect: TRect;
var DefaultDraw: Boolean) of object;
TLVCustomDrawItemEvent = procedure(Sender: TCustomListView; Item: TListItem;
State: TCustomDrawState; var DefaultDraw: Boolean) of object;
TLVCustomDrawSubItemEvent=procedure(Sender: TCustomListView; Item: TListItem;
SubItem: Integer; State: TCustomDrawState;
var DefaultDraw: Boolean) of object;
TLVAdvancedCustomDrawEvent = procedure(Sender: TCustomListView; const ARect: TRect;
Stage: TCustomDrawStage; var DefaultDraw: Boolean) of object;
TLVAdvancedCustomDrawItemEvent = procedure(Sender: TCustomListView; Item: TListItem;
State: TCustomDrawState; Stage: TCustomDrawStage;
var DefaultDraw: Boolean) of object;
TLVAdvancedCustomDrawSubItemEvent=procedure(Sender: TCustomListView; Item: TListItem;
SubItem: Integer; State: TCustomDrawState;
Stage: TCustomDrawStage; var DefaultDraw: Boolean) of object;
TListViewProperty = ( TListViewProperty = (
lvpAutoArrange, lvpAutoArrange,
@ -814,6 +836,12 @@ type
FOnDeletion: TLVDeletedEvent; FOnDeletion: TLVDeletedEvent;
FOnInsert: TLVInsertEvent; FOnInsert: TLVInsertEvent;
FOnSelectItem: TLVSelectItemEvent; FOnSelectItem: TLVSelectItemEvent;
FOnCustomDraw: TLVCustomDrawEvent;
FOnCustomDrawItem: TLVCustomDrawItemEvent;
FOnCustomDrawSubItem: TLVCustomDrawSubItemEvent;
FOnAdvancedCustomDraw: TLVAdvancedCustomDrawEvent;
FOnAdvancedCustomDrawItem: TLVAdvancedCustomDrawItemEvent;
FOnAdvancedCustomDrawSubItem: TLVAdvancedCustomDrawSubItemEvent;
FProperties: TListViewProperties; FProperties: TListViewProperties;
function GetBoundingRect: TRect; function GetBoundingRect: TRect;
function GetColumnFromIndex(AIndex: Integer): TListColumn; function GetColumnFromIndex(AIndex: Integer): TListColumn;
@ -858,6 +886,7 @@ type
protected protected
procedure InitializeWnd; override; procedure InitializeWnd; override;
procedure DestroyWnd; override;
procedure Change(AItem: TListItem; AChange: Integer); dynamic; procedure Change(AItem: TListItem; AChange: Integer); dynamic;
procedure ColClick(AColumn: TListColumn); dynamic; procedure ColClick(AColumn: TListColumn); dynamic;
@ -902,6 +931,12 @@ type
property OnDeletion: TLVDeletedEvent read FOnDeletion write FOnDeletion; property OnDeletion: TLVDeletedEvent read FOnDeletion write FOnDeletion;
property OnInsert: TLVInsertEvent read FOnInsert write FOnInsert; property OnInsert: TLVInsertEvent read FOnInsert write FOnInsert;
property OnSelectItem: TLVSelectItemEvent read FOnSelectItem write FOnSelectItem; property OnSelectItem: TLVSelectItemEvent read FOnSelectItem write FOnSelectItem;
property OnCustomDraw: TLVCustomDrawEvent read FOnCustomDraw write FOnCustomDraw;
property OnCustomDrawItem: TLVCustomDrawItemEvent read FOnCustomDrawItem write FOnCustomDrawItem;
property OnCustomDrawSubItem: TLVCustomDrawSubItemEvent read FOnCustomDrawSubItem write FOnCustomDrawSubItem;
property OnAdvancedCustomDraw: TLVAdvancedCustomDrawEvent read FOnAdvancedCustomDraw write FOnAdvancedCustomDraw;
property OnAdvancedCustomDrawItem: TLVAdvancedCustomDrawItemEvent read FOnAdvancedCustomDrawItem write FOnAdvancedCustomDrawItem;
property OnAdvancedCustomDrawSubItem: TLVAdvancedCustomDrawSubItemEvent read FOnAdvancedCustomDrawSubItem write FOnAdvancedCustomDrawSubItem;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -909,6 +944,7 @@ type
procedure Clear; procedure Clear;
procedure EndUpdate; procedure EndUpdate;
function FindCaption(StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean; PartStart: Boolean = True): TListItem; function FindCaption(StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean; PartStart: Boolean = True): TListItem;
function GetItemAt(x,y: integer): TListItem;
property BoundingRect: TRect read GetBoundingRect; property BoundingRect: TRect read GetBoundingRect;
property Canvas: TCanvas read FCanvas; property Canvas: TCanvas read FCanvas;
property Checkboxes: Boolean index Ord(lvpCheckboxes) read GetProperty write SetProperty default False; property Checkboxes: Boolean index Ord(lvpCheckboxes) read GetProperty write SetProperty default False;
@ -939,7 +975,7 @@ type
property BorderSpacing; property BorderSpacing;
// property BorderStyle; // property BorderStyle;
property BorderWidth; property BorderWidth;
// property Checkboxes; property Checkboxes;
property Color default clWindow; property Color default clWindow;
property Columns; property Columns;
property ColumnClick; property ColumnClick;
@ -987,6 +1023,12 @@ type
property OnKeyDown; property OnKeyDown;
property OnDeletion; property OnDeletion;
property OnSelectItem; property OnSelectItem;
property OnCustomDraw;
property OnCustomDrawItem;
property OnCustomDrawSubItem;
property OnAdvancedCustomDraw;
property OnAdvancedCustomDrawItem;
property OnAdvancedCustomDrawSubItem;
end; end;
TProgressBarOrientation = (pbHorizontal, pbVertical, pbRightToLeft, pbTopDown); TProgressBarOrientation = (pbHorizontal, pbVertical, pbRightToLeft, pbTopDown);

View File

@ -45,8 +45,24 @@ uses
const const
//all controls //all controls
NM_FIRST = 0; NM_FIRST = 0;
NM_LAST = -99; NM_OUTOFMEMORY = NM_FIRST - 1;
NM_CLICK = NM_FIRST - 2;
NM_DBLCLK = NM_FIRST - 3;
NM_RETURN = NM_FIRST - 4;
NM_RCLICK = NM_FIRST - 5;
NM_RDBLCLK = NM_FIRST - 6;
NM_SETFOCUS = NM_FIRST - 7;
NM_KILLFOCUS = NM_FIRST - 8;
NM_CUSTOMDRAW = NM_FIRST - 12;
NM_HOVER = NM_FIRST - 13;
NM_NCHITTEST = NM_FIRST - 14;
NM_KEYDOWN = NM_FIRST - 15;
NM_RELEASEDCAPTURE = NM_FIRST - 16;
NM_SETCURSOR = NM_FIRST - 17;
NM_CHAR = NM_FIRST - 18;
NM_LAST = NM_FIRST - 99;
//listview //listview
LVN_FIRST = -100; LVN_FIRST = -100;

View File

@ -27,17 +27,31 @@ begin
FCompStyle := csListView; FCompStyle := csListView;
FViewStyle := vsList; FViewStyle := vsList;
FSortType := stNone; FSortType := stNone;
// MWE:
// A class is initalized to 0 when created
// so no need to initialize these here again
(*
FSortColumn := 0; FSortColumn := 0;
FOnCompare := nil; FOnCompare := nil;
FImageChangeLink := TChangeLink.Create; FOnCustomDraw := nil;
FImageChangeLink.OnChange := @ImageChanged; FOnCustomDrawItem := nil;
FOnCustomDrawSubItem := nil;
FOnAdvancedCustomDraw := nil;
FOnAdvancedCustomDrawItem := nil;
FOnAdvancedCustomDrawSubItem := nil;
FSelected := nil; FSelected := nil;
FFocused := nil; FFocused := nil;
*)
FImageChangeLink := TChangeLink.Create;
FImageChangeLink.OnChange := @ImageChanged;
FHoverTime := -1; FHoverTime := -1;
TabStop := true; TabStop := true;
SetInitialBounds(0,0,100,90); SetInitialBounds(0,0,100,90);
ParentColor := False; ParentColor := False;
Color := clWindow; Color := clWindow;
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
FProperties := [lvpColumnClick, lvpHideSelection, lvpShowColumnHeaders]; FProperties := [lvpColumnClick, lvpHideSelection, lvpShowColumnHeaders];
end; end;
@ -78,11 +92,13 @@ var
begin begin
nm := PNMListView(AMessage.NMHdr); nm := PNMListView(AMessage.NMHdr);
if nm^.iItem>=Items.Count then exit; if nm^.iItem>=Items.Count then exit;
//remark: NMHdr^.code is normally unhanged by the win32 interface, so the others
case AMessage.NMHdr^.code of // maps there codes to the of win32
// HDN_TRACK: case AMessage.NMHdr^.code of
// NM_CUSTOMDRAW: // HDN_TRACK:
// LVN_BEGINDRAG: // NM_CUSTOMDRAW: //Custom Drawing is handled direct from the interfaces
//(at least win32 does so)
// LVN_BEGINDRAG:
LVN_DELETEITEM: begin LVN_DELETEITEM: begin
Item := FListItems[nm^.iItem]; Item := FListItems[nm^.iItem];
if FSelected = Item then if FSelected = Item then
@ -393,12 +409,27 @@ destructor TCustomListView.Destroy;
begin begin
// Better destroy the wincontrol (=widget) first. So wo don't have to delete // Better destroy the wincontrol (=widget) first. So wo don't have to delete
// all items/columns and we won't get notifications for each. // all items/columns and we won't get notifications for each.
FreeAndNil(FCanvas);
inherited Destroy; inherited Destroy;
FreeAndNil(FColumns); FreeAndNil(FColumns);
FreeAndNil(FImageChangeLink); FreeAndNil(FImageChangeLink);
FreeAndNil(FListItems); FreeAndNil(FListItems);
end; end;
{------------------------------------------------------------------------------
TCustomListView DestroyWnd
Params: None
Result: none
Frees the canvas
------------------------------------------------------------------------------}
procedure TCustomListView.DestroyWnd;
begin
if FCanvas<>nil then
TControlCanvas(FCanvas).FreeHandle;
inherited DestroyWnd;
end;
{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
TCustomListView BeginUpdate TCustomListView BeginUpdate
Params: None Params: None
@ -479,6 +510,19 @@ begin
else Result := FHoverTime; else Result := FHoverTime;
end; end;
function TCustomListView.GetItemAt(x,y: Integer): TListItem;
var
Item: Integer;
begin
Result := nil;
if HandleAllocated
then begin
Item := TWSCustomListViewClass(WidgetSetClass).GetItemAt(Self,x,y);
if Item <> -1
then Result := Items[Item];
end;
end;
function TCustomListView.GetProperty(const ALvpOrd: Integer): Boolean; function TCustomListView.GetProperty(const ALvpOrd: Integer): Boolean;
begin begin
Result := (TListViewProperty(ALvpOrd) in FProperties); Result := (TListViewProperty(ALvpOrd) in FProperties);

View File

@ -337,6 +337,33 @@ begin
inherited Destroy; inherited Destroy;
end; end;
{------------------------------------------------------------------------------}
{ TListItem DisplayRect }
{------------------------------------------------------------------------------}
function TListItem.DisplayRect(Code: TDisplayCode): TRect;
var
LV: TCustomListView;
begin
LV := FOwner.FOwner;
Result := TWSCustomListViewClass(LV.WidgetSetClass).ItemDisplayRect(
LV, GetIndex, 0, code);
end;
{------------------------------------------------------------------------------}
{ TListItem DisplayRectSubItem }
{ The same as DisplayRect, except that it works for the sub items in the }
{ tecord view }
{ If subItem = 0 then it will should return DisplayRect(code) }
{------------------------------------------------------------------------------}
function TListItem.DisplayRectSubItem(subItem: integer; Code: TDisplayCode): TRect;
var
LV: TCustomListView;
begin
LV := FOwner.FOwner;
Result := TWSCustomListViewClass(LV.WidgetSetClass).ItemDisplayRect(
LV, GetIndex, subItem, code);
end;
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
{ TListItem IntfUpdateText } { TListItem IntfUpdateText }
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
@ -421,23 +448,36 @@ begin
and (FStates = AItem.FStates); and (FStates = AItem.FStates);
end; end;
{------------------------------------------------------------------------------}
{ TListItem GetChecked }
{------------------------------------------------------------------------------}
function TListItem.GetChecked(): Boolean;
var
LV: TCustomListView;
begin
LV := FOwner.FOwner;
Result := LV.Checkboxes and
TWSCustomListViewClass(LV.WidgetSetClass).ItemGetChecked(LV, GetIndex, Self);
end;
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
{ TListItem GetState } { TListItem GetState }
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
function TListItem.GetState(const ALisOrd: Integer): Boolean; function TListItem.GetState(const ALisOrd: Integer): Boolean;
var var
AState: TListItemState; AState: TListItemState;
LV: TCustomListView;
begin begin
AState := TListItemState(ALisOrd); AState := TListItemState(ALisOrd);
LV := FOwner.FOwner;
if IntfUpdateAllowed if IntfUpdateAllowed
and TWSCustomListViewClass(FOwner.FOwner.WidgetSetClass) and TWSCustomListViewClass(LV.WidgetSetClass).ItemGetState(LV, GetIndex, Self, AState, Result)
.ItemGetState(FOwner.FOwner, GetIndex, Self, AState, Result)
then begin then begin
// update FStates // update FStates
if Result if Result
then Include(FStates, AState) then Include(FStates, AState)
else Exclude(FStates, AState); else Exclude(FStates, AState);
end end
else Result := AState in FStates; else Result := AState in FStates;
end; end;
@ -482,11 +522,26 @@ end;
{ TListItem SetCaption } { TListItem SetCaption }
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
procedure TListItem.SetCaption(const AValue : String); procedure TListItem.SetCaption(const AValue : String);
var
LV: TCustomListView;
begin begin
if FCaption = AValue then Exit; if FCaption = AValue then Exit;
FCaption := AValue; FCaption := AValue;
LV := FOwner.FOwner;
if IntfUpdateAllowed if IntfUpdateAllowed
then TWSCustomListViewClass(FOwner.FOwner.WidgetSetClass).ItemSetText(FOwner.FOwner, GetIndex, Self, 0, FCaption); then TWSCustomListViewClass(LV.WidgetSetClass).ItemSetText(LV, GetIndex, Self, 0, FCaption);
end;
{------------------------------------------------------------------------------}
{ TListItem SetChecked }
{------------------------------------------------------------------------------}
procedure TListItem.SetChecked(AValue: Boolean);
var
LV: TCustomListView;
begin
LV := FOwner.FOwner;
if LV.Checkboxes and IntfUpdateAllowed
then TWSCustomListViewClass(LV.WidgetSetClass).ItemSetChecked(LV, GetIndex, Self, AValue);
end; end;
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
@ -548,3 +603,4 @@ begin
if (AValue = nil) and (FSubItems = nil) then Exit; if (AValue = nil) and (FSubItems = nil) then Exit;
SubItems.Assign(AValue); SubItems.Assign(AValue);
end; end;

View File

@ -787,8 +787,88 @@ Var
SetWin32SizePoint(MaxWidth, MaxHeight, MinMaxInfo.ptMaxTrackSize); SetWin32SizePoint(MaxWidth, MaxHeight, MinMaxInfo.ptMaxTrackSize);
end; end;
end; end;
//MWE: I noticed to late that eventhandlers are called here (to much code cleanup otherwise the patch was rejected)
// this should not be done here.
// we need a proper place in tcustomlistview.
// to be compatible (or consistent) with other controls,
// each OnXXX should be called from a virtual DoXXX, so descendants can override these.
//TODO: remove this code from here !!!!
procedure HandleListViewCustomDraw(ListView: TListView);
function ConvState(const state:uint): TCustomDrawState;
begin
Result := [];
if state and CDIS_CHECKED <> 0 then Include(Result, cdsChecked);
if state and CDIS_DEFAULT <> 0 then Include(Result, cdsDefault);
if state and CDIS_DISABLED <> 0 then Include(Result, cdsDisabled);
if state and CDIS_FOCUS <> 0 then Include(Result, cdsFocused);
if state and CDIS_GRAYED <> 0 then Include(Result, cdsGrayed);
if state and CDIS_HOT <> 0 then Include(Result, cdsHot);
if state and CDIS_INDETERMINATE <> 0 then Include(Result, cdsIndeterminate);
if state and CDIS_MARKED <> 0 then Include(Result, cdsMarked);
if state and CDIS_SELECTED <> 0 then Include(Result, cdsSelected);
end;
Begin var
DefaultDraw: boolean;
DrawInfo:PNMLVCustomDraw;
Stage: TCustomDrawStage;
begin
DefaultDraw:=true;
DrawInfo:=PNMLVCustomDraw(lmnotify.NMHdr);
lmnotify.result:=CDRF_DODEFAULT;
WinProcess:=false;
case drawInfo^.dwDrawStage and $7 of //Get drawing state
CDDS_PREPAINT: Stage:=cdPrePaint;
CDDS_POSTPAINT: Stage:=cdPostPaint;
CDDS_PREERASE: Stage:=cdPreErase;
CDDS_POSTERASE: Stage:=cdPostErase;
end;
case DrawInfo^.dwDrawStage and (CDDS_ITEM or CDDS_SUBITEM) of //Get drawn part
$0: begin //Whole control
if assigned(listView.OnAdvancedCustomDraw) then
listView.OnAdvancedCustomDraw(listView,drawInfo^.rc,Stage,defaultDraw);
if Stage = cdPrePaint then
begin
if assigned(listView.OnCustomDraw) then
listView.OnCustomDraw(listView,drawInfo^.rc,defaultDraw);
if assigned(listView.OnCustomDrawItem) or assigned(listView.OnCustomDrawSubItem) then
lmnotify.result:=lmnotify.result or CDRF_NOTIFYITEMDRAW;
if assigned(listView.OnAdvancedCustomDrawItem) or assigned (listView.OnAdvancedCustomDrawSubItem) then
lmnotify.result:=lmnotify.result or CDRF_NOTIFYITEMDRAW or CDRF_NOTIFYITEMERASE;
if assigned(listView.OnAdvancedCustomDraw) then
lmnotify.result:=lmnotify.result or CDRF_NOTIFYPOSTERASE or CDRF_NOTIFYPOSTPAINT;
end;
if not defaultDraw then
lmnotify.result:=lmnotify.result or CDRF_SKIPDEFAULT;
end;
CDDS_ITEM: begin //One item (= line in report mode)
if assigned(listView.OnAdvancedCustomDrawItem) then
listView.OnAdvancedCustomDrawItem(listView,listView.Items[drawInfo^.dwItemSpec], convState(drawInfo^.uItemState),Stage,defaultDraw);
if Stage = cdPrePaint then
begin
if assigned(listView.OnCustomDrawItem) then
listView.OnCustomDrawItem(listView,listView.Items[drawInfo^.dwItemSpec], convState(drawInfo^.uItemState),defaultDraw);
if (assigned(listView.OnCustomDrawSubItem) or assigned(listView.OnAdvancedCustomDrawSubItem)) and (listView.viewStyle=vsReport) then
lmnotify.result:=lmnotify.result or CDRF_NOTIFYSUBITEMDRAW;
end;
if not defaultDraw then
lmnotify.result:=lmnotify.result or CDRF_SKIPDEFAULT;
end;
CDDS_SUBITEM or CDDS_ITEM: begin //One sub item
if assigned(listView.OnAdvancedCustomDrawSubItem) then
listView.OnAdvancedCustomDrawSubItem(listView,listView.Items[drawInfo^.dwItemSpec],drawInfo^.iSubItem,
convState(drawInfo^.uItemState),Stage,defaultDraw);
if assigned(listView.OnCustomDrawSubItem) then
listView.OnCustomDrawSubItem(listView,listView.Items[drawInfo^.dwItemSpec],drawInfo^.iSubItem,
convState(drawInfo^.uItemState),defaultDraw);
if not defaultDraw then lmnotify.result:=CDRF_SKIPDEFAULT;
end;
end;
end;
begin
Assert(False, 'Trace:WindowProc - Start'); Assert(False, 'Trace:WindowProc - Start');
LMessage.Result := 0; LMessage.Result := 0;
@ -1489,6 +1569,11 @@ Begin
if WindowInfo^.WinControl <> nil then if WindowInfo^.WinControl <> nil then
lWinControl := WindowInfo^.WinControl; lWinControl := WindowInfo^.WinControl;
end; end;
NM_CUSTOMDRAW:
begin
if WindowInfo^.WinControl is TListView //what about TCustomlistView
then HandleListViewCustomDraw(TListView(WindowInfo^.WinControl));
end;
UDN_DELTAPOS: UDN_DELTAPOS:
begin begin
if WindowInfo^.WinControl <> nil then if WindowInfo^.WinControl <> nil then

View File

@ -43,7 +43,7 @@ Interface
Uses Uses
Windows, Classes, ComCtrls, Controls, Buttons, Dialogs, DynHashArray, Windows, Classes, ComCtrls, Controls, Buttons, Dialogs, DynHashArray,
ExtCtrls, Forms, GraphMath, GraphType, InterfaceBase, LCLIntf, LCLType, ExtCtrls, Forms, GraphMath, GraphType, InterfaceBase, LCLIntf, LCLType,
LMessages, StdCtrls, SysUtils, Win32Def, Graphics, Menus; LMessages, StdCtrls, SysUtils, Win32Def, Graphics, Menus, CommCtrl;
const const

View File

@ -101,8 +101,11 @@ type
// items // items
class procedure ItemDelete(const ALV: TCustomListView; const AIndex: Integer); override; class procedure ItemDelete(const ALV: TCustomListView; const AIndex: Integer); override;
class function ItemDisplayRect(const ALV: TCustomListView; const AIndex, ASubItem: Integer; ACode: TDisplayCode): TRect; override;
class function ItemGetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem): Boolean; override;
class function ItemGetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; out AIsSet: Boolean): Boolean; override; // returns True if supported class function ItemGetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; out AIsSet: Boolean): Boolean; override; // returns True if supported
class procedure ItemInsert(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem); override; class procedure ItemInsert(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem); override;
class procedure ItemSetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AChecked: Boolean); override;
class procedure ItemSetImage(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex, AImageIndex: Integer); override; class procedure ItemSetImage(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex, AImageIndex: Integer); override;
class procedure ItemSetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; const AIsSet: Boolean); override; class procedure ItemSetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; const AIsSet: Boolean); override;
class procedure ItemSetText(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex: Integer; const AText: String); override; class procedure ItemSetText(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex: Integer; const AText: String); override;
@ -118,6 +121,7 @@ type
class function GetDropTarget(const ALV: TCustomListView): Integer; override; class function GetDropTarget(const ALV: TCustomListView): Integer; override;
class function GetFocused(const ALV: TCustomListView): Integer; override; class function GetFocused(const ALV: TCustomListView): Integer; override;
class function GetHoverTime(const ALV: TCustomListView): Integer; override; class function GetHoverTime(const ALV: TCustomListView): Integer; override;
class function GetItemAt(const ALV: TCustomListView; x,y: Integer): Integer; override;
class function GetSelCount(const ALV: TCustomListView): Integer; override; class function GetSelCount(const ALV: TCustomListView): Integer; override;
class function GetSelection(const ALV: TCustomListView): Integer; override; class function GetSelection(const ALV: TCustomListView): Integer; override;
class function GetTopItem(const ALV: TCustomListView): Integer; override; class function GetTopItem(const ALV: TCustomListView): Integer; override;

View File

@ -272,6 +272,39 @@ begin
ListView_DeleteItem(ALV.Handle, AIndex); ListView_DeleteItem(ALV.Handle, AIndex);
end; end;
class function TWin32WSCustomListView.ItemDisplayRect(const ALV: TCustomListView; const AIndex, ASubItem: Integer; ACode: TDisplayCode):TRect;
const
DISPLAYCODES: array[TDisplayCode] of DWORD=(LVIR_BOUNDS, LVIR_ICON, LVIR_LABEL, LVIR_SELECTBOUNDS);
var
mes: uint;
begin
Result := Rect(0,0,0,0);
if not WSCheckHandleAllocated(ALV, 'ItemDisplayRect')
then Exit;
if ASubItem = 0
then mes:=LVM_GETITEMRECT
else begin
mes:=LVM_GETSUBITEMRECT;
if ACode = drSelectBounds
then ACode := drBounds;
end;
Result.top := ASubItem;
Result.left := DISPLAYCODES[ACode];
SendMessage(ALV.Handle, mes, AIndex, lparam(@Result));
end;
class function TWin32WSCustomListView.ItemGetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem): Boolean;
begin
Result := False;
if not WSCheckHandleAllocated(ALV, 'ItemGetChecked')
then Exit;
// shr 12 will give teh stateimage index, however a value of
// 0 means no image and 1 means unchecked. All other 14 are checked (?)
// so shifting 13 will always result in something <> 0 when checked.
Result := SendMessage(ALV.Handle, LVM_GETITEMSTATE, AIndex, LVIS_STATEIMAGEMASK) shr 13 <> 0;
end;
class function TWin32WSCustomListView.ItemGetState(const ALV: TCustomListView; class function TWin32WSCustomListView.ItemGetState(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
out AIsSet: Boolean): Boolean; out AIsSet: Boolean): Boolean;
@ -303,6 +336,17 @@ begin
ListView_InsertItem(ALV.Handle, lvi); ListView_InsertItem(ALV.Handle, lvi);
end; end;
class procedure TWin32WSCustomListView.ItemSetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AChecked: Boolean);
begin
if not WSCheckHandleAllocated(ALV, 'ItemSetChecked')
then Exit;
if AChecked then
ListView_SetItemState(ALV.Handle, AIndex, IndexToStateImageMask(2), LVIS_STATEIMAGEMASK)
else
ListView_SetItemState(ALV.Handle, AIndex, IndexToStateImageMask(1), LVIS_STATEIMAGEMASK);
end;
class procedure TWin32WSCustomListView.ItemSetImage(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex, AImageIndex: Integer); class procedure TWin32WSCustomListView.ItemSetImage(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex, AImageIndex: Integer);
var var
lvi: TLvItem; lvi: TLvItem;
@ -395,6 +439,7 @@ end;
class function TWin32WSCustomListView.GetBoundingRect(const ALV: TCustomListView): TRect; class function TWin32WSCustomListView.GetBoundingRect(const ALV: TCustomListView): TRect;
begin begin
Result := Rect(0,0,0,0);
if not WSCheckHandleAllocated(ALV, 'GetBoundingRect') if not WSCheckHandleAllocated(ALV, 'GetBoundingRect')
then Exit; then Exit;
@ -403,6 +448,7 @@ end;
class function TWin32WSCustomListView.GetDropTarget(const ALV: TCustomListView): Integer; class function TWin32WSCustomListView.GetDropTarget(const ALV: TCustomListView): Integer;
begin begin
Result := -1;
if not WSCheckHandleAllocated(ALV, 'GetDropTarget') if not WSCheckHandleAllocated(ALV, 'GetDropTarget')
then Exit; then Exit;
@ -410,7 +456,8 @@ begin
end; end;
class function TWin32WSCustomListView.GetFocused(const ALV: TCustomListView): Integer; class function TWin32WSCustomListView.GetFocused(const ALV: TCustomListView): Integer;
begin begin
Result := -1;
if not WSCheckHandleAllocated(ALV, 'GetFocused') if not WSCheckHandleAllocated(ALV, 'GetFocused')
then Exit; then Exit;
@ -419,14 +466,31 @@ end;
class function TWin32WSCustomListView.GetHoverTime(const ALV: TCustomListView): Integer; class function TWin32WSCustomListView.GetHoverTime(const ALV: TCustomListView): Integer;
begin begin
Result := -1;
if not WSCheckHandleAllocated(ALV, 'GetHoverTime') if not WSCheckHandleAllocated(ALV, 'GetHoverTime')
then Exit; then Exit;
Result := ListView_GetHoverTime(ALV.Handle); Result := ListView_GetHoverTime(ALV.Handle);
end; end;
class function TWin32WSCustomListView.GetItemAt(const ALV: TCustomListView; x,y: integer): Integer;
var
HitInfo: LV_HITTESTINFO;
begin
Result := -1;
if not WSCheckHandleAllocated(ALV, 'GetItemAt')
then Exit;
HitInfo.pt.x:=x;
HitInfo.pt.y:=y;
ListView_HitTest(alv.Handle,HitInfo);
if HitInfo.flags <> LVHT_NOWHERE
then Result:=HitInfo.iItem;
end;
class function TWin32WSCustomListView.GetSelCount(const ALV: TCustomListView): Integer; class function TWin32WSCustomListView.GetSelCount(const ALV: TCustomListView): Integer;
begin begin
Result := 0;
if not WSCheckHandleAllocated(ALV, 'GetSelCount') if not WSCheckHandleAllocated(ALV, 'GetSelCount')
then Exit; then Exit;
@ -435,6 +499,7 @@ end;
class function TWin32WSCustomListView.GetSelection(const ALV: TCustomListView): Integer; class function TWin32WSCustomListView.GetSelection(const ALV: TCustomListView): Integer;
begin begin
Result := -1;
if not WSCheckHandleAllocated(ALV, 'GetSelection') if not WSCheckHandleAllocated(ALV, 'GetSelection')
then Exit; then Exit;
@ -443,6 +508,7 @@ end;
class function TWin32WSCustomListView.GetTopItem(const ALV: TCustomListView): Integer; class function TWin32WSCustomListView.GetTopItem(const ALV: TCustomListView): Integer;
begin begin
Result := -1;
if not WSCheckHandleAllocated(ALV, 'GetTopItem') if not WSCheckHandleAllocated(ALV, 'GetTopItem')
then Exit; then Exit;
@ -456,6 +522,7 @@ end;
class function TWin32WSCustomListView.GetVisibleRowCount(const ALV: TCustomListView): Integer; class function TWin32WSCustomListView.GetVisibleRowCount(const ALV: TCustomListView): Integer;
begin begin
Result := 0;
if not WSCheckHandleAllocated(ALV, 'GetVisibleRowCount') if not WSCheckHandleAllocated(ALV, 'GetVisibleRowCount')
then Exit; then Exit;

View File

@ -42,6 +42,19 @@ Type
{ Pointer to @link(COMBOBOXINFO) } { Pointer to @link(COMBOBOXINFO) }
PComboBoxInfo = ^COMBOBOXINFO; PComboBoxInfo = ^COMBOBOXINFO;
TNMLVCustomDraw = Record
hdr : NMHDR;
dwDrawStage : DWORD;
hdc : HDC;
rc : TRECT;
dwItemSpec : DWORD;
uItemState : UINT;
lItemlParam : longint;
clrText,clrTextBk:COLORREF;
iSubItem :longint;
END;
PNMLVCustomDraw=^TNMLVCustomDraw;
{ Win32 API constants not included in windows.pp } { Win32 API constants not included in windows.pp }
Const Const
{ Recommended modal-dialog style } { Recommended modal-dialog style }
@ -106,6 +119,7 @@ Const
LVM_GETHEADER = LVM_FIRST + 31; LVM_GETHEADER = LVM_FIRST + 31;
LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54; LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54;
LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55; LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55;
LVM_GETSUBITEMRECT = LVM_FIRST + 56;
LVM_SETHOVERTIME = LVM_FIRST + 71; LVM_SETHOVERTIME = LVM_FIRST + 71;
LVM_GETHOVERTIME = LVM_FIRST + 72; LVM_GETHOVERTIME = LVM_FIRST + 72;
@ -142,6 +156,40 @@ Const
LVS_EX_SNAPTOGRID = $00080000; LVS_EX_SNAPTOGRID = $00080000;
LVS_EX_SIMPLESELECT = $00100000; LVS_EX_SIMPLESELECT = $00100000;
//state information for common control items (used for listview)
CDIS_SELECTED = $001;
CDIS_GRAYED = $002;
CDIS_DISABLED = $004;
CDIS_CHECKED = $008;
CDIS_FOCUS = $010;
CDIS_DEFAULT = $020;
CDIS_HOT = $040;
CDIS_MARKED = $080;
CDIS_INDETERMINATE = $100;
//custom draw event stage information
CDDS_PREPAINT = $00001;
CDDS_POSTPAINT = $00002;
CDDS_PREERASE = $00003;
CDDS_POSTERASE = $00004;
CDDS_ITEM = $10000;
CDDS_ITEMPREPAINT = $10001;
CDDS_ITEMPOSTPAINT = $10002;
CDDS_ITEMPREERASE = $10003;
CDDS_ITEMPOSTERASE = $10004;
CDDS_SUBITEM = $20000;
//values returned by an custom draw event
CDRF_DODEFAULT = $00;
CDRF_SKIPDEFAULT = $04;
CDRF_NOTIFYPOSTPAINT = $10;
CDRF_NOTIFYITEMDRAW = $20;
CDRF_NOTIFYSUBITEMDRAW = $20; // flags are the same, we can distinguish by context
CDRF_NOTIFYPOSTERASE = $40;
CDRF_NOTIFYITEMERASE = $80;
// progressbar // progressbar
PBM_SETRANGE32 = 1030; PBM_SETRANGE32 = 1030;
@ -219,6 +267,9 @@ begin
Result := SendMessage(hwndLV, LVM_SETHOVERTIME, 0, dwHoverTimeMs); Result := SendMessage(hwndLV, LVM_SETHOVERTIME, 0, dwHoverTimeMs);
end; end;
procedure ListView_SetCheckState(hwndLV: HWND; iIndex: UINT;fCheck:BOOL);
begin
end;
Var Var
@ -296,4 +347,4 @@ Except
Assert(False, Format('Trace:Could not deallocate string --> %S', [E.Message])); Assert(False, Format('Trace:Could not deallocate string --> %S', [E.Message]));
End; End;
End. End.

View File

@ -92,8 +92,11 @@ type
// Item // Item
class procedure ItemDelete(const ALV: TCustomListView; const AIndex: Integer); virtual; class procedure ItemDelete(const ALV: TCustomListView; const AIndex: Integer); virtual;
class function ItemDisplayRect(const ALV: TCustomListView; const AIndex, ASubItem: Integer; ACode: TDisplayCode): TRect; virtual;
class function ItemGetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem): Boolean; virtual;
class function ItemGetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; out AIsSet: Boolean): Boolean; virtual; // returns True if supported class function ItemGetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; out AIsSet: Boolean): Boolean; virtual; // returns True if supported
class procedure ItemInsert(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem); virtual; class procedure ItemInsert(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem); virtual;
class procedure ItemSetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AChecked: Boolean); virtual;
class procedure ItemSetImage(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex, AImageIndex: Integer); virtual; class procedure ItemSetImage(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex, AImageIndex: Integer); virtual;
class procedure ItemSetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; const AIsSet: Boolean); virtual; class procedure ItemSetState(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; const AIsSet: Boolean); virtual;
class procedure ItemSetText(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex: Integer; const AText: String); virtual; class procedure ItemSetText(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const ASubIndex: Integer; const AText: String); virtual;
@ -107,6 +110,7 @@ type
class function GetDropTarget(const ALV: TCustomListView): Integer; virtual; class function GetDropTarget(const ALV: TCustomListView): Integer; virtual;
class function GetFocused(const ALV: TCustomListView): Integer; virtual; class function GetFocused(const ALV: TCustomListView): Integer; virtual;
class function GetHoverTime(const ALV: TCustomListView): Integer; virtual; class function GetHoverTime(const ALV: TCustomListView): Integer; virtual;
class function GetItemAt(const ALV: TCustomListView; x,y: integer): Integer; virtual;
class function GetSelCount(const ALV: TCustomListView): Integer; virtual; class function GetSelCount(const ALV: TCustomListView): Integer; virtual;
class function GetSelection(const ALV: TCustomListView): Integer; virtual; class function GetSelection(const ALV: TCustomListView): Integer; virtual;
class function GetTopItem(const ALV: TCustomListView): Integer; virtual; class function GetTopItem(const ALV: TCustomListView): Integer; virtual;
@ -272,6 +276,16 @@ class procedure TWSCustomListView.ItemDelete(const ALV: TCustomListView;
begin begin
end; end;
class function TWSCustomListView.ItemDisplayRect(const ALV: TCustomListView; const AIndex, ASubItem: Integer; ACode: TDisplayCode): TRect;
begin
Result := Rect(0,0,0,0);
end;
class function TWSCustomListView.ItemGetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem): Boolean;
begin
Result := False;
end;
class function TWSCustomListView.ItemGetState(const ALV: TCustomListView; class function TWSCustomListView.ItemGetState(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState; const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
out AIsSet: Boolean): Boolean; out AIsSet: Boolean): Boolean;
@ -286,6 +300,10 @@ class procedure TWSCustomListView.ItemInsert(const ALV: TCustomListView;
begin begin
end; end;
class procedure TWSCustomListView.ItemSetChecked(const ALV: TCustomListView; const AIndex: Integer; const AItem: TListItem; const AChecked: Boolean);
begin
end;
class procedure TWSCustomListView.ItemSetImage(const ALV: TCustomListView; class procedure TWSCustomListView.ItemSetImage(const ALV: TCustomListView;
const AIndex: Integer; const AItem: TListItem; const AIndex: Integer; const AItem: TListItem;
const ASubIndex, AImageIndex: Integer); const ASubIndex, AImageIndex: Integer);
@ -337,6 +355,11 @@ begin
Result := -1; Result := -1;
end; end;
class function TWSCustomListView.GetItemAt(const ALV: TCustomListView; x,y: integer): Integer;
begin
result:=-1;
end;
class function TWSCustomListView.GetSelCount(const ALV: TCustomListView): Integer; class function TWSCustomListView.GetSelCount(const ALV: TCustomListView): Integer;
begin begin
Result := 0; Result := 0;
@ -473,4 +496,4 @@ initialization
// RegisterWSComponent(TCustomTreeView, TWSCustomTreeView); // RegisterWSComponent(TCustomTreeView, TWSCustomTreeView);
// RegisterWSComponent(TCustomTreeView, TWSTreeView); // RegisterWSComponent(TCustomTreeView, TWSTreeView);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
end. end.