fctreeview带checkbox的状态下如何实现像杀毒软件选择目录那样的效果

LevnWang 2006-10-09 11:15:05
fctreeview带checkbox的状态下如何实现像杀毒软件选择目录那样的效果。比如:
一、选中一个父结点的时候,它的所有子结点都被选中。当取消其选中状态,它的子结点的选中状态也被取消;
二、选中一个有父结点的结点,其所有的父结点也都被选中。
三、只要存在有子结点被选中,则对应的父结点为选中状态。

...全文
490 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
股神 2006-10-12
  • 打赏
  • 举报
回复
gobiz 2006-10-11
  • 打赏
  • 举报
回复
使用方法:
procedure TfrmTest.FormCreate(Sender: TObject);
var
i, j: Integer;
FNode, FSubNode: TTreeNode;
begin
for i:=0 to 9 do
begin
FNode := zmCheckTreeView1.Items.AddChild(nil, '父节点' + IntToStr(i));
zmCheckTreeView1.CheckBoxState[FNode] := cbUnchecked;
for j:=0 to 9 do
begin
FSubNode := zmCheckTreeView1.Items.AddChild(FNode, '子节点' + IntToStr(i) + IntToStr(j));
zmCheckTreeView1.CheckBoxState[FSubNode] := cbUnchecked;
end;
end;
end;
gobiz 2006-10-11
  • 打赏
  • 举报
回复
其中zmCheckTreeView.res是一个资源文件,建立一个宽64高16的Bitmap,也就是4中状态16×16图标,第一个16×16图标是空的(表示不使用CheckBox模式),第二个16×16图标是未选中,第三个16×16图标是表示全部子节点选中,第四个16×16图标是表示部分子节点选中。然后把这个Bitmap资源名称修改为ZMTREESTATUS就可以安装了!
gobiz 2006-10-11
  • 打赏
  • 举报
回复
给你一个控件,自己编译一下吧:
unit zmCheckTreeView;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, Commctrl, StdCtrls;

type

TzmCheckTreeView = class(TTreeView)
private
{ Private declarations }
FStateImages: TImageList;
function GetCheckBoxState(Node: TTreeNode): TCheckBoxState;
procedure SetCheckBoxState(Node: TTreeNode;
const Value: TCheckBoxState);
function GetChecked(Node: TTreeNode): Boolean;
procedure SetChecked(Node: TTreeNode; const Value: Boolean);
protected
{ Protected declarations }
procedure WndProc(var message: TMessage); override;
procedure KeyPress(var Key: Char); override;
procedure Loaded; override;
function ToggleCheckedByPos(x, y: Integer): Boolean;
function ToggleChecked(Node: TTreeNode): Boolean;
procedure SyncChildNode(Node: TTreeNode);
procedure SyncParentNode(Node: TTreeNode);
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

property CheckBoxState[Node: TTreeNode]: TCheckBoxState read GetCheckBoxState
write SetCheckBoxState;
property Checked[Node: TTreeNode]: Boolean read GetChecked write SetChecked;
end;

procedure Register;

implementation

{$R zmCheckTreeView.res}

{ TzmCheckTreeView }

procedure Register;
begin
RegisterComponents('zmSoft', [TzmCheckTreeView]);
end;

constructor TzmCheckTreeView.Create(AOwner: TComponent);
begin
inherited;
FStateImages := TImageList.CreateSize(16, 16);
FStateImages.Handle := ImageList_LoadBitmap(hInstance, 'ZMTREESTATUS',
16, 0, clFuchsia);
StateImages := FStateImages;
end;

destructor TzmCheckTreeView.Destroy;
begin
FStateImages.Free;
inherited;
end;

procedure TzmCheckTreeView.Loaded;
var
i: Integer;
begin
inherited Loaded;
for i := 0 to Items.Count - 1 do
SetChecked(Items[i], True);
end;

function TzmCheckTreeView.GetCheckBoxState(Node: TTreeNode): TCheckBoxState;
begin
if Node.StateIndex in [1..3] then
Result := TCheckBoxState(Node.StateIndex - 1)
else
Result := cbUnchecked;
end;

procedure TzmCheckTreeView.SetCheckBoxState(Node: TTreeNode;
const Value: TCheckBoxState);
begin
if (Node.StateIndex - 1 <> Ord(Value)) and (Value <> cbGrayed) then
begin
Node.StateIndex := Ord(Value) + 1;
SyncChildNode(Node);
SyncParentNode(Node);
end;
end;

function TzmCheckTreeView.GetChecked(Node: TTreeNode): Boolean;
begin
Result := GetCheckBoxState(Node) = cbChecked;
end;

procedure TzmCheckTreeView.SetChecked(Node: TTreeNode;
const Value: Boolean);
begin
if Value then
SetCheckBoxState(Node, cbChecked)
else
SetCheckBoxState(Node, cbUnchecked);
end;

function TzmCheckTreeView.ToggleChecked(Node: TTreeNode): Boolean;
begin
if Assigned(Node) then
begin
SetChecked(Node, not GetChecked(Node));
Result := True;
end
else
Result := False;
end;

function TzmCheckTreeView.ToggleCheckedByPos(x, y: Integer): Boolean;
var
Node: TTreeNode;
begin
Result := False;
if htOnStateIcon in GetHitTestInfoAt(x, y) then
begin
Node := GetNodeAt(x, y);
Result := ToggleChecked(Node);
end;
end;

procedure TzmCheckTreeView.KeyPress(var Key: Char);
begin
if (Key = ' ') and Assigned(Selected) then
ToggleChecked(Selected)
else
inherited;
end;

procedure TzmCheckTreeView.SyncChildNode(Node: TTreeNode);
var
i: Integer;
begin
if Node.StateIndex <> Ord(cbGrayed) + 1 then
for i := 0 to Node.Count - 1 do
begin
Node.Item[i].StateIndex := Node.StateIndex;
SyncChildNode(Node.Item[i]);
end;
end;

procedure TzmCheckTreeView.SyncParentNode(Node: TTreeNode);
var
i, SelCount, UnSelCount: Integer;
begin
if Node.Parent <> nil then
begin
SelCount := 0;
UnSelCount := 0;

for i := 0 to Node.Parent.Count - 1 do
begin
if GetCheckBoxState(Node.Parent.Item[i]) = cbChecked then
Inc(SelCount)
else if GetCheckBoxState(Node.Parent.Item[i]) = cbUnchecked then
Inc(UnSelCount);
end;

if SelCount = Node.Parent.Count then
begin
if GetCheckBoxState(Node.Parent) <> cbChecked then
begin
Node.Parent.StateIndex := Ord(cbChecked) + 1;
SyncParentNode(Node.Parent);
end;
end
else if UnSelCount = Node.Parent.Count then
begin
if GetCheckBoxState(Node.Parent) <> cbUnchecked then
begin
Node.Parent.StateIndex := Ord(cbUnchecked) + 1;
SyncParentNode(Node.Parent);
end;
end
else if GetCheckBoxState(Node.Parent) <> cbGrayed then
begin
Node.Parent.StateIndex := Ord(cbGrayed) + 1;
SyncParentNode(Node.Parent);
end;
end;
end;

procedure TzmCheckTreeView.WndProc(var message: TMessage);
begin
case message.Msg of
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
begin
if ToggleCheckedByPos(TWMLButtonDown(message).XPos, TWMLButtonDown(message).YPos)
then
Exit;
end;
WM_LBUTTONUP, WM_RBUTTONUP:
begin
if htOnStateIcon in GetHitTestInfoAt(TWMLButtonDown(message).XPos,
TWMLButtonDown(message).YPos) then
Exit;
end;
end;
inherited WndProc(message);
end;

end.
chenylin 2006-10-11
  • 打赏
  • 举报
回复
一定要写递规

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, fcTreeView, StdCtrls;

type
TForm1 = class(TForm)
fcTreeView1: TfcTreeView;
procedure SetChildrenCheck(TreeNode: TfcTreeNode; CheckStyle:Boolean);
procedure SetTreeViewCheck(TreeView:TfcTreeView);
procedure fcTreeView1Click(Sender: TObject);
procedure fcTreeView1Collapsing(TreeView: TfcCustomTreeView;
Node: TfcTreeNode; var AllowCollapse: Boolean);
procedure fcTreeView1Expanding(TreeView: TfcCustomTreeView;
Node: TfcTreeNode; var AllowExpansion: Boolean);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
TreeStatus:Boolean;

implementation

{$R *.dfm}

procedure TForm1.SetChildrenCheck(TreeNode: TfcTreeNode; CheckStyle:Boolean);
var
CurrNode:TfcTreeNode;
begin
TreeNode.Checked:=CheckStyle;
if TreeNode.HasChildren then
begin
CurrNode:=TreeNode.GetFirstChild;
While CurrNode <> Nil do
begin
if CurrNode.HasChildren then
SetChildrenCheck(CurrNode,CheckStyle)
else
CurrNode.Checked:=CheckStyle;
CurrNode:=CurrNode.GetNextSibling;
end;
end;
end;

procedure TForm1.SetTreeViewCheck(TreeView: TfcTreeView);
var
CurrNode:TfcTreeNode;
i,CheckCount:integer;
begin
for i:=TreeView.Items.Count-1 downto 0 do
begin
if TreeView.Items[i].HasChildren then
begin
CheckCount:=0;
CurrNode:=TreeView.Items[i].GetFirstChild;
While CurrNode <> Nil do
begin
if CurrNode.Checked then CheckCount:=CheckCount+1;
CurrNode:=CurrNode.GetNextSibling;
end;
if CheckCount>0 then
TreeView.Items[i].Checked:=true
else
TreeView.Items[i].Checked:=false;
end;
end;
end;

procedure TForm1.fcTreeView1Click(Sender: TObject);
begin
if TreeStatus then begin TreeStatus:=false; exit; end;
fcTreeView1.Selected.Checked:=not fcTreeView1.Selected.Checked;
SetChildrenCheck(fcTreeView1.Selected,fcTreeView1.Selected.Checked);
SetTreeViewCheck(fcTreeView1);
end;

procedure TForm1.fcTreeView1Collapsing(TreeView: TfcCustomTreeView;
Node: TfcTreeNode; var AllowCollapse: Boolean);
begin
TreeStatus:=true;
end;

procedure TForm1.fcTreeView1Expanding(TreeView: TfcCustomTreeView;
Node: TfcTreeNode; var AllowExpansion: Boolean);
begin
TreeStatus:=true;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
fcTreeView1.ReadOnly:=true;
end;

end.
spirit_sheng 2006-10-11
  • 打赏
  • 举报
回复
1楼正解
LevnWang 2006-10-10
  • 打赏
  • 举报
回复
自己顶上去
LevnWang 2006-10-10
  • 打赏
  • 举报
回复
up
GARNETT2183 2006-10-09
  • 打赏
  • 举报
回复
你在OnChange事件里面就可以做到了。。。
LevnWang 2006-10-09
  • 打赏
  • 举报
回复
还是实现不了呢,偶比较笨,实在想不出来了,能给点提示吗?
代码转载自:https://pan.quark.cn/s/11d565366452 【USB转I2C/IIC适配器上位机应用程序】是一种针对I2C(Inter-Integrated Circuit)通信协议而构建的工具,其通过USB端口将个人计算机转变为能够与I2C设备进行交互的控制器。该适配器使开发人员与工程师能够便捷地对遵循I2C协议的芯片执行读取和写入任务,因此在硬件构建和测试阶段能够显著提升效率,对于核实I2C接口芯片的工作性能具有特别的价值。 I2C协议是由飞利浦(现NXP半导体)于1980年代初创立的一种双线式串行总线,其目的是用于连接微控制器及其他外围设备。该协议仅需两条信号线(SDA - 数据线,SCL - 时钟线)即可完成多设备间的通信,大幅度削减了电路板上的布线需求,从而降低了生产成本。I2C协议提供多种速度等级,涵盖标准模式(100kbps)、快速模式(400kbps)以及高速模式(3.4Mbps),旨在满足不同场景下的应用要求。 Ginkgo USB转I2C适配器是这项技术的具体应用实例,它提供了一个物理接口,用于将USB端口转换为I2C端口。适配器内部装配有一个微控制器单元,该单元负责处理从USB到I2C的信号转换,并且通过USB线路向计算机传输信息,同时接收来自计算机的指令以操控I2C总线。这种设计使用户无需具备深厚的硬件知识,仅需借助上位机软件即可实现对I2C设备的操控。 Ginkgo I2C Adapter Classic是与该适配器相配套的软件,通常包含以下几项核心功能: 1. 设备识别:自动检测并建立与USB转I2C适配器的连接。 2. 总线探查:扫描I2C总线上所连接的设备地址,有助于准确定位设备的位置。 3. 读写指令...
代码转载自:https://pan.quark.cn/s/4c053f9292d9 在Android应用程序的设计与实现过程中,有时需要借助C或C++语言所具备的高性能特点,此时就必须借助Android Studio的NDK(Native Development Kit)工具来对C/C++代码进行编译,进而生成SO(Shared Object)动态链接库文件。本篇文章将详尽阐述在Android Studio环境下如何执行这一流程。 我们首先需要掌握Android Studio项目的基本组织架构。在Android Studio的`app`文件夹内,存在一个名为`src`的子文件夹,该文件夹通常包含了`main`以及其他相关源代码目录。在`main`文件夹中,除了我们常见的`java`文件夹外,还设立了一个`jniLibs`文件夹,此文件夹专门用于存储SO文件。除此之外,还有一个`jni`文件夹,它是用来存放C/C++源代码的地方。 为了实现C/C++代码的编写与编译,我们必须在`build.gradle`文件中配置NDK的支持。打开`app/build.gradle`文件,在`defaultConfig`部分中嵌入以下内容: ```groovy externalNativeBuild { ndkBuild { path src/main/jni/Android.mk } } ``` 这段内容明确指示Android Studio去何处寻找`Android.mk`文件,该文件是一种Makefile的变体,主要用于设定编译规则和编译目标。 接下来,我们需要创建`Android.mk`文件。在这个文件中,我们将明确指定源代码文件、编译选项以及要生成的库名称。一个基础的...
内容概要:本文围绕麦克斯韦旋度方程的差分形式在平面极化磁场中的应用展开深入研究,并通过Matlab代码实现相关数值仿真。研究的核心是将经典的麦克斯韦方程组转化为适用于数值计算的有限差分格式,构建离散化数学模型,进而模拟和分析平面极化条件下磁场的空间分布特征与时间演化规律。文中系统阐述了差分方法的理论基础与数学推导过程,详细说明网格划分、边界条件设定及迭代求解策略,最终利用Matlab编程实现电磁场的可视化仿真,有效验证了差分方法在求解复杂电磁场问题中的准确性与可行性。该研究不仅加深了对电磁波传播机理的理解,也为电磁器件的设计优化与工程仿真提供了可靠的数值分析手段。; 适合人群:具备电磁场与电磁波理论基础,熟悉偏微分方程数值解法,且掌握Matlab编程技能的电气工程、物理学、应用数学等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①深入掌握麦克斯韦旋度方程的有限差分法基本原理及其在二维平面磁场仿真中的具体实施步骤;②学习如何利用Matlab进行电磁场问题的建模、编程求解与结果可视化;③为后续开展更复杂的电磁兼容、天线设计或光子晶体等领域的数值模拟研究奠定坚实的技术基础。; 阅读建议:建议读者结合经典电磁场理论教材,透彻理解麦克斯韦方程组的物理内涵,然后循序渐进地跟进文中的差分格式推导过程,务必动手复现并调试所提供的Matlab代码,通过调整参数观察仿真结果的变化,从而深刻领悟数值方法的实质与应用技巧。

5,943

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧