权限树
unit uckDroitTreeView;
interface
uses
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;
implementation
procedure 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.
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/archive/2008/04/01/2941047.html