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; 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.TreeView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure pSelect(mTreeNode: TTreeNode; mChecked: Boolean); var I: Integer; begin TreeNodeSetChecked(mTreeNode, mChecked); for I := 0 to mTreeNode.Count - 1 do pSelect(mTreeNode[I], mChecked); end;
procedure pSelectYes(mTreeNode: TTreeNode); begin while Assigned(mTreeNode.Parent) and not TreeNodeGetChecked(mTreeNode.Parent) do begin TreeNodeSetChecked(mTreeNode.Parent, True); mTreeNode := mTreeNode.Parent; end; end;
procedure pSelectNo(mTreeNode: TTreeNode); var I: Integer; begin if Assigned(mTreeNode.Parent) and TreeNodeGetChecked(mTreeNode.Parent) then begin for I := 0 to mTreeNode.Parent.Count - 1 do if TreeNodeGetChecked(mTreeNode.Parent[I]) then Exit; TreeNodeSetChecked(mTreeNode.Parent, False); pSelectNo(mTreeNode.Parent); end; end;
var vTreeNode: TTreeNode; begin if not (htOnStateIcon in TTreeView(Sender).GetHitTestInfoAt(X, Y)) then Exit; vTreeNode := TTreeView(Sender).GetNodeAt(X, Y); pSelect(vTreeNode, TreeNodeGetChecked(vTreeNode)); if not TreeNodeGetChecked(vTreeNode) then pSelectNo(vTreeNode) else pSelectYes(vTreeNode); end;
重载TreeView的CreateParams:typeTCheckBoxTreeView = class(TTreeView)protectedprocedure CreateParams(var Params: TCreateParams); override;end;procedure TCheckBoxTreeView.CreateParams(var Params: TCreateParams);begininherited;Params.Style:=Params.Style or TVS_CHECKBOXES;{ TVS_CHECKBOXES declared in CommCtrl }end;如果要Check这个CheckBox,可以用下面的代码:function IsNodeChecked(Node :TTreeNode) :Boolean;constTVIS_CHECKED = $2000;varTvItem :TTVItem;beginTvItem.Mask := TVIF_STATE;TvItem.hItem := Node.ItemId;TreeView_GetItem(Node.TreeView.Handle, TvItem);Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED;end;procedure SetNodeChecked(Node :TTreeNode; Checked :Boolean);constTVIS_CHECKED = $2000;varTvItem :TTVItem;beginFillChar(TvItem, SizeOf(TvItem), 0);with TvItem do beginhItem := Node.ItemId;Mask := TVIF_STATE;StateMask := TVIS_STATEIMAGEMASK;if Checked thenTvItem.State :=TVIS_CHECKEDelseTvItem.State :=TVIS_CHECKED shr 1;TreeView_SetItem(Node.TreeView.Handle, TvItem);end;end;可以做成事件和封装成一个类:private OldState :Boolean;procedure Change(Node: TTreeNode); override;begininherited Change(Node);OldState := IsNodeChecked(Node);end;procedure Click; override;varNewState :Boolean;begininherited Click;NewState := IsNodeChecked(Self.Selected);if NewState = OldState then Exit;if (NewState) and Assigned(OnNodeChecked) then OnNodeChecked()else if (not NewState) and Assigned(OnNodeUnChecked) thenOnNodeUnChecked()// OnNodeChecked & OnNodeUnchecked will be events that you declareend;
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;
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.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure pSelect(mTreeNode: TTreeNode; mChecked: Boolean);
var
I: Integer;
begin
TreeNodeSetChecked(mTreeNode, mChecked);
for I := 0 to mTreeNode.Count - 1 do pSelect(mTreeNode[I], mChecked);
end;
procedure pSelectYes(mTreeNode: TTreeNode);
begin
while Assigned(mTreeNode.Parent) and
not TreeNodeGetChecked(mTreeNode.Parent) do begin
TreeNodeSetChecked(mTreeNode.Parent, True);
mTreeNode := mTreeNode.Parent;
end;
end;
procedure pSelectNo(mTreeNode: TTreeNode);
var
I: Integer;
begin
if Assigned(mTreeNode.Parent) and TreeNodeGetChecked(mTreeNode.Parent) then begin
for I := 0 to mTreeNode.Parent.Count - 1 do
if TreeNodeGetChecked(mTreeNode.Parent[I]) then Exit;
TreeNodeSetChecked(mTreeNode.Parent, False);
pSelectNo(mTreeNode.Parent);
end;
end;
var
vTreeNode: TTreeNode;
begin
if not (htOnStateIcon in TTreeView(Sender).GetHitTestInfoAt(X, Y)) then Exit;
vTreeNode := TTreeView(Sender).GetNodeAt(X, Y);
pSelect(vTreeNode, TreeNodeGetChecked(vTreeNode));
if not TreeNodeGetChecked(vTreeNode) then
pSelectNo(vTreeNode)
else pSelectYes(vTreeNode);
end;
object TreeView1: TTreeView
Left = 432
Top = 16
Width = 121
Height = 217
Images = ImageList1
Indent = 19
TabOrder = 2
OnMouseDown = TreeView2MouseDown
Items.Data = {
040000001B0000000000000000000000FFFFFFFFFFFFFFFF0000000002000000
0231311B0000000000000000000000FFFFFFFFFFFFFFFF000000000300000002
63631B0000000000000000000000FFFFFFFFFFFFFFFF00000000000000000264
641B0000000000000000000000FFFFFFFFFFFFFFFF0000000000000000026565
1B0000000000000000000000FFFFFFFFFFFFFFFF00000000000000000266661B
0000000000000000000000FFFFFFFFFFFFFFFF00000000010000000261611B00
00000000000000000000FFFFFFFFFFFFFFFF00000000000000000264641B0000
000000000000000000FFFFFFFFFFFFFFFF00000000000000000232321B000000
0000000000000000FFFFFFFFFFFFFFFF00000000020000000233331B00000000
00000000000000FFFFFFFFFFFFFFFF00000000000000000234341B0000000000
000000000000FFFFFFFFFFFFFFFF00000000000000000235351C000000000000
0000000000FFFFFFFFFFFFFFFF0000000001000000036161611B000000000000
0000000000FFFFFFFFFFFFFFFF0000000000000000026262}
end
object ImageList1: TImageList
Height = 13
Width = 13
Left = 376
Top = 8
Bitmap = {
494C01010300040004000D000D00FFFFFFFFFF00FFFFFFFFFFFFFFFF424D3600
0000000000003600000028000000340000000D00000001001000000000004805
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000001042104210421042104210421042104210421042104210421042
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000104210421042104210421042104210421042
1042104210421042000000000000000000000000000000000000000000000000
000000000000FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F0000000000000000
FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F00000000104210421863FF7F1863
FF7F1863FF7F1863FF7F18631042104200000000000000000000000000000000
0000000000000000000000000000FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F
0000000000000000FF7FFF7FFF7F0000FF7FFF7FFF7FFF7FFF7F000000001042
1042FF7F1863FF7F1042FF7F1863FF7F1863FF7F104210420000000000000000
00000000000000000000000000000000000000000000FF7FFF7FFF7FFF7FFF7F
FF7FFF7FFF7FFF7F0000000000000000FF7FFF7F000000000000FF7FFF7FFF7F
FF7F00000000104210421863FF7F104210421042FF7F1863FF7F186310421042
000000000000000000000000000000000000000000000000000000000000FF7F
FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F0000000000000000FF7F000000000000
00000000FF7FFF7FFF7F0000000010421042FF7F10421042104210421042FF7F
1863FF7F10421042000000000000000000000000000000000000000000000000
000000000000FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F0000000000000000
FF7F00000000FF7F000000000000FF7FFF7F0000000010421042186310421042
FF7F104210421042FF7F18631042104200000000000000000000000000000000
0000000000000000000000000000FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F
0000000000000000FF7F0000FF7FFF7FFF7F000000000000FF7F000000001042
1042FF7F1042FF7F1863FF7F104210421042FF7F104210420000000000000000
00000000000000000000000000000000000000000000FF7FFF7FFF7FFF7FFF7F
FF7FFF7FFF7FFF7F0000000000000000FF7FFF7FFF7FFF7FFF7FFF7F00000000
FF7F00000000104210421863FF7F1863FF7F1863FF7F10421042186310421042
000000000000000000000000000000000000000000000000000000000000FF7F
FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F0000000000000000FF7FFF7FFF7FFF7F
FF7FFF7FFF7F0000FF7F0000000010421042FF7F1863FF7F1863FF7F1863FF7F
1042FF7F10421042000000000000000000000000000000000000000000000000
000000000000FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F0000000000000000
FF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7FFF7F00000000104210421863FF7F1863
FF7F1863FF7F1863FF7F18631042104200000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000001042
1042104210421042104210421042104210421042104210420000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000001042104210421042104210421042104210421042104210421042
0000000000000000000000000000000000000000000000000000424D3E000000
000000003E00000028000000340000000D000000010001000000000068000000
0000000000000000000000000000000000000000FFFFFF000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000}
end