unit uckDroitTreeView;interfaceuses Windows, Messages, SysUtils, Classes, Controls, ComCtrls,CommCtrl;{权限树} type TuckDroitTreeView = class(TTreeView) private FCheckBoxReadOnly : Boolean; FOldState : Boolean; FOnCheckedChange : TTVChangedEvent; function IsNodeChecked(Node :TTreeNode) :Boolean; function CheckDroitString(const DroitStr: String): Boolean; procedure SetNodeChecked(Node :TTreeNode; Checked :Boolean); procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN; procedure SetChildren(Node: TTreeNode; Checked: Boolean); procedure SetParant(Node: TTreeNode; Checked: Boolean); function GetDroitString: String; procedure SetDroitString(DroitStr: String); protected procedure CreateParams(var Params: TCreateParams); override; public constructor Create(AOwner: TComponent); override; function Checked(Node: TTreeNode): Boolean; procedure SetChecked(Node: TTreeNode; Checked: Boolean); published property CheckBoxReadOnly: Boolean read FCheckBoxReadOnly write FCheckBoxReadOnly; property OnCheckedChange: TTVChangedEvent read FOnCheckedChange write FOnCheckedChange; property DroitString: String read GetDroitString write SetDroitString; end;procedure Register;implementationprocedure Register; begin RegisterComponents('Samples', [TuckDroitTreeView]); end; //----------------------------------------------------------------------------------- function TuckDroitTreeView.CheckDroitString(const DroitStr: String): Boolean; var I : Integer; begin Result := False; if DroitStr = '' then Exit; for I :=1 to Length(DroitStr) do begin if not( (DroitStr[I] = '0') or (DroitStr[I] = '1') ) then begin Result := False; Exit; end; end; Result := True; end;//----------------------------------------------------------------------------------- function TuckDroitTreeView.Checked(Node: TTreeNode): Boolean; begin Result := IsNodeChecked(Node); end;//----------------------------------------------------------------------------------- constructor TuckDroitTreeView.Create(AOwner: TComponent); begin inherited Create(AOwner); FCheckBoxReadOnly := False; end;//----------------------------------------------------------------------------------- procedure TuckDroitTreeView.CreateParams(var Params: TCreateParams); begin inherited; Params.Style:=Params.Style or TVS_CHECKBOXES; end;//----------------------------------------------------------------------------------- function TuckDroitTreeView.GetDroitString: String; var I : Integer; begin Result := ''; if Self.Items.Count < 1 then Exit; for I :=0 to Self.Items.Count - 1 do begin if Self.Checked(Self.Items[I]) then Result := Result + '1' else Result := Result + '0'; end; end;//----------------------------------------------------------------------------------- procedure TuckDroitTreeView.SetDroitString(DroitStr: String); var I, Len : Integer; begin if Self.Items.Count < 1 then Exit; if not CheckDroitString(DroitStr) then Exit; for I :=0 to Self.Items.Count - 1 do Self.SetChecked(Self.Items[I], False); Len := Length(DroitStr); for I :=0 to Self.Items.Count - 1 do begin if I + 1 <= Len then begin Self.SetChecked(Self.Items[I], (DroitStr[I+1]='1')); end; end; end;//----------------------------------------------------------------------------------- function TuckDroitTreeView.IsNodeChecked(Node: TTreeNode): Boolean; const TVIS_CHECKED = $2000; var TvItem :TTVItem; begin TvItem.Mask := TVIF_STATE; TvItem.hItem := Node.ItemId; TreeView_GetItem(Node.TreeView.Handle, TvItem); Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED; end;//----------------------------------------------------------------------------------- procedure TuckDroitTreeView.SetChecked(Node: TTreeNode; Checked: Boolean); begin if Node <> nil then SetNodeChecked(Node, Checked); end;//----------------------------------------------------------------------------------- procedure TuckDroitTreeView.SetChildren(Node: TTreeNode; Checked: Boolean); var TmpNode : TTreeNode; begin TmpNode := Node.GetFirstChild; while TmpNode <> nil do begin Self.SetChecked(TmpNode, Checked); if TmpNode.HasChildren then SetChildren(TmpNode, Checked); TmpNode := Node.GetNextChild(TmpNode); end; end;//----------------------------------------------------------------------------------- procedure TuckDroitTreeView.SetNodeChecked(Node: TTreeNode; Checked: Boolean); const TVIS_CHECKED = $2000; var TvItem :TTVItem; begin FillChar(TvItem, SizeOf(TvItem), 0); with TvItem do begin hItem := Node.ItemId; Mask := TVIF_STATE; StateMask := TVIS_STATEIMAGEMASK; if Checked then TvItem.State :=TVIS_CHECKED else TvItem.State :=TVIS_CHECKED shr 1; TreeView_SetItem(Node.TreeView.Handle, TvItem); end; end;//----------------------------------------------------------------------------------- procedure TuckDroitTreeView.SetParant(Node: TTreeNode; Checked: Boolean); var TmpNode : TTreeNode; begin TmpNode := Node.Parent; while TmpNode <> nil do begin Self.SetChecked(TmpNode, Checked); TmpNode := TmpNode.Parent; end; end;//----------------------------------------------------------------------------------- procedure TuckDroitTreeView.WMLButtonDown(var Message: TWMLButtonDown); var TmpNode : TTreeNode; OldState, bChecked : Boolean; begin TmpNode := Self.GetNodeAt(Message.XPos, Message.YPos); if TmpNode <> nil then OldState := IsNodeChecked(TmpNode); inherited; if TmpNode <> nil then begin if FCheckBoxReadOnly then SetNodeChecked(TmpNode, OldState); FOldState := IsNodeChecked(TmpNode); //---- if TmpNode.HasChildren then SetChildren(TmpNode, Self.Checked(TmpNode)); if TmpNode.Parent <> nil then begin bChecked := Self.Checked(TmpNode); if bChecked then SetParant(TmpNode, bChecked); end; //---- if Assigned(OnCheckedChange) then if FOldState <> OldState then OnCheckedChange(Self, TmpNode); end; end;end.
添加CheckBox 感谢zsWang http://search.csdn.net/Expert/topic/2137/2137712.xml?temp=.6334497 //参考如下代码~~ uses CommCtrl;function TreeNodeGetChecked(mTreeNode: TTreeNode): Boolean; var vTVItem: TTVItem; begin Result := False; if not Assigned(mTreeNode) or not Assigned(mTreeNode.TreeView) then Exit; vTVItem.mask := TVIF_STATE; vTVItem.hItem := mTreeNode.ItemId; if TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem) then Result := (vTVItem.State and IndexToStateImageMask(2)) > 0; //0: None 1: False 2: True end; { TreeNodeGetChecked }function TreeNodeSetChecked(mTreeNode: TTreeNode; mChecked: Boolean): Boolean; var vTVItem: TTVItem; Template:integer; begin Result := False; if not Assigned(mTreeNode) or not Assigned(mTreeNode.TreeView) then Exit; vTVItem.mask := TVIF_STATE; vTVItem.hItem := mTreeNode.ItemId; TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem); if not TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem) then Exit; vTVItem.stateMask := TVIS_STATEIMAGEMASK; vTVItem.state := IndexToStateImageMask(Succ(Ord(mChecked))); Result := TreeView_SetItem(mTreeNode.TreeView.Handle, vTVItem); end; { TreeNodeSetChecked }procedure TForm1.FormCreate(Sender: TObject); begin SetWindowLong(TreeView1.Handle, GWL_STYLE, GetWindowLong(TreeView1.Handle, GWL_STYLE) or TVS_CHECKBOXES); end;procedure TForm1.Button1Click(Sender: TObject); begin TreeNodeSetChecked(TreeView1.Selected, True); end;procedure TForm1.Button2Click(Sender: TObject); begin TreeNodeSetChecked(TreeView1.Selected, False); end;procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if htOnStateIcon in TreeView1.GetHitTestInfoAt(X, Y) then Caption := BoolToStr(TreeNodeGetChecked(TreeView1.GetNodeAt(X, Y)), True) //TODO -oZswang -c事件 : 触发点击选择框 else Caption := ''; end;procedure TForm1.Button3Click(Sender: TObject); var I: Integer; begin Memo1.Clear; for I := 0 to TreeView1.Items.Count - 1 do if TreeNodeGetChecked(TreeView1.Items[I]) then Memo1.Lines.Add(TreeView1.Items[I].Text); end;
Windows, Messages, SysUtils, Classes, Controls, ComCtrls,CommCtrl;{权限树}
type
TuckDroitTreeView = class(TTreeView)
private
FCheckBoxReadOnly : Boolean;
FOldState : Boolean;
FOnCheckedChange : TTVChangedEvent;
function IsNodeChecked(Node :TTreeNode) :Boolean;
function CheckDroitString(const DroitStr: String): Boolean;
procedure SetNodeChecked(Node :TTreeNode; Checked :Boolean);
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure SetChildren(Node: TTreeNode; Checked: Boolean);
procedure SetParant(Node: TTreeNode; Checked: Boolean);
function GetDroitString: String;
procedure SetDroitString(DroitStr: String);
protected
procedure CreateParams(var Params: TCreateParams); override;
public
constructor Create(AOwner: TComponent); override;
function Checked(Node: TTreeNode): Boolean;
procedure SetChecked(Node: TTreeNode; Checked: Boolean);
published
property CheckBoxReadOnly: Boolean read FCheckBoxReadOnly write FCheckBoxReadOnly;
property OnCheckedChange: TTVChangedEvent read FOnCheckedChange write FOnCheckedChange;
property DroitString: String read GetDroitString write SetDroitString;
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('Samples', [TuckDroitTreeView]);
end;
//-----------------------------------------------------------------------------------
function TuckDroitTreeView.CheckDroitString(const DroitStr: String): Boolean;
var
I : Integer;
begin
Result := False;
if DroitStr = '' then Exit;
for I :=1 to Length(DroitStr) do begin
if not( (DroitStr[I] = '0') or (DroitStr[I] = '1') ) then begin
Result := False;
Exit;
end;
end;
Result := True;
end;//-----------------------------------------------------------------------------------
function TuckDroitTreeView.Checked(Node: TTreeNode): Boolean;
begin
Result := IsNodeChecked(Node);
end;//-----------------------------------------------------------------------------------
constructor TuckDroitTreeView.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCheckBoxReadOnly := False;
end;//-----------------------------------------------------------------------------------
procedure TuckDroitTreeView.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.Style:=Params.Style or TVS_CHECKBOXES;
end;//-----------------------------------------------------------------------------------
function TuckDroitTreeView.GetDroitString: String;
var
I : Integer;
begin
Result := '';
if Self.Items.Count < 1 then Exit;
for I :=0 to Self.Items.Count - 1 do begin
if Self.Checked(Self.Items[I]) then Result := Result + '1'
else Result := Result + '0';
end;
end;//-----------------------------------------------------------------------------------
procedure TuckDroitTreeView.SetDroitString(DroitStr: String);
var
I, Len : Integer;
begin
if Self.Items.Count < 1 then Exit;
if not CheckDroitString(DroitStr) then Exit;
for I :=0 to Self.Items.Count - 1 do
Self.SetChecked(Self.Items[I], False);
Len := Length(DroitStr);
for I :=0 to Self.Items.Count - 1 do begin
if I + 1 <= Len then begin
Self.SetChecked(Self.Items[I], (DroitStr[I+1]='1'));
end;
end;
end;//-----------------------------------------------------------------------------------
function TuckDroitTreeView.IsNodeChecked(Node: TTreeNode): Boolean;
const
TVIS_CHECKED = $2000;
var
TvItem :TTVItem;
begin
TvItem.Mask := TVIF_STATE;
TvItem.hItem := Node.ItemId;
TreeView_GetItem(Node.TreeView.Handle, TvItem);
Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED;
end;//-----------------------------------------------------------------------------------
procedure TuckDroitTreeView.SetChecked(Node: TTreeNode; Checked: Boolean);
begin
if Node <> nil then
SetNodeChecked(Node, Checked);
end;//-----------------------------------------------------------------------------------
procedure TuckDroitTreeView.SetChildren(Node: TTreeNode; Checked: Boolean);
var
TmpNode : TTreeNode;
begin
TmpNode := Node.GetFirstChild;
while TmpNode <> nil do begin
Self.SetChecked(TmpNode, Checked);
if TmpNode.HasChildren then SetChildren(TmpNode, Checked);
TmpNode := Node.GetNextChild(TmpNode);
end;
end;//-----------------------------------------------------------------------------------
procedure TuckDroitTreeView.SetNodeChecked(Node: TTreeNode; Checked: Boolean);
const
TVIS_CHECKED = $2000;
var
TvItem :TTVItem;
begin
FillChar(TvItem, SizeOf(TvItem), 0);
with TvItem do begin
hItem := Node.ItemId;
Mask := TVIF_STATE;
StateMask := TVIS_STATEIMAGEMASK;
if Checked then
TvItem.State :=TVIS_CHECKED
else
TvItem.State :=TVIS_CHECKED shr 1;
TreeView_SetItem(Node.TreeView.Handle, TvItem);
end;
end;//-----------------------------------------------------------------------------------
procedure TuckDroitTreeView.SetParant(Node: TTreeNode; Checked: Boolean);
var
TmpNode : TTreeNode;
begin
TmpNode := Node.Parent;
while TmpNode <> nil do begin
Self.SetChecked(TmpNode, Checked);
TmpNode := TmpNode.Parent;
end;
end;//-----------------------------------------------------------------------------------
procedure TuckDroitTreeView.WMLButtonDown(var Message: TWMLButtonDown);
var
TmpNode : TTreeNode;
OldState, bChecked : Boolean;
begin
TmpNode := Self.GetNodeAt(Message.XPos, Message.YPos);
if TmpNode <> nil then OldState := IsNodeChecked(TmpNode); inherited; if TmpNode <> nil then begin
if FCheckBoxReadOnly then
SetNodeChecked(TmpNode, OldState);
FOldState := IsNodeChecked(TmpNode);
//----
if TmpNode.HasChildren then
SetChildren(TmpNode, Self.Checked(TmpNode));
if TmpNode.Parent <> nil then begin
bChecked := Self.Checked(TmpNode);
if bChecked then SetParant(TmpNode, bChecked);
end;
//----
if Assigned(OnCheckedChange) then
if FOldState <> OldState then
OnCheckedChange(Self, TmpNode);
end;
end;end.
http://search.csdn.net/Expert/topic/2137/2137712.xml?temp=.6334497
//参考如下代码~~
uses CommCtrl;function TreeNodeGetChecked(mTreeNode: TTreeNode): Boolean;
var
vTVItem: TTVItem;
begin
Result := False;
if not Assigned(mTreeNode) or not Assigned(mTreeNode.TreeView) then Exit;
vTVItem.mask := TVIF_STATE;
vTVItem.hItem := mTreeNode.ItemId;
if TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem) then
Result := (vTVItem.State and IndexToStateImageMask(2)) > 0; //0: None 1: False 2: True
end; { TreeNodeGetChecked }function TreeNodeSetChecked(mTreeNode: TTreeNode; mChecked: Boolean): Boolean;
var
vTVItem: TTVItem;
Template:integer;
begin
Result := False;
if not Assigned(mTreeNode) or not Assigned(mTreeNode.TreeView) then Exit; vTVItem.mask := TVIF_STATE;
vTVItem.hItem := mTreeNode.ItemId;
TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem);
if not TreeView_GetItem(mTreeNode.TreeView.Handle, vTVItem) then Exit;
vTVItem.stateMask := TVIS_STATEIMAGEMASK;
vTVItem.state := IndexToStateImageMask(Succ(Ord(mChecked)));
Result := TreeView_SetItem(mTreeNode.TreeView.Handle, vTVItem);
end; { TreeNodeSetChecked }procedure TForm1.FormCreate(Sender: TObject);
begin
SetWindowLong(TreeView1.Handle, GWL_STYLE,
GetWindowLong(TreeView1.Handle, GWL_STYLE) or TVS_CHECKBOXES);
end;procedure TForm1.Button1Click(Sender: TObject);
begin
TreeNodeSetChecked(TreeView1.Selected, True);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
TreeNodeSetChecked(TreeView1.Selected, False);
end;procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if htOnStateIcon in TreeView1.GetHitTestInfoAt(X, Y) then
Caption := BoolToStr(TreeNodeGetChecked(TreeView1.GetNodeAt(X, Y)), True)
//TODO -oZswang -c事件 : 触发点击选择框
else Caption := '';
end;procedure TForm1.Button3Click(Sender: TObject);
var
I: Integer;
begin
Memo1.Clear;
for I := 0 to TreeView1.Items.Count - 1 do
if TreeNodeGetChecked(TreeView1.Items[I]) then
Memo1.Lines.Add(TreeView1.Items[I].Text);
end;