Delphi下Treeview控件基于节点编号的访问1
有时我们需要保存和重建treeview控件,本文提供一种方法,通过以树结构节点的编号访问树结构,该控件主要提供的方法如下:   
   function GetGlobeNumCode(inNode:TTreeNode):String;
   功能:返回当前节点的编号,编号规则见源码内说明。
   function LocatOrGenerateNode(inNumCode:String):TTreeNode;
   功能:以编号返回节点,假如节点的父节点和它的前继兄弟节点不存在,该方法会创建它们,名称为'Temp',当然假如已经存在,就不执行创建工作。
   通过以上两个函数,这样我们就可以不加限制的创建和访问节点。该控件在我以前开发的,现在提供给大家做一个参考,希望能对你有帮助。
源码:
// ***********************************************
//
//  用于实现对TreeView控件的树结构的保存和重建
//  编写该控件主要用于实现对行政文件等具有树的层次结构的对象
//  实现保存和显示
//  节点编号规则:
//               + *****  ->1
//                 + ***** ->1.1
//                   + ***** ->1.1.1
//                 + ***** ->1.2
//  作者:Jack
//  最后修改日期:2002-12-24
//
//  **********************************************
unit CtrlTree;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls;
type
  TCtrlTree = class(TTreeView)
  private
    { Private declarations }
    function GetPosAtBound(inString:String;inStart:Integer):Integer;
    function GetTheLastPointPos(inString:String):Integer;
  protected
    { Protected declarations }
  public
    { Public declarations }
    function GetNumInSameLevel(inNode:TTreeNode):Integer;
    function GetGlobeNumCode(inNode:TTreeNode):String;
    function GetParent(inNumCode:String):TTreeNode;
    function LocateNodeInLevel(parNode:TTReeNode;LevelCode:integer):TTReeNode;
  published
    { Published declarations }
    function LocatOrGenerateNode(inNumCode:String):TTreeNode;
    function InsertAsFinalChild(inString:String;inNode:TTreeNode):TTReeNode;
    function InsertAsPreviousSibling(inString:String;inNode:TTreeNode):TTReeNode;
  end;
procedure Register;
implementation
procedure Register;
begin
  RegisterComponents('Standard', [TCtrlTree]);
end;
{ TCtrTree }
function TCtrlTree.GetNumInSameLevel(inNode: TTreeNode): integer;
{功能:产生已存在节点在兄弟节点层中对应的编号,从1起编
 入口参数:inCode:TTreeNode节点
 返回:同层编号
}
var
   i:integer;
   tmp:TTreeNode;
begin
   i:=0;
   tmp:=inNode;
   while tmp<>nil do
   begin
        tmp:=tmp.getPrevSibling;
        i:=i+1;
   end;
   Result:=i;
end;
function TCtrlTree.GetGlobeNumCode(inNode: TTreeNode): string;
{功能:产生已存在节点对应的全局编号
 入口参数:inCode:TTreeNode节点
 返回:全局编号
}
var
   nocode:string;
   tmp:TTreeNode;
begin
   tmp:=inNode;
   nocode:=IntToStr(GetNumInSameLevel(tmp));
   while tmp.Level<>0 do
   begin
         tmp:=tmp.Parent;
         nocode:=inttostr(GetNumInSameLevel(tmp))+'.'+nocode;
   end;
   Result:=nocode;
end;
function TCtrlTree.LocatOrGenerateNode(inNumCode: String): TTreeNode;
{功能:根据提供的全局编号进行定位,如路径不全,则创建路径
       在定位过程产生的节点的Text为Temp
       最终返回对应于全局编号的子节点
 入口参数:inNumCode:String为全局编号
 返回:全局编号对应的字节点
}
var
    i,j:Cardinal;
    NumInLevel:integer;
    tmp:TTreeNode;
    par:TTreeNode;
begin
    tmp:=nil;
    i:=1;
    while i<=StrLen(PChar(inNumCode)) do
    begin
        //得到下一个点号的开始位
        j:=GetPosAtBound(inNumCode,i);
        //得到在兄弟节点中的排行数
        NumInLevel:=StrToInt(Copy(inNumCode,i,j-i+1));
        //定位父节点
        par:=GetParent(Copy(inNumCode,1,j));
        //得到对应的节点
        tmp:=LocateNodeInLevel(par,numInLevel);
        i:=j+2;
    end;
    Result:=tmp;
end;
function TCtrlTree.GetParent(inNumCode: String): TTreeNode;
{功能:根据提供的全局编号找到对应的父节点
       如果是第一层的节点,则父节点为nil
 入口参数:inNumCode:String为全局编号
 返回:全局编号对应的父节点
}
var
    GoStep:integer;
    i:integer;
    j:integer;
    k:integer;
    SearChInNode:TTReeNode;
    ReturnNode:TTReeNode;
begin
    //是第一层节点,返回nil;
    k:=GetTheLastPointPos(inNumCode);
    if k=0 then
    begin
         Result:=nil;
         Exit;
    end;
    //是第二层或第二层以上节点
    i:=1;
    SearchInNode:=Items.GetFirstNode;
    while i < GetTheLastPointPos(inNumCode) do
    begin
       j:=GetPosAtBound(inNumCode,i);
       GoStep:=StrToInt(Copy(inNumCode,i,j-i+1));
       if i=1 then //在第一层节点中搜索
       begin
          ReturnNode:=SearchInNode;
          for k:=1 to GoStep-1 do
                ReturnNode:=ReturnNode.getNextSibling;
       end
       else //在第二层或第二层以上节点中搜索
       begin
          GoStep:=StrToInt(Copy(inNumCode,i,j-i+1));
          ReturnNode:=SearchInNode.Item[GoStep-1];
       end;
       SearchInNode:=ReturnNode;
       i:=j+2
    end;
    Result:=SearchInNode;
end;
function TCtrlTree.LocateNodeInLevel(parNode: TTReeNode;LevelCode: integer): TTReeNode;
{功能:根据父节点以及在兄弟节点中的编号找到对应的节点
       如果要创建兄弟及自己,则新创建的节点的Text为Temp
 入口参数:parNode: TTReeNode为父节点
           LevelCode: integer为编号
 返回:在parNode中编号为LevelCode的孩子节点
}
var
    i:integer;
    j:integer;
    tmp:TTreeNode;
    tmps:TTreeNode;
begin
    //父节点为空,是第一层节点
    tmp:=nil;
    if parNode=nil then
    begin
        i:=1;
        tmps:=Items.GetFirstNode;
        while (tmps<>nil) and (i<=LevelCode) do
        begin
             tmp:=tmps;
             tmps:=tmps.getNextSibling;
             i:=i+1;
        end;
        i:=i-1;
        for j:=1 to LevelCode-i do
             tmp:=Items.AddChild(nil,'Temp');
        Result:=tmp;
    end
    else //父节点不为空,正常处理
    begin
        if parNode.Count<LevelCode then
            for i:= 1 to LevelCode-parNode.Count do
                Items.AddChild(parNode,'Temp');
        Result:=parNode.Item[LevelCode-1];
    end;
end;
function TCtrlTree.GetPosAtBound(inString: String;inStart:Integer): Integer;
{功能:根据起始位置找到下一个'.'的前一个位置
 入口参数:inString: String节点编号
           inStart: Integer当前处理层次的起始位置
 返回:当前处理层次的结束位置
}
var
     tmp:Char;
     pos:integer;
begin
     pos:=inStart+1;
     while pos <= Integer(StrLen(PChar(inString))) do
     begin
         tmp:=inString[pos];
         if tmp='.' then
             Break
         else
             pos:=pos+1;
     end;
     Result:=pos-1;
end;
function TCtrlTree.GetTheLastPointPos(inString: String): Integer;
{功能:找到编号中最后的'.'的位置
 入口参数:inString: String为节点编号
 返回:节点编号中最后的'.'的位置
}
var
     tmp:Char;
     pos:integer;
begin
     pos:=Integer(StrLen(PChar(inString)));
     while pos>=1 do
     begin
        tmp:=inString[pos];
        if tmp='.' then
            Break
        else
            pos:=pos-1;
     end;
     Result:=pos;
end;
function TCtrlTree.InsertAsFinalChild(inString: String; inNode: TTreeNode):TTReeNode;
{功能:为当前节点插入一个孩子节点,位置为最后
 入口参数:inString: String为节点编号为待插入节点的字符串
           inNode: TTreeNode,当前节点
}
begin
    Result:=Items.AddChild(inNode,inString);
end;
function TCtrlTree.InsertAsPreviousSibling(inString: String;
  inNode: TTreeNode):TTReeNode;
{功能:为当前节点插入一个前导的兄弟节点
 入口参数:inString: String为节点编号为待插入节点的字符串
           inNode: TTreeNode,当前节点
}
begin
    Result:=Items.AddChildFirst(inNode,inString);
end;
end.
Delphi下Treeview控件基于节点编号的访问1的更多相关文章
- Delphi下Treeview控件基于节点编号的访问
		有时我们需要保存和重建treeview控件,本文提供一种方法,通过以树结构节点的编号访问树结构,该控件主要提供的方法如下: function GetGlobeNumCode(inNode:T ... 
- C# treeview控件部分节点添加checkbox
		一.先初始化treeview this.treeView1.CheckBoxes = true; this.treeView1.ShowLines = false; this.treeView1.Dr ... 
- 在DELPHI中用TreeView控件从数据库中动态装载信息
		1.PInfo表结构ID VARCHAR(50)FullName VARCHAR(50)ParentID VARCHAR(50) 2.Unit文件unit Info; interface uses ... 
- 【ASP.NET 进阶】TreeView控件学习
		这几天上班没事做,也不好打酱油,学点没接触过的新东西吧,基本了解了下TreeView控件. TreeView 控件用于在树结构中显示分层数据,例如目录或文件目录等. 下面看代码吧: 1.效果图 2.静 ... 
- TreeView控件概述、属性与方法
		1.作用:用于显示Node结点的分层列表.2.添加到控件箱菜单命令:工程 | 部件,在部件对话框中选择:Microsoft Windows Common Controls 6.03.TreeView控 ... 
- C# TreeView 控件的综合使用方法
		1.概述 该篇文章开发使用的语言c#,环境visualstudio2010,sql数据库.主要内容包括: (1)treeView控件添加根节点.子节点的基本方法,节点的删除. (2)把treeView ... 
- 基于Treeview控件遍历本地磁盘
		一.前言 Treeview控件常用于遍历本地文件信息,通常与Datagridview与ImageList搭配.ImageList控件用于提供小图片给TreeView控件,DatagridView通常显 ... 
- C#TreeView控件遍历文件夹下所有子文件夹以及文件
		一直对递归的理解不深刻,有时候觉得很简单,可是用起来总会出错.这里需要在TreeView控件里显示一个文件夹下的所有目录以及文件,毫无意外的需要用到递归. 一开始,想到用递归写一个生成每一个节点(Tr ... 
- Treeview控件的Node节点延迟加载
		Treeview控件是一个很常用的控件,用于展示资源或者组织结构的时候很方便,通常会在系统启动时进行资源的加载和节点目录的初始化,但在资源较多和层级较深的情况下,所有节点加载出来会耗费太多时间,影响体 ... 
随机推荐
- Parameter 0 of method redisTemplate in org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration required a bean of type 'org.springframework.data.redis.connection.RedisConnectionFactor
			Error starting ApplicationContext. To display the conditions report re-run your application with 'de ... 
- effective Java 第三版学习笔记
			创建对象类型的 1,静态工厂方法代替构造器 静态工厂方法有名称,不容易混乱他的作用 不必再每次调用他的时候创建实例,创建实例的代价是高的,可以重复利用缓存的对象 静态工厂甚至能返回子类对象,例如在接口 ... 
- 在Vue中加入国际化(i18n)中英文功能
			1.npm安装方法 npm install vue-i18n --save 2.在src资源文件下创建文件夹i18n,i18n下面创建index.js文件,引入VueI18n和导入语言包(按开发需求可 ... 
- svg创建分支
			是这样的 我之前的项目上传到svn上一直没有开过分支,今天其中的一个项目改动会比较大,想创建一个分支,在此分支上修改(目的是改动如果比较大,不想影响原来主干上的分支) 首先打开我们的项目存放的文件:右 ... 
- faster-rcnn CUDA8.0编译错误
			之前编译Faster-RCNN的时候用的都是CUDA7.5,最近换了机器,变成了CUDA8.0,果然编译出现错误了…… 参考下面这篇博客解决了问题: http://blog.csdn.net/kexi ... 
- 走进JavaWeb技术世界9:Java日志系统的诞生与发展
			本文转自[码农翻身] ## 一个著名的日志系统是怎么设计出来的? # 1前言 Java帝国在诞生之初就提供了集合.线程.IO.网络等常用功能,从C和C++领地那里吸引了大量程序员过来加盟,但是却有意无 ... 
- SpringCloud介绍及入门一
			springcloud是什么 基于spring boot实现的服务治理工具包,管理和协微服务 把别人的东西拿来组合在一起,形成各种组件 微服务协调者[service registtry注册中心 Eur ... 
- chrome-添加JSON-handler插件
			1.访问http://jsonhandle.sinaapp.com/下载 2.谷歌访问 chrome://extensions/ 然后找到你下载的JSON-handle_0.5.2.crx文件,直 ... 
- Leetcode题目437:路径总和III(递归-简单)
			题目描述: 给定一个二叉树,它的每个结点都存放着一个整数值. 找出路径和等于给定数值的路径总数. 路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点). 二 ... 
- CodeForces - 1175D Array Splitting(数组划分+后缀和+贪心)
			You are given an array a1,a2,…,ana1,a2,…,an and an integer kk. You are asked to divide this array in ... 
