怎么自己设计一个有带复选框的树形控件(50分)

  • 主题发起人 主题发起人 zyr76
  • 开始时间 开始时间
Z

zyr76

Unregistered / Unconfirmed
GUEST, unregistred user!
怎么自己设计一个有带复选框的树形控件,有这样的实现代码吗?问两个问题:
1。怎么生成这个带复选框的树形控件的变量
2。怎么实现点击父结点的复选框,使得子结点的全被选中或撤销选中,怎么取得结点的父结点和子结点以及其文本?
希望能用代码回答一下谢谢了!
 
1。怎么生成这个带复选框的树形控件的变量
图片可以替代 API也可以实现
2。怎么实现点击父结点的复选框,使得子结点的全被选中或撤销选中,怎么取得结点的父结点和子结点以及其文本?
递归+childnodes
 
参考dev 的cxtreelist,有原代码
 
cxtreelist都有了,还自己设计啥。。。并且人家也给源码,可以自己继承修改。。。
 
{ 29/5/1999 1:27 GMT }
unit CheckTV;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls,CommCtrl;
type
TCheckKind = (ckNone, ckCheck, ckRadio, ckGroup);
TCheckFlatness = (cfAlwaysFlat, cfAlways3d, cfHotTrack);
TCheckTreeNode = class;
TCheckTreeView = class(TCustomTreeView)
private
FDesignInteractive: Boolean;
FGrayedIsChecked: Boolean;
FStateImages: TImageList;
FFlatness: TCheckFlatness;
function GetChecked(Node: TTreeNode): Boolean;
procedure SetChecked(Node: TTreeNode;
Value: Boolean);
function GetState(Node: TTreeNode): TCheckBoxState;
procedure SetState(Node: TTreeNode;
Value: TCheckBoxState);
function GetKind(Node: TTreeNode): TCheckKind;
procedure SetKind(Node: TTreeNode;
Value: TCheckKind);
procedure SetFlatness(const Value: TCheckFlatness);
function GetNodeEnabled(Node: TTreeNode): Boolean;
procedure SetNodeEnabled(Node: TTreeNode;
const Value: Boolean);
procedure ReadData(Stream: TStream);
procedure WriteData(Stream: TStream);
procedure CMMouseLeave(var Message: TMessage);
message CM_MOUSELEAVE;
procedure CMDesignHitTest(var Message: TCMDesignHitTest);
message
CM_DESIGNHITTEST;
procedure WMKeyDown(var Message: TWMKeyDown);
message WM_KEYDOWN;
procedure WMLButtonDblClk(var Message: TWMLButtonDblClk);
message
WM_LBUTTONDBLCLK;
protected
FHoverCache: TCheckTreeNode;
procedure ToggleNode(Node: TCheckTreeNode);
dynamic;
procedure Change(Node: TTreeNode);
override;
procedure CreateCheckMarks;
dynamic;
function CreateNode: TTreeNode;
override;
procedure DefineProperties(Filer: TFiler);
override;
procedure MouseDown(Button: TMouseButton;
Shift: TShiftState;
X, Y:
Integer);
override;
procedure MouseMove(Shift: TShiftState;
X, Y: Integer);
override;
procedure Loaded;
override;
procedure Click;override;
procedure CreateParams(var Param:TCreateParams);override;
public
constructor Create(AOwner: TComponent);
override;
destructor Destroy;
override;
procedure MakeRadioGroup(Node: TTreeNode);
property Checked[Node: TTreeNode]: Boolean read GetChecked write SetChecked;
property State[Node: TTreeNode]: TCheckBoxState read GetState write
SetState;
property CheckKind[Node: TTreeNode]: TCheckKind read GetKind write SetKind;
property NodeEnabled[Node: TTreeNode]: Boolean read GetNodeEnabled write
SetNodeEnabled;
published
property DesignActive: Boolean read FDesignInteractive write FDesignInteractive stored False;
property Align;
property Anchors;
property AutoExpand;
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 Flatness: TCheckFlatness read FFlatness write SetFlatness;
property GrayedIsChecked: Boolean read FGrayedIsChecked write
FGrayedIsChecked;
property HideSelection;
property HotTrack;
property Images;
property Indent;
property Items;
property ParentBiDiMode;
property ParentColor default False;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly default True;
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 OnChange;
property OnChanging;
property OnClick;
property OnCollapsing;
property OnCollapsed;
property OnCompare;
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;
end;

TCheckTreeNode = class(TTreeNode)
private
FReflexChildren: Boolean;
FCheckKind: TCheckKind;
FCache: TCheckBoxState;
FEnabled: Boolean;
FReflexParent: Boolean;
function IsEqual(Node: TTreeNode): Boolean;
function GetItemIndex: Integer;
function GetChecked: Boolean;
procedure SetChecked(Value: Boolean);
procedure SetCheckKind(Value: TCheckKind);
procedure SetEnabled(Value: Boolean);
function GetState: TCheckBoxState;
procedure SetState(Value: TCheckBoxState);
procedure SetItemIndex(Value: Integer);
procedure SetReflexChildren(Value: Boolean);
procedure SetReflexParent(Value: Boolean);
procedure ReadSelf(Stream: TStream);
procedure WriteSelf(Stream: TStream);
protected
procedure InternalSetState(Value: TCheckBoxState;
CheckChildren: Boolean = True;
CheckParent: Boolean = True);
proceduredo
CheckChildren(Cur: TCheckBoxState);
proceduredo
CheckParent(Cur: TCheckBoxState);
procedure UpdateHotTrack(Hover: Boolean);
virtual;
public
procedure AfterConstruction;
override;
procedure MakeRadioGroup;
procedure Assign(Source: TPersistent);
override;
property Checked: Boolean read GetChecked write SetChecked;
property CheckKind: TCheckKind read FCheckKind write SetCheckKind;
property CheckState: TCheckBoxState read GetState write SetState;
property Enabled: Boolean read FEnabled write SetEnabled;
property ItemIndex: Integer read GetItemIndex write SetItemIndex;
property ReflexChildren: Boolean read FReflexChildren write
SetReflexChildren;
property ReflexParent: Boolean read FReflexParent write SetReflexParent;
end;

ECheckTreeViewError = class(Exception);
EIndexError = class(ECheckTreeViewError);
resourcestring
SIndexError = 'Tree node index (%d) out of range';
SInvalidKind = 'Trying to set index (%d) of non-radio item';
procedure Register;
implementation
{ TCheckTreeView }
procedure Register;
begin
RegisterComponents('Win32', [TCheckTreeView]);
end;

type
PCheckNodeData = ^TCheckNodeData;
TCheckNodeData = packed record
Kind: TCheckKind;
Enabled: Boolean;
end;

procedure TCheckTreeView.CMDesignHitTest(var Message: TCMDesignHitTest);
var
N : TTreeNode;
begin
Message.Result := 0;
if FDesignInteractive then
begin
N := GetNodeAt(Message.XPos, Message.YPos);
if N <> nil then
Message.Result := Integer(N.DisplayRect(True).Right > Message.XPos);
end;
end;

procedure TCheckTreeView.CMMouseLeave(var Message: TMessage);
begin
if FHoverCache <> nil then
FHoverCache.UpdateHotTrack(False);
FHoverCache := nil;
inherited;
end;

constructor TCheckTreeView.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
DesignActive :=True;
//ReadOnly := True;
end;

procedure TCheckTreeView.CreateCheckMarks;
const
R : TRect = (Left: 2;
Top: 2;
Right: 15;
Bottom: 15);
var
Bmp, M : TBitmap;
procedure Add(MaskColor: TColor = clWhite);
begin
FStateImages.AddMasked(Bmp, MaskColor);
end;

begin
if FStateImages = nil then
Exit;
Items.begin
Update;
Bmp := TBitmap.Create;
M := TBitmap.Create;
try
Bmp.Width := 16;
Bmp.Height := 16;
M.Width := 16;
M.Height := 16;
{ Add stub image }
{1} Add;
{ Add flat images }
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONCHECK or
DFCS_FLAT);
{2} Add;
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONCHECK or
DFCS_FLAT or DFCS_CHECKED);
{3} Add;
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONCHECK or
DFCS_FLAT or DFCS_CHECKED or DFCS_BUTTON3STATE);
{4} Add;
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOIMAGE or
DFCS_FLAT);
DrawFrameControl(M.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOMASK or
DFCS_FLAT);
{5} FStateImages.Add(Bmp, M);
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOIMAGE or
DFCS_FLAT or DFCS_CHECKED);
DrawFrameControl(M.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOMASK or
DFCS_FLAT or DFCS_CHECKED);
{6} FStateImages.Add(Bmp, M);
{ Add 3d images }
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONCHECK);
{7} Add;
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONCHECK or
DFCS_CHECKED);
{8} Add;
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONCHECK or
DFCS_CHECKED or DFCS_BUTTON3STATE);
{9} Add;
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOIMAGE);
DrawFrameControl(M.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOMASK);
{10} FStateImages.Add(Bmp, M);
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOIMAGE or
DFCS_CHECKED);
DrawFrameControl(M.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOMASK or
DFCS_CHECKED);
{11} FStateImages.Add(Bmp, M);
{ Add disabled images }
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONCHECK
or DFCS_INACTIVE);
{12} Add;
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONCHECK or
DFCS_CHECKED or DFCS_INACTIVE);
{13} Add;
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONCHECK or
DFCS_CHECKED or DFCS_BUTTON3STATE or DFCS_INACTIVE);
{14} Add;
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOIMAGE
or DFCS_INACTIVE);
DrawFrameControl(M.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOMASK
or DFCS_INACTIVE);
{15} FStateImages.Add(Bmp, M);
DrawFrameControl(Bmp.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOIMAGE or
DFCS_CHECKED or DFCS_INACTIVE);
DrawFrameControl(M.Canvas.Handle, R, DFC_BUTTON, DFCS_BUTTONRADIOMASK or
DFCS_CHECKED or DFCS_INACTIVE);
{16} FStateImages.Add(Bmp, M);
finally
M.Free;
Bmp.Free;
Items.EndUpdate;
end;
end;

function TCheckTreeView.CreateNode: TTreeNode;
begin
Result := TCheckTreeNode.Create(Items);
{ with TCheckTreeNode(Result)do
begin
ReflexChildren := True;
ReflexParent := True;
end;
}
end;

destructor TCheckTreeView.Destroy;
begin
inherited Destroy;
end;

function TCheckTreeView.GetChecked(Node: TTreeNode): Boolean;
begin
Result := TCheckTreeNode(Node).Checked
end;

function TCheckTreeView.GetNodeEnabled(Node: TTreeNode): Boolean;
begin
Result := TCheckTreeNode(Node).Enabled;
end;

function TCheckTreeView.GetKind(Node: TTreeNode): TCheckKind;
begin
Result := TCheckTreeNode(Node).CheckKind
end;

function TCheckTreeView.GetState(Node: TTreeNode): TCheckBoxState;
begin
Result := TCheckTreeNode(Node).CheckState
end;

procedure TCheckTreeView.Loaded;
begin
FStateImages := TImageList.Create(Self);
StateImages := FStateImages;
CreateCheckMarks;
FDesignInteractive := True;
inherited Loaded;
end;

procedure TCheckTreeView.MakeRadioGroup(Node: TTreeNode);
begin
TCheckTreeNode(Node).MakeRadioGroup;
end;

procedure TCheckTreeView.MouseDown(Button: TMouseButton;
Shift: TShiftState;
X, Y: Integer);
begin
if (Button = mbLeft) and (htOnStateIcon in GetHitTestInfoAt(X, Y)) then
ToggleNode(TCheckTreeNode(GetNodeAt(X, Y)));
inherited MouseDown(Button, Shift, X, Y);
end;

procedure TCheckTreeView.MouseMove(Shift: TShiftState;
X, Y: Integer);
var
N : TCheckTreeNode;
begin
N := TCheckTreeNode(GetNodeAt(X, Y));
if HotTrack and (Flatness = cfHotTrack) then
begin
if (FHoverCache <> N) then
begin
if FHoverCache <> nil then
FHoverCache.UpdateHotTrack(False);
if N <> nil then
N.UpdateHotTrack(True);
FHoverCache := N;
end;
end;
inherited MouseMove(Shift, X, Y);
end;

procedure TCheckTreeView.SetChecked(Node: TTreeNode;
Value: Boolean);
begin
TCheckTreeNode(Node).Checked := Value
end;

procedure TCheckTreeView.SetNodeEnabled(Node: TTreeNode;
const Value: Boolean);
begin
TCheckTreeNode(Node).Enabled := Value
end;

procedure TCheckTreeView.SetFlatness(const Value: TCheckFlatness);
var
I : Integer;
begin
if FFlatness <> Value then
begin
FFlatness := Value;
for I := 0 to Items.Count - 1do
TCheckTreeNode(Items).InternalSetState(
TCheckTreeNode(Items).GetState, False, False)
end;
end;

procedure TCheckTreeView.SetKind(Node: TTreeNode;
Value: TCheckKind);
begin
TCheckTreeNode(Node).CheckKind := Value
end;

procedure TCheckTreeView.SetState(Node: TTreeNode;
Value: TCheckBoxState);
begin
TCheckTreeNode(Node).CheckState := Value
end;

procedure TCheckTreeView.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin
if not (htOnStateIcon in GetHitTestInfoAt(Message.XPos, Message.YPos)) then
inherited;
end;

procedure TCheckTreeView.Change(Node: TTreeNode);
begin
if csDesigning in ComponentState then
GetParentForm(Self).Designer.Modified;
inherited Change(Node);
end;

procedure TCheckTreeView.WMKeyDown(var Message: TWMKeyDown);
begin
if Message.CharCode = VK_SPACE then
begin
ToggleNode(TCheckTreeNode(Selected));
Message.Result := 0;
end
else
inherited;
end;

procedure TCheckTreeView.ToggleNode(Node: TCheckTreeNode);
var
PrevCheck : TCheckBoxState;
Frm : TCustomForm;
begin
if (Node <> nil) and Node.Enabled then
begin
if Node.CheckKind = ckCheck then
begin
PrevCheck := Node.GetState;
if PrevCheck <> cbChecked then
begin
Node.InternalSetState(cbChecked);
if Node.GetState = PrevCheck then
Node.InternalSetState(cbUnchecked);
end
else
Node.InternalSetState(cbUnchecked);
end
else
if Node.CheckKind = ckRadio then
Node.Checked := True;
if csDesigning in ComponentState then
begin
Frm := GetParentForm(Self);
if Frm <> nil then
Frm.Designer.Modified
end;
end;
end;

procedure TCheckTreeView.DefineProperties(Filer: TFiler);
function WriteNodes: Boolean;
var
I : Integer;
Nodes : TTreeNodes;
begin
Nodes := TTreeNodes(Filer.Ancestor);
if Nodes = nil then
Result := Items.Count > 0
else
if Nodes.Count <> Items.Count then
Result := True
else
begin
Result := False;
for I := 0 to Items.Count - 1do
begin
Result := not TCheckTreeNode(Items.Item).IsEqual(Nodes);
if Result then
Break;
end
end;
end;

begin
inherited DefineProperties(Filer);
Filer.DefineBinaryProperty('CheckNodesData', ReadData, WriteData, WriteNodes);
end;

procedure TCheckTreeView.ReadData(Stream: TStream);
var
I : Integer;
begin
for I := 0 to Items.Count - 1do
TCheckTreeNode(Items).ReadSelf(Stream);
end;

procedure TCheckTreeView.WriteData(Stream: TStream);
var
I : Integer;
begin
for I := 0 to Items.Count - 1do
TCheckTreeNode(Items).WriteSelf(Stream);
end;

procedure TCheckTreeView.CreateParams(var Param: TCreateParams);
begin
inherited;
Param.Style :=Param.Style or TVS_CHECKBOXES;
end;

procedure TCheckTreeView.Click;
begin
inherited;
end;

{ TCheckTreeNode }
const
StateIndexes : array[TCheckKind, TCheckBoxState] of Integer =
((-1, -1, -1), (1, 2, 3), (4, 5, 4), (-1, -1, -1));
procedure TCheckTreeNode.AfterConstruction;
begin
FEnabled := True;
FReflexParent := True;
FReflexChildren := True;
FCheckKind := ckCheck;
end;

procedure TCheckTreeNode.Assign(Source: TPersistent);
var
Node : TCheckTreeNode;
begin
inherited Assign(Source);
if Source is TCheckTreeNode then
begin
Node := TCheckTreeNode(Source);
StateIndex := Node.StateIndex;
ReflexChildren := Node.ReflexChildren;
ReflexParent := Node.ReflexParent;
FCheckKind := Node.CheckKind;
end;
end;

procedure TCheckTreeNode.DoCheckChildren(Cur: TCheckBoxState);
var
I : Integer;
MustCheckParent : Boolean;
N, D : TCheckTreeNode;
begin
MustCheckParent := False;
D := nil;
if (FCheckKind in [ckCheck, ckGroup]) and FReflexChildren and (Cur <> cbGrayed)
then
begin
for I := 0 to Count - 1do
begin
N := TCheckTreeNode(Item);
if N.Enabled then
N.InternalSetState(Cur, True, False)
else
begin
MustCheckParent := True;
D := N;
end;
end;
if MustCheckParent then
D.DoCheckParent(Cur);
end;
end;

procedure TCheckTreeNode.DoCheckParent(Cur: TCheckBoxState);
var
I : Integer;
Ch, Un : Boolean;
begin
Ch := True;
Un := True;
if (FCheckKind in [ckCheck, ckGroup]) and FReflexParent and (Parent <> nil)
then
with TCheckTreeNode(Parent)do
begin
for I := 0 to Count - 1do
begin
if TCheckTreeNode(Item).FCheckKind in [ckCheck, ckGroup] then
case TCheckTreeNode(Item).GetState of
cbUnchecked: Ch := False;
cbChecked:
Un := False
else
begin
Ch := False;
Un := False;
Break;
end
end;
if not Ch and not Un then
Break;
end;
if Ch then
InternalSetState(cbChecked, False, True)
else
if Un then
InternalSetState(cbUnchecked, False, True)
else
InternalSetState(cbGrayed, False, True)
end;
end;

function TCheckTreeNode.GetChecked: Boolean;
var
S : TCheckBoxState;
begin
S := GetState;
Result := S = cbChecked;
if (FCheckKind in [ckCheck, ckGroup]) and
TCheckTreeView(TreeView).FGrayedIsChecked and (S = cbGrayed) then
Result := True
end;

function TCheckTreeNode.GetItemIndex: Integer;
begin
for Result := 0 to Count - 1do
with TCheckTreeNode(Item[Result])do
if (FCheckKind = ckRadio) and Checked then
Exit;
Result := -1;
end;

function TCheckTreeNode.GetState: TCheckBoxState;
begin
case StateIndex of
- 1..1, 4, 6, 9, 11, 14: Result := cbUnchecked;
2, 5, 7, 10, 12, 15:
Result := cbChecked
else
Result := cbGrayed
end;
if FCheckKind = ckGroup then
Result := FCache;
end;

procedure TCheckTreeNode.InternalSetState(Value: TCheckBoxState;
CheckChildren, CheckParent: Boolean);
var
I : Integer;
Node : TCheckTreeNode;
SI : Integer;
begin
SI := StateIndexes[FCheckKind, Value];
if SI > 0 then
if not Enabled then
StateIndex := SI + 10
else
if TCheckTreeView(TreeView).Flatness = cfAlways3d then
StateIndex := SI + 5
else
StateIndex := SI;
UpdateHotTrack(TCheckTreeView(TreeView).FHoverCache = Self);
if FCheckKind = ckGroup then
FCache := Value;
if (FCheckKind = ckRadio) and (Value = cbChecked) then
for I := 0 to Parent.Count - 1do
begin
Node := TCheckTreeNode(Parent.Item);
if (Node <> Self) and (Node.FCheckKind = ckRadio) then
Node.InternalSetState(cbUnchecked, False, False);
end;
if CheckChildren then
do
CheckChildren(Value);
if CheckParent then
do
CheckParent(Value);
end;

const
BoolChecks : array[Boolean] of TCheckBoxState = (cbUnchecked, cbChecked);
function TCheckTreeNode.IsEqual(Node: TTreeNode): Boolean;
begin
Result := (Text = Node.Text) and (Data = Node.Data);
end;

procedure TCheckTreeNode.MakeRadioGroup;
var
I : Integer;
begin
CheckKind := ckNone;
for I := Count - 1do
wnto 0do
if not Item.HasChildren then
with TCheckTreeNode(Item)do
begin
CheckKind := ckRadio;
//Checked := True
end;
end;

procedure TCheckTreeNode.ReadSelf(Stream: TStream);
var
Data : TCheckNodeData;
begin
Stream.ReadBuffer(Data, SizeOf(Data));
FCheckKind := Data.Kind;
FEnabled := Data.Enabled;
end;

procedure TCheckTreeNode.SetChecked(Value: Boolean);
begin
if GetState <> BoolChecks[Value] then
InternalSetState(BoolChecks[Value])
end;

procedure TCheckTreeNode.SetCheckKind(Value: TCheckKind);
begin
if FCheckKind <> Value then
begin
FCheckKind := Value;
if FCheckKind = ckNone then
StateIndex := -1
else
if FCheckKind = ckGroup then
begin
FCache := GetState;
StateIndex := -1;
end
else
InternalSetState(GetState);
end;
end;

procedure TCheckTreeNode.SetEnabled(Value: Boolean);
var
I : Integer;
begin
if FEnabled <> Value then
begin
FEnabled := Value;
InternalSetState(GetState, False, False);
end;
for I := 0 to Count - 1do
TCheckTreeNode(Item).Enabled := Value;
end;

procedure TCheckTreeNode.SetItemIndex(Value: Integer);
begin
if Value > Count then
raise EIndexError.CreateFmt(SIndexError, [Value]);
if TCheckTreeNode(Item[Value]).FCheckKind <> ckRadio then
EIndexError.CreateFmt(SInvalidKind, [Value]);
TCheckTreeNode(Item[Value]).SetState(cbChecked);
end;

procedure TCheckTreeNode.SetReflexChildren(Value: Boolean);
begin
if FReflexChildren <> Value then
begin
FReflexChildren := Value;
do
CheckChildren(GetState)
end;
end;

procedure TCheckTreeNode.SetReflexParent(Value: Boolean);
begin
if FReflexParent <> Value then
begin
FReflexParent := Value;
do
CheckParent(GetState);
end;
end;

procedure TCheckTreeNode.SetState(Value: TCheckBoxState);
begin
if Value <> GetState then
InternalSetState(Value)
end;

procedure TCheckTreeNode.UpdateHotTrack(Hover: Boolean);
begin
if (FCheckKind in [ckCheck, ckRadio]) and Enabled and
(TCheckTreeView(TreeView).Flatness <> cfAlways3d) then
begin
if Hover then
StateIndex := StateIndexes[FCheckKind, GetState] + 5
else
StateIndex := StateIndexes[FCheckKind, GetState];
end;
end;

procedure TCheckTreeNode.WriteSelf(Stream: TStream);
var
Data : TCheckNodeData;
begin
Data.Kind := CheckKind;
Data.Enabled := Enabled;
Stream.WriteBuffer(Data, SizeOf(Data));
end;

end.
 
为了使的解答更完整,我测试了一下代码,太好了,我的测试代码如下:
真的非常谢谢“寻绎”,这样的人太少了,多几个“寻绎”,中国的软件业才有希望。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
uses CheckTV;
var ctv:TCheckTreeView;
procedure TForm1.FormCreate(Sender: TObject);
begin
ctv:=TCheckTreeView.Create(Form1);
ctv.Parent:=Form1;
ctv.Top:=20;
ctv.Left:=20;
ctv.Height:=260;
ctv.Width:=200;
ctv.Items.AddFirst(nil,'根节点');
ctv.Items.AddChild(ctv.Items.GetFirstNode,'子节点1');
ctv.Items.AddChild(ctv.Items.GetFirstNode,'子节点2');
ctv.Items.AddChild(ctv.Items.GetFirstNode,'子节点3');
ctv.Items.AddChild(ctv.Items.GetFirstNode,'子节点4');
ctv.Items.AddChild(ctv.Items.GetFirstNode,'子节点5');
ctv.FullExpand;
end;

end.
 
接受答案了.
 
这个代码有个小问题怎么修改,就是子节点未选中时,父节点的复选框没有显示出来,怎么改写一下上面的代码呀?
 
后退
顶部