mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-11 22:56:06 +02:00
* modified customdraw listview patch from BeniBela
git-svn-id: trunk@9770 -
This commit is contained in:
parent
ecc5c01e5b
commit
d05adb23c1
@ -564,6 +564,8 @@ type
|
||||
|
||||
TListItemFlag = (lifDestroying, lifCreated);
|
||||
TListItemFlags = set of TListItemFlag;
|
||||
|
||||
TDisplayCode = (drBounds, drIcon, drLabel, drSelectBounds);
|
||||
|
||||
{ TListItem }
|
||||
|
||||
@ -576,6 +578,7 @@ type
|
||||
FData: Pointer;
|
||||
FImageIndex: Integer;
|
||||
FStates: TListItemStates;
|
||||
function GetChecked: Boolean;
|
||||
function GetListView: TCustomListView;
|
||||
function GetState(const ALisOrd: Integer): Boolean;
|
||||
function GetIndex: Integer;
|
||||
@ -586,6 +589,7 @@ type
|
||||
procedure IntfUpdateText;
|
||||
procedure IntfUpdateImages;
|
||||
|
||||
procedure SetChecked(AValue: Boolean);
|
||||
procedure SetState(const ALisOrd: Integer; const AIsSet: Boolean);
|
||||
procedure SetData(const AValue: Pointer);
|
||||
procedure SetImageIndex(const AValue: Integer);
|
||||
@ -601,8 +605,11 @@ type
|
||||
destructor Destroy; override;
|
||||
procedure Delete;
|
||||
procedure MakeVisible(PartialOK: Boolean);
|
||||
function DisplayRect(Code: TDisplayCode): TRect;
|
||||
function DisplayRectSubItem(subItem: integer;Code: TDisplayCode): TRect;
|
||||
|
||||
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 Data: Pointer read FData write SetData;
|
||||
property DropTarget: Boolean index Ord(lisDropTarget) read GetState write SetState;
|
||||
@ -613,8 +620,7 @@ type
|
||||
property Owner: TListItems read FOwner;
|
||||
property Selected: Boolean index Ord(lisSelected) read GetState write SetState;
|
||||
property SubItems: TStrings read GetSubItems write SetSubItems;
|
||||
property SubItemImages[const AIndex: Integer]: Integer
|
||||
read GetSubItemImages write SetSubItemImages;
|
||||
property SubItemImages[const AIndex: Integer]: Integer read GetSubItemImages write SetSubItemImages;
|
||||
end;
|
||||
|
||||
|
||||
@ -751,6 +757,22 @@ type
|
||||
TLVInsertEvent = TLVDeletedEvent;
|
||||
TLVSelectItemEvent = procedure(Sender: TObject; Item: TListItem;
|
||||
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 = (
|
||||
lvpAutoArrange,
|
||||
@ -814,6 +836,12 @@ type
|
||||
FOnDeletion: TLVDeletedEvent;
|
||||
FOnInsert: TLVInsertEvent;
|
||||
FOnSelectItem: TLVSelectItemEvent;
|
||||
FOnCustomDraw: TLVCustomDrawEvent;
|
||||
FOnCustomDrawItem: TLVCustomDrawItemEvent;
|
||||
FOnCustomDrawSubItem: TLVCustomDrawSubItemEvent;
|
||||
FOnAdvancedCustomDraw: TLVAdvancedCustomDrawEvent;
|
||||
FOnAdvancedCustomDrawItem: TLVAdvancedCustomDrawItemEvent;
|
||||
FOnAdvancedCustomDrawSubItem: TLVAdvancedCustomDrawSubItemEvent;
|
||||
FProperties: TListViewProperties;
|
||||
function GetBoundingRect: TRect;
|
||||
function GetColumnFromIndex(AIndex: Integer): TListColumn;
|
||||
@ -858,6 +886,7 @@ type
|
||||
|
||||
protected
|
||||
procedure InitializeWnd; override;
|
||||
procedure DestroyWnd; override;
|
||||
procedure Change(AItem: TListItem; AChange: Integer); dynamic;
|
||||
procedure ColClick(AColumn: TListColumn); dynamic;
|
||||
|
||||
@ -902,6 +931,12 @@ type
|
||||
property OnDeletion: TLVDeletedEvent read FOnDeletion write FOnDeletion;
|
||||
property OnInsert: TLVInsertEvent read FOnInsert write FOnInsert;
|
||||
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
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
@ -909,6 +944,7 @@ type
|
||||
procedure Clear;
|
||||
procedure EndUpdate;
|
||||
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 Canvas: TCanvas read FCanvas;
|
||||
property Checkboxes: Boolean index Ord(lvpCheckboxes) read GetProperty write SetProperty default False;
|
||||
@ -939,7 +975,7 @@ type
|
||||
property BorderSpacing;
|
||||
// property BorderStyle;
|
||||
property BorderWidth;
|
||||
// property Checkboxes;
|
||||
property Checkboxes;
|
||||
property Color default clWindow;
|
||||
property Columns;
|
||||
property ColumnClick;
|
||||
@ -987,6 +1023,12 @@ type
|
||||
property OnKeyDown;
|
||||
property OnDeletion;
|
||||
property OnSelectItem;
|
||||
property OnCustomDraw;
|
||||
property OnCustomDrawItem;
|
||||
property OnCustomDrawSubItem;
|
||||
property OnAdvancedCustomDraw;
|
||||
property OnAdvancedCustomDrawItem;
|
||||
property OnAdvancedCustomDrawSubItem;
|
||||
end;
|
||||
|
||||
TProgressBarOrientation = (pbHorizontal, pbVertical, pbRightToLeft, pbTopDown);
|
||||
|
@ -45,8 +45,24 @@ uses
|
||||
|
||||
const
|
||||
//all controls
|
||||
NM_FIRST = 0;
|
||||
NM_LAST = -99;
|
||||
NM_FIRST = 0;
|
||||
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
|
||||
LVN_FIRST = -100;
|
||||
|
@ -27,17 +27,31 @@ begin
|
||||
FCompStyle := csListView;
|
||||
FViewStyle := vsList;
|
||||
FSortType := stNone;
|
||||
|
||||
// MWE:
|
||||
// A class is initalized to 0 when created
|
||||
// so no need to initialize these here again
|
||||
(*
|
||||
FSortColumn := 0;
|
||||
FOnCompare := nil;
|
||||
FImageChangeLink := TChangeLink.Create;
|
||||
FImageChangeLink.OnChange := @ImageChanged;
|
||||
FOnCustomDraw := nil;
|
||||
FOnCustomDrawItem := nil;
|
||||
FOnCustomDrawSubItem := nil;
|
||||
FOnAdvancedCustomDraw := nil;
|
||||
FOnAdvancedCustomDrawItem := nil;
|
||||
FOnAdvancedCustomDrawSubItem := nil;
|
||||
FSelected := nil;
|
||||
FFocused := nil;
|
||||
*)
|
||||
FImageChangeLink := TChangeLink.Create;
|
||||
FImageChangeLink.OnChange := @ImageChanged;
|
||||
FHoverTime := -1;
|
||||
TabStop := true;
|
||||
SetInitialBounds(0,0,100,90);
|
||||
ParentColor := False;
|
||||
Color := clWindow;
|
||||
FCanvas := TControlCanvas.Create;
|
||||
TControlCanvas(FCanvas).Control := Self;
|
||||
FProperties := [lvpColumnClick, lvpHideSelection, lvpShowColumnHeaders];
|
||||
end;
|
||||
|
||||
@ -78,11 +92,13 @@ var
|
||||
begin
|
||||
nm := PNMListView(AMessage.NMHdr);
|
||||
if nm^.iItem>=Items.Count then exit;
|
||||
|
||||
case AMessage.NMHdr^.code of
|
||||
// HDN_TRACK:
|
||||
// NM_CUSTOMDRAW:
|
||||
// LVN_BEGINDRAG:
|
||||
//remark: NMHdr^.code is normally unhanged by the win32 interface, so the others
|
||||
// maps there codes to the of win32
|
||||
case AMessage.NMHdr^.code of
|
||||
// HDN_TRACK:
|
||||
// NM_CUSTOMDRAW: //Custom Drawing is handled direct from the interfaces
|
||||
//(at least win32 does so)
|
||||
// LVN_BEGINDRAG:
|
||||
LVN_DELETEITEM: begin
|
||||
Item := FListItems[nm^.iItem];
|
||||
if FSelected = Item then
|
||||
@ -393,12 +409,27 @@ destructor TCustomListView.Destroy;
|
||||
begin
|
||||
// Better destroy the wincontrol (=widget) first. So wo don't have to delete
|
||||
// all items/columns and we won't get notifications for each.
|
||||
FreeAndNil(FCanvas);
|
||||
inherited Destroy;
|
||||
FreeAndNil(FColumns);
|
||||
FreeAndNil(FImageChangeLink);
|
||||
FreeAndNil(FListItems);
|
||||
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
|
||||
Params: None
|
||||
@ -479,6 +510,19 @@ begin
|
||||
else Result := FHoverTime;
|
||||
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;
|
||||
begin
|
||||
Result := (TListViewProperty(ALvpOrd) in FProperties);
|
||||
|
@ -337,6 +337,33 @@ begin
|
||||
inherited Destroy;
|
||||
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 }
|
||||
{------------------------------------------------------------------------------}
|
||||
@ -421,23 +448,36 @@ begin
|
||||
and (FStates = AItem.FStates);
|
||||
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 }
|
||||
{------------------------------------------------------------------------------}
|
||||
function TListItem.GetState(const ALisOrd: Integer): Boolean;
|
||||
var
|
||||
AState: TListItemState;
|
||||
LV: TCustomListView;
|
||||
begin
|
||||
AState := TListItemState(ALisOrd);
|
||||
LV := FOwner.FOwner;
|
||||
|
||||
if IntfUpdateAllowed
|
||||
and TWSCustomListViewClass(FOwner.FOwner.WidgetSetClass)
|
||||
.ItemGetState(FOwner.FOwner, GetIndex, Self, AState, Result)
|
||||
if IntfUpdateAllowed
|
||||
and TWSCustomListViewClass(LV.WidgetSetClass).ItemGetState(LV, GetIndex, Self, AState, Result)
|
||||
then begin
|
||||
// update FStates
|
||||
if Result
|
||||
if Result
|
||||
then Include(FStates, AState)
|
||||
else Exclude(FStates, AState);
|
||||
else Exclude(FStates, AState);
|
||||
end
|
||||
else Result := AState in FStates;
|
||||
end;
|
||||
@ -482,11 +522,26 @@ end;
|
||||
{ TListItem SetCaption }
|
||||
{------------------------------------------------------------------------------}
|
||||
procedure TListItem.SetCaption(const AValue : String);
|
||||
var
|
||||
LV: TCustomListView;
|
||||
begin
|
||||
if FCaption = AValue then Exit;
|
||||
FCaption := AValue;
|
||||
LV := FOwner.FOwner;
|
||||
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;
|
||||
|
||||
{------------------------------------------------------------------------------}
|
||||
@ -548,3 +603,4 @@ begin
|
||||
if (AValue = nil) and (FSubItems = nil) then Exit;
|
||||
SubItems.Assign(AValue);
|
||||
end;
|
||||
|
||||
|
@ -787,8 +787,88 @@ Var
|
||||
SetWin32SizePoint(MaxWidth, MaxHeight, MinMaxInfo.ptMaxTrackSize);
|
||||
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');
|
||||
|
||||
LMessage.Result := 0;
|
||||
@ -1489,6 +1569,11 @@ Begin
|
||||
if WindowInfo^.WinControl <> nil then
|
||||
lWinControl := WindowInfo^.WinControl;
|
||||
end;
|
||||
NM_CUSTOMDRAW:
|
||||
begin
|
||||
if WindowInfo^.WinControl is TListView //what about TCustomlistView
|
||||
then HandleListViewCustomDraw(TListView(WindowInfo^.WinControl));
|
||||
end;
|
||||
UDN_DELTAPOS:
|
||||
begin
|
||||
if WindowInfo^.WinControl <> nil then
|
||||
|
@ -43,7 +43,7 @@ Interface
|
||||
Uses
|
||||
Windows, Classes, ComCtrls, Controls, Buttons, Dialogs, DynHashArray,
|
||||
ExtCtrls, Forms, GraphMath, GraphType, InterfaceBase, LCLIntf, LCLType,
|
||||
LMessages, StdCtrls, SysUtils, Win32Def, Graphics, Menus;
|
||||
LMessages, StdCtrls, SysUtils, Win32Def, Graphics, Menus, CommCtrl;
|
||||
|
||||
const
|
||||
|
||||
|
@ -101,8 +101,11 @@ type
|
||||
|
||||
// items
|
||||
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 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 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;
|
||||
@ -118,6 +121,7 @@ type
|
||||
class function GetDropTarget(const ALV: TCustomListView): Integer; override;
|
||||
class function GetFocused(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 GetSelection(const ALV: TCustomListView): Integer; override;
|
||||
class function GetTopItem(const ALV: TCustomListView): Integer; override;
|
||||
|
@ -272,6 +272,39 @@ begin
|
||||
ListView_DeleteItem(ALV.Handle, AIndex);
|
||||
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;
|
||||
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
|
||||
out AIsSet: Boolean): Boolean;
|
||||
@ -303,6 +336,17 @@ begin
|
||||
ListView_InsertItem(ALV.Handle, lvi);
|
||||
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);
|
||||
var
|
||||
lvi: TLvItem;
|
||||
@ -395,6 +439,7 @@ end;
|
||||
|
||||
class function TWin32WSCustomListView.GetBoundingRect(const ALV: TCustomListView): TRect;
|
||||
begin
|
||||
Result := Rect(0,0,0,0);
|
||||
if not WSCheckHandleAllocated(ALV, 'GetBoundingRect')
|
||||
then Exit;
|
||||
|
||||
@ -403,6 +448,7 @@ end;
|
||||
|
||||
class function TWin32WSCustomListView.GetDropTarget(const ALV: TCustomListView): Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
if not WSCheckHandleAllocated(ALV, 'GetDropTarget')
|
||||
then Exit;
|
||||
|
||||
@ -410,7 +456,8 @@ begin
|
||||
end;
|
||||
|
||||
class function TWin32WSCustomListView.GetFocused(const ALV: TCustomListView): Integer;
|
||||
begin
|
||||
begin
|
||||
Result := -1;
|
||||
if not WSCheckHandleAllocated(ALV, 'GetFocused')
|
||||
then Exit;
|
||||
|
||||
@ -419,14 +466,31 @@ end;
|
||||
|
||||
class function TWin32WSCustomListView.GetHoverTime(const ALV: TCustomListView): Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
if not WSCheckHandleAllocated(ALV, 'GetHoverTime')
|
||||
then Exit;
|
||||
|
||||
Result := ListView_GetHoverTime(ALV.Handle);
|
||||
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;
|
||||
begin
|
||||
Result := 0;
|
||||
if not WSCheckHandleAllocated(ALV, 'GetSelCount')
|
||||
then Exit;
|
||||
|
||||
@ -435,6 +499,7 @@ end;
|
||||
|
||||
class function TWin32WSCustomListView.GetSelection(const ALV: TCustomListView): Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
if not WSCheckHandleAllocated(ALV, 'GetSelection')
|
||||
then Exit;
|
||||
|
||||
@ -443,6 +508,7 @@ end;
|
||||
|
||||
class function TWin32WSCustomListView.GetTopItem(const ALV: TCustomListView): Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
if not WSCheckHandleAllocated(ALV, 'GetTopItem')
|
||||
then Exit;
|
||||
|
||||
@ -456,6 +522,7 @@ end;
|
||||
|
||||
class function TWin32WSCustomListView.GetVisibleRowCount(const ALV: TCustomListView): Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
if not WSCheckHandleAllocated(ALV, 'GetVisibleRowCount')
|
||||
then Exit;
|
||||
|
||||
|
@ -42,6 +42,19 @@ Type
|
||||
{ Pointer to @link(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 }
|
||||
Const
|
||||
{ Recommended modal-dialog style }
|
||||
@ -106,6 +119,7 @@ Const
|
||||
LVM_GETHEADER = LVM_FIRST + 31;
|
||||
LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54;
|
||||
LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55;
|
||||
LVM_GETSUBITEMRECT = LVM_FIRST + 56;
|
||||
LVM_SETHOVERTIME = LVM_FIRST + 71;
|
||||
LVM_GETHOVERTIME = LVM_FIRST + 72;
|
||||
|
||||
@ -142,6 +156,40 @@ Const
|
||||
LVS_EX_SNAPTOGRID = $00080000;
|
||||
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
|
||||
PBM_SETRANGE32 = 1030;
|
||||
|
||||
@ -219,6 +267,9 @@ begin
|
||||
Result := SendMessage(hwndLV, LVM_SETHOVERTIME, 0, dwHoverTimeMs);
|
||||
end;
|
||||
|
||||
procedure ListView_SetCheckState(hwndLV: HWND; iIndex: UINT;fCheck:BOOL);
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
Var
|
||||
@ -296,4 +347,4 @@ Except
|
||||
Assert(False, Format('Trace:Could not deallocate string --> %S', [E.Message]));
|
||||
End;
|
||||
|
||||
End.
|
||||
End.
|
||||
|
@ -92,8 +92,11 @@ type
|
||||
|
||||
// Item
|
||||
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 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 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;
|
||||
@ -107,6 +110,7 @@ type
|
||||
class function GetDropTarget(const ALV: TCustomListView): Integer; virtual;
|
||||
class function GetFocused(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 GetSelection(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
|
||||
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;
|
||||
const AIndex: Integer; const AItem: TListItem; const AState: TListItemState;
|
||||
out AIsSet: Boolean): Boolean;
|
||||
@ -286,6 +300,10 @@ class procedure TWSCustomListView.ItemInsert(const ALV: TCustomListView;
|
||||
begin
|
||||
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;
|
||||
const AIndex: Integer; const AItem: TListItem;
|
||||
const ASubIndex, AImageIndex: Integer);
|
||||
@ -337,6 +355,11 @@ begin
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
class function TWSCustomListView.GetItemAt(const ALV: TCustomListView; x,y: integer): Integer;
|
||||
begin
|
||||
result:=-1;
|
||||
end;
|
||||
|
||||
class function TWSCustomListView.GetSelCount(const ALV: TCustomListView): Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
@ -473,4 +496,4 @@ initialization
|
||||
// RegisterWSComponent(TCustomTreeView, TWSCustomTreeView);
|
||||
// RegisterWSComponent(TCustomTreeView, TWSTreeView);
|
||||
////////////////////////////////////////////////////
|
||||
end.
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user