delphi的treeview中增加checkbox複選框

不知道delphi中爲啥treeview中沒有提供checkbox複選框的功能,也有一些第三方的控件可以做,這裏不使用第三方控件,直接使用delphi中的TTreeview 做一些修改,看看效果.

unit wenhq;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,CommCtrl,
Dialogs, ComCtrls, StdCtrls;
type
Twenhqform = class(TForm)
TreeView1: TTreeView;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure TreeView1Click(Sender: TObject);
private
{ Private declarations }
procedure tvToggleCheckbox(TreeView: TTreeView;Node: TTreeNode;isclick:boolean =false);
procedure SetChecked(Node: TTreeNode; Checked: Boolean);
function IsChecked(Node: TTreeNode): Boolean;
public
{ Public declarations }
end;

var
wenhqform: Twenhqform;

implementation

{$R *.dfm}
const
TVIS_CHECKED = $2000;
procedure Twenhqform.FormCreate(Sender: TObject);
begin
//僅僅這一句話就能讓treeview 顯示覆選框
SetWindowLong(TreeView1.Handle, GWL_STYLE, GetWindowLong(TreeView1.Handle, GWL_STYLE) or $00000100);
end;
//檢查某個節點是否被 選中
function Twenhqform.IsChecked(Node: TTreeNode): Boolean;
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 Twenhqform.SetChecked(Node: TTreeNode; Checked: Boolean);
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 Twenhqform.tvToggleCheckbox(TreeView: TTreeView;
Node: TTreeNode ;isclick :boolean=false);
var CurNode, ParentNode, GrandSonNode,sonNode: TTreeNode;
flg1: boolean;
begin
CurNode :=node;
with TreeView do begin
if IsChecked(CurNode) then //
begin
sonNode := CurNode.GetFirstChild; //遍歷子樹,選中 則子節點 全部 爲選中;
while sonNode<>nil do
begin
SetChecked(sonNode, true);
tvToggleCheckbox(TreeView,sonNode,true);
sonNode := sonNode.GetNextSibling;
end;

ParentNode:= CurNode.Parent; //父;
if ParentNode<>nil then
begin
if not isChecked(parentNode) then begin
GrandSonNode := ParentNode.GetFirstChild; //遍歷子樹;
flg1 := false;
while GrandSonNode<>nil do
begin
if (not IsChecked(GrandSonNode)) then //true,有未選中
flg1 := true;
if flg1 then //已有、退出loop;
GrandSonNode := nil
else
GrandSonNode := GrandSonNode.GetNextSibling;
end;
SetChecked(ParentNode, not flg1);
tvToggleCheckbox(TreeView,ParentNode,false);
end;
end; // end parentNode 不等於空
end else if not IsChecked(CurNode) then
begin
ParentNode := CurNode.Parent; //父;
if ParentNode<>nil then
begin
if isChecked(parentNode) then begin
SetChecked(ParentNode, false);
tvToggleCheckbox(TreeView,ParentNode);
end;
end; //end parentnode

if (isclick) then begin
sonNode := CurNode.GetFirstChild; //遍歷子樹,未選中 則子節點 全部 爲未選中;
while sonNode<>nil do
begin
SetChecked(sonNode, false);
tvToggleCheckbox(TreeView,sonNode,true);
sonNode := sonNode.GetNextSibling;
end;
end;

end;
end;
end;

procedure Twenhqform.TreeView1Click(Sender: TObject);
var
P:TPoint;
treenode :TTreeNode;
begin
GetCursorPos(P);
P := TreeView1.ScreenToClient(P);
if (htOnStateIcon in TreeView1.GetHitTestInfoAt(P.X,P.Y)) then begin
treenode := TreeView1.GetNodeAt(P.X,P.Y);
tvToggleCheckbox(TreeView1,treenode ,true);
end;
end;
end.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章