1stClass控件组里有。
也可以自己写一个。
// ***********************************************************************
//
// TCheckTreeView
//
// l940801@yahoo.com
//
// ***********************************************************************
unit CheckTreeViews;
interface
uses
Windows, Messages, Classes, Controls, ComCtrls, CommCtrl;
type
TTVCheckChangingEvent = procedure(Sender: TObject; Node: TTreeNode; var CanCheck: boolean) of Object;
TTVCheckChangedEvent = procedure(Sender: TObject; Node: TTreeNode) of Object;
TTVCheckClick = procedure(Sender: TObject; Node: TTreeNode) of Object;
{ TCustomCheckTreeView }
TCustomCheckTreeView = class(TCustomTreeView)
private
FCheckBoxes: boolean;
FCheckStream: TMemoryStream;
FOnCheckChanged: TTVCheckChangedEvent;
FOnCheckChanging: TTVCheckChangingEvent;
FOnCheckClick:TTVCheckClick;
procedure SetCheckBoxes(const Value: boolean);
procedure SaveChecks;
procedure RestoreChecks;
function GetChecked(Index: integer): boolean;
procedure SetChecked(Index: integer; const Value: boolean);
procedure TVMSetItem(var Msg: TMessage); message TVM_SETITEM;
procedure WMLButtonDown(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;
protected
procedure CreateWnd; override;
procedure DestroyWnd; override;
public
constructor Create(AOwner: TComponent); override;
property Checked[Index: integer]: boolean read GetChecked write SetChecked;
property CheckBoxes: boolean read FCheckBoxes write SetCheckBoxes;
property OnCheckChanging: TTVCheckChangingEvent read FOnCheckChanging write FOnCheckChanging;
property OnCheckChanged: TTVCheckChangedEvent read FOnCheckChanged write FOnCheckChanged;
property OnCheckClick:TTVCheckClick read FOnCheckClick write FOnCheckClick;
end;
{ TCheckTreeView }
TCheckTreeView = class(TCustomCheckTreeView)
published
property CheckBoxes;
property OnCheckChanging;
property OnCheckChanged;
property OnCheckClick;
property Align;
property Anchors;
property AutoExpand;
property BevelEdges;
property BevelInner;
property BevelOuter;
property BevelKind default bkNone;
property BevelWidth;
property BiDiMode;
property BorderStyle;
property BorderWidth;
property ChangeDelay;
property Color;
property Ctl3D;
property Constraints;
property DragKind;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property HideSelection;
property HotTrack;
property Images;
property Indent;
property MultiSelect;
property MultiSelectStyle;
property ParentBiDiMode;
property ParentColor default False;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly;
property RightClickSelect;
property RowSelect;
property ShowButtons;
property ShowHint;
property ShowLines;
property ShowRoot;
property SortType;
property StateImages;
property TabOrder;
property TabStop default True;
property ToolTips;
property Visible;
property OnAddition;
property OnAdvancedCustomDraw;
property OnAdvancedCustomDrawItem;
property OnChange;
property OnChanging;
property OnClick;
property OnCollapsed;
property OnCollapsing;
property OnCompare;
property OnContextPopup;
property OnCreateNodeClass;
property OnCustomDraw;
property OnCustomDrawItem;
property OnDblClick;
property OnDeletion;
property OnDragDrop;
property OnDragOver;
property OnEdited;
property OnEditing;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnExpanding;
property OnExpanded;
property OnGetImageIndex;
property OnGetSelectedIndex;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
{ Items must be published after OnGetImageIndex and OnGetSelectedIndex }
property Items;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('MyVcl', [TCheckTreeView]);
end;
procedure SetComCtlStyle(Ctl: TWinControl; Value: Integer; UseStyle: Boolean);
var
Style: Integer;
begin
if Ctl.HandleAllocated then
begin
Style:= GetWindowLong(Ctl.Handle, GWL_STYLE);
if not UseStyle then
Style:= Style and not Value
else
Style:= Style or Value;
SetWindowLong(Ctl.Handle, GWL_STYLE, Style);
end;
end;
{ TCustomCheckTreeView }
constructor TCustomCheckTreeView.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCheckBoxes:= false;
end;
procedure TCustomCheckTreeView.CreateWnd;
begin
inherited CreateWnd;
if FCheckBoxes then SetCheckBoxes(true);
RestoreChecks;
end;
procedure TCustomCheckTreeView.DestroyWnd;
begin
SaveChecks;
inherited DestroyWnd;
end;
function TCustomCheckTreeView.GetChecked(Index: integer): boolean;
var
TVItem: TTVItem;
begin
// Prepare to receive the desired information.
TVItem.mask:= TVIF_HANDLE or TVIF_STATE;
TVItem.hItem:= Items[Index].ItemId;
TVItem.stateMask:= TVIS_STATEIMAGEMASK;
// Request the information.
TreeView_GetItem(Handle, TVItem);
// Return false if it's not checked, or true otherwise.
Result:= ((TVItem.state shr 12) - 1) > 0;
end;
procedure TCustomCheckTreeView.RestoreChecks;
var
I: Integer;
Value: Boolean;
begin
if not Assigned(FCheckStream) then Exit;
for I:= 0 to Items.Count - 1 do
begin
FCheckStream.Read(Value, SizeOf(Value));
Checked:= Value;
end;
FCheckStream.Free;
FCheckStream:= nil;
end;
procedure TCustomCheckTreeView.SaveChecks;
var
I: Integer;
Value: Boolean;
begin
if FCheckStream = nil then
FCheckStream:= TMemoryStream.Create
else
FCheckStream.Size:= 0;
for I:= 0 to Items.Count - 1 do
begin
Value:= Checked;
FCheckStream.Write(Value, SizeOf(Value));
end;
FCheckStream.Position:= 0;
end;
procedure TCustomCheckTreeView.SetCheckBoxes(const Value: boolean);
begin
FCheckBoxes:= Value;
SetComCtlStyle(Self, TVS_CHECKBOXES, Value);
end;
procedure TCustomCheckTreeView.SetChecked(Index: integer;
const Value: boolean);
var
TVItem: TTVItem;
StateIndex: integer;
begin
// Prepare to receive the desired information.
TVItem.mask:= TVIF_HANDLE or TVIF_STATE;
TVItem.hItem:= Items[Index].ItemId;
TVItem.stateMask:= TVIS_STATEIMAGEMASK;
//Image 1 in the tree view check box image list is the unchecked box. Image 2 is the checked box.
if Value then
StateIndex:= 2
else
StateIndex:= 1;
TVItem.state:= INDEXTOSTATEIMAGEMASK(StateIndex);
TreeView_SetItem(Handle, TVItem);
end;
procedure TCustomCheckTreeView.TVMSetItem(var Msg: TMessage);
var
Node: TTreeNode;
CanCheck: boolean;
begin
with PTVItem(Msg.lParam)^ do
if (Mask and (TVIF_STATE or TVIF_HANDLE) > 0) and Assigned(FOnCheckChanging) then
begin
Node:= Items.GetNode(hItem);
CanCheck:=True;
FOnCheckChanging(Self, Node, CanCheck);
if CanCheck then
begin
inherited;
if Assigned(FOnCheckChanged) then FOnCheckChanged(Self, Node);
end;
end
else
inherited;
end;
procedure TCustomCheckTreeView.WMLButtonDown(var Msg: TWMLButtonDown);
var
HitTests: THitTests;
Node: TTreeNode;
CanCheck: boolean;
begin
if FCheckBoxes then
begin
HitTests:= GetHitTestInfoAt(Msg.XPos, Msg.YPos);
if (htOnStateIcon in HitTests) and Assigned(FOnCheckChanging) then
begin
Node:= GetNodeAt(Msg.XPos, Msg.YPos);
CanCheck:=True;
FOnCheckChanging(Self, Node, CanCheck);
if CanCheck then
begin
inherited;
if Assigned(FOnCheckChanged) then FOnCheckChanged(Self, Node);
if Assigned(FOnCheckClick) then FOnCheckClick(Self,Node);
end;
end
else
inherited;
end
else
inherited;
end;
end.